Skip to contentSkip to conversation

System Cache support for GPU and required SMMU support

PATCH Superseded Sai Prakash Ranjan 3 participants 23 messages Nov 17, 2020 – Nov 24, 2020

Subsystems (7)

v8 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v8 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 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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 (5):
iommu/io-pgtable-arm: Add support to use system cache iommu/arm-smmu: Add domain attribute for pagetable configuration iommu/arm-smmu: Move non-strict mode to use domain_attr_io_pgtbl_cfg
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      |  30 +++++-
 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, 203 insertions(+), 26 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
#1 lore raw

PATCH v8 1/8 iommu/io-pgtable-arm: Add support to use system cache

Add a quirk IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to override the attributes set in TCR for the 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
index a7a9bc08dcd1..7c9ea9d7874a 100644
@@ -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
index 4cde111e425b..a9a2c59fab37 100644
@@ -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 attributes set in TCR for
+	 *	the page table walker when using system cache.
 	 */
 	#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
maintainer
#2 lore raw

Re: [PATCHv8 1/8] iommu/io-pgtable-arm: Add support to use system cache

Quoted 46 lines · Sai Prakash Ranjan

Add a quirk IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to override the attributes set in TCR for the 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
index a7a9bc08dcd1..7c9ea9d7874a 100644
@@ -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 +0 -0
index 4cde111e425b..a9a2c59fab37 100644

include/linux/io-pgtable.h struct io_pgtable_cfg { · line 91

Quoted 6 lines
include/linux/io-pgtable.h +3 -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 attributes set in TCR for
+	 *	the page table walker when using system cache.

Please can you reword this to say:

"Override the outer-cacheability attributes set in the TCR for a non-coherent
page-table walker."

Will
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#3 lore raw

Re: [PATCHv8 1/8] iommu/io-pgtable-arm: Add support to use system cache

Quoted 59 lines · Will Deacon
Quoted 54 lines · Sai Prakash Ranjan

Add a quirk IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to override the attributes set in TCR for the 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 +2 -1
index a7a9bc08dcd1..7c9ea9d7874a 100644
@@ -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;
 
drivers/iommu/io-pgtable-arm.c +6 -1
 	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;
 	}
 
drivers/iommu/io-pgtable-arm.c +0 -0
 	tg1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1;
include/linux/io-pgtable.h +2 -0
index 4cde111e425b..a9a2c59fab37 100644
@@ -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 attributes set in 

TCR for

include/linux/io-pgtable.h struct io_pgtable_cfg { · line 91

Quoted 1 line
include/linux/io-pgtable.h +1 -0
+	 *	the page table walker when using system cache.

Please can you reword this to say:

Quoted 4 lines

"Override the outer-cacheability attributes set in the TCR for a
non-coherent
page-table walker."

Sure, thanks.

Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
#4 lore raw

PATCH v8 2/8 iommu/arm-smmu: Add domain attribute for pagetable configuration

In reply to Sai Prakash Ranjan

Add iommu domain attribute 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.

---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 25 +++++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 include/linux/io-pgtable.h            |  4 ++++
 include/linux/iommu.h                 |  1 +
 4 files changed, 31 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu.c +25 -0
index 0f28a8614da3..7b05782738e2 100644
@@ -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 domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+			*pgtbl_cfg = smmu_domain->pgtbl_cfg;
+
+			return 0;
+		}
 		default:
 			return -ENODEV;
 		}
@@ -1551,6 +1560,22 @@ 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 domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+
+			if (smmu_domain->smmu) {
+				ret = -EPERM;
+				goto out_unlock;
+			}
+
+			if (!pgtbl_cfg) {
+				ret = -ENODEV;
+				goto out_unlock;
+			}
+
+			smmu_domain->pgtbl_cfg = *pgtbl_cfg;
+			break;
+		}
 		default:
 			ret = -ENODEV;
 		}
drivers/iommu/arm/arm-smmu/arm-smmu.h +1 -0
index 04288b6fc619..18fbed376afb 100644
@@ -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 domain_attr_io_pgtbl_cfg	pgtbl_cfg;
 	const struct iommu_flush_ops	*flush_ops;
 	struct arm_smmu_cfg		cfg;
 	enum arm_smmu_domain_stage	stage;
