* [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver
@ 2012-05-10 7:42 Hiroshi DOYU
[not found] ` <1336635764-30597-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-05-10 17:23 ` [PATCH 1/4] ARM: tegra20: " Stephen Warren
0 siblings, 2 replies; 7+ messages in thread
From: Hiroshi DOYU @ 2012-05-10 7:42 UTC (permalink / raw)
To: hdoyu
Cc: linux-tegra, Grant Likely, Rob Herring, Rob Landley, Colin Cross,
Olof Johansson, Stephen Warren, Russell King, Santosh Shilimkar,
Greg Kroah-Hartman, Benoit Cousson, Aneesh V, devicetree-discuss,
linux-doc, linux-kernel, linux-arm-kernel
Tegra Memory Controller(MC) driver for Tegra20
Added to support MC General interrupts, mainly for IOMMU(GART).
Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
---
.../bindings/arm/tegra/nvidia,tegra20-mc.txt | 16 ++
arch/arm/mach-tegra/Kconfig | 2 +
drivers/memory/Kconfig | 4 +
drivers/memory/Makefile | 1 +
drivers/memory/tegra20-mc.c | 262 ++++++++++++++++++++
5 files changed, 285 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt
new file mode 100644
index 0000000..c25a0a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt
@@ -0,0 +1,16 @@
+NVIDIA Tegra20 MC(Memory Controller)
+
+Required properties:
+- compatible : "nvidia,tegra20-mc"
+- reg : Should contain 2 register ranges(address and length); see the
+ example below. Note that the MC registers are interleaved with the
+ GART registers, and hence must be represented as multiple ranges.
+- interrupts : Should contain MC General interrupt.
+
+Example:
+ mc {
+ compatible = "nvidia,tegra20-mc";
+ reg = <0x7000f000 0x024
+ 0x7000f03c 0x3c4>;
+ interrupts = <0 77 0x04>;
+ };
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 6a113a9..abaf5d0 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -20,6 +20,8 @@ config ARCH_TEGRA_2x_SOC
select PL310_ERRATA_727915 if CACHE_L2X0
select PL310_ERRATA_769419 if CACHE_L2X0
select CPU_FREQ_TABLE if CPU_FREQ
+ select MEMORY
+ select TEGRA20_MC
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index e0b3156..ebade16 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -20,4 +20,8 @@ config TI_EMIF
parameters and other settings during frequency, voltage and
temperature changes
+config TEGRA20_MC
+ bool
+ depends on ARCH_TEGRA_2x_SOC
+
endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index e27f80b..1f58518 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_TI_EMIF) += emif.o
+obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
diff --git a/drivers/memory/tegra20-mc.c b/drivers/memory/tegra20-mc.c
new file mode 100644
index 0000000..c0bfffa
--- /dev/null
+++ b/drivers/memory/tegra20-mc.c
@@ -0,0 +1,262 @@
+/*
+ * Tegra20 Memory Controller
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ratelimit.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#define DRV_NAME "tegra20-mc"
+
+#define MC_INTSTATUS 0x0
+#define MC_INTMASK 0x4
+
+#define MC_INT_ERR_SHIFT 6
+#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
+#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
+#define MC_INT_INVALID_GART_PAGE BIT(MC_INT_ERR_SHIFT + 1)
+#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
+#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
+
+#define MC_GART_ERROR_REQ 0x30
+#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
+#define MC_SECURITY_VIOLATION_STATUS 0x74
+
+#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
+
+#define MC_CLIENT_ID_MASK 0x3f
+
+#define NUM_MC_REG_BANKS 2
+
+struct tegra20_mc {
+ void __iomem *regs[NUM_MC_REG_BANKS];
+ struct device *dev;
+};
+
+static inline u32 mc_readl(struct tegra20_mc *mc, u32 offs)
+{
+ if (offs < 0x24)
+ return readl(mc->regs[0] + offs);
+ BUG_ON(offs < 0x3c);
+ if (offs < 0x400)
+ return readl(mc->regs[1] + offs - 0x3c);
+ BUG();
+}
+
+static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs)
+{
+ if (offs < 0x24) {
+ writel(val, mc->regs[0] + offs);
+ return;
+ }
+ BUG_ON(offs < 0x3c);
+ if (offs < 0x400) {
+ writel(val, mc->regs[1] + offs - 0x3c);
+ return;
+ }
+ BUG();
+}
+
+static const char * const tegra20_mc_client[] = {
+ "cbr_display0a",
+ "cbr_display0ab",
+ "cbr_display0b",
+ "cbr_display0bb",
+ "cbr_display0c",
+ "cbr_display0cb",
+ "cbr_display1b",
+ "cbr_display1bb",
+ "cbr_eppup",
+ "cbr_g2pr",
+ "cbr_g2sr",
+ "cbr_mpeunifbr",
+ "cbr_viruv",
+ "csr_avpcarm7r",
+ "csr_displayhc",
+ "csr_displayhcb",
+ "csr_fdcdrd",
+ "csr_g2dr",
+ "csr_host1xdmar",
+ "csr_host1xr",
+ "csr_idxsrd",
+ "csr_mpcorer",
+ "csr_mpe_ipred",
+ "csr_mpeamemrd",
+ "csr_mpecsrd",
+ "csr_ppcsahbdmar",
+ "csr_ppcsahbslvr",
+ "csr_texsrd",
+ "csr_vdebsevr",
+ "csr_vdember",
+ "csr_vdemcer",
+ "csr_vdetper",
+ "cbw_eppu",
+ "cbw_eppv",
+ "cbw_eppy",
+ "cbw_mpeunifbw",
+ "cbw_viwsb",
+ "cbw_viwu",
+ "cbw_viwv",
+ "cbw_viwy",
+ "ccw_g2dw",
+ "csw_avpcarm7w",
+ "csw_fdcdwr",
+ "csw_host1xw",
+ "csw_ispw",
+ "csw_mpcorew",
+ "csw_mpecswr",
+ "csw_ppcsahbdmaw",
+ "csw_ppcsahbslvw",
+ "csw_vdebsevw",
+ "csw_vdembew",
+ "csw_vdetpmw",
+};
+
+static void tegra20_mc_decode(struct tegra20_mc *mc, int n)
+{
+ u32 addr, req;
+ const char *client = "Unknown";
+ int idx, cid;
+ const struct reg_info {
+ u32 offset;
+ u32 write_bit; /* 0=READ, 1=WRITE */
+ int cid_shift;
+ char *message;
+ } reg[] = {
+ {
+ .offset = MC_DECERR_EMEM_OTHERS_STATUS,
+ .write_bit = 31,
+ .message = "MC_DECERR",
+ },
+ {
+ .offset = MC_GART_ERROR_REQ,
+ .cid_shift = 1,
+ .message = "MC_GART_ERR",
+
+ },
+ {
+ .offset = MC_SECURITY_VIOLATION_STATUS,
+ .write_bit = 31,
+ .message = "MC_SECURITY_ERR",
+ },
+ };
+
+ idx = n - MC_INT_ERR_SHIFT;
+ if ((idx < 0) || (idx >= ARRAY_SIZE(reg))) {
+ pr_err_ratelimited("Unknown interrupt status %08lx\n", BIT(n));
+ return;
+ }
+
+ req = mc_readl(mc, reg[idx].offset);
+ cid = (req >> reg[idx].cid_shift) & MC_CLIENT_ID_MASK;
+ if (cid < ARRAY_SIZE(tegra20_mc_client))
+ client = tegra20_mc_client[cid];
+
+ addr = mc_readl(mc, reg[idx].offset + sizeof(u32));
+
+ pr_err_ratelimited("%s (0x%08x): 0x%08x %s (%s %s)\n",
+ reg[idx].message, req, addr, client,
+ (req & BIT(reg[idx].write_bit)) ? "write" : "read",
+ (reg[idx].offset == MC_SECURITY_VIOLATION_STATUS) ?
+ ((req & SECURITY_VIOLATION_TYPE) ?
+ "carveout" : "trustzone") : "");
+}
+
+static const struct of_device_id tegra20_mc_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra20-mc", },
+ {},
+};
+
+static irqreturn_t tegra20_mc_isr(int irq, void *data)
+{
+ u32 stat, mask, bit;
+ struct tegra20_mc *mc = data;
+
+ stat = mc_readl(mc, MC_INTSTATUS);
+ mask = mc_readl(mc, MC_INTMASK);
+ mask &= stat;
+ if (!mask)
+ return IRQ_NONE;
+ while ((bit = ffs(mask)) != 0)
+ tegra20_mc_decode(mc, bit - 1);
+ mc_writel(mc, stat, MC_INTSTATUS);
+ return IRQ_HANDLED;
+}
+
+static int __devinit tegra20_mc_probe(struct platform_device *pdev)
+{
+ struct resource *irq;
+ struct tegra20_mc *mc;
+ int i, err;
+ u32 intmask;
+
+ mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
+ if (!mc)
+ return -ENOMEM;
+ mc->dev = &pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ return -ENODEV;
+ mc->regs[i] = devm_request_and_ioremap(&pdev->dev, res);
+ if (!mc->regs[i])
+ return -EBUSY;
+ }
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq)
+ return -ENODEV;
+ err = devm_request_irq(&pdev->dev, irq->start, tegra20_mc_isr,
+ IRQF_SHARED, dev_name(&pdev->dev), mc);
+ if (err)
+ return -ENODEV;
+
+ platform_set_drvdata(pdev, mc);
+
+ intmask = MC_INT_INVALID_GART_PAGE |
+ MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
+ mc_writel(mc, intmask, MC_INTMASK);
+ return 0;
+}
+
+static int __devexit tegra20_mc_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver tegra20_mc_driver = {
+ .probe = tegra20_mc_probe,
+ .remove = __devexit_p(tegra20_mc_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = tegra20_mc_of_match,
+ },
+};
+module_platform_driver(tegra20_mc_driver);
+
+MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
+MODULE_DESCRIPTION("Tegra20 MC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] ARM: tegra30: Add Tegra Memory Controller(MC) driver
[not found] ` <1336635764-30597-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-05-10 7:42 ` Hiroshi DOYU
[not found] ` <1336635764-30597-3-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Hiroshi DOYU @ 2012-05-10 7:42 UTC (permalink / raw)
To: hdoyu-DDmLM1+adcrQT0dZR+AlfA
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
Rob Landley, Colin Cross, Olof Johansson, Stephen Warren,
Russell King, Santosh Shilimkar, Greg Kroah-Hartman,
Benoit Cousson, Aneesh V,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Tegra Memory Controller(MC) driver for Tegra30
Added to support MC General interrupts, mainly for IOMMU(SMMU).
Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
.../bindings/arm/tegra/nvidia,tegra30-mc.txt | 18 +
arch/arm/mach-tegra/Kconfig | 2 +
drivers/memory/Kconfig | 4 +
drivers/memory/Makefile | 1 +
drivers/memory/tegra30-mc.c | 391 ++++++++++++++++++++
5 files changed, 416 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt
new file mode 100644
index 0000000..e47e73f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt
@@ -0,0 +1,18 @@
+NVIDIA Tegra30 MC(Memory Controller)
+
+Required properties:
+- compatible : "nvidia,tegra30-mc"
+- reg : Should contain 4 register ranges(address and length); see the
+ example below. Note that the MC registers are interleaved with the
+ SMMU registers, and hence must be represented as multiple ranges.
+- interrupts : Should contain MC General interrupt.
+
+Example:
+ mc {
+ compatible = "nvidia,tegra30-mc";
+ reg = <0x7000f000 0x010
+ 0x7000f03c 0x1b4
+ 0x7000f200 0x028
+ 0x7000f284 0x17c>;
+ interrupts = <0 77 0x04>;
+ };
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index abaf5d0..16fe065 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -43,6 +43,8 @@ config ARCH_TEGRA_3x_SOC
select ARM_ERRATA_764369
select PL310_ERRATA_769419 if CACHE_L2X0
select CPU_FREQ_TABLE if CPU_FREQ
+ select MEMORY
+ select TEGRA30_MC
help
Support for NVIDIA Tegra T30 processor family, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index ebade16..42e6d66 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -24,4 +24,8 @@ config TEGRA20_MC
bool
depends on ARCH_TEGRA_2x_SOC
+config TEGRA30_MC
+ bool
+ depends on ARCH_TEGRA_3x_SOC
+
endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 1f58518..42b3ce9 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
+obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o
diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c
new file mode 100644
index 0000000..c982125
--- /dev/null
+++ b/drivers/memory/tegra30-mc.c
@@ -0,0 +1,391 @@
+/*
+ * Tegra30 Memory Controller
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ratelimit.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#define DRV_NAME "tegra30-mc"
+
+#define MC_INTSTATUS 0x0
+#define MC_INTMASK 0x4
+
+#define MC_INT_ERR_SHIFT 6
+#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
+#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
+#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
+#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
+#define MC_INT_INVALID_SMMU_PAGE BIT(MC_INT_ERR_SHIFT + 4)
+
+#define MC_ERR_STATUS 0x8
+#define MC_ERR_ADR 0xc
+
+#define MC_ERR_TYPE_SHIFT 28
+#define MC_ERR_TYPE_MASK (7 << MC_ERR_TYPE_SHIFT)
+#define MC_ERR_TYPE_DECERR_EMEM 2
+#define MC_ERR_TYPE_SECURITY_TRUSTZONE 3
+#define MC_ERR_TYPE_SECURITY_CARVEOUT 4
+#define MC_ERR_TYPE_INVALID_SMMU_PAGE 6
+
+#define MC_ERR_INVALID_SMMU_PAGE_SHIFT 25
+#define MC_ERR_INVALID_SMMU_PAGE_MASK (7 << MC_ERR_INVALID_SMMU_PAGE_SHIFT)
+#define MC_ERR_RW_SHIFT 16
+#define MC_ERR_RW BIT(MC_ERR_RW_SHIFT)
+#define MC_ERR_SECURITY BIT(MC_ERR_RW_SHIFT + 1)
+
+#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
+
+#define MC_EMEM_ARB_CFG 0x90
+#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
+#define MC_EMEM_ARB_TIMING_RCD 0x98
+#define MC_EMEM_ARB_TIMING_RP 0x9c
+#define MC_EMEM_ARB_TIMING_RC 0xa0
+#define MC_EMEM_ARB_TIMING_RAS 0xa4
+#define MC_EMEM_ARB_TIMING_FAW 0xa8
+#define MC_EMEM_ARB_TIMING_RRD 0xac
+#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
+#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
+#define MC_EMEM_ARB_TIMING_R2R 0xb8
+#define MC_EMEM_ARB_TIMING_W2W 0xbc
+#define MC_EMEM_ARB_TIMING_R2W 0xc0
+#define MC_EMEM_ARB_TIMING_W2R 0xc4
+
+#define MC_EMEM_ARB_DA_TURNS 0xd0
+#define MC_EMEM_ARB_DA_COVERS 0xd4
+#define MC_EMEM_ARB_MISC0 0xd8
+#define MC_EMEM_ARB_MISC1 0xdc
+
+#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
+#define MC_EMEM_ARB_OVERRIDE 0xe8
+
+#define MC_TIMING_CONTROL 0xfc
+
+#define MC_CLIENT_ID_MASK 0x7f
+
+#define NUM_MC_REG_BANKS 4
+
+struct tegra30_mc {
+ void __iomem *regs[NUM_MC_REG_BANKS];
+ struct device *dev;
+ u32 ctx[0];
+};
+
+static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs)
+{
+ if (offs < 0x10)
+ return readl(mc->regs[0] + offs);
+ BUG_ON(offs < 0x3c);
+ if (offs < 0x1f0)
+ return readl(mc->regs[1] + offs - 0x3c);
+ BUG_ON(offs < 0x200);
+ if (offs < 0x228)
+ return readl(mc->regs[2] + offs - 0x200);
+ BUG_ON(offs < 0x284);
+ if (offs < 0x400)
+ return readl(mc->regs[3] + offs - 0x284);
+ BUG();
+}
+
+static inline void mc_writel(struct tegra30_mc *mc, u32 val, u32 offs)
+{
+ if (offs < 0x10) {
+ writel(val, mc->regs[0] + offs);
+ return;
+ }
+ BUG_ON(offs < 0x3c);
+ if (offs < 0x1f0) {
+ writel(val, mc->regs[1] + offs - 0x3c);
+ return;
+ }
+ BUG_ON(offs < 0x200);
+ if (offs < 0x228) {
+ writel(val, mc->regs[2] + offs - 0x200);
+ return;
+ }
+ BUG_ON(offs < 0x284);
+ if (offs < 0x400) {
+ writel(val, mc->regs[3] + offs - 0x284);
+ return;
+ }
+ BUG();
+}
+
+static const char * const tegra30_mc_client[] = {
+ "csr_ptcr",
+ "cbr_display0a",
+ "cbr_display0ab",
+ "cbr_display0b",
+ "cbr_display0bb",
+ "cbr_display0c",
+ "cbr_display0cb",
+ "cbr_display1b",
+ "cbr_display1bb",
+ "cbr_eppup",
+ "cbr_g2pr",
+ "cbr_g2sr",
+ "cbr_mpeunifbr",
+ "cbr_viruv",
+ "csr_afir",
+ "csr_avpcarm7r",
+ "csr_displayhc",
+ "csr_displayhcb",
+ "csr_fdcdrd",
+ "csr_fdcdrd2",
+ "csr_g2dr",
+ "csr_hdar",
+ "csr_host1xdmar",
+ "csr_host1xr",
+ "csr_idxsrd",
+ "csr_idxsrd2",
+ "csr_mpe_ipred",
+ "csr_mpeamemrd",
+ "csr_mpecsrd",
+ "csr_ppcsahbdmar",
+ "csr_ppcsahbslvr",
+ "csr_satar",
+ "csr_texsrd",
+ "csr_texsrd2",
+ "csr_vdebsevr",
+ "csr_vdember",
+ "csr_vdemcer",
+ "csr_vdetper",
+ "csr_mpcorelpr",
+ "csr_mpcorer",
+ "cbw_eppu",
+ "cbw_eppv",
+ "cbw_eppy",
+ "cbw_mpeunifbw",
+ "cbw_viwsb",
+ "cbw_viwu",
+ "cbw_viwv",
+ "cbw_viwy",
+ "ccw_g2dw",
+ "csw_afiw",
+ "csw_avpcarm7w",
+ "csw_fdcdwr",
+ "csw_fdcdwr2",
+ "csw_hdaw",
+ "csw_host1xw",
+ "csw_ispw",
+ "csw_mpcorelpw",
+ "csw_mpcorew",
+ "csw_mpecswr",
+ "csw_ppcsahbdmaw",
+ "csw_ppcsahbslvw",
+ "csw_sataw",
+ "csw_vdebsevw",
+ "csw_vdedbgw",
+ "csw_vdembew",
+ "csw_vdetpmw",
+};
+
+static void tegra30_mc_decode(struct tegra30_mc *mc, int n)
+{
+ u32 err, addr;
+ const char * const mc_int_err[] = {
+ "MC_DECERR",
+ "Unknown",
+ "MC_SECURITY_ERR",
+ "MC_ARBITRATION_EMEM",
+ "MC_SMMU_ERR",
+ };
+ const char * const err_type[] = {
+ "Unknown",
+ "Unknown",
+ "DECERR_EMEM",
+ "SECURITY_TRUSTZONE",
+ "SECURITY_CARVEOUT",
+ "Unknown",
+ "INVALID_SMMU_PAGE",
+ "Unknown",
+ };
+ char attr[6];
+ int cid, perm, type, idx;
+ const char *client = "Unknown";
+
+ idx = n - MC_INT_ERR_SHIFT;
+ if ((idx < 0) || (idx >= ARRAY_SIZE(mc_int_err)) || (idx == 1)) {
+ pr_err_ratelimited("Unknown interrupt status %08lx\n", BIT(n));
+ return;
+ }
+
+ err = readl(mc + MC_ERR_STATUS);
+
+ type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT;
+ perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >>
+ MC_ERR_INVALID_SMMU_PAGE_SHIFT;
+ if (type == MC_ERR_TYPE_INVALID_SMMU_PAGE)
+ sprintf(attr, "%c-%c-%c",
+ (perm & BIT(2)) ? 'R' : '-',
+ (perm & BIT(1)) ? 'W' : '-',
+ (perm & BIT(0)) ? 'S' : '-');
+ else
+ attr[0] = '\0';
+
+ cid = err & MC_CLIENT_ID_MASK;
+ if (cid < ARRAY_SIZE(tegra30_mc_client))
+ client = tegra30_mc_client[cid];
+
+ addr = readl(mc + MC_ERR_ADR);
+
+ pr_err_ratelimited("%s (0x%08x): 0x%08x %s (%s %s %s %s)\n",
+ mc_int_err[idx], err, addr, client,
+ (err & MC_ERR_SECURITY) ? "secure" : "non-secure",
+ (err & MC_ERR_RW) ? "write" : "read",
+ err_type[type], attr);
+}
+
+static const u32 tegra30_mc_ctx[] = {
+ MC_EMEM_ARB_CFG,
+ MC_EMEM_ARB_OUTSTANDING_REQ,
+ MC_EMEM_ARB_TIMING_RCD,
+ MC_EMEM_ARB_TIMING_RP,
+ MC_EMEM_ARB_TIMING_RC,
+ MC_EMEM_ARB_TIMING_RAS,
+ MC_EMEM_ARB_TIMING_FAW,
+ MC_EMEM_ARB_TIMING_RRD,
+ MC_EMEM_ARB_TIMING_RAP2PRE,
+ MC_EMEM_ARB_TIMING_WAP2PRE,
+ MC_EMEM_ARB_TIMING_R2R,
+ MC_EMEM_ARB_TIMING_W2W,
+ MC_EMEM_ARB_TIMING_R2W,
+ MC_EMEM_ARB_TIMING_W2R,
+ MC_EMEM_ARB_DA_TURNS,
+ MC_EMEM_ARB_DA_COVERS,
+ MC_EMEM_ARB_MISC0,
+ MC_EMEM_ARB_MISC1,
+ MC_EMEM_ARB_RING3_THROTTLE,
+ MC_EMEM_ARB_OVERRIDE,
+ MC_INTMASK,
+};
+
+static int tegra30_mc_suspend(struct device *dev)
+{
+ int i;
+ struct tegra30_mc *mc = dev_get_drvdata(dev);
+
+ for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
+ mc->ctx[i] = mc_readl(mc, tegra30_mc_ctx[i]);
+ return 0;
+}
+
+static int tegra30_mc_resume(struct device *dev)
+{
+ int i;
+ struct tegra30_mc *mc = dev_get_drvdata(dev);
+
+ for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
+ mc_writel(mc, mc->ctx[i], tegra30_mc_ctx[i]);
+
+ mc_writel(mc, 1, MC_TIMING_CONTROL);
+ /* Read-back to ensure that write reached */
+ mc_readl(mc, MC_TIMING_CONTROL);
+ return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm,
+ tegra30_mc_suspend,
+ tegra30_mc_resume, NULL);
+
+static const struct of_device_id tegra30_mc_of_match[] __devinitconst = {
+ { .compatible = "nvidia,tegra30-mc", },
+ {},
+};
+
+static irqreturn_t tegra30_mc_isr(int irq, void *data)
+{
+ u32 stat, mask, bit;
+ struct tegra30_mc *mc = data;
+
+ stat = mc_readl(mc, MC_INTSTATUS);
+ mask = mc_readl(mc, MC_INTMASK);
+ mask &= stat;
+ if (!mask)
+ return IRQ_NONE;
+ while ((bit = ffs(mask)) != 0)
+ tegra30_mc_decode(mc, bit - 1);
+ mc_writel(mc, stat, MC_INTSTATUS);
+ return IRQ_HANDLED;
+}
+
+static int __devinit tegra30_mc_probe(struct platform_device *pdev)
+{
+ struct resource *irq;
+ struct tegra30_mc *mc;
+ size_t bytes;
+ int err, i;
+ u32 intmask;
+
+ bytes = sizeof(*mc) + sizeof(u32) * ARRAY_SIZE(tegra30_mc_ctx);
+ mc = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
+ if (!mc)
+ return -ENOMEM;
+ mc->dev = &pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res)
+ return -ENODEV;
+ mc->regs[i] = devm_request_and_ioremap(&pdev->dev, res);
+ if (!mc->regs[i])
+ return -EBUSY;
+ }
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq)
+ return -ENODEV;
+ err = devm_request_irq(&pdev->dev, irq->start, tegra30_mc_isr,
+ IRQF_SHARED, dev_name(&pdev->dev), mc);
+ if (err)
+ return -ENODEV;
+
+ platform_set_drvdata(pdev, mc);
+
+ intmask = MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
+ mc_writel(mc, intmask, MC_INTMASK);
+ return 0;
+}
+
+static int __devexit tegra30_mc_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver tegra30_mc_driver = {
+ .probe = tegra30_mc_probe,
+ .remove = __devexit_p(tegra30_mc_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = tegra30_mc_of_match,
+ .pm = &tegra30_mc_pm,
+ },
+};
+module_platform_driver(tegra30_mc_driver);
+
+MODULE_AUTHOR("Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Tegra30 MC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver
2012-05-10 7:42 [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver Hiroshi DOYU
[not found] ` <1336635764-30597-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-05-10 17:23 ` Stephen Warren
[not found] ` <4FABF9AB.6020902-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-05-11 6:50 ` Hiroshi Doyu
1 sibling, 2 replies; 7+ messages in thread
From: Stephen Warren @ 2012-05-10 17:23 UTC (permalink / raw)
To: Hiroshi DOYU, Greg Kroah-Hartman
Cc: linux-tegra, Grant Likely, Rob Herring, Rob Landley, Colin Cross,
Olof Johansson, Russell King, Santosh Shilimkar, Benoit Cousson,
Aneesh V, devicetree-discuss, linux-doc, linux-kernel,
linux-arm-kernel
On 05/10/2012 01:42 AM, Hiroshi DOYU wrote:
> Tegra Memory Controller(MC) driver for Tegra20
> Added to support MC General interrupts, mainly for IOMMU(GART).
Greg, you appear to have been commiting all of drivers/memory. I assume
you'll take patches 1 and 3 in this series, and I will take 2 and 4
through the Tegra tree? I can take them all through the Tegra tree if
you want. Taking the .dts patches through your tree might cause
conflicts in 3.6, since I anticipate some DT-wide cleanup in 3.6.
Hiroshi, one question below (same for patch 3)
> diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
> @@ -20,6 +20,8 @@ config ARCH_TEGRA_2x_SOC
> select PL310_ERRATA_727915 if CACHE_L2X0
> select PL310_ERRATA_769419 if CACHE_L2X0
> select CPU_FREQ_TABLE if CPU_FREQ
> + select MEMORY
> + select TEGRA20_MC
Does ARCH_TEGRA_2x_SOC /have/ to select these?
I'd be inclined to drop the change to mach-tegra/Kconfig. As rationale,
the code works fine without the driver right now. You'd need to make
config TEGRA*_MC user-visible/selectable though.
You could replace this change with a patch to tegra_defconfig which
enables MEMORY and TEGRA*_MC, or perhaps make config TEGRA20_MC default y.
What are people's thoughts here?
Aside from this, the series looks fine to me.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver
[not found] ` <4FABF9AB.6020902-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-05-10 18:18 ` Greg Kroah-Hartman
0 siblings, 0 replies; 7+ messages in thread
From: Greg Kroah-Hartman @ 2012-05-10 18:18 UTC (permalink / raw)
To: Stephen Warren
Cc: Hiroshi DOYU, linux-tegra-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
Rob Herring, Rob Landley, Colin Cross, Olof Johansson,
Russell King, Santosh Shilimkar, Benoit Cousson, Aneesh V,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Thu, May 10, 2012 at 11:23:55AM -0600, Stephen Warren wrote:
> On 05/10/2012 01:42 AM, Hiroshi DOYU wrote:
> > Tegra Memory Controller(MC) driver for Tegra20
> > Added to support MC General interrupts, mainly for IOMMU(GART).
>
> Greg, you appear to have been commiting all of drivers/memory. I assume
> you'll take patches 1 and 3 in this series, and I will take 2 and 4
> through the Tegra tree? I can take them all through the Tegra tree if
> you want.
I think you will get a conflict if you take the memory ones in your
tree, so I will take those two, thanks.
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/4] ARM: tegra30: Add Tegra Memory Controller(MC) driver
[not found] ` <1336635764-30597-3-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-05-10 21:46 ` Greg Kroah-Hartman
2012-05-11 6:16 ` Hiroshi Doyu
0 siblings, 1 reply; 7+ messages in thread
From: Greg Kroah-Hartman @ 2012-05-10 21:46 UTC (permalink / raw)
To: Hiroshi DOYU
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
Rob Landley, Colin Cross, Olof Johansson, Stephen Warren,
Russell King, Santosh Shilimkar, Benoit Cousson, Aneesh V,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Thu, May 10, 2012 at 10:42:32AM +0300, Hiroshi DOYU wrote:
> Tegra Memory Controller(MC) driver for Tegra30
> Added to support MC General interrupts, mainly for IOMMU(SMMU).
I'll apply this, but:
> +static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs)
> +{
> + if (offs < 0x10)
> + return readl(mc->regs[0] + offs);
> + BUG_ON(offs < 0x3c);
> + if (offs < 0x1f0)
> + return readl(mc->regs[1] + offs - 0x3c);
> + BUG_ON(offs < 0x200);
> + if (offs < 0x228)
> + return readl(mc->regs[2] + offs - 0x200);
> + BUG_ON(offs < 0x284);
> + if (offs < 0x400)
> + return readl(mc->regs[3] + offs - 0x284);
> + BUG();
> +}
That's a lot of BUG* calls. Same thing with the 1/4 patch in this
series.
We really should not have a BUG call in any driver, as you just stopped
the whole system. I can understand this being there for debugging when
you create the code originally, but as these are things no one should
ever be able to hit now, you should remove them, right?
Care to write a follow-on patch removing all of these BUG_ON and BUG
calls in this and the drivers/memory/tegra20-mc.c driver?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/4] ARM: tegra30: Add Tegra Memory Controller(MC) driver
2012-05-10 21:46 ` Greg Kroah-Hartman
@ 2012-05-11 6:16 ` Hiroshi Doyu
0 siblings, 0 replies; 7+ messages in thread
From: Hiroshi Doyu @ 2012-05-11 6:16 UTC (permalink / raw)
To: gregkh@linuxfoundation.org
Cc: linux-tegra@vger.kernel.org, grant.likely@secretlab.ca,
rob.herring@calxeda.com, rob@landley.net, ccross@android.com,
olof@lixom.net, swarren@wwwdotorg.org, linux@arm.linux.org.uk,
santosh.shilimkar@ti.com, b-cousson@ti.com, aneesh@ti.com,
devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Hi Greg,
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [PATCH 3/4] ARM: tegra30: Add Tegra Memory Controller(MC) driver
Date: Thu, 10 May 2012 23:46:04 +0200
Message-ID: <20120510214604.GA3525@kroah.com>
> On Thu, May 10, 2012 at 10:42:32AM +0300, Hiroshi DOYU wrote:
> > Tegra Memory Controller(MC) driver for Tegra30
> > Added to support MC General interrupts, mainly for IOMMU(SMMU).
>
> I'll apply this, but:
Thanks.
> > +static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs)
> > +{
> > + if (offs < 0x10)
> > + return readl(mc->regs[0] + offs);
> > + BUG_ON(offs < 0x3c);
> > + if (offs < 0x1f0)
> > + return readl(mc->regs[1] + offs - 0x3c);
> > + BUG_ON(offs < 0x200);
> > + if (offs < 0x228)
> > + return readl(mc->regs[2] + offs - 0x200);
> > + BUG_ON(offs < 0x284);
> > + if (offs < 0x400)
> > + return readl(mc->regs[3] + offs - 0x284);
> > + BUG();
> > +}
>
> That's a lot of BUG* calls. Same thing with the 1/4 patch in this
> series.
>
> We really should not have a BUG call in any driver, as you just stopped
> the whole system. I can understand this being there for debugging when
> you create the code originally, but as these are things no one should
> ever be able to hit now, you should remove them, right?
>
> Care to write a follow-on patch removing all of these BUG_ON and BUG
> calls in this and the drivers/memory/tegra20-mc.c driver?
Ok, they are replying to this email.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver
2012-05-10 17:23 ` [PATCH 1/4] ARM: tegra20: " Stephen Warren
[not found] ` <4FABF9AB.6020902-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-05-11 6:50 ` Hiroshi Doyu
1 sibling, 0 replies; 7+ messages in thread
From: Hiroshi Doyu @ 2012-05-11 6:50 UTC (permalink / raw)
To: Greg Kroah-Hartman, Stephen Warren
Cc: linux-tegra@vger.kernel.org, Grant Likely, Rob Herring,
Rob Landley, Colin Cross, Olof Johansson, Russell King,
Santosh Shilimkar, Benoit Cousson, Aneesh V,
devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Hi Greg, Stephen,
On Thu, 10 May 2012 19:23:55 +0200
Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 05/10/2012 01:42 AM, Hiroshi DOYU wrote:
> > Tegra Memory Controller(MC) driver for Tegra20
> > Added to support MC General interrupts, mainly for IOMMU(GART).
>
> Greg, you appear to have been commiting all of drivers/memory. I assume
> you'll take patches 1 and 3 in this series, and I will take 2 and 4
> through the Tegra tree? I can take them all through the Tegra tree if
> you want. Taking the .dts patches through your tree might cause
> conflicts in 3.6, since I anticipate some DT-wide cleanup in 3.6.
>
> Hiroshi, one question below (same for patch 3)
>
> > diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
>
> > @@ -20,6 +20,8 @@ config ARCH_TEGRA_2x_SOC
> > select PL310_ERRATA_727915 if CACHE_L2X0
> > select PL310_ERRATA_769419 if CACHE_L2X0
> > select CPU_FREQ_TABLE if CPU_FREQ
> > + select MEMORY
> > + select TEGRA20_MC
>
> Does ARCH_TEGRA_2x_SOC /have/ to select these?
>
> I'd be inclined to drop the change to mach-tegra/Kconfig. As rationale,
> the code works fine without the driver right now. You'd need to make
> config TEGRA*_MC user-visible/selectable though.
>
> You could replace this change with a patch to tegra_defconfig which
> enables MEMORY and TEGRA*_MC, or perhaps make config TEGRA20_MC default y.
I'm sending the fixup patches, following this mail, since Greg has
already put the original patches in queue. I think that the following
fixup patches could be squashed into the original ones. The fixup
patches are:
[PATCH 1/3] ARM: tegra20: Make MC optional in Kconfig
[PATCH 2/3] ARM: tegra30: Make MC optional in Kconfig
[PATCH 3/3] ARM: tegra: Make TEGRA{20,30}_MC selectable in defconfig
Let me know if it's better to resend the complete patches again.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-05-11 6:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-10 7:42 [PATCH 1/4] ARM: tegra20: Add Tegra Memory Controller(MC) driver Hiroshi DOYU
[not found] ` <1336635764-30597-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-05-10 7:42 ` [PATCH 3/4] ARM: tegra30: " Hiroshi DOYU
[not found] ` <1336635764-30597-3-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-05-10 21:46 ` Greg Kroah-Hartman
2012-05-11 6:16 ` Hiroshi Doyu
2012-05-10 17:23 ` [PATCH 1/4] ARM: tegra20: " Stephen Warren
[not found] ` <4FABF9AB.6020902-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-05-10 18:18 ` Greg Kroah-Hartman
2012-05-11 6:50 ` 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).