linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT
@ 2016-03-13 22:01 Yong Wu
  2016-03-13 22:01 ` [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor Yong Wu
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Yong Wu @ 2016-03-13 22:01 UTC (permalink / raw)
  To: Joerg Roedel, Robin Murphy, Will Deacon
  Cc: Matthias Brugger, Daniel Kurtz, Tomasz Figa, Lucas Stach,
	Rob Herring, Catalin Marinas, linux-mediatek, Sasha Hauer,
	srv_heupstream, linux-kernel, linux-arm-kernel, iommu, arnd,
	Laurent Pinchart, youhua.li, milton.chiang

This patch-set add MTK 4GB mode support on the Short-Descriptor.

Normally, the memory map in mt8173 looks like below:

Physical addr
| 1st GB |    ->  HW SRAM and Regs
|--------
| 2nd GB |    ->  Dram 1st GB
|--------
| 3rd GB |    ->  Dram 2nd GB
|--------
| 4th GB |    ->  Dram 3rd GB
|--------

Then if the dram size is 4GB, we have to add bit33 in the physical
address. We have a "DRAM 4GB mode" toggle bit for this.
If it is enabled, from CPU's point of view, the dram will
be shifted to start from PA 0x1_00000000. Then the dram PA is from
0x1_00000000~0x1_ffffffff.

MTK extend the bit9 of the standard pgtable descriptor as the 4GB mode.
we add a special quirk for this.

v2:
- Rebase on next-20160310.
- Rename IO_PGTABLE_QUIRK_MTK_4GB_EXT to IO_PGTABLE_QUIRK_ARM_MTK_4GB.
- Improve the comment of this "4GB mode".

Yong Wu (2):
  iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor
  iommu/mediatek: Add 4GB mode support

 drivers/iommu/io-pgtable-arm-v7s.c | 13 ++++++++++++-
 drivers/iommu/io-pgtable.h         |  6 ++++++
 drivers/iommu/mtk_iommu.c          | 14 +++++++++++---
 3 files changed, 29 insertions(+), 4 deletions(-)

-- 
1.8.1.1.dirty

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor
  2016-03-13 22:01 [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Yong Wu
@ 2016-03-13 22:01 ` Yong Wu
  2016-03-14 12:37   ` Robin Murphy
  2016-03-13 22:01 ` [PATCH v2 2/2] iommu/mediatek: Add 4GB mode support Yong Wu
  2016-04-05 13:41 ` [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Joerg Roedel
  2 siblings, 1 reply; 5+ messages in thread
From: Yong Wu @ 2016-03-13 22:01 UTC (permalink / raw)
  To: Joerg Roedel, Robin Murphy, Will Deacon
  Cc: Matthias Brugger, Daniel Kurtz, Tomasz Figa, Lucas Stach,
	Rob Herring, Catalin Marinas, linux-mediatek, Sasha Hauer,
	srv_heupstream, linux-kernel, linux-arm-kernel, iommu, arnd,
	Laurent Pinchart, youhua.li, milton.chiang, Yong Wu

In MT8173, Normally the first 1GB PA is for the HW SRAM and Regs,
so the PA will be 33bits if the dram size is 4GB. We have a
"DRAM 4GB mode" toggle bit for this. If it's enabled, from CPU's
point of view, the dram PA will be from 0x1_00000000~0x1_ffffffff.

In short descriptor, the pagetable descriptor is always 32bit.
Mediatek extend bit9 in the lvl1 and lvl2 pgtable descriptor
as the 4GB mode.

In the 4GB mode, the bit9 must be set, then M4U help add 0x1_00000000
based on the PA in pagetable. Thus the M4U output address to EMI is
always 33bits(the input address is still 32bits).

We add a special quirk for this MTK-4GB mode. And in the standard
spec, Bit9 in the lvl1 is "IMPLEMENTATION DEFINED", while it's AP[2]
in the lvl2, therefore if this quirk is enabled, NO_PERMS is also
expected.

Signed-off-by: Yong Wu <yong.wu@mediatek.com>
---
 drivers/iommu/io-pgtable-arm-v7s.c | 13 ++++++++++++-
 drivers/iommu/io-pgtable.h         |  6 ++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 9fcceb1..32b371b 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -121,6 +121,8 @@
 #define ARM_V7S_TEX_MASK		0x7
 #define ARM_V7S_ATTR_TEX(val)		(((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT)
 
+#define ARM_V7S_ATTR_MTK_4GB		BIT(9) /* MTK extend it for 4GB mode */
+
 /* *well, except for TEX on level 2 large pages, of course :( */
 #define ARM_V7S_CONT_PAGE_TEX_SHIFT	6
 #define ARM_V7S_CONT_PAGE_TEX_MASK	(ARM_V7S_TEX_MASK << ARM_V7S_CONT_PAGE_TEX_SHIFT)
@@ -364,6 +366,9 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
 	if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
 		pte |= ARM_V7S_ATTR_NS_SECTION;
 
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB)
+		pte |= ARM_V7S_ATTR_MTK_4GB;
+
 	if (num_entries > 1)
 		pte = arm_v7s_pte_to_cont(pte, lvl);
 
@@ -625,9 +630,15 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
 			    IO_PGTABLE_QUIRK_NO_PERMS |
-			    IO_PGTABLE_QUIRK_TLBI_ON_MAP))
+			    IO_PGTABLE_QUIRK_TLBI_ON_MAP |
+			    IO_PGTABLE_QUIRK_ARM_MTK_4GB))
 		return NULL;
 
+	/* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB &&
+	    !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS))
+			return NULL;
+
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return NULL;
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index d4f5027..969d82c 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -60,10 +60,16 @@ struct io_pgtable_cfg {
 	 * IO_PGTABLE_QUIRK_TLBI_ON_MAP: If the format forbids caching invalid
 	 *	(unmapped) entries but the hardware might do so anyway, perform
 	 *	TLB maintenance when mapping as well as when unmapping.
+	 *
+	 * IO_PGTABLE_QUIRK_ARM_MTK_4GB: (ARM v7s format) Set bit 9 in all
+	 *	PTEs, for Mediatek IOMMUs which treat it as a 33rd address bit
+	 *	when the SoC is in "4GB mode" and they can only access the high
+	 *	remap of DRAM (0x1_00000000 to 0x1_ffffffff).
 	 */
 	#define IO_PGTABLE_QUIRK_ARM_NS		BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS	BIT(1)
 	#define IO_PGTABLE_QUIRK_TLBI_ON_MAP	BIT(2)
+	#define IO_PGTABLE_QUIRK_ARM_MTK_4GB	BIT(3)
 	unsigned long			quirks;
 	unsigned long			pgsize_bitmap;
 	unsigned int			ias;
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] iommu/mediatek: Add 4GB mode support
  2016-03-13 22:01 [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Yong Wu
  2016-03-13 22:01 ` [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor Yong Wu
@ 2016-03-13 22:01 ` Yong Wu
  2016-04-05 13:41 ` [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Joerg Roedel
  2 siblings, 0 replies; 5+ messages in thread
From: Yong Wu @ 2016-03-13 22:01 UTC (permalink / raw)
  To: Joerg Roedel, Robin Murphy, Will Deacon
  Cc: Matthias Brugger, Daniel Kurtz, Tomasz Figa, Lucas Stach,
	Rob Herring, Catalin Marinas, linux-mediatek, Sasha Hauer,
	srv_heupstream, linux-kernel, linux-arm-kernel, iommu, arnd,
	Laurent Pinchart, youhua.li, milton.chiang, Yong Wu

This patch add 4GB mode support for m4u.

Signed-off-by: Yong Wu <yong.wu@mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 721ffdb..b97de21 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -11,6 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include <linux/bootmem.h>
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/component.h>
@@ -56,7 +57,7 @@
 #define F_MMU_TF_PROTECT_SEL(prot)		(((prot) & 0x3) << 5)
 
 #define REG_MMU_IVRP_PADDR			0x114
-#define F_MMU_IVRP_PA_SET(pa)			((pa) >> 1)
+#define F_MMU_IVRP_PA_SET(pa, ext)		(((pa) >> 1) | ((!!(ext)) << 31))
 
 #define REG_MMU_INT_CONTROL0			0x120
 #define F_L2_MULIT_HIT_EN			BIT(0)
@@ -125,6 +126,7 @@ struct mtk_iommu_data {
 	struct mtk_iommu_domain		*m4u_dom;
 	struct iommu_group		*m4u_group;
 	struct mtk_smi_iommu		smi_imu;      /* SMI larb iommu info */
+	bool                            enable_4GB;
 };
 
 static struct iommu_ops mtk_iommu_ops;
@@ -257,6 +259,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_data *data)
 		.iommu_dev = data->dev,
 	};
 
