Loading Documentation/devicetree/bindings/gpu/adreno.txt +5 −3 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ 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 shader memory base address and size (if it exists), and the base address and size of the CX_DBGC block (if it exists). base address and size (if it exists), base address and size of the CX_DBGC block (if it exists), and the base address and size of the CX_MISC 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 Loading @@ -15,7 +16,8 @@ Required properties: specified, "qfprom_memory" gives the range for the efuse registers used for various configuration options. If specified, "kgsl_3d0_cx_dbgc_memory" gives the physical address and length of the CX DBGC block. of the CX DBGC block. If specified, "cx_misc" gives the physical address and length of the CX_MISC 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/a6xx_reg.h +11 −0 Original line number Diff line number Diff line Loading @@ -1113,5 +1113,16 @@ #define A6XX_RGMU_CX_PCC_STATUS 0x1F83C #define A6XX_RGMU_CX_PCC_DEBUG 0x1F83D /* GPU CX_MISC registers */ #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x1 #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x2 #define A6XX_LLC_NUM_GPU_SCIDS 5 #define A6XX_GPU_LLC_SCID_NUM_BITS 5 #define A6XX_GPU_LLC_SCID_MASK \ ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1) #define A6XX_GPUHTW_LLC_SCID_SHIFT 25 #define A6XX_GPUHTW_LLC_SCID_MASK \ (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT) #endif /* _A6XX_REG_H */ drivers/gpu/msm/adreno.c +67 −0 Original line number Diff line number Diff line Loading @@ -1224,6 +1224,22 @@ static void adreno_cx_dbgc_probe(struct kgsl_device *device) KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n"); } static void adreno_cx_misc_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, "cx_misc"); if (res == NULL) return; adreno_dev->cx_misc_len = resource_size(res); adreno_dev->cx_misc_virt = devm_ioremap(device->dev, res->start, adreno_dev->cx_misc_len); } static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev) { unsigned int val; Loading Loading @@ -1356,6 +1372,9 @@ static int adreno_probe(struct platform_device *pdev) /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); /* Probe for the optional CX_MISC block */ adreno_cx_misc_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 @@ -3380,6 +3399,54 @@ void adreno_cx_dbgc_regwrite(struct kgsl_device *device, __raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset); } void adreno_cx_misc_regread(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int *value) { unsigned int cx_misc_offset; cx_misc_offset = (offsetwords << 2); if (!adreno_dev->cx_misc_virt || (cx_misc_offset >= adreno_dev->cx_misc_len)) return; *value = __raw_readl(adreno_dev->cx_misc_virt + cx_misc_offset); /* * ensure this read finishes before the next one. * i.e. act like normal readl() */ rmb(); } void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int value) { unsigned int cx_misc_offset; cx_misc_offset = (offsetwords << 2); if (!adreno_dev->cx_misc_virt || (cx_misc_offset >= adreno_dev->cx_misc_len)) return; /* * ensure previous writes post before this one, * i.e. act like normal writel() */ wmb(); __raw_writel(value, adreno_dev->cx_misc_virt + cx_misc_offset); } void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int mask, unsigned int bits) { unsigned int val = 0; adreno_cx_misc_regread(adreno_dev, offsetwords, &val); val &= ~mask; adreno_cx_misc_regwrite(adreno_dev, offsetwords, val | bits); } /** * adreno_waittimestamp - sleep while waiting for the specified timestamp * @device - pointer to a KGSL device structure Loading drivers/gpu/msm/adreno.h +12 −0 Original line number Diff line number Diff line Loading @@ -441,6 +441,8 @@ enum gpu_coresight_sources { * @chipid: Chip ID specific to the GPU * @gmem_base: Base physical address of GMEM * @gmem_size: GMEM size * @cx_misc_len: Length of the CX MISC register block * @cx_misc_virt: Pointer where the CX MISC block is mapped * @gpucore: Pointer to the adreno_gpu_core structure * @pfp_fw: Buffer which holds the pfp ucode * @pfp_fw_size: Size of pfp ucode buffer Loading Loading @@ -521,6 +523,8 @@ struct adreno_device { unsigned long cx_dbgc_base; unsigned int cx_dbgc_len; void __iomem *cx_dbgc_virt; unsigned int cx_misc_len; void __iomem *cx_misc_virt; const struct adreno_gpu_core *gpucore; struct adreno_firmware fw[2]; size_t gpmu_cmds_size; Loading Loading @@ -1169,6 +1173,14 @@ 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); void adreno_cx_misc_regread(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int *value); void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int value); void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int mask, unsigned int bits); #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ Loading drivers/gpu/msm/adreno_a6xx.c +7 −48 Original line number Diff line number Diff line Loading @@ -32,18 +32,6 @@ #define MIN_HBB 13 #define A6XX_LLC_NUM_GPU_SCIDS 5 #define A6XX_GPU_LLC_SCID_NUM_BITS 5 #define A6XX_GPU_LLC_SCID_MASK \ ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1) #define A6XX_GPUHTW_LLC_SCID_SHIFT 25 #define A6XX_GPUHTW_LLC_SCID_MASK \ (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT) #define A6XX_GPU_CX_REG_BASE 0x509E000 #define A6XX_GPU_CX_REG_SIZE 0x1000 static const struct adreno_vbif_data a630_vbif[] = { {A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009}, {A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3}, Loading Loading @@ -1594,24 +1582,6 @@ static void a6xx_err_callback(struct adreno_device *adreno_dev, int bit) } } /* GPU System Cache control registers */ #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x4 #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x8 static inline void _reg_rmw(void __iomem *regaddr, unsigned int mask, unsigned int bits) { unsigned int val = 0; val = __raw_readl(regaddr); /* Make sure the above read completes before we proceed */ rmb(); val &= ~mask; __raw_writel(val | bits, regaddr); /* Make sure the above write posts before we proceed*/ wmb(); } /* * a6xx_llc_configure_gpu_scid() - Program the sub-cache ID for all GPU blocks * @adreno_dev: The adreno device pointer Loading @@ -1631,13 +1601,9 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev) kgsl_regrmw(KGSL_DEVICE(adreno_dev), A6XX_GBIF_SCACHE_CNTL1, A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val); } else { void __iomem *gpu_cx_reg; gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, adreno_cx_misc_regrmw(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val); iounmap(gpu_cx_reg); } } Loading @@ -1648,7 +1614,6 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev) static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) { uint32_t gpuhtw_scid; void __iomem *gpu_cx_reg; /* * On A640, the GPUHTW SCID is configured via a NoC override in the Loading @@ -1659,11 +1624,10 @@ static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) gpuhtw_scid = adreno_llc_get_scid(adreno_dev->gpuhtw_llc_slice); gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, adreno_cx_misc_regrmw(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, A6XX_GPUHTW_LLC_SCID_MASK, gpuhtw_scid << A6XX_GPUHTW_LLC_SCID_SHIFT); iounmap(gpu_cx_reg); } /* Loading @@ -1672,8 +1636,6 @@ static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) */ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) { void __iomem *gpu_cx_reg; /* * Attributes override through GBIF is not supported with MMU-500. * Attributes are used as configured through SMMU pagetable entries. Loading @@ -1687,11 +1649,8 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) * writenoallocoverrideen=1 * write-no-alloc=1 - Do not allocates lines on write miss */ gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); __raw_writel(0x3, gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0); /* Make sure the above write posts before we proceed*/ wmb(); iounmap(gpu_cx_reg); adreno_cx_misc_regwrite(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0x3); } static const char *fault_block[8] = { Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +5 −3 Original line number Diff line number Diff line Loading @@ -6,8 +6,9 @@ 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 shader memory base address and size (if it exists), and the base address and size of the CX_DBGC block (if it exists). base address and size (if it exists), base address and size of the CX_DBGC block (if it exists), and the base address and size of the CX_MISC 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 Loading @@ -15,7 +16,8 @@ Required properties: specified, "qfprom_memory" gives the range for the efuse registers used for various configuration options. If specified, "kgsl_3d0_cx_dbgc_memory" gives the physical address and length of the CX DBGC block. of the CX DBGC block. If specified, "cx_misc" gives the physical address and length of the CX_MISC 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/a6xx_reg.h +11 −0 Original line number Diff line number Diff line Loading @@ -1113,5 +1113,16 @@ #define A6XX_RGMU_CX_PCC_STATUS 0x1F83C #define A6XX_RGMU_CX_PCC_DEBUG 0x1F83D /* GPU CX_MISC registers */ #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x1 #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x2 #define A6XX_LLC_NUM_GPU_SCIDS 5 #define A6XX_GPU_LLC_SCID_NUM_BITS 5 #define A6XX_GPU_LLC_SCID_MASK \ ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1) #define A6XX_GPUHTW_LLC_SCID_SHIFT 25 #define A6XX_GPUHTW_LLC_SCID_MASK \ (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT) #endif /* _A6XX_REG_H */
drivers/gpu/msm/adreno.c +67 −0 Original line number Diff line number Diff line Loading @@ -1224,6 +1224,22 @@ static void adreno_cx_dbgc_probe(struct kgsl_device *device) KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n"); } static void adreno_cx_misc_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, "cx_misc"); if (res == NULL) return; adreno_dev->cx_misc_len = resource_size(res); adreno_dev->cx_misc_virt = devm_ioremap(device->dev, res->start, adreno_dev->cx_misc_len); } static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev) { unsigned int val; Loading Loading @@ -1356,6 +1372,9 @@ static int adreno_probe(struct platform_device *pdev) /* Probe for the optional CX_DBGC block */ adreno_cx_dbgc_probe(device); /* Probe for the optional CX_MISC block */ adreno_cx_misc_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 @@ -3380,6 +3399,54 @@ void adreno_cx_dbgc_regwrite(struct kgsl_device *device, __raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset); } void adreno_cx_misc_regread(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int *value) { unsigned int cx_misc_offset; cx_misc_offset = (offsetwords << 2); if (!adreno_dev->cx_misc_virt || (cx_misc_offset >= adreno_dev->cx_misc_len)) return; *value = __raw_readl(adreno_dev->cx_misc_virt + cx_misc_offset); /* * ensure this read finishes before the next one. * i.e. act like normal readl() */ rmb(); } void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int value) { unsigned int cx_misc_offset; cx_misc_offset = (offsetwords << 2); if (!adreno_dev->cx_misc_virt || (cx_misc_offset >= adreno_dev->cx_misc_len)) return; /* * ensure previous writes post before this one, * i.e. act like normal writel() */ wmb(); __raw_writel(value, adreno_dev->cx_misc_virt + cx_misc_offset); } void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int mask, unsigned int bits) { unsigned int val = 0; adreno_cx_misc_regread(adreno_dev, offsetwords, &val); val &= ~mask; adreno_cx_misc_regwrite(adreno_dev, offsetwords, val | bits); } /** * adreno_waittimestamp - sleep while waiting for the specified timestamp * @device - pointer to a KGSL device structure Loading
drivers/gpu/msm/adreno.h +12 −0 Original line number Diff line number Diff line Loading @@ -441,6 +441,8 @@ enum gpu_coresight_sources { * @chipid: Chip ID specific to the GPU * @gmem_base: Base physical address of GMEM * @gmem_size: GMEM size * @cx_misc_len: Length of the CX MISC register block * @cx_misc_virt: Pointer where the CX MISC block is mapped * @gpucore: Pointer to the adreno_gpu_core structure * @pfp_fw: Buffer which holds the pfp ucode * @pfp_fw_size: Size of pfp ucode buffer Loading Loading @@ -521,6 +523,8 @@ struct adreno_device { unsigned long cx_dbgc_base; unsigned int cx_dbgc_len; void __iomem *cx_dbgc_virt; unsigned int cx_misc_len; void __iomem *cx_misc_virt; const struct adreno_gpu_core *gpucore; struct adreno_firmware fw[2]; size_t gpmu_cmds_size; Loading Loading @@ -1169,6 +1173,14 @@ 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); void adreno_cx_misc_regread(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int *value); void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int value); void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int mask, unsigned int bits); #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ Loading
drivers/gpu/msm/adreno_a6xx.c +7 −48 Original line number Diff line number Diff line Loading @@ -32,18 +32,6 @@ #define MIN_HBB 13 #define A6XX_LLC_NUM_GPU_SCIDS 5 #define A6XX_GPU_LLC_SCID_NUM_BITS 5 #define A6XX_GPU_LLC_SCID_MASK \ ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1) #define A6XX_GPUHTW_LLC_SCID_SHIFT 25 #define A6XX_GPUHTW_LLC_SCID_MASK \ (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT) #define A6XX_GPU_CX_REG_BASE 0x509E000 #define A6XX_GPU_CX_REG_SIZE 0x1000 static const struct adreno_vbif_data a630_vbif[] = { {A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009}, {A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3}, Loading Loading @@ -1594,24 +1582,6 @@ static void a6xx_err_callback(struct adreno_device *adreno_dev, int bit) } } /* GPU System Cache control registers */ #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0 0x4 #define A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1 0x8 static inline void _reg_rmw(void __iomem *regaddr, unsigned int mask, unsigned int bits) { unsigned int val = 0; val = __raw_readl(regaddr); /* Make sure the above read completes before we proceed */ rmb(); val &= ~mask; __raw_writel(val | bits, regaddr); /* Make sure the above write posts before we proceed*/ wmb(); } /* * a6xx_llc_configure_gpu_scid() - Program the sub-cache ID for all GPU blocks * @adreno_dev: The adreno device pointer Loading @@ -1631,13 +1601,9 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev) kgsl_regrmw(KGSL_DEVICE(adreno_dev), A6XX_GBIF_SCACHE_CNTL1, A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val); } else { void __iomem *gpu_cx_reg; gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, adreno_cx_misc_regrmw(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, A6XX_GPU_LLC_SCID_MASK, gpu_cntl1_val); iounmap(gpu_cx_reg); } } Loading @@ -1648,7 +1614,6 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev) static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) { uint32_t gpuhtw_scid; void __iomem *gpu_cx_reg; /* * On A640, the GPUHTW SCID is configured via a NoC override in the Loading @@ -1659,11 +1624,10 @@ static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) gpuhtw_scid = adreno_llc_get_scid(adreno_dev->gpuhtw_llc_slice); gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); _reg_rmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, adreno_cx_misc_regrmw(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, A6XX_GPUHTW_LLC_SCID_MASK, gpuhtw_scid << A6XX_GPUHTW_LLC_SCID_SHIFT); iounmap(gpu_cx_reg); } /* Loading @@ -1672,8 +1636,6 @@ static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev) */ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) { void __iomem *gpu_cx_reg; /* * Attributes override through GBIF is not supported with MMU-500. * Attributes are used as configured through SMMU pagetable entries. Loading @@ -1687,11 +1649,8 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) * writenoallocoverrideen=1 * write-no-alloc=1 - Do not allocates lines on write miss */ gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE); __raw_writel(0x3, gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0); /* Make sure the above write posts before we proceed*/ wmb(); iounmap(gpu_cx_reg); adreno_cx_misc_regwrite(adreno_dev, A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0x3); } static const char *fault_block[8] = { Loading