Loading Documentation/devicetree/bindings/gpu/adreno.txt +8 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading drivers/gpu/msm/adreno.c +47 −51 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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) Loading @@ -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)) Loading Loading @@ -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; Loading Loading @@ -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); Loading drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; }; /** Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +8 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: Loading
drivers/gpu/msm/adreno.c +47 −51 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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) Loading @@ -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)) Loading Loading @@ -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; Loading Loading @@ -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); Loading
drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; }; /** Loading