+	if (data->enable_4GB)
+		dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_4GB;
+
 	dom->iop = alloc_io_pgtable_ops(ARM_V7S, &dom->cfg, data);
 	if (!dom->iop) {
 		dev_err(data->dev, "Failed to alloc io pgtable\n");
@@ -530,7 +535,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
 	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
 
-	writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base),
+	writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base, data->enable_4GB),
 		       data->base + REG_MMU_IVRP_PADDR);
 
 	writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
@@ -592,6 +597,9 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
 
+	/* Whether the current dram is over 4GB */
+	data->enable_4GB = !!(max_pfn > (0xffffffffUL >> PAGE_SHIFT));
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	data->base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(data->base))
@@ -691,7 +699,7 @@ static int mtk_iommu_resume(struct device *dev)
 	writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
 	writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
 	writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
-	writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base),
+	writel_relaxed(F_MMU_IVRP_PA_SET(data->protect_base, data->enable_4GB),
 		       base + REG_MMU_IVRP_PADDR);
 	return 0;
 }
-- 
1.8.1.1.dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor
  2016-03-13 22:01 ` [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor Yong Wu
@ 2016-03-14 12:37   ` Robin Murphy
  0 siblings, 0 replies; 5+ messages in thread
From: Robin Murphy @ 2016-03-14 12:37 UTC (permalink / raw)
  To: Yong Wu, Joerg Roedel, Will Deacon
  Cc: Matthias Brugger, Daniel Kurtz, Tomasz Figa, Lucas Stach,
	Rob Herring, Catalin Marinas, linux-mediatek, Sasha Hauer,
	srv_heupstream, linux-kernel, linux-arm-kernel, iommu, arnd,
	Laurent Pinchart, youhua.li, milton.chiang

