* [PATCH 0/6] iommu/tegra124: smmu: add T124 enhancement
@ 2013-12-05 12:25 Hiroshi Doyu
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu
Hi,
The basics of Tegra SMMU has been same over generations except that
each SoC has its own combination of HardWare Accelerators(HWA). This
combination is presented by swgroup ID. This difference is handled by
the previous "Unifying SMMU driver among Tegra SoCs" patch
series[1]. For the new Tegra SoC 124 SMMU has been slightly
enhanced. To support this minor changes, Tegra SMMU platfrom data is
introduced. This data set can be choosen by DT ".comptibility"
flag. If the further tegra SoC need to tweak those parameters, we can
think of moving some of them into DT bindings eventually.
This series depend on v6 of:
"[PATCHv6 00/13] Unifying SMMU driver among Tegra SoCs"[1]
A whole patches is available in the git repository at:
git://git-HoETi0wPbwRDw2glCA4ptUEOCMrvLtNR@public.gmane.org/user/hdoyu/linux.git smmu-upstreaming@20131205
Hiroshi Doyu (6):
iommu/tegra124: smmu: optionaly AHB enables SMMU
iommu/tegra124: smmu: convert swgroup ID to asid offset
iommu/tegra124: smmu: add support platform data
iommu/tegra124: smmu: support more than 32 bit pa
iommu/tegra124: smmu: {TLB,PTC} reset value per SoC
yiommu/tegra124: smmu: adjust TLB_FLUSH_ASID bit range
.../bindings/iommu/nvidia,tegra30-smmu.txt | 4 +-
drivers/iommu/tegra-smmu.c | 157 +++++++++++++++------
2 files changed, 115 insertions(+), 46 deletions(-)
--
1.8.1.5
[1] http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007048.html
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/6] iommu/tegra124: smmu: optionaly AHB enables SMMU
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-12-05 12:25 ` Hiroshi Doyu
[not found] ` <1386246319-17851-2-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 2/6] iommu/tegra124: smmu: convert swgroup ID to asid offset Hiroshi Doyu
` (5 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu
SMMU used to depend on AHB bus. AHB driver needs to be populated and
AHB_XBAR_CTRL_SMMU_INIT_DONE bit needs to be set earliear than SMMU
being populated. Later Tegra SoC (>= T124) doesn't need AHB to enable
SMMU on AHB_XBAR_CTRL for AHB_XBAR_CTRL_SMMU_INIT_DONE any more. This
setting bit is now optional, depending on DT passing ahb phandle or
not.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/iommu/tegra-smmu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index d0f0ba7..f63d54a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -500,7 +500,10 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_flush_regs(smmu, 1);
- return tegra_ahb_enable_smmu(smmu->ahb);
+ if (smmu->ahb)
+ return tegra_ahb_enable_smmu(smmu->ahb);
+
+ return 0;
}
static void flush_ptc_and_tlb(struct smmu_device *smmu,
@@ -1284,9 +1287,6 @@ static int tegra_smmu_probe(struct platform_device *pdev)
return -EINVAL;
smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0);
- if (!smmu->ahb)
- return -ENODEV;
-
smmu->iommu.dev = dev;
smmu->num_as = asids;
smmu->iovmm_base = base;
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/6] iommu/tegra124: smmu: convert swgroup ID to asid offset
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 1/6] iommu/tegra124: smmu: optionaly AHB enables SMMU Hiroshi Doyu
@ 2013-12-05 12:25 ` Hiroshi Doyu
2013-12-05 12:25 ` [PATCH 3/6] iommu/tegra124: smmu: add support platform data Hiroshi Doyu
` (4 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Provide a conversion table from swgroup ID to MC_SMMU_<swgroup
name>_ASID_0 register offset to support non-linear conversion. This
conversion used to be exactly linear but after T124 we need a
conversion table to support non-linear cases. We would also need
another table to convert swgroup ID to HOTRESET bit.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/iommu/tegra-smmu.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index f63d54a..a723a1b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -184,8 +184,6 @@ enum {
#define __smmu_client_enable_swgroups(c, m) __smmu_client_set_swgroups(c, m, 1)
#define __smmu_client_disable_swgroups(c) __smmu_client_set_swgroups(c, 0, 0)
-#define SWGROUPS_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
-
/*
* Per client for address space
*/
@@ -314,6 +312,23 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
*/
#define FLUSH_SMMU_REGS(smmu) smmu_read(smmu, SMMU_CONFIG)
+static size_t smmu_get_asid_offset(int id)
+{
+ switch (id) {
+ case TEGRA_SWGROUP_DC14:
+ return 0x490;
+ case TEGRA_SWGROUP_DC12:
+ return 0xa88;
+ case TEGRA_SWGROUP_AFI...TEGRA_SWGROUP_ISP:
+ case TEGRA_SWGROUP_MPE...TEGRA_SWGROUP_PPCS1:
+ return (id - TEGRA_SWGROUP_AFI) * sizeof(u32) + SMMU_ASID_BASE;
+ case TEGRA_SWGROUP_SDMMC1A...63:
+ return (id - TEGRA_SWGROUP_SDMMC1A) * sizeof(u32) + 0xa94;
+ };
+
+ BUG();
+}
+
static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
struct device_node *dev_node)
{
@@ -416,7 +431,7 @@ static int __smmu_client_set_swgroups(struct smmu_client *c,
map = c->swgroups;
for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
- offs = SWGROUPS_ASID_REG(i);
+ offs = smmu_get_asid_offset(i);
val = smmu_read(smmu, offs);
if (on) {
if (val) {
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/6] iommu/tegra124: smmu: add support platform data
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 1/6] iommu/tegra124: smmu: optionaly AHB enables SMMU Hiroshi Doyu
2013-12-05 12:25 ` [PATCH 2/6] iommu/tegra124: smmu: convert swgroup ID to asid offset Hiroshi Doyu
@ 2013-12-05 12:25 ` Hiroshi Doyu
[not found] ` <1386246319-17851-4-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa Hiroshi Doyu
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu
The later Tegra SoC(>= T124) has more registers for
MC_SMMU_TRANSLATION_ENABLE_*. Now those info is provided as platfrom
data. If those varies a lot on SoCs in the future, we can consider
putting them into DT later.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
.../bindings/iommu/nvidia,tegra30-smmu.txt | 4 +-
drivers/iommu/tegra-smmu.c | 68 ++++++++++++++--------
2 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index fd53f54..71be0d2 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -1,8 +1,8 @@
NVIDIA Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit)
Required properties in the IOMMU node:
-- compatible : "nvidia,tegra30-smmu"
-- reg : Should contain 3 register banks(address and length) for each
+- compatible : "nvidia,tegra124-smmu", "nvidia,tegra30-smmu"
+- reg : Can contain multiple register banks(address and length) for each
of the SMMU register blocks.
- interrupts : Should contain MC General interrupt.
- nvidia,#asids : # of ASIDs
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index a723a1b..b5737f9 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -32,6 +32,7 @@
#include <linux/iommu.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_iommu.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -108,8 +109,6 @@ enum {
(SMMU_STATS_CACHE_COUNT_BASE + 8 * cache + 4 * hitmiss)
#define SMMU_TRANSLATION_ENABLE_0 0x228
-#define SMMU_TRANSLATION_ENABLE_1 0x22c
-#define SMMU_TRANSLATION_ENABLE_2 0x230
#define SMMU_AFI_ASID 0x238 /* PCIE */
#define SMMU_ASID_BASE SMMU_AFI_ASID
@@ -237,12 +236,12 @@ struct smmu_device {
struct rb_root clients;
struct page *avp_vector_page; /* dummy page shared by all AS's */
+ int nr_xlats; /* number of translation_enable registers */
+
/*
* Register image savers for suspend/resume
*/
- unsigned long translation_enable_0;
- unsigned long translation_enable_1;
- unsigned long translation_enable_2;
+ u32 *xlat;
unsigned long asid_security;
struct dentry *debugfs_root;
@@ -256,6 +255,11 @@ struct smmu_device {
struct smmu_as as[0]; /* Run-time allocated array */
};
+struct smmu_platform_data {
+ int asids; /* number of asids */
+ int nr_xlats; /* number of translation_enable registers */
+};
+
static struct smmu_device *smmu_handle; /* unique for a system */
/*
@@ -506,9 +510,10 @@ static int smmu_setup_regs(struct smmu_device *smmu)
__smmu_client_set_swgroups(c, c->swgroups, 1);
}
- smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
- smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1);
- smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2);
+ for (i = 0; i < smmu->nr_xlats; i++)
+ smmu_write(smmu, smmu->xlat[i],
+ SMMU_TRANSLATION_ENABLE_0 + i * sizeof(u32));
+
smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_TLB));
smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_PTC));
@@ -1205,11 +1210,13 @@ err_out:
static int tegra_smmu_suspend(struct device *dev)
{
+ int i;
struct smmu_device *smmu = dev_get_drvdata(dev);
- smmu->translation_enable_0 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_0);
- smmu->translation_enable_1 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_1);
- smmu->translation_enable_2 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_2);
+ for (i = 0; i < smmu->nr_xlats; i++)
+ smmu->xlat[i] = smmu_read(smmu,
+ SMMU_TRANSLATION_ENABLE_0 + i * sizeof(u32));
+
smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY);
return 0;
}
@@ -1243,6 +1250,18 @@ static void tegra_smmu_create_default_map(struct smmu_device *smmu)
}
}
+static const struct smmu_platform_data tegra124_smmu_pdata = {
+ .asids = 128,
+ .nr_xlats = 4,
+};
+
+static struct of_device_id tegra_smmu_of_match[] = {
+ { .compatible = "nvidia,tegra124-smmu", .data = &tegra124_smmu_pdata, },
+ { .compatible = "nvidia,tegra30-smmu", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tegra_smmu_of_match);
+
static int tegra_smmu_probe(struct platform_device *pdev)
{
struct smmu_device *smmu;
@@ -1250,20 +1269,29 @@ static int tegra_smmu_probe(struct platform_device *pdev)
int i, asids, err = 0;
dma_addr_t uninitialized_var(base);
size_t bytes, uninitialized_var(size);
+ const struct of_device_id *match;
+ const struct smmu_platform_data *pdata;
+ int nr_xlats;
if (smmu_handle)
return -EIO;
BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT);
- if (of_property_read_u32(dev->of_node, "nvidia,#asids", &asids))
- return -ENODEV;
+ match = of_match_device(tegra_smmu_of_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+ pdata = match->data;
+ nr_xlats = (pdata && pdata->nr_xlats) ? pdata->nr_xlats : 3;
+ if (of_property_read_u32(dev->of_node, "nvidia,#asids", &asids))
+ asids = (pdata && pdata->asids) ? pdata->asids : 4;
if (asids < NUM_OF_STATIC_MAPS)
return -EINVAL;
bytes = sizeof(*smmu) + asids * (sizeof(*smmu->as) +
sizeof(struct dma_iommu_mapping *));
+ bytes += sizeof(u32) * nr_xlats;
smmu = devm_kzalloc(dev, bytes, GFP_KERNEL);
if (!smmu) {
dev_err(dev, "failed to allocate smmu_device\n");
@@ -1272,6 +1300,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->clients = RB_ROOT;
smmu->map = (struct dma_iommu_mapping **)(smmu->as + asids);
+ smmu->xlat = (u32 *)(smmu->map + smmu->num_as);
smmu->nregs = pdev->num_resources;
smmu->regs = devm_kzalloc(dev, 2 * smmu->nregs * sizeof(*smmu->regs),
GFP_KERNEL);
@@ -1304,13 +1333,12 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0);
smmu->iommu.dev = dev;
smmu->num_as = asids;
+ smmu->nr_xlats = nr_xlats;
smmu->iovmm_base = base;
smmu->page_count = size;
-
- smmu->translation_enable_0 = ~0;
- smmu->translation_enable_1 = ~0;
- smmu->translation_enable_2 = ~0;
smmu->asid_security = 0;
+ for (i = 0; i < smmu->nr_xlats; i++)
+ smmu->xlat[i] = ~0;
for (i = 0; i < smmu->num_as; i++) {
struct smmu_as *as = &smmu->as[i];
@@ -1365,12 +1393,6 @@ static const struct dev_pm_ops tegra_smmu_pm_ops = {
.resume = tegra_smmu_resume,
};
-static struct of_device_id tegra_smmu_of_match[] = {
- { .compatible = "nvidia,tegra30-smmu", },
- { },
-};
-MODULE_DEVICE_TABLE(of, tegra_smmu_of_match);
-
static struct platform_driver tegra_smmu_driver = {
.probe = tegra_smmu_probe,
.remove = tegra_smmu_remove,
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2013-12-05 12:25 ` [PATCH 3/6] iommu/tegra124: smmu: add support platform data Hiroshi Doyu
@ 2013-12-05 12:25 ` Hiroshi Doyu
[not found] ` <1386246319-17851-5-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 5/6] iommu/tegra124: smmu: {TLB,PTC} reset value per SoC Hiroshi Doyu
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu, Pavan Kunapuli
Add support for more than 32 bit physical address. If physical
address space is 32bit, there will be no register write
happening. Based on Pavan's internal patch.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: Pavan Kunapuli <pkunapuli-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/iommu/tegra-smmu.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index b5737f9..04e7199 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -101,6 +101,8 @@ enum {
#define SMMU_PTC_FLUSH_TYPE_ADR 1
#define SMMU_PTC_FLUSH_ADR_SHIFT 4
+#define SMMU_PTC_FLUSH_1 0x9b8
+
#define SMMU_ASID_SECURITY 0x38
#define SMMU_STATS_CACHE_COUNT_BASE 0x1f0
@@ -143,7 +145,7 @@ enum {
#define SMMU_PDIR_SHIFT 12
#define SMMU_PDE_SHIFT 12
#define SMMU_PTE_SHIFT 12
-#define SMMU_PFN_MASK 0x000fffff
+#define SMMU_PFN_MASK 0x0fffffff
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
@@ -301,6 +303,8 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
#define VA_PAGE_TO_PA(va, page) \
(page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK))
+#define VA_PAGE_TO_PA_HI(va, page) (u32)((u64)page_to_phys(page) >> 32)
+
#define FLUSH_CPU_DCACHE(va, page, size) \
do { \
unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \
@@ -526,6 +530,21 @@ static int smmu_setup_regs(struct smmu_device *smmu)
return 0;
}
+static void flush_ptc_by_addr(struct smmu_device *smmu, unsigned long *pte,
+ struct page *page)
+{
+ u32 val;
+
+ val = VA_PAGE_TO_PA_HI(pte, page);
+ if (val)
+ smmu_write(smmu, val, SMMU_PTC_FLUSH_1);
+
+ val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
+ smmu_write(smmu, val, SMMU_PTC_FLUSH);
+
+ FLUSH_SMMU_REGS(smmu);
+}
+
static void flush_ptc_and_tlb(struct smmu_device *smmu,
struct smmu_as *as, dma_addr_t iova,
unsigned long *pte, struct page *page, int is_pde)
@@ -535,9 +554,8 @@ static void flush_ptc_and_tlb(struct smmu_device *smmu,
? SMMU_TLB_FLUSH_VA(iova, SECTION)
: SMMU_TLB_FLUSH_VA(iova, GROUP);
- val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
- smmu_write(smmu, val, SMMU_PTC_FLUSH);
- FLUSH_SMMU_REGS(smmu);
+ flush_ptc_by_addr(smmu, pte, page);
+
val = tlb_flush_va |
SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
(as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
@@ -702,9 +720,9 @@ static int alloc_pdir(struct smmu_as *as)
for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
pdir[pdn] = _PDE_VACANT(pdn);
FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE);
- val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page);
- smmu_write(smmu, val, SMMU_PTC_FLUSH);
- FLUSH_SMMU_REGS(as->smmu);
+
+ flush_ptc_by_addr(as->smmu, pdir, page);
+
val = SMMU_TLB_FLUSH_VA_MATCH_ALL |
SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
(as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/6] iommu/tegra124: smmu: {TLB,PTC} reset value per SoC
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (3 preceding siblings ...)
2013-12-05 12:25 ` [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa Hiroshi Doyu
@ 2013-12-05 12:25 ` Hiroshi Doyu
[not found] ` <1386246319-17851-6-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 6/6] iommu/tegra124: smmu: adjust TLB_FLUSH_ASID bit range Hiroshi Doyu
2013-12-09 7:16 ` [PATCH 7/6] iommu/tegra124: smmu: add multiple asid_security support Hiroshi Doyu
6 siblings, 1 reply; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu
T124 has some new register bits in {TLB,PTC}_CONFIG:
- TLB_RR_ARB and PTC_REQ_LIMIT
- TLB_ACTIVE_LINES 0x20 instead of 0x10
They are defined as platform data now.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/iommu/tegra-smmu.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 04e7199..9b81e3a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -71,12 +71,13 @@ enum {
#define SMMU_CACHE_CONFIG_STATS_TEST (1 << SMMU_CACHE_CONFIG_STATS_TEST_SHIFT)
#define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE (1 << 29)
-#define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE 0x10
-#define SMMU_TLB_CONFIG_RESET_VAL 0x20000010
+#define SMMU_TLB_CONFIG_RESET_VAL 0x20000000
+#define SMMU_TLB_RR_ARB (1 << 28)
#define SMMU_PTC_CONFIG_CACHE__ENABLE (1 << 29)
#define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN 0x3f
#define SMMU_PTC_CONFIG_RESET_VAL 0x2000003f
+#define SMMU_PTC_REQ_LIMIT (8 << 24)
#define SMMU_PTB_ASID 0x1c
#define SMMU_PTB_ASID_CURRENT_SHIFT 0
@@ -239,6 +240,8 @@ struct smmu_device {
struct page *avp_vector_page; /* dummy page shared by all AS's */
int nr_xlats; /* number of translation_enable registers */
+ u32 tlb_reset; /* TLB config reset value */
+ u32 ptc_reset; /* PTC config reset value */
/*
* Register image savers for suspend/resume
@@ -260,6 +263,8 @@ struct smmu_device {
struct smmu_platform_data {
int asids; /* number of asids */
int nr_xlats; /* number of translation_enable registers */
+ u32 tlb_reset; /* TLB config reset value */
+ u32 ptc_reset; /* PTC config reset value */
};
static struct smmu_device *smmu_handle; /* unique for a system */
@@ -519,8 +524,8 @@ static int smmu_setup_regs(struct smmu_device *smmu)
SMMU_TRANSLATION_ENABLE_0 + i * sizeof(u32));
smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
- smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_TLB));
- smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_PTC));
+ smmu_write(smmu, smmu->ptc_reset, SMMU_CACHE_CONFIG(_PTC));
+ smmu_write(smmu, smmu->tlb_reset, SMMU_CACHE_CONFIG(_TLB));
smmu_flush_regs(smmu, 1);
@@ -1271,6 +1276,8 @@ static void tegra_smmu_create_default_map(struct smmu_device *smmu)
static const struct smmu_platform_data tegra124_smmu_pdata = {
.asids = 128,
.nr_xlats = 4,
+ .tlb_reset = SMMU_TLB_CONFIG_RESET_VAL | SMMU_TLB_RR_ARB | 0x20,
+ .ptc_reset = SMMU_PTC_CONFIG_RESET_VAL | SMMU_PTC_REQ_LIMIT,
};
static struct of_device_id tegra_smmu_of_match[] = {
@@ -1320,6 +1327,10 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->map = (struct dma_iommu_mapping **)(smmu->as + asids);
smmu->xlat = (u32 *)(smmu->map + smmu->num_as);
smmu->nregs = pdev->num_resources;
+ smmu->tlb_reset = (pdata && pdata->tlb_reset) ? pdata->tlb_reset :
+ (SMMU_TLB_CONFIG_RESET_VAL | 0x10);
+ smmu->ptc_reset = (pdata && pdata->ptc_reset) ? pdata->ptc_reset :
+ (SMMU_PTC_CONFIG_RESET_VAL | SMMU_PTC_REQ_LIMIT);
smmu->regs = devm_kzalloc(dev, 2 * smmu->nregs * sizeof(*smmu->regs),
GFP_KERNEL);
smmu->rege = smmu->regs + smmu->nregs;
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/6] iommu/tegra124: smmu: adjust TLB_FLUSH_ASID bit range
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (4 preceding siblings ...)
2013-12-05 12:25 ` [PATCH 5/6] iommu/tegra124: smmu: {TLB,PTC} reset value per SoC Hiroshi Doyu
@ 2013-12-05 12:25 ` Hiroshi Doyu
2013-12-09 7:16 ` [PATCH 7/6] iommu/tegra124: smmu: add multiple asid_security support Hiroshi Doyu
6 siblings, 0 replies; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-05 12:25 UTC (permalink / raw)
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A, Hiroshi Doyu, Terje Bergstrom
TLB_FLUSH_ASID bit range depends on the number of asids to support
other number than the current 4, especially for a new Tegra124. Based
on Terje's internal patch.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: Terje Bergstrom <tbergstrom-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/iommu/tegra-smmu.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 9b81e3a..535b14a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -92,11 +92,14 @@ enum {
#define SMMU_TLB_FLUSH_VA_MATCH_ALL 0
#define SMMU_TLB_FLUSH_VA_MATCH_SECTION 2
#define SMMU_TLB_FLUSH_VA_MATCH_GROUP 3
-#define SMMU_TLB_FLUSH_ASID_SHIFT 29
+#define SMMU_TLB_FLUSH_ASID_SHIFT_BASE 31
#define SMMU_TLB_FLUSH_ASID_MATCH_DISABLE 0
#define SMMU_TLB_FLUSH_ASID_MATCH_ENABLE 1
#define SMMU_TLB_FLUSH_ASID_MATCH_SHIFT 31
+#define SMMU_TLB_FLUSH_ASID_SHIFT(as) \
+ (SMMU_TLB_FLUSH_ASID_SHIFT_BASE - __ffs((as)->smmu->num_as))
+
#define SMMU_PTC_FLUSH 0x34
#define SMMU_PTC_FLUSH_TYPE_ALL 0
#define SMMU_PTC_FLUSH_TYPE_ADR 1
@@ -563,7 +566,7 @@ static void flush_ptc_and_tlb(struct smmu_device *smmu,
val = tlb_flush_va |
SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
- (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
+ (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT(as));
smmu_write(smmu, val, SMMU_TLB_FLUSH);
FLUSH_SMMU_REGS(smmu);
}
@@ -730,7 +733,7 @@ static int alloc_pdir(struct smmu_as *as)
val = SMMU_TLB_FLUSH_VA_MATCH_ALL |
SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
- (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
+ (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT(as));
smmu_write(smmu, val, SMMU_TLB_FLUSH);
FLUSH_SMMU_REGS(as->smmu);
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/6] iommu/tegra124: smmu: add multiple asid_security support
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (5 preceding siblings ...)
2013-12-05 12:25 ` [PATCH 6/6] iommu/tegra124: smmu: adjust TLB_FLUSH_ASID bit range Hiroshi Doyu
@ 2013-12-09 7:16 ` Hiroshi Doyu
6 siblings, 0 replies; 14+ messages in thread
From: Hiroshi Doyu @ 2013-12-09 7:16 UTC (permalink / raw)
To: hdoyu-DDmLM1+adcrQT0dZR+AlfA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A
In Tegra124 the number of MC_SMMU_ASID_SECURITY_# registers
increased. Now this info is provided as platfrom data. If no platfrom
data the default valude(1) is used.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
Sending now as [PATCH 7/6] because this was missed from the thread.
---
drivers/iommu/tegra-smmu.c | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 535b14a..5524773 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -108,6 +108,13 @@ enum {
#define SMMU_PTC_FLUSH_1 0x9b8
#define SMMU_ASID_SECURITY 0x38
+#define SMMU_ASID_SECURITY_1 0x3c
+#define SMMU_ASID_SECURITY_2 0x9e0
+#define SMMU_ASID_SECURITY_3 0x9e4
+#define SMMU_ASID_SECURITY_4 0x9e8
+#define SMMU_ASID_SECURITY_5 0x9ec
+#define SMMU_ASID_SECURITY_6 0x9f0
+#define SMMU_ASID_SECURITY_7 0x9f4
#define SMMU_STATS_CACHE_COUNT_BASE 0x1f0
@@ -243,6 +250,7 @@ struct smmu_device {
struct page *avp_vector_page; /* dummy page shared by all AS's */
int nr_xlats; /* number of translation_enable registers */
+ int nr_asid_secs; /* number of asid_security registers */
u32 tlb_reset; /* TLB config reset value */
u32 ptc_reset; /* PTC config reset value */
@@ -250,7 +258,7 @@ struct smmu_device {
* Register image savers for suspend/resume
*/
u32 *xlat;
- unsigned long asid_security;
+ u32 *asid_sec;
struct dentry *debugfs_root;
struct smmu_debugfs_info *debugfs_info;
@@ -266,6 +274,7 @@ struct smmu_device {
struct smmu_platform_data {
int asids; /* number of asids */
int nr_xlats; /* number of translation_enable registers */
+ int nr_asid_secs; /* number of asid_security registers */
u32 tlb_reset; /* TLB config reset value */
u32 ptc_reset; /* PTC config reset value */
};
@@ -328,6 +337,17 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
*/
#define FLUSH_SMMU_REGS(smmu) smmu_read(smmu, SMMU_CONFIG)
+static const u32 smmu_asid_sec_ofs[] = {
+ SMMU_ASID_SECURITY,
+ SMMU_ASID_SECURITY_1,
+ SMMU_ASID_SECURITY_2,
+ SMMU_ASID_SECURITY_3,
+ SMMU_ASID_SECURITY_4,
+ SMMU_ASID_SECURITY_5,
+ SMMU_ASID_SECURITY_6,
+ SMMU_ASID_SECURITY_7,
+};
+
static size_t smmu_get_asid_offset(int id)
{
switch (id) {
@@ -526,7 +546,9 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, smmu->xlat[i],
SMMU_TRANSLATION_ENABLE_0 + i * sizeof(u32));
- smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
+ for (i = 0; i < smmu->nr_asid_secs; i++)
+ smmu_write(smmu, smmu->asid_sec[i], smmu_asid_sec_ofs[i]);
+
smmu_write(smmu, smmu->ptc_reset, SMMU_CACHE_CONFIG(_PTC));
smmu_write(smmu, smmu->tlb_reset, SMMU_CACHE_CONFIG(_TLB));
@@ -1243,7 +1265,9 @@ static int tegra_smmu_suspend(struct device *dev)
smmu->xlat[i] = smmu_read(smmu,
SMMU_TRANSLATION_ENABLE_0 + i * sizeof(u32));
- smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY);
+ for (i = 0; i < smmu->nr_asid_secs; i++)
+ smmu->asid_sec[i] =
+ smmu_read(smmu, smmu_asid_sec_ofs[i]);
return 0;
}
@@ -1279,6 +1303,7 @@ static void tegra_smmu_create_default_map(struct smmu_device *smmu)
static const struct smmu_platform_data tegra124_smmu_pdata = {
.asids = 128,
.nr_xlats = 4,
+ .nr_asid_secs = 8,
.tlb_reset = SMMU_TLB_CONFIG_RESET_VAL | SMMU_TLB_RR_ARB | 0x20,
.ptc_reset = SMMU_PTC_CONFIG_RESET_VAL | SMMU_PTC_REQ_LIMIT,
};
@@ -1299,7 +1324,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
size_t bytes, uninitialized_var(size);
const struct of_device_id *match;
const struct smmu_platform_data *pdata;
- int nr_xlats;
+ int nr_xlats, nr_asid_secs;
if (smmu_handle)
return -EIO;
@@ -1311,6 +1336,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
return -EINVAL;
pdata = match->data;
nr_xlats = (pdata && pdata->nr_xlats) ? pdata->nr_xlats : 3;
+ nr_asid_secs = (pdata && pdata->nr_asid_secs) ? pdata->nr_asid_secs : 1;
if (of_property_read_u32(dev->of_node, "nvidia,#asids", &asids))
asids = (pdata && pdata->asids) ? pdata->asids : 4;
@@ -1319,7 +1345,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
bytes = sizeof(*smmu) + asids * (sizeof(*smmu->as) +
sizeof(struct dma_iommu_mapping *));
- bytes += sizeof(u32) * nr_xlats;
+ bytes += sizeof(u32) * (nr_asid_secs + nr_xlats);
smmu = devm_kzalloc(dev, bytes, GFP_KERNEL);
if (!smmu) {
dev_err(dev, "failed to allocate smmu_device\n");
@@ -1329,6 +1355,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->clients = RB_ROOT;
smmu->map = (struct dma_iommu_mapping **)(smmu->as + asids);
smmu->xlat = (u32 *)(smmu->map + smmu->num_as);
+ smmu->asid_sec = smmu->xlat + smmu->nr_xlats;
smmu->nregs = pdev->num_resources;
smmu->tlb_reset = (pdata && pdata->tlb_reset) ? pdata->tlb_reset :
(SMMU_TLB_CONFIG_RESET_VAL | 0x10);
@@ -1368,7 +1395,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu->nr_xlats = nr_xlats;
smmu->iovmm_base = base;
smmu->page_count = size;
- smmu->asid_security = 0;
+ smmu->nr_asid_secs = nr_asid_secs;
for (i = 0; i < smmu->nr_xlats; i++)
smmu->xlat[i] = ~0;
--
1.8.1.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/6] iommu/tegra124: smmu: add support platform data
[not found] ` <1386246319-17851-4-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-12-16 20:36 ` Stephen Warren
0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2013-12-16 20:36 UTC (permalink / raw)
To: Hiroshi Doyu, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A
On 12/05/2013 05:25 AM, Hiroshi Doyu wrote:
> The later Tegra SoC(>= T124) has more registers for
> MC_SMMU_TRANSLATION_ENABLE_*. Now those info is provided as platfrom
> data. If those varies a lot on SoCs in the future, we can consider
> putting them into DT later.
This shouldn't be called "platform data", since that phrase already has
an existing different meaning within Linux. Instead, perhaps
"SoC-specific configuration" or "HW-specific configuration" (or
s/configuration/parameters/).
> diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
> Required properties in the IOMMU node:
> -- compatible : "nvidia,tegra30-smmu"
> -- reg : Should contain 3 register banks(address and length) for each
> +- compatible : "nvidia,tegra124-smmu", "nvidia,tegra30-smmu"
> +- reg : Can contain multiple register banks(address and length) for each
Not all DTs should include both. I would phrase this as:
- compatible : One of the following:
- nvidia,tegra30-smmu
- nvidia,tegra124-smmu
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> +struct smmu_platform_data {
> + int asids; /* number of asids */
> + int nr_xlats; /* number of translation_enable registers */
> +};
Shouldn't both or neither of those fields be prefixed with "nr_" for
consistency?
> +static const struct smmu_platform_data tegra124_smmu_pdata = {
> + .asids = 128,
> + .nr_xlats = 4,
> +};
> +
> +static struct of_device_id tegra_smmu_of_match[] = {
> + { .compatible = "nvidia,tegra124-smmu", .data = &tegra124_smmu_pdata, },
> + { .compatible = "nvidia,tegra30-smmu", },
Where is tegra30_smmu_pdata, and why doesn't this table entry point at
it? That would avoid conditional code elsewhere.
> @@ -1250,20 +1269,29 @@ static int tegra_smmu_probe(struct platform_device *pdev)
> + smmu->nr_xlats = nr_xlats;
Why not just:
smmu->pdata = pdata;
That would avoid having to change this code to copy new fields every
time they get added.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/6] iommu/tegra124: smmu: optionaly AHB enables SMMU
[not found] ` <1386246319-17851-2-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-12-16 20:37 ` Stephen Warren
0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2013-12-16 20:37 UTC (permalink / raw)
To: Hiroshi Doyu, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: joro-zLv9SwRftAIdnm+yROfE0A
On 12/05/2013 05:25 AM, Hiroshi Doyu wrote:
> SMMU used to depend on AHB bus. AHB driver needs to be populated and
> AHB_XBAR_CTRL_SMMU_INIT_DONE bit needs to be set earliear than SMMU
> being populated. Later Tegra SoC (>= T124) doesn't need AHB to enable
> SMMU on AHB_XBAR_CTRL for AHB_XBAR_CTRL_SMMU_INIT_DONE any more. This
> setting bit is now optional, depending on DT passing ahb phandle or
> not.
This patch should happen after 1/3, and the "platform data" should
indicate whether tegra_ahb_enable_smmu() needs to be called, so that on
Tegra30...
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> @@ -1284,9 +1287,6 @@ static int tegra_smmu_probe(struct platform_device *pdev)
> smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0);
> - if (!smmu->ahb)
> - return -ENODEV;
... that error-checking is still in place, yet on Tegra124,
of_parse_phandle() isn't even called.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/6] iommu/tegra124: smmu: {TLB,PTC} reset value per SoC
[not found] ` <1386246319-17851-6-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2013-12-16 20:41 ` Stephen Warren
0 siblings, 0 replies; 14+ messages in thread
From: Stephen Warren @ 2013-12-16 20:41 UTC (permalink / raw)
To: Hiroshi Doyu, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
On 12/05/2013 05:25 AM, Hiroshi Doyu wrote:
> T124 has some new register bits in {TLB,PTC}_CONFIG:
>
> - TLB_RR_ARB and PTC_REQ_LIMIT
> - TLB_ACTIVE_LINES 0x20 instead of 0x10
>
> They are defined as platform data now.
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> @@ -239,6 +240,8 @@ struct smmu_device {
> struct page *avp_vector_page; /* dummy page shared by all AS's */
>
> int nr_xlats; /* number of translation_enable registers */
> + u32 tlb_reset; /* TLB config reset value */
> + u32 ptc_reset; /* PTC config reset value */
> @@ -1320,6 +1327,10 @@ static int tegra_smmu_probe(struct platform_device *pdev)
> + smmu->tlb_reset = (pdata && pdata->tlb_reset) ? pdata->tlb_reset :
> + (SMMU_TLB_CONFIG_RESET_VAL | 0x10);
> + smmu->ptc_reset = (pdata && pdata->ptc_reset) ? pdata->ptc_reset :
> + (SMMU_PTC_CONFIG_RESET_VAL | SMMU_PTC_REQ_LIMIT);
These two parts of this patch could be removed, given my suggestions re:
patch 3/6.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa
[not found] ` <1386246319-17851-5-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2014-01-07 5:25 ` Mark Zhang
[not found] ` <52CB8FD1.4070306-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 14+ messages in thread
From: Mark Zhang @ 2014-01-07 5:25 UTC (permalink / raw)
To: Hiroshi Doyu, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
Cc: Pavan Kunapuli
On 12/05/2013 08:25 PM, Hiroshi Doyu wrote:
> Add support for more than 32 bit physical address. If physical
> address space is 32bit, there will be no register write
> happening. Based on Pavan's internal patch.
>
> Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: Pavan Kunapuli <pkunapuli-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> drivers/iommu/tegra-smmu.c | 32 +++++++++++++++++++++++++-------
> 1 file changed, 25 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> index b5737f9..04e7199 100644
> --- a/drivers/iommu/tegra-smmu.c
> +++ b/drivers/iommu/tegra-smmu.c
> @@ -101,6 +101,8 @@ enum {
> #define SMMU_PTC_FLUSH_TYPE_ADR 1
> #define SMMU_PTC_FLUSH_ADR_SHIFT 4
>
> +#define SMMU_PTC_FLUSH_1 0x9b8
> +
> #define SMMU_ASID_SECURITY 0x38
>
> #define SMMU_STATS_CACHE_COUNT_BASE 0x1f0
> @@ -143,7 +145,7 @@ enum {
> #define SMMU_PDIR_SHIFT 12
> #define SMMU_PDE_SHIFT 12
> #define SMMU_PTE_SHIFT 12
> -#define SMMU_PFN_MASK 0x000fffff
> +#define SMMU_PFN_MASK 0x0fffffff
>
> #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
> #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
> @@ -301,6 +303,8 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
> #define VA_PAGE_TO_PA(va, page) \
> (page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK))
>
> +#define VA_PAGE_TO_PA_HI(va, page) (u32)((u64)page_to_phys(page) >> 32)
> +
> #define FLUSH_CPU_DCACHE(va, page, size) \
> do { \
> unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \
> @@ -526,6 +530,21 @@ static int smmu_setup_regs(struct smmu_device *smmu)
> return 0;
> }
>
> +static void flush_ptc_by_addr(struct smmu_device *smmu, unsigned long *pte,
> + struct page *page)
> +{
> + u32 val;
> +
> + val = VA_PAGE_TO_PA_HI(pte, page);
> + if (val)
> + smmu_write(smmu, val, SMMU_PTC_FLUSH_1);
> +
This is not correct, according to my tests. We should write
"SMMU_PTC_FLUSH_1" even when the "val" is zero.
So I just copied Pavan's original work here, after applied this, the
SMMU works correctly:
- val = VA_PAGE_TO_PA_HI(pte, page);
- if (val)
+ if (!pte) {
+ smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH);
+ return;
+ }
+
+ if (of_machine_is_compatible("nvidia,tegra124")) {
+ val = VA_PAGE_TO_PA_HI(pte, page);
smmu_write(smmu, val, SMMU_PTC_FLUSH_1);
+ }
Mark
> + val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
> + smmu_write(smmu, val, SMMU_PTC_FLUSH);
> +
> + FLUSH_SMMU_REGS(smmu);
> +}
> +
> static void flush_ptc_and_tlb(struct smmu_device *smmu,
> struct smmu_as *as, dma_addr_t iova,
> unsigned long *pte, struct page *page, int is_pde)
> @@ -535,9 +554,8 @@ static void flush_ptc_and_tlb(struct smmu_device *smmu,
> ? SMMU_TLB_FLUSH_VA(iova, SECTION)
> : SMMU_TLB_FLUSH_VA(iova, GROUP);
>
> - val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
> - smmu_write(smmu, val, SMMU_PTC_FLUSH);
> - FLUSH_SMMU_REGS(smmu);
> + flush_ptc_by_addr(smmu, pte, page);
> +
> val = tlb_flush_va |
> SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
> (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
> @@ -702,9 +720,9 @@ static int alloc_pdir(struct smmu_as *as)
> for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
> pdir[pdn] = _PDE_VACANT(pdn);
> FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE);
> - val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page);
> - smmu_write(smmu, val, SMMU_PTC_FLUSH);
> - FLUSH_SMMU_REGS(as->smmu);
> +
> + flush_ptc_by_addr(as->smmu, pdir, page);
> +
> val = SMMU_TLB_FLUSH_VA_MATCH_ALL |
> SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
> (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa
[not found] ` <52CB8FD1.4070306-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-01-08 13:45 ` Thierry Reding
[not found] ` <20140108134550.GF1592-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
0 siblings, 1 reply; 14+ messages in thread
From: Thierry Reding @ 2014-01-08 13:45 UTC (permalink / raw)
To: Mark Zhang
Cc: Hiroshi Doyu, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, joro-zLv9SwRftAIdnm+yROfE0A,
Pavan Kunapuli
[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]
On Tue, Jan 07, 2014 at 01:25:37PM +0800, Mark Zhang wrote:
> On 12/05/2013 08:25 PM, Hiroshi Doyu wrote:
[...]
> > @@ -526,6 +530,21 @@ static int smmu_setup_regs(struct smmu_device *smmu)
> > return 0;
> > }
> >
> > +static void flush_ptc_by_addr(struct smmu_device *smmu, unsigned long *pte,
> > + struct page *page)
> > +{
> > + u32 val;
> > +
> > + val = VA_PAGE_TO_PA_HI(pte, page);
> > + if (val)
> > + smmu_write(smmu, val, SMMU_PTC_FLUSH_1);
> > +
>
> This is not correct, according to my tests. We should write
> "SMMU_PTC_FLUSH_1" even when the "val" is zero.
>
> So I just copied Pavan's original work here, after applied this, the
> SMMU works correctly:
>
> - val = VA_PAGE_TO_PA_HI(pte, page);
> - if (val)
> + if (!pte) {
> + smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH);
> + return;
> + }
> +
> + if (of_machine_is_compatible("nvidia,tegra124")) {
This check should be replaced by some flag so we don't have to compare
strings every time the PTC is flushed.
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa
[not found] ` <20140108134550.GF1592-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
@ 2014-01-09 2:28 ` Mark Zhang
0 siblings, 0 replies; 14+ messages in thread
From: Mark Zhang @ 2014-01-09 2:28 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Pavan Kunapuli
On 01/08/2014 09:45 PM, Thierry Reding wrote:
> On Tue, Jan 07, 2014 at 01:25:37PM +0800, Mark Zhang wrote:
>> On 12/05/2013 08:25 PM, Hiroshi Doyu wrote:
> [...]
>>> @@ -526,6 +530,21 @@ static int smmu_setup_regs(struct smmu_device *smmu)
>>> return 0;
>>> }
>>>
>>> +static void flush_ptc_by_addr(struct smmu_device *smmu, unsigned long *pte,
>>> + struct page *page)
>>> +{
>>> + u32 val;
>>> +
>>> + val = VA_PAGE_TO_PA_HI(pte, page);
>>> + if (val)
>>> + smmu_write(smmu, val, SMMU_PTC_FLUSH_1);
>>> +
>>
>> This is not correct, according to my tests. We should write
>> "SMMU_PTC_FLUSH_1" even when the "val" is zero.
>>
>> So I just copied Pavan's original work here, after applied this, the
>> SMMU works correctly:
>>
>> - val = VA_PAGE_TO_PA_HI(pte, page);
>> - if (val)
>> + if (!pte) {
>> + smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH);
>> + return;
>> + }
>> +
>> + if (of_machine_is_compatible("nvidia,tegra124")) {
>
> This check should be replaced by some flag so we don't have to compare
> strings every time the PTC is flushed.
>
Yes, I believe Hiroshi will consider this in his v8 series.
Mark
> Thierry
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2014-01-09 2:28 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-05 12:25 [PATCH 0/6] iommu/tegra124: smmu: add T124 enhancement Hiroshi Doyu
[not found] ` <1386246319-17851-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-05 12:25 ` [PATCH 1/6] iommu/tegra124: smmu: optionaly AHB enables SMMU Hiroshi Doyu
[not found] ` <1386246319-17851-2-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-16 20:37 ` Stephen Warren
2013-12-05 12:25 ` [PATCH 2/6] iommu/tegra124: smmu: convert swgroup ID to asid offset Hiroshi Doyu
2013-12-05 12:25 ` [PATCH 3/6] iommu/tegra124: smmu: add support platform data Hiroshi Doyu
[not found] ` <1386246319-17851-4-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-16 20:36 ` Stephen Warren
2013-12-05 12:25 ` [PATCH 4/6] iommu/tegra124: smmu: support more than 32 bit pa Hiroshi Doyu
[not found] ` <1386246319-17851-5-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-01-07 5:25 ` Mark Zhang
[not found] ` <52CB8FD1.4070306-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-01-08 13:45 ` Thierry Reding
[not found] ` <20140108134550.GF1592-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2014-01-09 2:28 ` Mark Zhang
2013-12-05 12:25 ` [PATCH 5/6] iommu/tegra124: smmu: {TLB,PTC} reset value per SoC Hiroshi Doyu
[not found] ` <1386246319-17851-6-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-12-16 20:41 ` Stephen Warren
2013-12-05 12:25 ` [PATCH 6/6] iommu/tegra124: smmu: adjust TLB_FLUSH_ASID bit range Hiroshi Doyu
2013-12-09 7:16 ` [PATCH 7/6] iommu/tegra124: smmu: add multiple asid_security support Hiroshi Doyu
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).