Loading Documentation/devicetree/bindings/gpu/adreno.txt +6 −3 Original line number Diff line number Diff line Loading @@ -5,14 +5,17 @@ Qualcomm Technologies, Inc. Adreno GPU Required properties: - label: A string used as a descriptive name for the device. - compatible: Must be "qcom,kgsl-3d0" and "qcom,kgsl-3d" - reg: Specifies the register base address and size. The second interval specifies the shader memory base address and size. - reg: Specifies the register base address and size, the shader memory base address and size (if it exists), and the base address and size of the CX_DBGC block (if it exists). - reg-names: Resource names used for the physical address of device registers and shader memory. "kgsl_3d0_reg_memory" gives the physical address and length of device registers while "kgsl_3d0_shader_memory" gives physical address and length of device shader memory. If specified, "qfprom_memory" gives the range for the efuse registers used for various configuration options. registers used for various configuration options. If specified, "kgsl_3d0_cx_dbgc_memory" gives the physical address and length of the CX DBGC block. - interrupts: Interrupt mapping for GPU IRQ. - interrupt-names: String property to describe the name of the interrupt. - qcom,id: An integer used as an identification number for the device. Loading drivers/gpu/msm/adreno.c +76 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/of_device.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/io.h> #include <soc/qcom/scm.h> #include <linux/msm-bus-board.h> Loading Loading @@ -1033,6 +1034,28 @@ adreno_ocmem_free(struct adreno_device *adreno_dev) } #endif static void adreno_cx_dbgc_probe(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct resource *res; res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "kgsl_3d0_cx_dbgc_memory"); if (res == NULL) return; adreno_dev->cx_dbgc_base = res->start - device->reg_phys; adreno_dev->cx_dbgc_len = resource_size(res); adreno_dev->cx_dbgc_virt = devm_ioremap(device->dev, device->reg_phys + adreno_dev->cx_dbgc_base, adreno_dev->cx_dbgc_len); if (adreno_dev->cx_dbgc_virt == NULL) KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n"); } static int adreno_probe(struct platform_device *pdev) { struct kgsl_device *device; Loading Loading @@ -1083,6 +1106,9 @@ static int adreno_probe(struct platform_device *pdev) return status; } /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); /* * qcom,iommu-secure-id is used to identify MMUs that can handle secure * content but that is only part of the story - the GPU also has to be Loading Loading @@ -2792,6 +2818,56 @@ static void adreno_gmu_regread(struct kgsl_device *device, rmb(); } bool adreno_is_cx_dbgc_register(struct kgsl_device *device, unsigned int offsetwords) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); return adreno_dev->cx_dbgc_virt && (offsetwords >= (adreno_dev->cx_dbgc_base >> 2)) && (offsetwords < (adreno_dev->cx_dbgc_base + adreno_dev->cx_dbgc_len) >> 2); } void adreno_cx_dbgc_regread(struct kgsl_device *device, unsigned int offsetwords, unsigned int *value) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int cx_dbgc_offset; if (!adreno_is_cx_dbgc_register(device, offsetwords)) return; cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base; *value = __raw_readl(adreno_dev->cx_dbgc_virt + cx_dbgc_offset); /* * ensure this read finishes before the next one. * i.e. act like normal readl() */ rmb(); } void adreno_cx_dbgc_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int cx_dbgc_offset; if (!adreno_is_cx_dbgc_register(device, offsetwords)) return; cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base; trace_kgsl_regwrite(device, offsetwords, value); /* * ensure previous writes post before this one, * i.e. act like normal writel() */ wmb(); __raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset); } /** * adreno_waittimestamp - sleep while waiting for the specified timestamp * @device - pointer to a KGSL device structure Loading drivers/gpu/msm/adreno.h +10 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,9 @@ struct adreno_device { unsigned int chipid; unsigned long gmem_base; unsigned long gmem_size; unsigned long cx_dbgc_base; unsigned int cx_dbgc_len; void __iomem *cx_dbgc_virt; const struct adreno_gpu_core *gpucore; struct adreno_firmware fw[2]; size_t gpmu_cmds_size; Loading Loading @@ -1063,6 +1066,13 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset, unsigned int *val); void adreno_efuse_unmap(struct adreno_device *adreno_dev); bool adreno_is_cx_dbgc_register(struct kgsl_device *device, unsigned int offset); void adreno_cx_dbgc_regread(struct kgsl_device *adreno_device, unsigned int offsetwords, unsigned int *value); void adreno_cx_dbgc_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value); #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ { \ Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +6 −3 Original line number Diff line number Diff line Loading @@ -5,14 +5,17 @@ Qualcomm Technologies, Inc. Adreno GPU Required properties: - label: A string used as a descriptive name for the device. - compatible: Must be "qcom,kgsl-3d0" and "qcom,kgsl-3d" - reg: Specifies the register base address and size. The second interval specifies the shader memory base address and size. - reg: Specifies the register base address and size, the shader memory base address and size (if it exists), and the base address and size of the CX_DBGC block (if it exists). - reg-names: Resource names used for the physical address of device registers and shader memory. "kgsl_3d0_reg_memory" gives the physical address and length of device registers while "kgsl_3d0_shader_memory" gives physical address and length of device shader memory. If specified, "qfprom_memory" gives the range for the efuse registers used for various configuration options. registers used for various configuration options. If specified, "kgsl_3d0_cx_dbgc_memory" gives the physical address and length of the CX DBGC block. - interrupts: Interrupt mapping for GPU IRQ. - interrupt-names: String property to describe the name of the interrupt. - qcom,id: An integer used as an identification number for the device. Loading
drivers/gpu/msm/adreno.c +76 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/of_device.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/io.h> #include <soc/qcom/scm.h> #include <linux/msm-bus-board.h> Loading Loading @@ -1033,6 +1034,28 @@ adreno_ocmem_free(struct adreno_device *adreno_dev) } #endif static void adreno_cx_dbgc_probe(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct resource *res; res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "kgsl_3d0_cx_dbgc_memory"); if (res == NULL) return; adreno_dev->cx_dbgc_base = res->start - device->reg_phys; adreno_dev->cx_dbgc_len = resource_size(res); adreno_dev->cx_dbgc_virt = devm_ioremap(device->dev, device->reg_phys + adreno_dev->cx_dbgc_base, adreno_dev->cx_dbgc_len); if (adreno_dev->cx_dbgc_virt == NULL) KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n"); } static int adreno_probe(struct platform_device *pdev) { struct kgsl_device *device; Loading Loading @@ -1083,6 +1106,9 @@ static int adreno_probe(struct platform_device *pdev) return status; } /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); /* * qcom,iommu-secure-id is used to identify MMUs that can handle secure * content but that is only part of the story - the GPU also has to be Loading Loading @@ -2792,6 +2818,56 @@ static void adreno_gmu_regread(struct kgsl_device *device, rmb(); } bool adreno_is_cx_dbgc_register(struct kgsl_device *device, unsigned int offsetwords) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); return adreno_dev->cx_dbgc_virt && (offsetwords >= (adreno_dev->cx_dbgc_base >> 2)) && (offsetwords < (adreno_dev->cx_dbgc_base + adreno_dev->cx_dbgc_len) >> 2); } void adreno_cx_dbgc_regread(struct kgsl_device *device, unsigned int offsetwords, unsigned int *value) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int cx_dbgc_offset; if (!adreno_is_cx_dbgc_register(device, offsetwords)) return; cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base; *value = __raw_readl(adreno_dev->cx_dbgc_virt + cx_dbgc_offset); /* * ensure this read finishes before the next one. * i.e. act like normal readl() */ rmb(); } void adreno_cx_dbgc_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int cx_dbgc_offset; if (!adreno_is_cx_dbgc_register(device, offsetwords)) return; cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base; trace_kgsl_regwrite(device, offsetwords, value); /* * ensure previous writes post before this one, * i.e. act like normal writel() */ wmb(); __raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset); } /** * adreno_waittimestamp - sleep while waiting for the specified timestamp * @device - pointer to a KGSL device structure Loading
drivers/gpu/msm/adreno.h +10 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,9 @@ struct adreno_device { unsigned int chipid; unsigned long gmem_base; unsigned long gmem_size; unsigned long cx_dbgc_base; unsigned int cx_dbgc_len; void __iomem *cx_dbgc_virt; const struct adreno_gpu_core *gpucore; struct adreno_firmware fw[2]; size_t gpmu_cmds_size; Loading Loading @@ -1063,6 +1066,13 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset, unsigned int *val); void adreno_efuse_unmap(struct adreno_device *adreno_dev); bool adreno_is_cx_dbgc_register(struct kgsl_device *device, unsigned int offset); void adreno_cx_dbgc_regread(struct kgsl_device *adreno_device, unsigned int offsetwords, unsigned int *value); void adreno_cx_dbgc_regwrite(struct kgsl_device *device, unsigned int offsetwords, unsigned int value); #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ { \ Loading