include/linux/io-pgtable.h +4 -0
index a9a2c59fab37..686b37d48743 100644
@@ -212,6 +212,10 @@ struct io_pgtable {
 
 #define io_pgtable_ops_to_pgtable(x) container_of((x), struct io_pgtable, ops)
 
+struct domain_attr_io_pgtbl_cfg {
+	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
index b95a6f8db6ff..ffaa389ea128 100644
@@ -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 · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
maintainer
#5 lore raw

Re: [PATCHv8 2/8] iommu/arm-smmu: Add domain attribute for pagetable configuration

Quoted 45 lines · Sai Prakash Ranjan

Add iommu domain attribute 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.

---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 25 +++++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 include/linux/io-pgtable.h            |  4 ++++
 include/linux/iommu.h                 |  1 +
 4 files changed, 31 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu.c +9 -0
index 0f28a8614da3..7b05782738e2 100644
@@ -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 domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+			*pgtbl_cfg = smmu_domain->pgtbl_cfg;
+
+			return 0;
+		}
 		default:
 			return -ENODEV;
 		}
@@ -1551,6 +1560,22 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
 			else
 				smmu_domain->stage = ARM_SMMU_DOMAIN_S1;

drivers/iommu/arm/arm-smmu/arm-smmu.c static int arm_smmu_domain_set_attr(struct iommu_domain *domain, · line 1571

Quoted 10 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +9 -0
 			break;
+		case DOMAIN_ATTR_IO_PGTABLE_CFG: {
+			struct domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+
+			if (smmu_domain->smmu) {
+				ret = -EPERM;
+				goto out_unlock;
+			}
+
+			if (!pgtbl_cfg) {

Do we really need to check this? If somebody passed us a NULL pointer then they have a bug and we don't check this for other domain attributes afaict.

Quoted 27 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +7 -0
+				ret = -ENODEV;
+				goto out_unlock;
+			}
+
+			smmu_domain->pgtbl_cfg = *pgtbl_cfg;
+			break;
+		}
 		default:
 			ret = -ENODEV;
 		}
drivers/iommu/arm/arm-smmu/arm-smmu.h +1 -0
index 04288b6fc619..18fbed376afb 100644
@@ -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 domain_attr_io_pgtbl_cfg	pgtbl_cfg;
 	const struct iommu_flush_ops	*flush_ops;
 	struct arm_smmu_cfg		cfg;
 	enum arm_smmu_domain_stage	stage;
include/linux/io-pgtable.h +0 -0
index a9a2c59fab37..686b37d48743 100644

include/linux/io-pgtable.h struct io_pgtable { · line 217

Quoted 6 lines
include/linux/io-pgtable.h +3 -0
@@ -212,6 +212,10 @@ struct io_pgtable {
 
 #define io_pgtable_ops_to_pgtable(x) container_of((x), struct io_pgtable, ops)
 
+struct domain_attr_io_pgtbl_cfg {
+	unsigned long quirks;
+};

nit: Can you rename this to 'struct io_pgtable_domain_attr' please?

Will
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#6 lore raw

Re: [PATCHv8 2/8] iommu/arm-smmu: Add domain attribute for pagetable configuration

Quoted 54 lines · Will Deacon
Quoted 53 lines · Sai Prakash Ranjan

Add iommu domain attribute 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.

---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 25 +++++++++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 include/linux/io-pgtable.h            |  4 ++++
 include/linux/iommu.h                 |  1 +
 4 files changed, 31 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu.c +3 -0
index 0f28a8614da3..7b05782738e2 100644
@@ -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) {
drivers/iommu/arm/arm-smmu/arm-smmu.c +6 -0
 		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 domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+			*pgtbl_cfg = smmu_domain->pgtbl_cfg;
+
+			return 0;
+		}
 		default:
 			return -ENODEV;
drivers/iommu/arm/arm-smmu/arm-smmu.c +4 -0
 		}
@@ -1551,6 +1560,22 @@ 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 domain_attr_io_pgtbl_cfg *pgtbl_cfg = data;
+
+			if (smmu_domain->smmu) {
Quoted 9 lines

drivers/iommu/arm/arm-smmu/arm-smmu.c static int arm_smmu_domain_set_attr(struct iommu_domain *domain, · line 1571

Quoted 5 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +5 -0
+				ret = -EPERM;
+				goto out_unlock;
+			}
+
+			if (!pgtbl_cfg) {

Do we really need to check this? If somebody passed us a NULL pointer then they have a bug and we don't check this for other domain attributes afaict.

True, I'll drop it.

Quoted 28 lines
Quoted 28 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +7 -0
+				ret = -ENODEV;
+				goto out_unlock;
+			}
+
+			smmu_domain->pgtbl_cfg = *pgtbl_cfg;
+			break;
+		}
 		default:
 			ret = -ENODEV;