On 13/03/16 22:01, Yong Wu wrote:
> In MT8173, Normally the first 1GB PA is for the HW SRAM and Regs,
> so the PA will be 33bits if the dram size is 4GB. We have a
> "DRAM 4GB mode" toggle bit for this. If it's enabled, from CPU's
> point of view, the dram PA will be from 0x1_00000000~0x1_ffffffff.
>
> In short descriptor, the pagetable descriptor is always 32bit.
> Mediatek extend bit9 in the lvl1 and lvl2 pgtable descriptor
> as the 4GB mode.
>
> In the 4GB mode, the bit9 must be set, then M4U help add 0x1_00000000
> based on the PA in pagetable. Thus the M4U output address to EMI is
> always 33bits(the input address is still 32bits).
>
> We add a special quirk for this MTK-4GB mode. And in the standard
> spec, Bit9 in the lvl1 is "IMPLEMENTATION DEFINED", while it's AP[2]
> in the lvl2, therefore if this quirk is enabled, NO_PERMS is also
> expected.

Cool, thanks for making it make sense.

> Signed-off-by: Yong Wu <yong.wu@mediatek.com>

I guess there's some other hardware magic that deals with the address in 
the TTBR being truncated to 32 bits, but for this code doing what it 
claims to do:

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> ---
>   drivers/iommu/io-pgtable-arm-v7s.c | 13 ++++++++++++-
>   drivers/iommu/io-pgtable.h         |  6 ++++++
>   2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
> index 9fcceb1..32b371b 100644
> --- a/drivers/iommu/io-pgtable-arm-v7s.c
> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> @@ -121,6 +121,8 @@
>   #define ARM_V7S_TEX_MASK		0x7
>   #define ARM_V7S_ATTR_TEX(val)		(((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT)
>
> +#define ARM_V7S_ATTR_MTK_4GB		BIT(9) /* MTK extend it for 4GB mode */
> +
>   /* *well, except for TEX on level 2 large pages, of course :( */
>   #define ARM_V7S_CONT_PAGE_TEX_SHIFT	6
>   #define ARM_V7S_CONT_PAGE_TEX_MASK	(ARM_V7S_TEX_MASK << ARM_V7S_CONT_PAGE_TEX_SHIFT)
> @@ -364,6 +366,9 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
>   	if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
>   		pte |= ARM_V7S_ATTR_NS_SECTION;
>
> +	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB)
> +		pte |= ARM_V7S_ATTR_MTK_4GB;
> +
>   	if (num_entries > 1)
>   		pte = arm_v7s_pte_to_cont(pte, lvl);
>
> @@ -625,9 +630,15 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
>
>   	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
>   			    IO_PGTABLE_QUIRK_NO_PERMS |
> -			    IO_PGTABLE_QUIRK_TLBI_ON_MAP))
> +			    IO_PGTABLE_QUIRK_TLBI_ON_MAP |
> +			    IO_PGTABLE_QUIRK_ARM_MTK_4GB))
>   		return NULL;
>
> +	/* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
> +	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB &&
> +	    !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS))
> +			return NULL;
> +
>   	data = kmalloc(sizeof(*data), GFP_KERNEL);
>   	if (!data)
>   		return NULL;
> diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
> index d4f5027..969d82c 100644
> --- a/drivers/iommu/io-pgtable.h
> +++ b/drivers/iommu/io-pgtable.h
> @@ -60,10 +60,16 @@ struct io_pgtable_cfg {
>   	 * IO_PGTABLE_QUIRK_TLBI_ON_MAP: If the format forbids caching invalid
>   	 *	(unmapped) entries but the hardware might do so anyway, perform
>   	 *	TLB maintenance when mapping as well as when unmapping.
> +	 *
> +	 * IO_PGTABLE_QUIRK_ARM_MTK_4GB: (ARM v7s format) Set bit 9 in all
> +	 *	PTEs, for Mediatek IOMMUs which treat it as a 33rd address bit
> +	 *	when the SoC is in "4GB mode" and they can only access the high
> +	 *	remap of DRAM (0x1_00000000 to 0x1_ffffffff).
>   	 */
>   	#define IO_PGTABLE_QUIRK_ARM_NS		BIT(0)
>   	#define IO_PGTABLE_QUIRK_NO_PERMS	BIT(1)
>   	#define IO_PGTABLE_QUIRK_TLBI_ON_MAP	BIT(2)
> +	#define IO_PGTABLE_QUIRK_ARM_MTK_4GB	BIT(3)
>   	unsigned long			quirks;
>   	unsigned long			pgsize_bitmap;
>   	unsigned int			ias;
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT
  2016-03-13 22:01 [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Yong Wu
  2016-03-13 22:01 ` [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor Yong Wu
  2016-03-13 22:01 ` [PATCH v2 2/2] iommu/mediatek: Add 4GB mode support Yong Wu
@ 2016-04-05 13:41 ` Joerg Roedel
  2 siblings, 0 replies; 5+ messages in thread
From: Joerg Roedel @ 2016-04-05 13:41 UTC (permalink / raw)
  To: Yong Wu
  Cc: Robin Murphy, Will Deacon, Matthias Brugger, Daniel Kurtz,
	Tomasz Figa, Lucas Stach, Rob Herring, Catalin Marinas,
	linux-mediatek, Sasha Hauer, srv_heupstream, linux-kernel,
	linux-arm-kernel, iommu, arnd, Laurent Pinchart, youhua.li,
	milton.chiang

On Mon, Mar 14, 2016 at 06:01:09AM +0800, Yong Wu wrote:
> Yong Wu (2):
>   iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor
>   iommu/mediatek: Add 4GB mode support

Applied both, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-04-05 13:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-13 22:01 [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Yong Wu
2016-03-13 22:01 ` [PATCH v2 1/2] iommu/io-pgtable: Add MTK 4GB mode in Short-descriptor Yong Wu
2016-03-14 12:37   ` Robin Murphy
2016-03-13 22:01 ` [PATCH v2 2/2] iommu/mediatek: Add 4GB mode support Yong Wu
2016-04-05 13:41 ` [PATCH v2 0/2] MT8173 IOMMU 4GB MODE SUPPORT Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).