Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8616e531 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Directly map and read soc hardware revision efuse"

parents 583aeee9 60532fc0
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -130,6 +130,13 @@ Optional Properties:
				mask   - mask for the relevant bits in the efuse register.
				shift  - number of bits to right shift to get the disable_gpu
				fuse bit value.

- qcom,soc-hw-rev-efuse:	SOC hardware revision fuse information in the format
				<offset bit_position mask>
				offset - offset of the efuse register from the base.
				bit_position - hardware revision starting bit in the efuse register.
				mask - mask for the relevant bits in the efuse register.

- qcom,highest-bank-bit:
				Specify the bit of the highest DDR bank. This
				is programmed into protected registers and also
@@ -230,7 +237,7 @@ Properties:
		Defines a SOC hardware revision.

Properties:
- reg:
-  qcom,soc-hw-revision:
		Identifier for the hardware revision - must match the value read
		from the hardware.
- qcom,chipid:
+47 −51
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <linux/input.h>
#include <linux/io.h>
#include <soc/qcom/scm.h>
#include <linux/nvmem-consumer.h>

#include <linux/msm-bus-board.h>
#include <linux/msm-bus.h>
@@ -747,62 +746,30 @@ static struct {
			"qcom,gpu-quirk-limit-uche-gbif-rw" },
};

#if defined(CONFIG_NVMEM) && defined(CONFIG_QCOM_QFPROM)
static struct device_node *
adreno_get_soc_hw_revision_node(struct platform_device *pdev)
adreno_get_soc_hw_revision_node(struct adreno_device *adreno_dev,
	struct platform_device *pdev)
{
	struct device_node *node, *child;
	struct nvmem_cell *cell;
	ssize_t len;
	u32 *buf, hw_rev, rev;
	unsigned int rev;

	node = of_find_node_by_name(pdev->dev.of_node, "qcom,soc-hw-revisions");
	if (node == NULL)
		goto err;

	/* read the soc hw revision and select revision node */
	cell = nvmem_cell_get(&pdev->dev, "minor_rev");
	if (IS_ERR_OR_NULL(cell)) {
		if (PTR_ERR(cell) == -EPROBE_DEFER)
			return (void *)cell;

		KGSL_CORE_ERR("Unable to get nvmem cell: ret=%ld\n",
				PTR_ERR(cell));
		goto err;
	}

	buf = nvmem_cell_read(cell, &len);
	nvmem_cell_put(cell);

	if (IS_ERR_OR_NULL(buf)) {
		KGSL_CORE_ERR("Unable to read nvmem cell: ret=%ld\n",
				PTR_ERR(buf));
		goto err;
	}

	hw_rev = *buf;
	kfree(buf);
		return NULL;

	for_each_child_of_node(node, child) {
		if (of_property_read_u32(child, "reg", &rev))
		if (of_property_read_u32(child, "qcom,soc-hw-revision", &rev))
			continue;

		if (rev == hw_rev)
		if (rev == adreno_dev->soc_hw_rev)
			return child;
	}

err:
	/* fall back to parent node */
	return pdev->dev.of_node;
}
#else
static struct device_node *
adreno_get_soc_hw_revision_node(struct platform_device *pdev)
{
	return pdev->dev.of_node;
	KGSL_DRV_WARN(KGSL_DEVICE(adreno_dev),
		"No matching SOC HW revision found for efused HW rev=%u\n",
		adreno_dev->soc_hw_rev);
	return NULL;
}
#endif


static int adreno_update_soc_hw_revision_quirks(
		struct adreno_device *adreno_dev, struct platform_device *pdev)
@@ -810,9 +777,9 @@ static int adreno_update_soc_hw_revision_quirks(
	struct device_node *node;
	int i;

	node = adreno_get_soc_hw_revision_node(pdev);
	if (IS_ERR(node))
		return PTR_ERR(node);
	node = adreno_get_soc_hw_revision_node(adreno_dev, pdev);
	if (node == NULL)
		node = pdev->dev.of_node;

	/* get chip id, fall back to parent if revision node does not have it */
	if (of_property_read_u32(node, "qcom,chipid", &adreno_dev->chipid))
@@ -1131,6 +1098,36 @@ static void adreno_cx_dbgc_probe(struct kgsl_device *device)
		KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n");
}

static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev)
{
	unsigned int val;
	unsigned int soc_hw_rev[3];
	int ret;

	if (of_property_read_u32_array(
		KGSL_DEVICE(adreno_dev)->pdev->dev.of_node,
		"qcom,soc-hw-rev-efuse", soc_hw_rev, 3))
		return;

	ret = adreno_efuse_map(adreno_dev);
	if (ret) {
		KGSL_CORE_ERR(
			"Unable to map hardware revision fuse: ret=%d\n", ret);
		return;
	}

	ret = adreno_efuse_read_u32(adreno_dev, soc_hw_rev[0], &val);
	adreno_efuse_unmap(adreno_dev);

	if (ret) {
		KGSL_CORE_ERR(
			"Unable to read hardware revision fuse: ret=%d\n", ret);
		return;
	}

	adreno_dev->soc_hw_rev = (val >> soc_hw_rev[1]) & soc_hw_rev[2];
}

static bool adreno_is_gpu_disabled(struct adreno_device *adreno_dev)
{
	unsigned int row0;
@@ -1179,11 +1176,10 @@ static int adreno_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	status = adreno_update_soc_hw_revision_quirks(adreno_dev, pdev);
	if (status) {
		device->pdev = NULL;
		return status;
	}
	/* Identify SOC hardware revision to be used */
	adreno_efuse_read_soc_hw_rev(adreno_dev);

	adreno_update_soc_hw_revision_quirks(adreno_dev, pdev);

	/* Get the chip ID from the DT and set up target specific parameters */
	adreno_identify_gpu(adreno_dev);
+2 −0
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ enum gpu_coresight_sources {
 * @gpuhtw_llc_slice: GPU pagetables system cache slice descriptor
 * @gpuhtw_llc_slice_enable: To enable the GPUHTW system cache slice or not
 * @zap_loaded: Used to track if zap was successfully loaded or not
 * @soc_hw_rev: Indicate which SOC hardware revision to use
 */
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -537,6 +538,7 @@ struct adreno_device {
	void *gpuhtw_llc_slice;
	bool gpuhtw_llc_slice_enable;
	unsigned int zap_loaded;
	unsigned int soc_hw_rev;
};

/**