drivers/iommu/arm/arm-smmu/arm-smmu.c +0 -0
 		}
drivers/iommu/arm/arm-smmu/arm-smmu.h +1 -0
index 04288b6fc619..18fbed376afb 100644
@@ -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 domain_attr_io_pgtbl_cfg	pgtbl_cfg;
 	const struct iommu_flush_ops	*flush_ops;
 	struct arm_smmu_cfg		cfg;
 	enum arm_smmu_domain_stage	stage;
include/linux/io-pgtable.h +0 -0
index a9a2c59fab37..686b37d48743 100644
@@ -212,6 +212,10 @@ struct io_pgtable {
 
Quoted 9 lines

include/linux/io-pgtable.h struct io_pgtable { · line 217

Quoted 6 lines
include/linux/io-pgtable.h +3 -0
 #define io_pgtable_ops_to_pgtable(x) container_of((x), struct 
 io_pgtable, ops)
 
+struct domain_attr_io_pgtbl_cfg {
+	unsigned long quirks;
+};

nit: Can you rename this to 'struct io_pgtable_domain_attr' please?

Done, thanks.

Signature · 6 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
#7 lore raw

PATCH v8 3/8 iommu/arm-smmu: Move non-strict mode to use domain_attr_io_pgtbl_cfg

In reply to Sai Prakash Ranjan

Now that we have a struct domain_attr_io_pgtbl_cfg 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 | 7 ++-----
 drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 -
 2 files changed, 2 insertions(+), 6 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +2 -5
index 7b05782738e2..5f066a1b7221 100644
@@ -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;
 
@@ -1527,7 +1524,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
 	case IOMMU_DOMAIN_DMA:
 		switch (attr) {
 		case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
-			*(int *)data = smmu_domain->non_strict;
+			*(int *)data = smmu_domain->pgtbl_cfg.quirks;
 			return 0;
 		default:
 			return -ENODEV;
@@ -1583,7 +1580,7 @@ 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;
+			smmu_domain->pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
 			break;
 		default:
 			ret = -ENODEV;
drivers/iommu/arm/arm-smmu/arm-smmu.h +0 -1
index 18fbed376afb..caae543ea077 100644
@@ -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
maintainer
#8 lore raw

Re: [PATCHv8 3/8] iommu/arm-smmu: Move non-strict mode to use domain_attr_io_pgtbl_cfg

Quoted 25 lines · Sai Prakash Ranjan

Now that we have a struct domain_attr_io_pgtbl_cfg 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 | 7 ++-----
 drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 -
 2 files changed, 2 insertions(+), 6 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +0 -3
index 7b05782738e2..5f066a1b7221 100644
@@ -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;
 

drivers/iommu/arm/arm-smmu/arm-smmu.c static int arm_smmu_domain_get_attr(struct iommu_domain *domain, · line 1527

Quoted 5 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +1 -1
@@ -1527,7 +1524,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
 	case IOMMU_DOMAIN_DMA:
 		switch (attr) {
 		case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
-			*(int *)data = smmu_domain->non_strict;
+			*(int *)data = smmu_domain->pgtbl_cfg.quirks;

Probably better to compare with IO_PGTABLE_QUIRK_NON_STRICT here even though we only support this one quirk for DMA domains atm.

Will
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#9 lore raw

Re: [PATCHv8 3/8] iommu/arm-smmu: Move non-strict mode to use domain_attr_io_pgtbl_cfg

Quoted 26 lines · Will Deacon
Quoted 25 lines · Sai Prakash Ranjan

Now that we have a struct domain_attr_io_pgtbl_cfg 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 | 7 ++-----
 drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 -
 2 files changed, 2 insertions(+), 6 deletions(-)
drivers/iommu/arm/arm-smmu/arm-smmu.c +0 -3
index 7b05782738e2..5f066a1b7221 100644
@@ -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;
Quoted 11 lines

drivers/iommu/arm/arm-smmu/arm-smmu.c static int arm_smmu_domain_get_attr(struct · line 1528

Quoted 7 lines
drivers/iommu/arm/arm-smmu/arm-smmu.c +1 -1
@@ -1527,7 +1524,7 @@ static int arm_smmu_domain_get_attr(struct 
 iommu_domain *domain,
 	case IOMMU_DOMAIN_DMA:
 		switch (attr) {
 		case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
-			*(int *)data = smmu_domain->non_strict;
+			*(int *)data = smmu_domain->pgtbl_cfg.quirks;

Probably better to compare with IO_PGTABLE_QUIRK_NON_STRICT here even though we only support this one quirk for DMA domains atm.

Ok will do, thanks.

Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
#10 lore raw

PATCH v8 4/8 drm/msm: rearrange the gpu_rmw() function

In reply to Sai Prakash Ranjan

From: 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
index 49685571dc0e..a1e22b974b77 100644
@@ -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
index b9dd8f8f4887..655b3b0424a1 100644
@@ -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
index 6c9e1fdc1a76..b2b419277953 100644
@@ -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
#11 lore raw

PATCH v8 5/8 drm/msm/a6xx: Add support for using system cache(LLC)

In reply to Sai Prakash Ranjan

From: 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.

[saiprakash.ranjan: fix to set attr before device attach to iommu and rebase]
---
 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
index 948f3656c20c..95c98c642876 100644
@@ -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
index 3eeebf6a754b..9e6079af679c 100644
@@ -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
index 458b5b26d3c2..df63f3fe639d 100644
@@ -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 domain_attr_io_pgtbl_cfg 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 · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
#12 lore raw

PATCH v8 6/8 drm/msm/a6xx: Add support for using system cache on MMU500 based targets

In reply to Sai Prakash Ranjan

From: 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
index 95c98c642876..3f8b92da8cba 100644
@@ -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
index 9e6079af679c..e793d329e77b 100644
@@ -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 · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
#13 lore raw

PATCH v8 7/8 iommu: arm-smmu-impl: Use table to list QCOM implementations

In reply to Sai Prakash Ranjan

Use 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
index 7fed89c9d18a..26e2734eb4d7 100644
@@ -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
index d0636c803a36..add1859b2899 100644
@@ -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
index caae543ea077..7db81c7c7833 100644
@@ -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
#14 lore raw

PATCH v8 8/8 iommu: arm-smmu-impl: Add a space before open parenthesis

In reply to Sai Prakash Ranjan

Fix 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
index 26e2734eb4d7..136872e77195 100644
@@ -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
maintainer
#15 lore raw
In reply to Sai Prakash Ranjan
Quoted 13 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.

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.

Quoted 7 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Modulo some minor comments I've made, this looks good to me. What is the plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the MSM GPU driver and I'd like to avoid conflicts with that.

Will

#16 lore raw
Quoted 23 lines · Will Deacon
Quoted 13 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.

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.

Quoted 8 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Quoted 4 lines

Modulo some minor comments I've made, this looks good to me. What is the plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the MSM GPU driver and I'd like to avoid conflicts with that.

SMMU bits are pretty much independent and GPU relies on the domain attribute and the quirk exposed, so as long as SMMU changes go in first it should be good. Rob?

Thanks,
Sai

Signature · 6 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
#17 lore raw
Quoted 32 lines · Sai Prakash Ranjan
Quoted 23 lines · Will Deacon
Quoted 13 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.

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.

Quoted 8 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Quoted 6 lines

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

Quoted 5 lines

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should be good.
Rob?

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

If Will/Robin dislike that approach, I'll pick up the parts of the drm patches which don't depend on the new attribute for v5.11 and the rest for v5.12.. or possibly a second late v5.11 pull req if airlied doesn't hate me too much for it.

Going forward, I think we will have one or two more co-dependent series, like the smmu iova fault handler improvements that Jordan posted. So I would like to hear how Will and Robin prefer to handle those.

BR,
-R

Quoted 7 lines

Thanks,
Sai

--
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

#18 lore raw
Quoted 34 lines · Rob Clark
Quoted 32 lines · Sai Prakash Ranjan
Quoted 29 lines · Will Deacon
Quoted 13 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.

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.

Quoted 8 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

Quoted 9 lines
Quoted 5 lines

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should be good.
Rob?

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

Ok I can split out domain attr and quirk into its own patch if Will is fine with that approach.

Quoted 5 lines

If Will/Robin dislike that approach, I'll pick up the parts of the drm patches which don't depend on the new attribute for v5.11 and the rest for v5.12.. or possibly a second late v5.11 pull req if airlied doesn't hate me too much for it.

Quoted 8 lines

Going forward, I think we will have one or two more co-dependent series, like the smmu iova fault handler improvements that Jordan posted. So I would like to hear how Will and Robin prefer to handle those.

BR,
-R

Thanks,
Sai

Signature · 6 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
maintainer
#19 lore raw
Quoted 42 lines · Sai Prakash Ranjan
Quoted 41 lines · Rob Clark
Quoted 38 lines · Sai Prakash Ranjan
Quoted 23 lines · Will Deacon
Quoted 13 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.

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.

Quoted 8 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Quoted 6 lines

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should
be good.
Rob?

Quoted 6 lines
Quoted 3 lines

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

Ok I can split out domain attr and quirk into its own patch if Will is fine with that approach.

Why don't I just queue the first two patches on their own branch and we both pull that?

Will

#20 lore raw
Quoted 48 lines · Will Deacon
Quoted 46 lines · Sai Prakash Ranjan
Quoted 44 lines · Rob Clark
Quoted 32 lines · Sai Prakash Ranjan
Quoted 23 lines · Will Deacon
Quoted 13 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.

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.

Quoted 8 lines

Patch 1 - Patch 6 adds system cache support in SMMU and GPU driver. Patch 7 and 8 are minor cleanups for arm-smmu impl.

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)

Quoted 6 lines

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

Quoted 6 lines

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should
be good.
Rob?

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

Quoted 5 lines
Quoted 2 lines

Ok I can split out domain attr and quirk into its own patch if Will is fine with that approach.

Why don't I just queue the first two patches on their own branch and we both pull that?

Ok, that works for me. I normally base msm-next on -rc1 but I guess as long as we base the branch on the older or our two -next branches, that should work out nicely

BR,
-R
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

maintainer
#21 lore raw
Quoted 27 lines · Rob Clark
Quoted 26 lines · Will Deacon
Quoted 24 lines · Sai Prakash Ranjan
Quoted 17 lines · Rob Clark
Quoted 8 lines · Sai Prakash Ranjan
Quoted 6 lines · Will Deacon

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

Quoted 6 lines

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should
be good.
Rob?

Quoted 3 lines

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

Ok I can split out domain attr and quirk into its own patch if Will is fine with that approach.

Quoted 6 lines
Quoted 2 lines

Why don't I just queue the first two patches on their own branch and we both pull that?

Ok, that works for me. I normally base msm-next on -rc1 but I guess as long as we base the branch on the older or our two -next branches, that should work out nicely

Turns out we're getting a v10 of Sai's stuff, so I've asked him to split patch two up anyway. Then I'll make a branch based on -rc1 that we can both pull.

Will
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#22 lore raw
Quoted 32 lines · Will Deacon
Quoted 30 lines · Rob Clark
Quoted 28 lines · Will Deacon
Quoted 18 lines · Sai Prakash Ranjan
Quoted 17 lines · Rob Clark
Quoted 14 lines · Sai Prakash Ranjan
Quoted 6 lines · Will Deacon

Modulo some minor comments I've made, this looks good to me. What is the
plan for merging it? I can take the IOMMU parts, but patches 4-6 touch the
MSM GPU driver and I'd like to avoid conflicts with that.

SMMU bits are pretty much independent and GPU relies on the domain attribute
and the quirk exposed, so as long as SMMU changes go in first it should
be good.
Rob?

Quoted 6 lines
Quoted 3 lines

I suppose one option would be to split out the patch that adds the attribute into it's own patch, and merge that both thru drm and iommu?

Ok I can split out domain attr and quirk into its own patch if Will is fine with that approach.

Why don't I just queue the first two patches on their own branch and we both pull that?

Quoted 7 lines
Quoted 3 lines

Ok, that works for me. I normally base msm-next on -rc1 but I guess as long as we base the branch on the older or our two -next branches, that should work out nicely

Turns out we're getting a v10 of Sai's stuff, so I've asked him to split patch two up anyway. Then I'll make a branch based on -rc1 that we can both pull.

Sounds good, thx

BR,
-R
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel