System Cache support for GPU and required SMMU support
Subsystems (7)
v10 cover System Cache support for GPU and required SMMU support
Some hardware variants contain a system cache or the last level cache(llc). This cache is typically a large block which is shared by multiple clients on the SOC. GPU uses the system cache to cache both the GPU data buffers(like textures) as well the SMMU pagetables. This helps with improved render performance as well as lower power consumption by reducing the bus traffic to the system memory.
The system cache architecture allows the cache to be split into slices which then be used by multiple SOC clients. This patch series is an effort to enable and use two of those slices preallocated for the GPU, one for the GPU data buffers and another for the GPU SMMU hardware pagetables.
Patch 1 - Patch 7 adds system cache support in SMMU and GPU driver. Patch 8 and 9 are minor cleanups for arm-smmu impl.
Changes in v10:
* Fix non-strict mode domain attr handling (Will)
* Split the domain attribute patch into two (Will)
Changes in v9:
* Change name from domain_attr_io_pgtbl_cfg to io_pgtable_domain_attr (Will)
* Modify comment for the quirk as suggested (Will)
* Compare with IO_PGTABLE_QUIRK_NON_STRICT for non-strict mode (Will)
Changes in v8:
* Introduce a generic domain attribute for pagetable config (Will)
* Rename quirk to more generic IO_PGTABLE_QUIRK_ARM_OUTER_WBWA (Will)
* Move non-strict mode to use new struct domain_attr_io_pgtbl_config (Will)
Changes in v7:
* Squash Jordan's patch to support MMU500 targets
* Rebase on top of for-joerg/arm-smmu/updates and Jordan's short series for adreno-smmu impl
Changes in v6:
* Move table to arm-smmu-qcom (Robin)
Changes in v5:
* Drop cleanup of blank lines since it was intentional (Robin)
* Rebase again on top of msm-next-pgtables as it moves pretty fast
Changes in v4:
* Drop IOMMU_SYS_CACHE prot flag
* Rebase on top of https://gitlab.freedesktop.org/drm/msm/-/tree/msm-next-pgtables
Changes in v3:
* Fix domain attribute setting to before iommu_attach_device()
* Fix few code style and checkpatch warnings
* Rebase on top of Jordan's latest split pagetables and per-instance pagetables support
Changes in v2:
* Addressed review comments and rebased on top of Jordan's split pagetables series
Jordan Crouse (1):
drm/msm/a6xx: Add support for using system cache on MMU500 based
targets
Sai Prakash Ranjan (6):
iommu/io-pgtable: Add a domain attribute for pagetable configuration iommu/io-pgtable-arm: Add support to use system cache iommu/arm-smmu: Add support for pagetable config domain attribute iommu/arm-smmu: Move non-strict mode to use io_pgtable_domain_attr
iommu: arm-smmu-impl: Use table to list QCOM implementations
iommu: arm-smmu-impl: Add a space before open parenthesis
Sharat Masetty (2):
drm/msm: rearrange the gpu_rmw() function drm/msm/a6xx: Add support for using system cache(LLC)
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 109 +++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 5 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 17 ++++ drivers/gpu/drm/msm/msm_drv.c | 8 ++ drivers/gpu/drm/msm/msm_drv.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 5 +- drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 11 +-- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 21 +++- drivers/iommu/arm/arm-smmu/arm-smmu.c | 33 ++++++- drivers/iommu/arm/arm-smmu/arm-smmu.h | 3 +- drivers/iommu/io-pgtable-arm.c | 10 +- include/linux/io-pgtable.h | 8 ++ include/linux/iommu.h | 1 + 13 files changed, 205 insertions(+), 27 deletions(-)
base-commit: a29bbb0861f487a5e144dc997a9f71a36c7a2404
Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v10 1/9 iommu/io-pgtable: Add a domain attribute for pagetable configuration
Add a new iommu domain attribute DOMAIN_ATTR_IO_PGTABLE_CFG for pagetable configuration which initially will be used to set quirks like for system cache aka last level cache to be used by client drivers like GPU to set right attributes for caching the hardware pagetables into the system cache and later can be extended to include other page table configuration data.
--- include/linux/io-pgtable.h | 4 ++++ include/linux/iommu.h | 1 + 2 files changed, 5 insertions(+)
include/linux/io-pgtable.h +4 -0
@@ -208,6 +208,10 @@ struct io_pgtable {#define io_pgtable_ops_to_pgtable (x) container_of((x), struct io_pgtable, ops) +struct io_pgtable_domain_attr { +unsigned long quirks; +}; +static inline void io_pgtable_tlb_flush_all (struct io_pgtable *iop) { iop->cfg.tlb->tlb_flush_all (iop->cookie);
include/linux/iommu.h +1 -0
@@ -118,6 +118,7 @@ enum iommu_attr {DOMAIN_ATTR_FSL_PAMUV1 ,DOMAIN_ATTR_NESTING ,/* two stages of translation */ DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE , +DOMAIN_ATTR_IO_PGTABLE_CFG , DOMAIN_ATTR_MAX, };
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
PATCH v10 2/9 iommu/io-pgtable-arm: Add support to use system cache
In reply to Sai Prakash RanjanAdd a quirk IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to override the outer-cacheability attributes set in the TCR for a non-coherent page table walker when using system cache.
--- drivers/iommu/io-pgtable-arm.c | 10 ++++++++-- include/linux/io-pgtable.h | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-)
drivers/iommu/io-pgtable-arm.c +8 -2
@@ -761,7 +761,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |IO_PGTABLE_QUIRK_NON_STRICT | -IO_PGTABLE_QUIRK_ARM_TTBR1 )) +IO_PGTABLE_QUIRK_ARM_TTBR1 | +IO_PGTABLE_QUIRK_ARM_OUTER_WBWA ))return NULL ; data =arm_lpae_alloc_pgtable (cfg);
@@ -773,10 +774,15 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) tcr->sh =ARM_LPAE_TCR_SH_IS ; tcr->irgn =ARM_LPAE_TCR_RGN_WBWA ; tcr->orgn =ARM_LPAE_TCR_RGN_WBWA ; +if (cfg->quirks &IO_PGTABLE_QUIRK_ARM_OUTER_WBWA ) + goto out_free_data; }else { tcr->sh =ARM_LPAE_TCR_SH_OS ; tcr->irgn =ARM_LPAE_TCR_RGN_NC ; - tcr->orgn =ARM_LPAE_TCR_RGN_NC ; +if (!(cfg->quirks &IO_PGTABLE_QUIRK_ARM_OUTER_WBWA )) + tcr->orgn =ARM_LPAE_TCR_RGN_NC ; +else + tcr->orgn =ARM_LPAE_TCR_RGN_WBWA ; } tg1 = cfg->quirks &IO_PGTABLE_QUIRK_ARM_TTBR1 ;
include/linux/io-pgtable.h +4 -0
@@ -86,6 +86,9 @@ struct io_pgtable_cfg {* * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table * for use in the upper half of a split address space. +* +* IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability +* attributes set in the TCR for a non-coherent page-table walker. */ #define IO_PGTABLE_QUIRK_ARM_NS BIT(0)#define IO_PGTABLE_QUIRK_NO_PERMS BIT(1)
@@ -93,6 +96,7 @@ struct io_pgtable_cfg {#define IO_PGTABLE_QUIRK_ARM_MTK_EXT BIT(3)#define IO_PGTABLE_QUIRK_NON_STRICT BIT(4)#define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5) +#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6)unsigned long quirks;unsigned long pgsize_bitmap;unsigned int ias;
Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v10 3/9 iommu/arm-smmu: Add support for pagetable config domain attribute
In reply to Sai Prakash RanjanAdd support for domain attribute DOMAIN_ATTR_IO_PGTABLE_CFG to get/set pagetable configuration data which initially will be used to set quirks and later can be extended to include other pagetable configuration data.
--- drivers/iommu/arm/arm-smmu/arm-smmu.c | 20 ++++++++++++++++++++ drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + 2 files changed, 21 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu.c +20 -0
@@ -789,6 +789,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,if (smmu_domain->non_strict) pgtbl_cfg.quirks |=IO_PGTABLE_QUIRK_NON_STRICT ; +if (smmu_domain->pgtbl_cfg.quirks) + pgtbl_cfg.quirks |= smmu_domain->pgtbl_cfg.quirks; + pgtbl_ops =alloc_io_pgtable_ops (fmt, &pgtbl_cfg, smmu_domain);if (!pgtbl_ops) { ret = -ENOMEM ;
@@ -1511,6 +1514,12 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,case DOMAIN_ATTR_NESTING : *(int *)data = (smmu_domain->stage ==ARM_SMMU_DOMAIN_NESTED );return 0 ; +case DOMAIN_ATTR_IO_PGTABLE_CFG : { +struct io_pgtable_domain_attr *pgtbl_cfg = data; + *pgtbl_cfg = smmu_domain->pgtbl_cfg; + +return 0 ; + }default :return -ENODEV ; }
@@ -1551,6 +1560,17 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,else smmu_domain->stage =ARM_SMMU_DOMAIN_S1 ;break ; +case DOMAIN_ATTR_IO_PGTABLE_CFG : { +struct io_pgtable_domain_attr *pgtbl_cfg = data; + +if (smmu_domain->smmu) { + ret = -EPERM ; + goto out_unlock; + } + + smmu_domain->pgtbl_cfg = *pgtbl_cfg; +break ; + }default : ret = -ENODEV ; }
drivers/iommu/arm/arm-smmu/arm-smmu.h +1 -0
@@ -364,6 +364,7 @@ enum arm_smmu_domain_stage {struct arm_smmu_domain {struct arm_smmu_device *smmu;struct io_pgtable_ops *pgtbl_ops; +struct io_pgtable_domain_attr pgtbl_cfg;const struct iommu_flush_ops *flush_ops;struct arm_smmu_cfg cfg;enum arm_smmu_domain_stage stage;
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
PATCH v10 4/9 iommu/arm-smmu: Move non-strict mode to use io_pgtable_domain_attr
In reply to Sai Prakash RanjanNow that we have a struct io_pgtable_domain_attr with quirks, use that for non_strict mode as well thereby removing the need for more members of arm_smmu_domain in the future.
--- drivers/iommu/arm/arm-smmu/arm-smmu.c | 15 +++++++++------ drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 - 2 files changed, 9 insertions(+), 7 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +9 -6
@@ -786,9 +786,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, goto out_clear_smmu; } -if (smmu_domain->non_strict) - pgtbl_cfg.quirks |=IO_PGTABLE_QUIRK_NON_STRICT ; -if (smmu_domain->pgtbl_cfg.quirks) pgtbl_cfg.quirks |= smmu_domain->pgtbl_cfg.quirks;
@@ -1526,9 +1523,12 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,break ;case IOMMU_DOMAIN_DMA :switch (attr) { -case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE : - *(int *)data = smmu_domain->non_strict; +case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE : { +bool non_strict = smmu_domain->pgtbl_cfg.quirks & +IO_PGTABLE_QUIRK_NON_STRICT ; + *(int *)data = non_strict;return 0 ; + }default :return -ENODEV ; }
@@ -1578,7 +1578,10 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,case IOMMU_DOMAIN_DMA :switch (attr) {case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE : - smmu_domain->non_strict = *(int *)data; +if (*(int *)data) + smmu_domain->pgtbl_cfg.quirks |=IO_PGTABLE_QUIRK_NON_STRICT ; +else + smmu_domain->pgtbl_cfg.quirks &= ~IO_PGTABLE_QUIRK_NON_STRICT ;break ;default : ret = -ENODEV ;
drivers/iommu/arm/arm-smmu/arm-smmu.h +0 -1
@@ -368,7 +368,6 @@ struct arm_smmu_domain {const struct iommu_flush_ops *flush_ops;struct arm_smmu_cfg cfg;enum arm_smmu_domain_stage stage; -bool non_strict;struct mutex init_mutex;/* Protects smmu pointer */ spinlock_t cb_lock;/* Serialises ATS1* ops and TLB syncs */ struct iommu_domain domain;
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
PATCH v10 5/9 drm/msm: rearrange the gpu_rmw() function
In reply to Sai Prakash RanjanFrom: Sharat Masetty <[email protected]>
The register read-modify-write construct is generic enough that it can be used by other subsystems as needed, create a more generic rmw() function and have the gpu_rmw() use this new function.
--- drivers/gpu/drm/msm/msm_drv.c | 8 ++++++++ drivers/gpu/drm/msm/msm_drv.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 5 +---- 3 files changed, 10 insertions(+), 4 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +8 -0
@@ -180,6 +180,14 @@ u32 msm_readl(const void __iomem *addr)return val; } +void msm_rmw (void __iomem *addr,u32 mask,u32 or) +{ +u32 val =msm_readl (addr); + + val &= ~mask; +msm_writel (val | or, addr); +} +struct msm_vblank_work {struct work_struct work;int crtc_id;
drivers/gpu/drm/msm/msm_drv.h +1 -0
@@ -478,6 +478,7 @@ void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name, const char *dbgname);void msm_writel (u32 data,void __iomem *addr);u32 msm_readl (const void __iomem *addr); +void msm_rmw (void __iomem *addr,u32 mask,u32 or);struct msm_gpu_submitqueue ;int msm_submitqueue_init (struct drm_device *drm,struct msm_file_private *ctx);
drivers/gpu/drm/msm/msm_gpu.h +1 -4
@@ -246,10 +246,7 @@ static inline u32 gpu_read(struct msm_gpu *gpu, u32 reg)static inline void gpu_rmw (struct msm_gpu *gpu,u32 reg,u32 mask,u32 or) { -uint32_t val =gpu_read (gpu, reg); - - val &= ~mask; -gpu_write (gpu, reg, val | or); +msm_rmw (gpu->mmio + (reg <<2 ), mask, or); }static inline u64 gpu_read64 (struct msm_gpu *gpu,u32 lo,u32 hi)
Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v10 6/9 drm/msm/a6xx: Add support for using system cache(LLC)
In reply to Sai Prakash RanjanFrom: Sharat Masetty <[email protected]>
The last level system cache can be partitioned to 32 different slices of which GPU has two slices preallocated. One slice is used for caching GPU buffers and the other slice is used for caching the GPU SMMU pagetables. This talks to the core system cache driver to acquire the slice handles, configure the SCID's to those slices and activates and deactivates the slices upon GPU power collapse and restore.
Some support from the IOMMU driver is also needed to make use of the system cache to set the right TCR attributes. GPU then has the ability to override a few cacheability parameters which it does to override write-allocate to write-no-allocate as the GPU hardware does not benefit much from it.
DOMAIN_ATTR_IO_PGTABLE_CFG is another domain level attribute used by the IOMMU driver for pagetable configuration which will be used to set a quirk initially to set the right attributes to cache the hardware pagetables into the system cache.
--- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 83 +++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 17 +++++ 3 files changed, 104 insertions(+)
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +83 -0
@@ -8,7 +8,9 @@#include "a6xx_gpu.h" #include "a6xx_gmu.xml.h" +#include <linux/bitfield.h> #include <linux/devfreq.h> +#include <linux/soc/qcom/llcc-qcom.h> #define GPU_PAS_ID 13
@@ -1022,6 +1024,79 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)return IRQ_HANDLED ; } +static void a6xx_llc_rmw (struct a6xx_gpu *a6xx_gpu,u32 reg,u32 mask,u32 or) +{ +return msm_rmw (a6xx_gpu->llc_mmio + (reg <<2 ), mask, or); +} + +static void a6xx_llc_write (struct a6xx_gpu *a6xx_gpu,u32 reg,u32 value) +{ +return msm_writel (value, a6xx_gpu->llc_mmio + (reg <<2 )); +} + +static void a6xx_llc_deactivate (struct a6xx_gpu *a6xx_gpu) +{ +llcc_slice_deactivate (a6xx_gpu->llc_slice); +llcc_slice_deactivate (a6xx_gpu->htw_llc_slice); +} + +static void a6xx_llc_activate (struct a6xx_gpu *a6xx_gpu) +{ +u32 cntl1_regval =0 ; + +if (IS_ERR (a6xx_gpu->llc_mmio)) +return ; + +if (!llcc_slice_activate (a6xx_gpu->llc_slice)) { +u32 gpu_scid =llcc_get_slice_id (a6xx_gpu->llc_slice); + + gpu_scid &=0x1f ; + cntl1_regval = (gpu_scid <<0 ) | (gpu_scid <<5 ) | (gpu_scid <<10 ) | + (gpu_scid <<15 ) | (gpu_scid <<20 ); + } + +if (!llcc_slice_activate (a6xx_gpu->htw_llc_slice)) { +u32 gpuhtw_scid =llcc_get_slice_id (a6xx_gpu->htw_llc_slice); + + gpuhtw_scid &=0x1f ; + cntl1_regval |=FIELD_PREP (GENMASK (29 ,25 ), gpuhtw_scid); + } + +if (cntl1_regval) { +/* +* Program the slice IDs for the various GPU blocks and GPU MMU +* pagetables +*/ +a6xx_llc_write (a6xx_gpu,REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1 , cntl1_regval); + +/* +* Program cacheability overrides to not allocate cache lines on +* a write miss +*/ +a6xx_llc_rmw (a6xx_gpu,REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0 ,0xF ,0x03 ); + } +} + +static void a6xx_llc_slices_destroy (struct a6xx_gpu *a6xx_gpu) +{ +llcc_slice_putd (a6xx_gpu->llc_slice); +llcc_slice_putd (a6xx_gpu->htw_llc_slice); +} + +static void a6xx_llc_slices_init (struct platform_device *pdev, +struct a6xx_gpu *a6xx_gpu) +{ + a6xx_gpu->llc_mmio =msm_ioremap (pdev,"cx_mem" ,"gpu_cx" ); +if (IS_ERR (a6xx_gpu->llc_mmio)) +return ; + + a6xx_gpu->llc_slice =llcc_slice_getd (LLCC_GPU ); + a6xx_gpu->htw_llc_slice =llcc_slice_getd (LLCC_GPUHTW ); + +if (IS_ERR (a6xx_gpu->llc_slice) &&IS_ERR (a6xx_gpu->htw_llc_slice)) + a6xx_gpu->llc_mmio =ERR_PTR (-EINVAL ); +} +static int a6xx_pm_resume (struct msm_gpu *gpu) {struct adreno_gpu *adreno_gpu =to_adreno_gpu (gpu);
@@ -1038,6 +1113,8 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)msm_gpu_resume_devfreq (gpu); +a6xx_llc_activate (a6xx_gpu); +return 0 ; }
@@ -1048,6 +1125,8 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)trace_msm_gpu_suspend (0 ); +a6xx_llc_deactivate (a6xx_gpu); +devfreq_suspend_device (gpu->devfreq.devfreq);return a6xx_gmu_stop (a6xx_gpu);
@@ -1091,6 +1170,8 @@ static void a6xx_destroy(struct msm_gpu *gpu)drm_gem_object_put (a6xx_gpu->shadow_bo); } +a6xx_llc_slices_destroy (a6xx_gpu); +a6xx_gmu_remove (a6xx_gpu);adreno_gpu_cleanup (adreno_gpu);
@@ -1209,6 +1290,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)if (info && info->revn ==650 ) adreno_gpu->base.hw_apriv = true; +a6xx_llc_slices_init (pdev, a6xx_gpu); + ret =adreno_gpu_init (dev, pdev, adreno_gpu, &funcs,1 );if (ret) {a6xx_destroy (&(a6xx_gpu->base.base));
drivers/gpu/drm/msm/adreno/a6xx_gpu.h +4 -0
@@ -28,6 +28,10 @@ struct a6xx_gpu {uint32_t *shadow;bool has_whereami; + +void __iomem *llc_mmio; +void *llc_slice; +void *htw_llc_slice; };#define to_a6xx_gpu (x) container_of(x, struct a6xx_gpu, base)
drivers/gpu/drm/msm/adreno/adreno_gpu.c +17 -0
@@ -16,6 +16,7 @@#include <linux/soc/qcom/mdt_loader.h> #include <soc/qcom/ocmem.h> #include "adreno_gpu.h" +#include "a6xx_gpu.h" #include "msm_gem.h" #include "msm_mmu.h"
@@ -189,6 +190,9 @@ struct msm_gem_address_space * adreno_iommu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); +struct a6xx_gpu *a6xx_gpu =to_a6xx_gpu (adreno_gpu); +struct io_pgtable_domain_attr pgtbl_cfg;struct iommu_domain *iommu;struct msm_mmu *mmu;struct msm_gem_address_space *aspace;
@@ -198,7 +202,20 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,if (!iommu)return NULL ; +/* +* This allows GPU to set the bus attributes required to use system +* cache on behalf of the iommu page table walker. +*/ +if (!IS_ERR (a6xx_gpu->htw_llc_slice)) { + pgtbl_cfg.quirks =IO_PGTABLE_QUIRK_ARM_OUTER_WBWA ; +iommu_domain_set_attr (iommu,DOMAIN_ATTR_IO_PGTABLE_CFG , &pgtbl_cfg); + } + mmu =msm_iommu_new (&pdev->dev, iommu); +if (IS_ERR (mmu)) { +iommu_domain_free (iommu); +return ERR_CAST (mmu); + }/* * Use the aperture start or SZ_16M, whichever is greater. This will
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
PATCH v10 7/9 drm/msm/a6xx: Add support for using system cache on MMU500 based targets
In reply to Sai Prakash RanjanFrom: Jordan Crouse <[email protected]>
GPU targets with an MMU-500 attached have a slightly different process for enabling system cache. Use the compatible string on the IOMMU phandle to see if an MMU-500 is attached and modify the programming sequence accordingly.
--- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 +++++++++++++++++++++------ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 + 2 files changed, 37 insertions(+), 10 deletions(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +36 -10
@@ -1042,6 +1042,8 @@ static void a6xx_llc_deactivate(struct a6xx_gpu *a6xx_gpu)static void a6xx_llc_activate (struct a6xx_gpu *a6xx_gpu) { +struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; +struct msm_gpu *gpu = &adreno_gpu->base;u32 cntl1_regval =0 ;if (IS_ERR (a6xx_gpu->llc_mmio))
@@ -1055,11 +1057,17 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) (gpu_scid <<15 ) | (gpu_scid <<20 ); } +/* +* For targets with a MMU500, activate the slice but don't program the +* register. The XBL will take care of that. +*/ if (!llcc_slice_activate (a6xx_gpu->htw_llc_slice)) { -u32 gpuhtw_scid =llcc_get_slice_id (a6xx_gpu->htw_llc_slice); +if (!a6xx_gpu->have_mmu500) { +u32 gpuhtw_scid =llcc_get_slice_id (a6xx_gpu->htw_llc_slice); - gpuhtw_scid &=0x1f ; - cntl1_regval |=FIELD_PREP (GENMASK (29 ,25 ), gpuhtw_scid); + gpuhtw_scid &=0x1f ; + cntl1_regval |=FIELD_PREP (GENMASK (29 ,25 ), gpuhtw_scid); + } }if (cntl1_regval) {
@@ -1067,13 +1075,20 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)* Program the slice IDs for the various GPU blocks and GPU MMU * pagetables */ -a6xx_llc_write (a6xx_gpu,REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1 , cntl1_regval); - -/* -* Program cacheability overrides to not allocate cache lines on -* a write miss -*/ -a6xx_llc_rmw (a6xx_gpu,REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0 ,0xF ,0x03 ); +if (a6xx_gpu->have_mmu500) +gpu_rmw (gpu,REG_A6XX_GBIF_SCACHE_CNTL1 ,GENMASK (24 ,0 ), + cntl1_regval); +else { +a6xx_llc_write (a6xx_gpu, +REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1 , cntl1_regval); + +/* +* Program cacheability overrides to not allocate cache +* lines on a write miss +*/ +a6xx_llc_rmw (a6xx_gpu, +REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0 ,0xF ,0x03 ); + } } }
@@ -1086,10 +1101,21 @@ static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)static void a6xx_llc_slices_init (struct platform_device *pdev,struct a6xx_gpu *a6xx_gpu) { +struct device_node *phandle; + a6xx_gpu->llc_mmio =msm_ioremap (pdev,"cx_mem" ,"gpu_cx" );if (IS_ERR (a6xx_gpu->llc_mmio))return ; +/* +* There is a different programming path for targets with an mmu500 +* attached, so detect if that is the case +*/ + phandle =of_parse_phandle (pdev->dev.of_node,"iommus" ,0 ); + a6xx_gpu->have_mmu500 = (phandle && +of_device_is_compatible (phandle,"arm,mmu-500" )); +of_node_put (phandle); + a6xx_gpu->llc_slice =llcc_slice_getd (LLCC_GPU ); a6xx_gpu->htw_llc_slice =llcc_slice_getd (LLCC_GPUHTW );
drivers/gpu/drm/msm/adreno/a6xx_gpu.h +1 -0
@@ -32,6 +32,7 @@ struct a6xx_gpu {void __iomem *llc_mmio;void *llc_slice;void *htw_llc_slice; +bool have_mmu500; };#define to_a6xx_gpu (x) container_of(x, struct a6xx_gpu, base)
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
PATCH v10 8/9 iommu: arm-smmu-impl: Use table to list QCOM implementations
In reply to Sai Prakash RanjanUse table and of_match_node() to match qcom implementation instead of multiple of_device_compatible() calls for each QCOM SMMU implementation.
--- drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 9 +-------- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 21 ++++++++++++++++----- drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 - 3 files changed, 17 insertions(+), 14 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu-impl.c +1 -8
@@ -214,14 +214,7 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)if (of_device_is_compatible (np,"nvidia,tegra194-smmu" ))return nvidia_smmu_impl_init (smmu); -if (of_device_is_compatible (np,"qcom,sdm845-smmu-500" ) || -of_device_is_compatible (np,"qcom,sc7180-smmu-500" ) || -of_device_is_compatible (np,"qcom,sm8150-smmu-500" ) || -of_device_is_compatible (np,"qcom,sm8250-smmu-500" )) -return qcom_smmu_impl_init (smmu); - -if (of_device_is_compatible (smmu->dev->of_node,"qcom,adreno-smmu" )) -return qcom_adreno_smmu_impl_init (smmu); + smmu =qcom_smmu_impl_init (smmu);if (of_device_is_compatible (np,"marvell,ap806-smmu-500" )) smmu->impl = &mrvl_mmu500_impl;
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +16 -5
@@ -318,12 +318,23 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,return &qsmmu->smmu; } +static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { + { .compatible ="qcom,sc7180-smmu-500" }, + { .compatible ="qcom,sdm845-smmu-500" }, + { .compatible ="qcom,sm8150-smmu-500" }, + { .compatible ="qcom,sm8250-smmu-500" }, + { } +}; +struct arm_smmu_device *qcom_smmu_impl_init (struct arm_smmu_device *smmu) { -return qcom_smmu_create (smmu, &qcom_smmu_impl); -} +const struct device_node *np = smmu->dev->of_node; -struct arm_smmu_device *qcom_adreno_smmu_impl_init (struct arm_smmu_device *smmu) -{ -return qcom_smmu_create (smmu, &qcom_adreno_smmu_impl); +if (of_match_node (qcom_smmu_impl_of_match, np)) +return qcom_smmu_create (smmu, &qcom_smmu_impl); + +if (of_device_is_compatible (np,"qcom,adreno-smmu" )) +return qcom_smmu_create (smmu, &qcom_adreno_smmu_impl); + +return smmu; }
drivers/iommu/arm/arm-smmu/arm-smmu.h +0 -1
@@ -523,7 +523,6 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,struct arm_smmu_device *arm_smmu_impl_init (struct arm_smmu_device *smmu);struct arm_smmu_device *nvidia_smmu_impl_init (struct arm_smmu_device *smmu);struct arm_smmu_device *qcom_smmu_impl_init (struct arm_smmu_device *smmu); -struct arm_smmu_device *qcom_adreno_smmu_impl_init (struct arm_smmu_device *smmu);void arm_smmu_write_context_bank (struct arm_smmu_device *smmu,int idx);int arm_mmu500_reset (struct arm_smmu_device *smmu);
Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v10 9/9 iommu: arm-smmu-impl: Add a space before open parenthesis
In reply to Sai Prakash RanjanFix the checkpatch warning for space required before the open parenthesis.
--- drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu/arm-smmu-impl.c +1 -1
@@ -12,7 +12,7 @@static int arm_smmu_gr0_ns (int offset) { -switch (offset) { +switch (offset) {case ARM_SMMU_GR0_sCR0:case ARM_SMMU_GR0_sACR:case ARM_SMMU_GR0_sGFSR:
Signature · 7 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Will Deacon
maintainerQuoted 8 lines · Sai Prakash Ranjan
Some hardware variants contain a system cache or the last level cache(llc). This cache is typically a large block which is shared by multiple clients on the SOC. GPU uses the system cache to cache both the GPU data buffers(like textures) as well the SMMU pagetables. This helps with improved render performance as well as lower power consumption by reducing the bus traffic to the system memory.
[...]
Applied the SMMU bits to arm64 (for-next/iommu/arm-smmu), thanks!
[3/9] iommu/arm-smmu: Add support for pagetable config domain attribute
https://git.kernel.org/arm64/c/c99110a865a3 [4/9] iommu/arm-smmu: Move non-strict mode to use io_pgtable_domain_attr https://git.kernel.org/arm64/c/12bc36793fd6
[8/9] iommu: arm-smmu-impl: Use table to list QCOM implementations
https://git.kernel.org/arm64/c/00597f9ff5ec [9/9] iommu: arm-smmu-impl: Add a space before open parenthesis https://git.kernel.org/arm64/c/7f575a6087f4
Cheers,
Signature · 9 lines
Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Will Deacon
maintainerQuoted 8 lines · Sai Prakash Ranjan
Some hardware variants contain a system cache or the last level cache(llc). This cache is typically a large block which is shared by multiple clients on the SOC. GPU uses the system cache to cache both the GPU data buffers(like textures) as well the SMMU pagetables. This helps with improved render performance as well as lower power consumption by reducing the bus traffic to the system memory.
[...]
Applied first two patches on a shared branch for Rob:
arm64 (for-next/iommu/io-pgtable-domain-attr), thanks!
[1/9] iommu/io-pgtable: Add a domain attribute for pagetable configuration
https://git.kernel.org/arm64/c/a7656ecf825a [2/9] iommu/io-pgtable-arm: Add support to use system cache https://git.kernel.org/arm64/c/e67890c97944
Cheers,
Signature · 9 lines
Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel