All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/15] Memory controller hot reset
@ 2018-04-09 19:28 Dmitry Osipenko
  2018-04-09 19:28 ` [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding Dmitry Osipenko
                   ` (14 more replies)
  0 siblings, 15 replies; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Tegra's memory controller has a "memory hot reset" functionality that
blocks all memory transactions for the memory client, which is required
for a proper HW resetting. HW could be in process of performing DMA while
being reset and this could lead to a system hang or memory corruption, so
here comes the memory hot reset that blocks all interactions of HW with
memory so that it could be reset safely.

Changelog:

V4:
        Fixed compilation warning about unused function for the case where
        Tegra20 SoC isn't enabled in Kconfig, corrected typos in commit
        messages.

V3:
        Addressed review comments to V2 from Thierry Reding. MC now
        uses generic reset controller API instead of a custom one,
        hence DT changes are now involved and so Rob Herring is CC'd
        for a review.

        Added couple minor cleanup/correction patches.

V2:
        Basically a re-send of V1 with some minor changes.


Dmitry Osipenko (14):
  dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding
  dt-bindings: memory: tegra: Document #reset-cells property of the
    Tegra30 MC
  dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20
    MC
  dt-bindings: memory: tegra: Add hot resets definitions
  memory: tegra: Do not handle spurious interrupts
  memory: tegra: Setup interrupts mask before requesting IRQ
  memory: tegra: Apply interrupts mask per SoC
  memory: tegra: Remove unused headers inclusions
  memory: tegra: Squash tegra20-mc into common tegra-mc driver
  memory: tegra: Introduce memory client hot reset
  memory: tegra: Add Tegra124 memory controller hot resets
  memory: tegra: Add Tegra114 memory controller hot resets
  memory: tegra: Add Tegra30 memory controller hot resets
  memory: tegra: Add Tegra20 memory controller hot resets

Thierry Reding (1):
  memory: tegra: Add Tegra210 memory controller hot resets

 .../bindings/arm/tegra/nvidia,tegra20-mc.txt       |  12 +-
 .../bindings/arm/tegra/nvidia,tegra30-mc.txt       |  18 --
 .../memory-controllers/nvidia,tegra30-mc.txt       |   5 +
 drivers/memory/Kconfig                             |  10 -
 drivers/memory/Makefile                            |   1 -
 drivers/memory/tegra/Makefile                      |   1 +
 drivers/memory/tegra/mc.c                          | 358 +++++++++++++++++++--
 drivers/memory/tegra/mc.h                          |  22 ++
 drivers/memory/tegra/tegra114.c                    |  35 ++
 drivers/memory/tegra/tegra124.c                    |  48 +++
 drivers/memory/tegra/tegra20.c                     | 296 +++++++++++++++++
 drivers/memory/tegra/tegra210.c                    |  53 ++-
 drivers/memory/tegra/tegra30.c                     |  35 ++
 drivers/memory/tegra20-mc.c                        | 254 ---------------
 include/dt-bindings/memory/tegra114-mc.h           |  19 ++
 include/dt-bindings/memory/tegra124-mc.h           |  25 ++
 include/dt-bindings/memory/tegra20-mc.h            |  21 ++
 include/dt-bindings/memory/tegra210-mc.h           |  31 ++
 include/dt-bindings/memory/tegra30-mc.h            |  19 ++
 include/soc/tegra/mc.h                             |  37 ++-
 20 files changed, 978 insertions(+), 322 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt
 create mode 100644 drivers/memory/tegra/tegra20.c
 delete mode 100644 drivers/memory/tegra20-mc.c
 create mode 100644 include/dt-bindings/memory/tegra20-mc.h

-- 
2.16.3

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

* [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:35   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC Dmitry Osipenko
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

There are two bindings for the same Memory Controller. One of the bindings
became obsolete long time ago and probably was left unnoticed, remove it
for consistency.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/arm/tegra/nvidia,tegra30-mc.txt           | 18 ------------------
 1 file changed, 18 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt
deleted file mode 100644
index bdf1a612422b..000000000000
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-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:
-	memory-controller {
-		compatible = "nvidia,tegra30-mc";
-		reg = <0x7000f000 0x010
-		       0x7000f03c 0x1b4
-		       0x7000f200 0x028
-		       0x7000f284 0x17c>;
-		interrupts = <0 77 0x04>;
-	};
-- 
2.16.3

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

* [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
  2018-04-09 19:28 ` [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:35   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC Dmitry Osipenko
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Memory Controller has a memory client "hot reset" functionality, which
resets the DMA interface of a memory client. So MC is a reset controller
in addition to IOMMU.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt     | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt
index 14968b048cd3..a878b5908a4d 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt
@@ -12,6 +12,9 @@ Required properties:
 - clock-names: Must include the following entries:
   - mc: the module's clock input
 - interrupts: The interrupt outputs from the controller.
+- #reset-cells : Should be 1. This cell represents memory client module ID.
+  The assignments may be found in header file <dt-bindings/memory/tegra30-mc.h>
+  or in the TRM documentation.
 
 Required properties for Tegra30, Tegra114, Tegra124, Tegra132 and Tegra210:
 - #iommu-cells: Should be 1. The single cell of the IOMMU specifier defines
@@ -72,12 +75,14 @@ Example SoC include file:
 		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 
 		#iommu-cells = <1>;
+		#reset-cells = <1>;
 	};
 
 	sdhci@700b0000 {
 		compatible = "nvidia,tegra124-sdhci";
 		...
 		iommus = <&mc TEGRA_SWGROUP_SDMMC1A>;
+		resets = <&mc TEGRA124_MC_RESET_SDMMC1>;
 	};
 };
 
-- 
2.16.3

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

* [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
  2018-04-09 19:28 ` [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding Dmitry Osipenko
  2018-04-09 19:28 ` [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:35   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions Dmitry Osipenko
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Memory Controller has a memory client "hot reset" functionality, which
resets the DMA interface of a memory client, so MC is a reset controller.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt      | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt
index f9632bacbd04..7d60a50a4fa1 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt
@@ -6,11 +6,21 @@ Required properties:
   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.
+- #reset-cells : Should be 1. This cell represents memory client module ID.
+  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>
+  or in the TRM documentation.
 
 Example:
-	memory-controller@7000f000 {
+	mc: memory-controller@7000f000 {
 		compatible = "nvidia,tegra20-mc";
 		reg = <0x7000f000 0x024
 		       0x7000f03c 0x3c4>;
 		interrupts = <0 77 0x04>;
+		#reset-cells = <1>;
+	};
+
+	video-codec@6001a000 {
+		compatible = "nvidia,tegra20-vde";
+		...
+		resets = <&mc TEGRA20_MC_RESET_VDE>;
 	};
-- 
2.16.3

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

* [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:36   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts Dmitry Osipenko
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Add definitions for the Tegra20+ memory controller hot resets.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 include/dt-bindings/memory/tegra114-mc.h | 19 +++++++++++++++++++
 include/dt-bindings/memory/tegra124-mc.h | 25 +++++++++++++++++++++++++
 include/dt-bindings/memory/tegra20-mc.h  | 21 +++++++++++++++++++++
 include/dt-bindings/memory/tegra210-mc.h | 31 +++++++++++++++++++++++++++++++
 include/dt-bindings/memory/tegra30-mc.h  | 19 +++++++++++++++++++
 5 files changed, 115 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra20-mc.h

diff --git a/include/dt-bindings/memory/tegra114-mc.h b/include/dt-bindings/memory/tegra114-mc.h
index 27c8386987ff..54a12adec7b8 100644
--- a/include/dt-bindings/memory/tegra114-mc.h
+++ b/include/dt-bindings/memory/tegra114-mc.h
@@ -23,4 +23,23 @@
 #define TEGRA_SWGROUP_EMUCIF	18
 #define TEGRA_SWGROUP_TSEC	19
 
+#define TEGRA114_MC_RESET_AFI		0
+#define TEGRA114_MC_RESET_AVPC		1
+#define TEGRA114_MC_RESET_DC		2
+#define TEGRA114_MC_RESET_DCB		3
+#define TEGRA114_MC_RESET_EPP		4
+#define TEGRA114_MC_RESET_2D		5
+#define TEGRA114_MC_RESET_HC		6
+#define TEGRA114_MC_RESET_HDA		7
+#define TEGRA114_MC_RESET_ISP		8
+#define TEGRA114_MC_RESET_MPCORE	9
+#define TEGRA114_MC_RESET_MPCORELP	10
+#define TEGRA114_MC_RESET_MPE		11
+#define TEGRA114_MC_RESET_3D		12
+#define TEGRA114_MC_RESET_3D2		13
+#define TEGRA114_MC_RESET_PPCS		14
+#define TEGRA114_MC_RESET_SATA		15
+#define TEGRA114_MC_RESET_VDE		16
+#define TEGRA114_MC_RESET_VI		17
+
 #endif
diff --git a/include/dt-bindings/memory/tegra124-mc.h b/include/dt-bindings/memory/tegra124-mc.h
index f534d7c06019..186e6b7e9b35 100644
--- a/include/dt-bindings/memory/tegra124-mc.h
+++ b/include/dt-bindings/memory/tegra124-mc.h
@@ -29,4 +29,29 @@
 #define TEGRA_SWGROUP_VIC	24
 #define TEGRA_SWGROUP_VI	25
 
+#define TEGRA124_MC_RESET_AFI		0
+#define TEGRA124_MC_RESET_AVPC		1
+#define TEGRA124_MC_RESET_DC		2
+#define TEGRA124_MC_RESET_DCB		3
+#define TEGRA124_MC_RESET_HC		4
+#define TEGRA124_MC_RESET_HDA		5
+#define TEGRA124_MC_RESET_ISP2		6
+#define TEGRA124_MC_RESET_MPCORE	7
+#define TEGRA124_MC_RESET_MPCORELP	8
+#define TEGRA124_MC_RESET_MSENC		9
+#define TEGRA124_MC_RESET_PPCS		10
+#define TEGRA124_MC_RESET_SATA		11
+#define TEGRA124_MC_RESET_VDE		12
+#define TEGRA124_MC_RESET_VI		13
+#define TEGRA124_MC_RESET_VIC		14
+#define TEGRA124_MC_RESET_XUSB_HOST	15
+#define TEGRA124_MC_RESET_XUSB_DEV	16
+#define TEGRA124_MC_RESET_TSEC		17
+#define TEGRA124_MC_RESET_SDMMC1	18
+#define TEGRA124_MC_RESET_SDMMC2	19
+#define TEGRA124_MC_RESET_SDMMC3	20
+#define TEGRA124_MC_RESET_SDMMC4	21
+#define TEGRA124_MC_RESET_ISP2B		22
+#define TEGRA124_MC_RESET_GPU		23
+
 #endif
diff --git a/include/dt-bindings/memory/tegra20-mc.h b/include/dt-bindings/memory/tegra20-mc.h
new file mode 100644
index 000000000000..35e131eee198
--- /dev/null
+++ b/include/dt-bindings/memory/tegra20-mc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef DT_BINDINGS_MEMORY_TEGRA20_MC_H
+#define DT_BINDINGS_MEMORY_TEGRA20_MC_H
+
+#define TEGRA20_MC_RESET_AVPC		0
+#define TEGRA20_MC_RESET_DC		1
+#define TEGRA20_MC_RESET_DCB		2
+#define TEGRA20_MC_RESET_EPP		3
+#define TEGRA20_MC_RESET_2D		4
+#define TEGRA20_MC_RESET_HC		5
+#define TEGRA20_MC_RESET_ISP		6
+#define TEGRA20_MC_RESET_MPCORE		7
+#define TEGRA20_MC_RESET_MPEA		8
+#define TEGRA20_MC_RESET_MPEB		9
+#define TEGRA20_MC_RESET_MPEC		10
+#define TEGRA20_MC_RESET_3D		11
+#define TEGRA20_MC_RESET_PPCS		12
+#define TEGRA20_MC_RESET_VDE		13
+#define TEGRA20_MC_RESET_VI		14
+
+#endif
diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h
index 4490f7cf4772..cacf05617e03 100644
--- a/include/dt-bindings/memory/tegra210-mc.h
+++ b/include/dt-bindings/memory/tegra210-mc.h
@@ -34,4 +34,35 @@
 #define TEGRA_SWGROUP_ETR	29
 #define TEGRA_SWGROUP_TSECB	30
 
+#define TEGRA210_MC_RESET_AFI		0
+#define TEGRA210_MC_RESET_AVPC		1
+#define TEGRA210_MC_RESET_DC		2
+#define TEGRA210_MC_RESET_DCB		3
+#define TEGRA210_MC_RESET_HC		4
+#define TEGRA210_MC_RESET_HDA		5
+#define TEGRA210_MC_RESET_ISP2		6
+#define TEGRA210_MC_RESET_MPCORE	7
+#define TEGRA210_MC_RESET_NVENC		8
+#define TEGRA210_MC_RESET_PPCS		9
+#define TEGRA210_MC_RESET_SATA		10
+#define TEGRA210_MC_RESET_VI		11
+#define TEGRA210_MC_RESET_VIC		12
+#define TEGRA210_MC_RESET_XUSB_HOST	13
+#define TEGRA210_MC_RESET_XUSB_DEV	14
+#define TEGRA210_MC_RESET_A9AVP		15
+#define TEGRA210_MC_RESET_TSEC		16
+#define TEGRA210_MC_RESET_SDMMC1	17
+#define TEGRA210_MC_RESET_SDMMC2	18
+#define TEGRA210_MC_RESET_SDMMC3	19
+#define TEGRA210_MC_RESET_SDMMC4	20
+#define TEGRA210_MC_RESET_ISP2B		21
+#define TEGRA210_MC_RESET_GPU		22
+#define TEGRA210_MC_RESET_NVDEC		23
+#define TEGRA210_MC_RESET_APE		24
+#define TEGRA210_MC_RESET_SE		25
+#define TEGRA210_MC_RESET_NVJPG		26
+#define TEGRA210_MC_RESET_AXIAP		27
+#define TEGRA210_MC_RESET_ETR		28
+#define TEGRA210_MC_RESET_TSECB		29
+
 #endif
diff --git a/include/dt-bindings/memory/tegra30-mc.h b/include/dt-bindings/memory/tegra30-mc.h
index 3cac81919023..169f005fbc78 100644
--- a/include/dt-bindings/memory/tegra30-mc.h
+++ b/include/dt-bindings/memory/tegra30-mc.h
@@ -22,4 +22,23 @@
 #define TEGRA_SWGROUP_MPCORE	17
 #define TEGRA_SWGROUP_ISP	18
 
+#define TEGRA30_MC_RESET_AFI		0
+#define TEGRA30_MC_RESET_AVPC		1
+#define TEGRA30_MC_RESET_DC		2
+#define TEGRA30_MC_RESET_DCB		3
+#define TEGRA30_MC_RESET_EPP		4
+#define TEGRA30_MC_RESET_2D		5
+#define TEGRA30_MC_RESET_HC		6
+#define TEGRA30_MC_RESET_HDA		7
+#define TEGRA30_MC_RESET_ISP		8
+#define TEGRA30_MC_RESET_MPCORE		9
+#define TEGRA30_MC_RESET_MPCORELP	10
+#define TEGRA30_MC_RESET_MPE		11
+#define TEGRA30_MC_RESET_3D		12
+#define TEGRA30_MC_RESET_3D2		13
+#define TEGRA30_MC_RESET_PPCS		14
+#define TEGRA30_MC_RESET_SATA		15
+#define TEGRA30_MC_RESET_VDE		16
+#define TEGRA30_MC_RESET_VI		17
+
 #endif
-- 
2.16.3

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

* [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:36   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ Dmitry Osipenko
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

The ISR reads interrupts-enable mask, but doesn't utilize it. Apply the
mask to the interrupt status and don't handle interrupts that MC driver
haven't asked for. Kernel would disable spurious MC IRQ and report the
error. This would happen only in a case of a very severe bug.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index a4803ac192bb..d2005b995821 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -252,8 +252,11 @@ static irqreturn_t tegra_mc_irq(int irq, void *data)
 	unsigned int bit;
 
 	/* mask all interrupts to avoid flooding */
-	status = mc_readl(mc, MC_INTSTATUS);
 	mask = mc_readl(mc, MC_INTMASK);
+	status = mc_readl(mc, MC_INTSTATUS) & mask;
+
+	if (!status)
+		return IRQ_NONE;
 
 	for_each_set_bit(bit, &status, 32) {
 		const char *error = status_names[bit] ?: "unknown";
-- 
2.16.3

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

* [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:36   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC Dmitry Osipenko
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

This avoids unwanted interrupt during MC driver probe.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index d2005b995821..e55b9733bd83 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -407,14 +407,6 @@ static int tegra_mc_probe(struct platform_device *pdev)
 		return mc->irq;
 	}
 
-	err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED,
-			       dev_name(&pdev->dev), mc);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
-			err);
-		return err;
-	}
-
 	WARN(!mc->soc->client_id_mask, "Missing client ID mask for this SoC\n");
 
 	value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
@@ -423,6 +415,14 @@ static int tegra_mc_probe(struct platform_device *pdev)
 
 	mc_writel(mc, value, MC_INTMASK);
 
+	err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED,
+			       dev_name(&pdev->dev), mc);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
+			err);
+		return err;
+	}
+
 	return 0;
 }
 
-- 
2.16.3

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

* [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (5 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:36   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions Dmitry Osipenko
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Currently we are enabling handling of interrupts specific to Tegra124+
which happen to overlap with previous generations. Let's specify
interrupts mask per SoC generation for consistency and in a preparation
of squashing of Tegra20 driver into the common one that will enable
handling of GART faults which may be undesirable by newer generations.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c       | 21 +++------------------
 drivers/memory/tegra/mc.h       |  9 +++++++++
 drivers/memory/tegra/tegra114.c |  2 ++
 drivers/memory/tegra/tegra124.c |  6 ++++++
 drivers/memory/tegra/tegra210.c |  3 +++
 drivers/memory/tegra/tegra30.c  |  2 ++
 include/soc/tegra/mc.h          |  2 ++
 7 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index e55b9733bd83..60509f0a386b 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -20,14 +20,6 @@
 #include "mc.h"
 
 #define MC_INTSTATUS 0x000
-#define  MC_INT_DECERR_MTS (1 << 16)
-#define  MC_INT_SECERR_SEC (1 << 13)
-#define  MC_INT_DECERR_VPR (1 << 12)
-#define  MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
-#define  MC_INT_INVALID_SMMU_PAGE (1 << 10)
-#define  MC_INT_ARBITRATION_EMEM (1 << 9)
-#define  MC_INT_SECURITY_VIOLATION (1 << 8)
-#define  MC_INT_DECERR_EMEM (1 << 6)
 
 #define MC_INTMASK 0x004
 
@@ -248,13 +240,11 @@ static const char *const error_names[8] = {
 static irqreturn_t tegra_mc_irq(int irq, void *data)
 {
 	struct tegra_mc *mc = data;
-	unsigned long status, mask;
+	unsigned long status;
 	unsigned int bit;
 
 	/* mask all interrupts to avoid flooding */
-	mask = mc_readl(mc, MC_INTMASK);
-	status = mc_readl(mc, MC_INTSTATUS) & mask;
-
+	status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
 	if (!status)
 		return IRQ_NONE;
 
@@ -349,7 +339,6 @@ static int tegra_mc_probe(struct platform_device *pdev)
 	const struct of_device_id *match;
 	struct resource *res;
 	struct tegra_mc *mc;
-	u32 value;
 	int err;
 
 	match = of_match_node(tegra_mc_of_match, pdev->dev.of_node);
@@ -409,11 +398,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
 
 	WARN(!mc->soc->client_id_mask, "Missing client ID mask for this SoC\n");
 
-	value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
-		MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
-		MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM;
-
-	mc_writel(mc, value, MC_INTMASK);
+	mc_writel(mc, mc->soc->intmask, MC_INTMASK);
 
 	err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED,
 			       dev_name(&pdev->dev), mc);
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index ddb16676c3af..24e020b4609b 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -14,6 +14,15 @@
 
 #include <soc/tegra/mc.h>
 
+#define MC_INT_DECERR_MTS (1 << 16)
+#define MC_INT_SECERR_SEC (1 << 13)
+#define MC_INT_DECERR_VPR (1 << 12)
+#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
+#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
+#define MC_INT_ARBITRATION_EMEM (1 << 9)
+#define MC_INT_SECURITY_VIOLATION (1 << 8)
+#define MC_INT_DECERR_EMEM (1 << 6)
+
 static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
 {
 	return readl(mc->regs + offset);
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index b20e6e3e208e..7560b2f558a7 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -945,4 +945,6 @@ const struct tegra_mc_soc tegra114_mc_soc = {
 	.atom_size = 32,
 	.client_id_mask = 0x7f,
 	.smmu = &tegra114_smmu_soc,
+	.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+		   MC_INT_DECERR_EMEM,
 };
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 8b6360eabb8a..bd16555cca0f 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1035,6 +1035,9 @@ const struct tegra_mc_soc tegra124_mc_soc = {
 	.smmu = &tegra124_smmu_soc,
 	.emem_regs = tegra124_mc_emem_regs,
 	.num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
+	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
 };
 #endif /* CONFIG_ARCH_TEGRA_124_SOC */
 
@@ -1059,5 +1062,8 @@ const struct tegra_mc_soc tegra132_mc_soc = {
 	.atom_size = 32,
 	.client_id_mask = 0x7f,
 	.smmu = &tegra132_smmu_soc,
+	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index d398bcd3fc57..3b8d0100088c 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -1092,4 +1092,7 @@ const struct tegra_mc_soc tegra210_mc_soc = {
 	.atom_size = 64,
 	.client_id_mask = 0xff,
 	.smmu = &tegra210_smmu_soc,
+	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
 };
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index d756c837f23e..d2ba50ed0490 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -967,4 +967,6 @@ const struct tegra_mc_soc tegra30_mc_soc = {
 	.atom_size = 16,
 	.client_id_mask = 0x7f,
 	.smmu = &tegra30_smmu_soc,
+	.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+		   MC_INT_DECERR_EMEM,
 };
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 233bae954970..be6e49124c6d 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -108,6 +108,8 @@ struct tegra_mc_soc {
 	u8 client_id_mask;
 
 	const struct tegra_smmu_soc *smmu;
+
+	u32 intmask;
 };
 
 struct tegra_mc {
-- 
2.16.3

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

* [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (6 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:37   ` Thierry Reding
  2018-04-09 19:28 ` [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver Dmitry Osipenko
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Tegra210 contains some unused leftover headers, remove them for
consistency.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra210.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index 3b8d0100088c..b729f49ffc8f 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -6,11 +6,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/of.h>
-#include <linux/mm.h>
-
-#include <asm/cacheflush.h>
-
 #include <dt-bindings/memory/tegra210-mc.h>
 
 #include "mc.h"
-- 
2.16.3

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

* [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (7 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions Dmitry Osipenko
@ 2018-04-09 19:28 ` Dmitry Osipenko
  2018-04-27  9:34   ` Thierry Reding
  2018-04-30  8:07   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset Dmitry Osipenko
                   ` (5 subsequent siblings)
  14 siblings, 2 replies; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-09 19:28 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Tegra30+ has some minor differences in registers / bits layout compared
to Tegra20. Let's squash Tegra20 driver into the common tegra-mc driver
in a preparation for the upcoming MC hot reset controls implementation,
avoiding code duplication.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/Kconfig         |  10 --
 drivers/memory/Makefile        |   1 -
 drivers/memory/tegra/Makefile  |   1 +
 drivers/memory/tegra/mc.c      | 120 +++++++++++++++++--
 drivers/memory/tegra/mc.h      |  11 ++
 drivers/memory/tegra/tegra20.c | 178 +++++++++++++++++++++++++++++
 drivers/memory/tegra20-mc.c    | 254 -----------------------------------------
 include/soc/tegra/mc.h         |   2 +-
 8 files changed, 299 insertions(+), 278 deletions(-)
 create mode 100644 drivers/memory/tegra/tegra20.c
 delete mode 100644 drivers/memory/tegra20-mc.c

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 19a0e83f260d..8d731d6c3e54 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -104,16 +104,6 @@ config MVEBU_DEVBUS
 	  Armada 370 and Armada XP. This controller allows to handle flash
 	  devices such as NOR, NAND, SRAM, and FPGA.
 
-config TEGRA20_MC
-	bool "Tegra20 Memory Controller(MC) driver"
-	default y
-	depends on ARCH_TEGRA_2x_SOC
-	help
-	  This driver is for the Memory Controller(MC) module available
-	  in Tegra20 SoCs, mainly for a address translation fault
-	  analysis, especially for IOMMU/GART(Graphics Address
-	  Relocation Table) module.
-
 config FSL_CORENET_CF
 	tristate "Freescale CoreNet Error Reporting"
 	depends on FSL_SOC_BOOKE
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 66f55240830e..a01ab3e22f94 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_OMAP_GPMC)		+= omap-gpmc.o
 obj-$(CONFIG_FSL_CORENET_CF)	+= fsl-corenet-cf.o
 obj-$(CONFIG_FSL_IFC)		+= fsl_ifc.o
 obj-$(CONFIG_MVEBU_DEVBUS)	+= mvebu-devbus.o
-obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o
 obj-$(CONFIG_JZ4780_NEMC)	+= jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)		+= mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL)	+= da8xx-ddrctl.o
diff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile
index ce87a9470034..94ab16ba075b 100644
--- a/drivers/memory/tegra/Makefile
+++ b/drivers/memory/tegra/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 tegra-mc-y := mc.o
 
+tegra-mc-$(CONFIG_ARCH_TEGRA_2x_SOC)  += tegra20.o
 tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC)  += tegra30.o
 tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o
 tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 60509f0a386b..5932ab33202a 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -37,6 +37,10 @@
 
 #define MC_ERR_ADR 0x0c
 
+#define MC_GART_ERROR_REQ		0x30
+#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
+#define MC_SECURITY_VIOLATION_STATUS	0x74
+
 #define MC_EMEM_ARB_CFG 0x90
 #define  MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x)	(((x) & 0x1ff) << 0)
 #define  MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK	0x1ff
@@ -46,6 +50,9 @@
 #define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
 
 static const struct of_device_id tegra_mc_of_match[] = {
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+	{ .compatible = "nvidia,tegra20-mc", .data = &tegra20_mc_soc },
+#endif
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
 	{ .compatible = "nvidia,tegra30-mc", .data = &tegra30_mc_soc },
 #endif
@@ -221,6 +228,7 @@ static int tegra_mc_setup_timings(struct tegra_mc *mc)
 static const char *const status_names[32] = {
 	[ 1] = "External interrupt",
 	[ 6] = "EMEM address decode error",
+	[ 7] = "GART page fault",
 	[ 8] = "Security violation",
 	[ 9] = "EMEM arbitration error",
 	[10] = "Page fault",
@@ -334,11 +342,85 @@ static irqreturn_t tegra_mc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
+{
+	struct tegra_mc *mc = data;
+	unsigned long status;
+	unsigned int bit;
+
+	/* mask all interrupts to avoid flooding */
+	status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
+	if (!status)
+		return IRQ_NONE;
+
+	for_each_set_bit(bit, &status, 32) {
+		const char *direction = "read", *secure = "";
+		const char *error = status_names[bit];
+		const char *client, *desc;
+		phys_addr_t addr;
+		u32 value, reg;
+		u8 id, type;
+
+		switch (BIT(bit)) {
+		case MC_INT_DECERR_EMEM:
+			reg = MC_DECERR_EMEM_OTHERS_STATUS;
+			value = mc_readl(mc, reg);
+
+			id = value & mc->soc->client_id_mask;
+			desc = error_names[2];
+
+			if (value & BIT(31))
+				direction = "write";
+			break;
+
+		case MC_INT_INVALID_GART_PAGE:
+			reg = MC_GART_ERROR_REQ;
+			value = mc_readl(mc, reg);
+
+			id = (value >> 1) & mc->soc->client_id_mask;
+			desc = error_names[2];
+
+			if (value & BIT(0))
+				direction = "write";
+			break;
+
+		case MC_INT_SECURITY_VIOLATION:
+			reg = MC_SECURITY_VIOLATION_STATUS;
+			value = mc_readl(mc, reg);
+
+			id = value & mc->soc->client_id_mask;
+			type = (value & BIT(30)) ? 4 : 3;
+			desc = error_names[type];
+			secure = "secure ";
+
+			if (value & BIT(31))
+				direction = "write";
+			break;
+
+		default:
+			continue;
+		}
+
+		client = mc->soc->clients[id].name;
+		addr = mc_readl(mc, reg + sizeof(u32));
+
+		dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s)\n",
+				    client, secure, direction, &addr, error,
+				    desc);
+	}
+
+	/* clear interrupts */
+	mc_writel(mc, status, MC_INTSTATUS);
+
+	return IRQ_HANDLED;
+}
+
 static int tegra_mc_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct resource *res;
 	struct tegra_mc *mc;
+	void *isr;
 	int err;
 
 	match = of_match_node(tegra_mc_of_match, pdev->dev.of_node);
@@ -361,18 +443,32 @@ static int tegra_mc_probe(struct platform_device *pdev)
 	if (IS_ERR(mc->regs))
 		return PTR_ERR(mc->regs);
 
-	mc->clk = devm_clk_get(&pdev->dev, "mc");
-	if (IS_ERR(mc->clk)) {
-		dev_err(&pdev->dev, "failed to get MC clock: %ld\n",
-			PTR_ERR(mc->clk));
-		return PTR_ERR(mc->clk);
-	}
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+	if (mc->soc == &tegra20_mc_soc) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		mc->regs2 = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(mc->regs2))
+			return PTR_ERR(mc->regs2);
 
-	err = tegra_mc_setup_latency_allowance(mc);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to setup latency allowance: %d\n",
-			err);
-		return err;
+		isr = tegra20_mc_irq;
+	} else
+#endif
+	{
+		mc->clk = devm_clk_get(&pdev->dev, "mc");
+		if (IS_ERR(mc->clk)) {
+			dev_err(&pdev->dev, "failed to get MC clock: %ld\n",
+				PTR_ERR(mc->clk));
+			return PTR_ERR(mc->clk);
+		}
+
+		err = tegra_mc_setup_latency_allowance(mc);
+		if (err < 0) {
+			dev_err(&pdev->dev, "failed to setup latency allowance: %d\n",
+				err);
+			return err;
+		}
+
+		isr = tegra_mc_irq;
 	}
 
 	err = tegra_mc_setup_timings(mc);
@@ -400,7 +496,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
 
 	mc_writel(mc, mc->soc->intmask, MC_INTMASK);
 
-	err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED,
+	err = devm_request_irq(&pdev->dev, mc->irq, isr, IRQF_SHARED,
 			       dev_name(&pdev->dev), mc);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index 24e020b4609b..cdd6911f4079 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -21,19 +21,30 @@
 #define MC_INT_INVALID_SMMU_PAGE (1 << 10)
 #define MC_INT_ARBITRATION_EMEM (1 << 9)
 #define MC_INT_SECURITY_VIOLATION (1 << 8)
+#define MC_INT_INVALID_GART_PAGE (1 << 7)
 #define MC_INT_DECERR_EMEM (1 << 6)
 
 static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
 {
+	if (mc->regs2 && offset >= 0x24)
+		return readl(mc->regs2 + offset - 0x3c);
+
 	return readl(mc->regs + offset);
 }
 
 static inline void mc_writel(struct tegra_mc *mc, u32 value,
 			     unsigned long offset)
 {
+	if (mc->regs2 && offset >= 0x24)
+		return writel(value, mc->regs2 + offset - 0x3c);
+
 	writel(value, mc->regs + offset);
 }
 
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+extern const struct tegra_mc_soc tegra20_mc_soc;
+#endif
+
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
 extern const struct tegra_mc_soc tegra30_mc_soc;
 #endif
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
new file mode 100644
index 000000000000..512a3418cb80
--- /dev/null
+++ b/drivers/memory/tegra/tegra20.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "mc.h"
+
+static const struct tegra_mc_client tegra20_mc_clients[] = {
+	{
+		.id = 0x00,
+		.name = "display0a",
+	}, {
+		.id = 0x01,
+		.name = "display0ab",
+	}, {
+		.id = 0x02,
+		.name = "display0b",
+	}, {
+		.id = 0x03,
+		.name = "display0bb",
+	}, {
+		.id = 0x04,
+		.name = "display0c",
+	}, {
+		.id = 0x05,
+		.name = "display0cb",
+	}, {
+		.id = 0x06,
+		.name = "display1b",
+	}, {
+		.id = 0x07,
+		.name = "display1bb",
+	}, {
+		.id = 0x08,
+		.name = "eppup",
+	}, {
+		.id = 0x09,
+		.name = "g2pr",
+	}, {
+		.id = 0x0a,
+		.name = "g2sr",
+	}, {
+		.id = 0x0b,
+		.name = "mpeunifbr",
+	}, {
+		.id = 0x0c,
+		.name = "viruv",
+	}, {
+		.id = 0x0d,
+		.name = "avpcarm7r",
+	}, {
+		.id = 0x0e,
+		.name = "displayhc",
+	}, {
+		.id = 0x0f,
+		.name = "displayhcb",
+	}, {
+		.id = 0x10,
+		.name = "fdcdrd",
+	}, {
+		.id = 0x11,
+		.name = "g2dr",
+	}, {
+		.id = 0x12,
+		.name = "host1xdmar",
+	}, {
+		.id = 0x13,
+		.name = "host1xr",
+	}, {
+		.id = 0x14,
+		.name = "idxsrd",
+	}, {
+		.id = 0x15,
+		.name = "mpcorer",
+	}, {
+		.id = 0x16,
+		.name = "mpe_ipred",
+	}, {
+		.id = 0x17,
+		.name = "mpeamemrd",
+	}, {
+		.id = 0x18,
+		.name = "mpecsrd",
+	}, {
+		.id = 0x19,
+		.name = "ppcsahbdmar",
+	}, {
+		.id = 0x1a,
+		.name = "ppcsahbslvr",
+	}, {
+		.id = 0x1b,
+		.name = "texsrd",
+	}, {
+		.id = 0x1c,
+		.name = "vdebsevr",
+	}, {
+		.id = 0x1d,
+		.name = "vdember",
+	}, {
+		.id = 0x1e,
+		.name = "vdemcer",
+	}, {
+		.id = 0x1f,
+		.name = "vdetper",
+	}, {
+		.id = 0x20,
+		.name = "eppu",
+	}, {
+		.id = 0x21,
+		.name = "eppv",
+	}, {
+		.id = 0x22,
+		.name = "eppy",
+	}, {
+		.id = 0x23,
+		.name = "mpeunifbw",
+	}, {
+		.id = 0x24,
+		.name = "viwsb",
+	}, {
+		.id = 0x25,
+		.name = "viwu",
+	}, {
+		.id = 0x26,
+		.name = "viwv",
+	}, {
+		.id = 0x27,
+		.name = "viwy",
+	}, {
+		.id = 0x28,
+		.name = "g2dw",
+	}, {
+		.id = 0x29,
+		.name = "avpcarm7w",
+	}, {
+		.id = 0x2a,
+		.name = "fdcdwr",
+	}, {
+		.id = 0x2b,
+		.name = "host1xw",
+	}, {
+		.id = 0x2c,
+		.name = "ispw",
+	}, {
+		.id = 0x2d,
+		.name = "mpcorew",
+	}, {
+		.id = 0x2e,
+		.name = "mpecswr",
+	}, {
+		.id = 0x2f,
+		.name = "ppcsahbdmaw",
+	}, {
+		.id = 0x30,
+		.name = "ppcsahbslvw",
+	}, {
+		.id = 0x31,
+		.name = "vdebsevw",
+	}, {
+		.id = 0x32,
+		.name = "vdembew",
+	}, {
+		.id = 0x33,
+		.name = "vdetpmw",
+	},
+};
+
+const struct tegra_mc_soc tegra20_mc_soc = {
+	.clients = tegra20_mc_clients,
+	.num_clients = ARRAY_SIZE(tegra20_mc_clients),
+	.num_address_bits = 32,
+	.client_id_mask = 0x3f,
+	.intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
+		   MC_INT_DECERR_EMEM,
+};
diff --git a/drivers/memory/tegra20-mc.c b/drivers/memory/tegra20-mc.c
deleted file mode 100644
index cc309a05289a..000000000000
--- a/drivers/memory/tegra20-mc.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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/err.h>
-#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)
-{
-	u32 val = 0;
-
-	if (offs < 0x24)
-		val = readl(mc->regs[0] + offs);
-	else if (offs < 0x400)
-		val = readl(mc->regs[1] + offs - 0x3c);
-
-	return val;
-}
-
-static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs)
-{
-	if (offs < 0x24)
-		writel(val, mc->regs[0] + offs);
-	else if (offs < 0x400)
-		writel(val, mc->regs[1] + offs - 0x3c);
-}
-
-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))) {
-		dev_err_ratelimited(mc->dev, "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));
-
-	dev_err_ratelimited(mc->dev, "%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[] = {
-	{ .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);
-		mask &= ~BIT(bit - 1);
-	}
-
-	mc_writel(mc, stat, MC_INTSTATUS);
-	return IRQ_HANDLED;
-}
-
-static int 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);
-		mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
-		if (IS_ERR(mc->regs[i]))
-			return PTR_ERR(mc->regs[i]);
-	}
-
-	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 struct platform_driver tegra20_mc_driver = {
-	.probe = tegra20_mc_probe,
-	.driver = {
-		.name = DRV_NAME,
-		.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);
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index be6e49124c6d..bea7fe776825 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -115,7 +115,7 @@ struct tegra_mc_soc {
 struct tegra_mc {
 	struct device *dev;
 	struct tegra_smmu *smmu;
-	void __iomem *regs;
+	void __iomem *regs, *regs2;
 	struct clk *clk;
 	int irq;
 
-- 
2.16.3

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

* [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (8 preceding siblings ...)
  2018-04-09 19:28 ` [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-30  8:08   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets Dmitry Osipenko
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

In order to reset busy HW properly, memory controller needs to be
involved, otherwise it is possible to get corrupted memory or hang machine
if HW was reset during DMA. Introduce memory client 'hot reset' that will
be used for resetting of busy HW.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c | 210 ++++++++++++++++++++++++++++++++++++++
 drivers/memory/tegra/mc.h |   2 +
 include/soc/tegra/mc.h    |  33 ++++++
 3 files changed, 245 insertions(+)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 5932ab33202a..6b211daa99bf 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -72,6 +73,207 @@ static const struct of_device_id tegra_mc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
 
+static int terga_mc_block_dma_common(struct tegra_mc *mc,
+				     const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->control) | BIT(rst->bit);
+	mc_writel(mc, value, rst->control);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+static bool terga_mc_dma_idling_common(struct tegra_mc *mc,
+				       const struct tegra_mc_reset *rst)
+{
+	return (mc_readl(mc, rst->status) & BIT(rst->bit)) != 0;
+}
+
+static int terga_mc_unblock_dma_common(struct tegra_mc *mc,
+				       const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
+	mc_writel(mc, value, rst->control);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+static int terga_mc_reset_status_common(struct tegra_mc *mc,
+					const struct tegra_mc_reset *rst)
+{
+	return (mc_readl(mc, rst->control) & BIT(rst->bit)) != 0;
+}
+
+const struct tegra_mc_reset_ops terga_mc_reset_ops_common = {
+	.block_dma = terga_mc_block_dma_common,
+	.dma_idling = terga_mc_dma_idling_common,
+	.unblock_dma = terga_mc_unblock_dma_common,
+	.reset_status = terga_mc_reset_status_common,
+};
+
+static inline struct tegra_mc *reset_to_mc(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct tegra_mc, reset);
+}
+
+static const struct tegra_mc_reset *tegra_mc_reset_find(struct tegra_mc *mc,
+							unsigned long id)
+{
+	unsigned int i;
+
+	for (i = 0; i < mc->soc->num_resets; i++)
+		if (mc->soc->resets[i].id == id)
+			return &mc->soc->resets[i];
+
+	return NULL;
+}
+
+static int tegra_mc_hotreset_assert(struct reset_controller_dev *rcdev,
+				    unsigned long id)
+{
+	struct tegra_mc *mc = reset_to_mc(rcdev);
+	const struct tegra_mc_reset_ops *rst_ops;
+	const struct tegra_mc_reset *rst;
+	int retries = 500;
+	int err;
+
+	rst = tegra_mc_reset_find(mc, id);
+	if (!rst)
+		return -ENODEV;
+
+	rst_ops = mc->soc->reset_ops;
+	if (!rst_ops)
+		return -ENODEV;
+
+	if (rst_ops->block_dma) {
+		/* block clients DMA requests */
+		err = rst_ops->block_dma(mc, rst);
+		if (err) {
+			dev_err(mc->dev, "Failed to block %s DMA: %d\n",
+				rst->name, err);
+			return err;
+		}
+	}
+
+	if (rst_ops->dma_idling) {
+		/* wait for completion of the outstanding DMA requests */
+		while (!rst_ops->dma_idling(mc, rst)) {
+			if (!retries--) {
+				dev_err(mc->dev, "Failed to flush %s DMA\n",
+					rst->name);
+				return -EBUSY;
+			}
+
+			usleep_range(10, 100);
+		}
+	}
+
+	if (rst_ops->hotreset_assert) {
+		/* clear clients DMA requests sitting before arbitration */
+		err = rst_ops->hotreset_assert(mc, rst);
+		if (err) {
+			dev_err(mc->dev, "Failed to hot reset %s: %d\n",
+				rst->name, err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int tegra_mc_hotreset_deassert(struct reset_controller_dev *rcdev,
+				      unsigned long id)
+{
+	struct tegra_mc *mc = reset_to_mc(rcdev);
+	const struct tegra_mc_reset_ops *rst_ops;
+	const struct tegra_mc_reset *rst;
+	int err;
+
+	rst = tegra_mc_reset_find(mc, id);
+	if (!rst)
+		return -ENODEV;
+
+	rst_ops = mc->soc->reset_ops;
+	if (!rst_ops)
+		return -ENODEV;
+
+	if (rst_ops->hotreset_deassert) {
+		/* take out client from hot reset */
+		err = rst_ops->hotreset_deassert(mc, rst);
+		if (err) {
+			dev_err(mc->dev, "Failed to deassert hot reset %s: %d\n",
+				rst->name, err);
+			return err;
+		}
+	}
+
+	if (rst_ops->unblock_dma) {
+		/* allow new DMA requests to proceed to arbitration */
+		err = rst_ops->unblock_dma(mc, rst);
+		if (err) {
+			dev_err(mc->dev, "Failed to unblock %s DMA : %d\n",
+				rst->name, err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int tegra_mc_hotreset_status(struct reset_controller_dev *rcdev,
+				    unsigned long id)
+{
+	struct tegra_mc *mc = reset_to_mc(rcdev);
+	const struct tegra_mc_reset_ops *rst_ops;
+	const struct tegra_mc_reset *rst;
+
+	rst = tegra_mc_reset_find(mc, id);
+	if (!rst)
+		return -ENODEV;
+
+	rst_ops = mc->soc->reset_ops;
+	if (!rst_ops)
+		return -ENODEV;
+
+	return rst_ops->reset_status(mc, rst);
+}
+
+static const struct reset_control_ops tegra_mc_reset_ops = {
+	.assert = tegra_mc_hotreset_assert,
+	.deassert = tegra_mc_hotreset_deassert,
+	.status = tegra_mc_hotreset_status,
+};
+
+static int tegra_mc_reset_setup(struct tegra_mc *mc)
+{
+	int err;
+
+	mc->reset.ops = &tegra_mc_reset_ops;
+	mc->reset.owner = THIS_MODULE;
+	mc->reset.of_node = mc->dev->of_node;
+	mc->reset.of_reset_n_cells = 1;
+	mc->reset.nr_resets = mc->soc->num_resets;
+
+	err = reset_controller_register(&mc->reset);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
 {
 	unsigned long long tick;
@@ -432,6 +634,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	platform_set_drvdata(pdev, mc);
+	spin_lock_init(&mc->lock);
 	mc->soc = match->data;
 	mc->dev = &pdev->dev;
 
@@ -486,6 +689,13 @@ static int tegra_mc_probe(struct platform_device *pdev)
 		}
 	}
 
+	err = tegra_mc_reset_setup(mc);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to register reset controller: %d\n",
+			err);
+		return err;
+	}
+
 	mc->irq = platform_get_irq(pdev, 0);
 	if (mc->irq < 0) {
 		dev_err(&pdev->dev, "interrupt not specified\n");
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index cdd6911f4079..01065f12ebeb 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -41,6 +41,8 @@ static inline void mc_writel(struct tegra_mc *mc, u32 value,
 	writel(value, mc->regs + offset);
 }
 
+extern const struct tegra_mc_reset_ops terga_mc_reset_ops_common;
+
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 extern const struct tegra_mc_soc tegra20_mc_soc;
 #endif
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index bea7fe776825..b43f37fea096 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -9,6 +9,7 @@
 #ifndef __SOC_TEGRA_MC_H__
 #define __SOC_TEGRA_MC_H__
 
+#include <linux/reset-controller.h>
 #include <linux/types.h>
 
 struct clk;
@@ -95,6 +96,30 @@ static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
 }
 #endif
 
+struct tegra_mc_reset {
+	const char *name;
+	unsigned long id;
+	unsigned int control;
+	unsigned int status;
+	unsigned int reset;
+	unsigned int bit;
+};
+
+struct tegra_mc_reset_ops {
+	int (*hotreset_assert)(struct tegra_mc *mc,
+			       const struct tegra_mc_reset *rst);
+	int (*hotreset_deassert)(struct tegra_mc *mc,
+				 const struct tegra_mc_reset *rst);
+	int (*block_dma)(struct tegra_mc *mc,
+			 const struct tegra_mc_reset *rst);
+	bool (*dma_idling)(struct tegra_mc *mc,
+			   const struct tegra_mc_reset *rst);
+	int (*unblock_dma)(struct tegra_mc *mc,
+			   const struct tegra_mc_reset *rst);
+	int (*reset_status)(struct tegra_mc *mc,
+			    const struct tegra_mc_reset *rst);
+};
+
 struct tegra_mc_soc {
 	const struct tegra_mc_client *clients;
 	unsigned int num_clients;
@@ -110,6 +135,10 @@ struct tegra_mc_soc {
 	const struct tegra_smmu_soc *smmu;
 
 	u32 intmask;
+
+	const struct tegra_mc_reset_ops *reset_ops;
+	const struct tegra_mc_reset *resets;
+	unsigned int num_resets;
 };
 
 struct tegra_mc {
@@ -124,6 +153,10 @@ struct tegra_mc {
 
 	struct tegra_mc_timing *timings;
 	unsigned int num_timings;
+
+	struct reset_controller_dev reset;
+
+	spinlock_t lock;
 };
 
 void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
-- 
2.17.0

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

* [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (9 preceding siblings ...)
  2018-04-13 11:33 ` [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-27  9:39   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 12/15] memory: tegra: Add Tegra124 " Dmitry Osipenko
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

From: Thierry Reding <treding@nvidia.com>

Define the table of memory controller hot resets for Tegra210.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/memory/tegra/tegra210.c | 45 +++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index b729f49ffc8f..d00a77160407 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -1080,6 +1080,48 @@ static const struct tegra_smmu_soc tegra210_smmu_soc = {
 	.num_asids = 128,
 };
 
+#define TEGRA210_MC_RESET(_name, _control, _status, _bit)	\
+	{							\
+		.name = #_name,					\
+		.id = TEGRA210_MC_RESET_##_name,		\
+		.control = _control,				\
+		.status = _status,				\
+		.bit = _bit,					\
+	}
+
+static const struct tegra_mc_reset tegra210_mc_resets[] = {
+	TEGRA210_MC_RESET(AFI,       0x200, 0x204,  0),
+	TEGRA210_MC_RESET(AVPC,      0x200, 0x204,  1),
+	TEGRA210_MC_RESET(DC,        0x200, 0x204,  2),
+	TEGRA210_MC_RESET(DCB,       0x200, 0x204,  3),
+	TEGRA210_MC_RESET(HC,        0x200, 0x204,  6),
+	TEGRA210_MC_RESET(HDA,       0x200, 0x204,  7),
+	TEGRA210_MC_RESET(ISP2,      0x200, 0x204,  8),
+	TEGRA210_MC_RESET(MPCORE,    0x200, 0x204,  9),
+	TEGRA210_MC_RESET(NVENC,     0x200, 0x204, 11),
+	TEGRA210_MC_RESET(PPCS,      0x200, 0x204, 14),
+	TEGRA210_MC_RESET(SATA,      0x200, 0x204, 15),
+	TEGRA210_MC_RESET(VI,        0x200, 0x204, 17),
+	TEGRA210_MC_RESET(VIC,       0x200, 0x204, 18),
+	TEGRA210_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
+	TEGRA210_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
+	TEGRA210_MC_RESET(A9AVP,     0x200, 0x204, 21),
+	TEGRA210_MC_RESET(TSEC,      0x200, 0x204, 22),
+	TEGRA210_MC_RESET(SDMMC1,    0x200, 0x204, 29),
+	TEGRA210_MC_RESET(SDMMC2,    0x200, 0x204, 30),
+	TEGRA210_MC_RESET(SDMMC3,    0x200, 0x204, 31),
+	TEGRA210_MC_RESET(SDMMC4,    0x970, 0x974,  0),
+	TEGRA210_MC_RESET(ISP2B,     0x970, 0x974,  1),
+	TEGRA210_MC_RESET(GPU,       0x970, 0x974,  2),
+	TEGRA210_MC_RESET(NVDEC,     0x970, 0x974,  5),
+	TEGRA210_MC_RESET(APE,       0x970, 0x974,  6),
+	TEGRA210_MC_RESET(SE,        0x970, 0x974,  7),
+	TEGRA210_MC_RESET(NVJPG,     0x970, 0x974,  8),
+	TEGRA210_MC_RESET(AXIAP,     0x970, 0x974, 11),
+	TEGRA210_MC_RESET(ETR,       0x970, 0x974, 12),
+	TEGRA210_MC_RESET(TSECB,     0x970, 0x974, 13),
+};
+
 const struct tegra_mc_soc tegra210_mc_soc = {
 	.clients = tegra210_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra210_mc_clients),
@@ -1090,4 +1132,7 @@ const struct tegra_mc_soc tegra210_mc_soc = {
 	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
 		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
 		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+	.reset_ops = &terga_mc_reset_ops_common,
+	.resets = tegra210_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra210_mc_resets),
 };
-- 
2.17.0

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

* [PATCH v4 12/15] memory: tegra: Add Tegra124 memory controller hot resets
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (10 preceding siblings ...)
  2018-04-13 11:33 ` [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-30  8:08   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 13/15] memory: tegra: Add Tegra114 " Dmitry Osipenko
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Define the table of memory controller hot resets for Tegra124.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra124.c | 42 +++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index bd16555cca0f..b561a1fe7f46 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1012,6 +1012,42 @@ static const struct tegra_smmu_group_soc tegra124_groups[] = {
 	},
 };
 
+#define TEGRA124_MC_RESET(_name, _control, _status, _bit)	\
+	{							\
+		.name = #_name,					\
+		.id = TEGRA124_MC_RESET_##_name,		\
+		.control = _control,				\
+		.status = _status,				\
+		.bit = _bit,					\
+	}
+
+static const struct tegra_mc_reset tegra124_mc_resets[] = {
+	TEGRA124_MC_RESET(AFI,       0x200, 0x204,  0),
+	TEGRA124_MC_RESET(AVPC,      0x200, 0x204,  1),
+	TEGRA124_MC_RESET(DC,        0x200, 0x204,  2),
+	TEGRA124_MC_RESET(DCB,       0x200, 0x204,  3),
+	TEGRA124_MC_RESET(HC,        0x200, 0x204,  6),
+	TEGRA124_MC_RESET(HDA,       0x200, 0x204,  7),
+	TEGRA124_MC_RESET(ISP2,      0x200, 0x204,  8),
+	TEGRA124_MC_RESET(MPCORE,    0x200, 0x204,  9),
+	TEGRA124_MC_RESET(MPCORELP,  0x200, 0x204, 10),
+	TEGRA124_MC_RESET(MSENC,     0x200, 0x204, 11),
+	TEGRA124_MC_RESET(PPCS,      0x200, 0x204, 14),
+	TEGRA124_MC_RESET(SATA,      0x200, 0x204, 15),
+	TEGRA124_MC_RESET(VDE,       0x200, 0x204, 16),
+	TEGRA124_MC_RESET(VI,        0x200, 0x204, 17),
+	TEGRA124_MC_RESET(VIC,       0x200, 0x204, 18),
+	TEGRA124_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
+	TEGRA124_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
+	TEGRA124_MC_RESET(TSEC,      0x200, 0x204, 21),
+	TEGRA124_MC_RESET(SDMMC1,    0x200, 0x204, 22),
+	TEGRA124_MC_RESET(SDMMC2,    0x200, 0x204, 23),
+	TEGRA124_MC_RESET(SDMMC3,    0x200, 0x204, 25),
+	TEGRA124_MC_RESET(SDMMC4,    0x970, 0x974,  0),
+	TEGRA124_MC_RESET(ISP2B,     0x970, 0x974,  1),
+	TEGRA124_MC_RESET(GPU,       0x970, 0x974,  2),
+};
+
 #ifdef CONFIG_ARCH_TEGRA_124_SOC
 static const struct tegra_smmu_soc tegra124_smmu_soc = {
 	.clients = tegra124_mc_clients,
@@ -1038,6 +1074,9 @@ const struct tegra_mc_soc tegra124_mc_soc = {
 	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
 		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
 		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+	.reset_ops = &terga_mc_reset_ops_common,
+	.resets = tegra124_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
 };
 #endif /* CONFIG_ARCH_TEGRA_124_SOC */
 
@@ -1065,5 +1104,8 @@ const struct tegra_mc_soc tegra132_mc_soc = {
 	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
 		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
 		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+	.reset_ops = &terga_mc_reset_ops_common,
+	.resets = tegra124_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
-- 
2.17.0

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

* [PATCH v4 13/15] memory: tegra: Add Tegra114 memory controller hot resets
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (11 preceding siblings ...)
  2018-04-13 11:33 ` [PATCH v4 12/15] memory: tegra: Add Tegra124 " Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-30  8:09   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 14/15] memory: tegra: Add Tegra30 " Dmitry Osipenko
  2018-04-13 11:33 ` [PATCH v4 15/15] memory: tegra: Add Tegra20 " Dmitry Osipenko
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Define the table of memory controller hot resets for Tegra114.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra114.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index 7560b2f558a7..12528aa3062b 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -938,6 +938,36 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = {
 	.num_asids = 4,
 };
 
+#define TEGRA114_MC_RESET(_name, _control, _status, _bit)	\
+	{							\
+		.name = #_name,					\
+		.id = TEGRA114_MC_RESET_##_name,		\
+		.control = _control,				\
+		.status = _status,				\
+		.bit = _bit,					\
+	}
+
+static const struct tegra_mc_reset tegra114_mc_resets[] = {
+	TEGRA114_MC_RESET(AFI,      0x200, 0x204,  0),
+	TEGRA114_MC_RESET(AVPC,     0x200, 0x204,  1),
+	TEGRA114_MC_RESET(DC,       0x200, 0x204,  2),
+	TEGRA114_MC_RESET(DCB,      0x200, 0x204,  3),
+	TEGRA114_MC_RESET(EPP,      0x200, 0x204,  4),
+	TEGRA114_MC_RESET(2D,       0x200, 0x204,  5),
+	TEGRA114_MC_RESET(HC,       0x200, 0x204,  6),
+	TEGRA114_MC_RESET(HDA,      0x200, 0x204,  7),
+	TEGRA114_MC_RESET(ISP,      0x200, 0x204,  8),
+	TEGRA114_MC_RESET(MPCORE,   0x200, 0x204,  9),
+	TEGRA114_MC_RESET(MPCORELP, 0x200, 0x204, 10),
+	TEGRA114_MC_RESET(MPE,      0x200, 0x204, 11),
+	TEGRA114_MC_RESET(3D,       0x200, 0x204, 12),
+	TEGRA114_MC_RESET(3D2,      0x200, 0x204, 13),
+	TEGRA114_MC_RESET(PPCS,     0x200, 0x204, 14),
+	TEGRA114_MC_RESET(SATA,     0x200, 0x204, 15),
+	TEGRA114_MC_RESET(VDE,      0x200, 0x204, 16),
+	TEGRA114_MC_RESET(VI,       0x200, 0x204, 17),
+};
+
 const struct tegra_mc_soc tegra114_mc_soc = {
 	.clients = tegra114_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra114_mc_clients),
@@ -947,4 +977,7 @@ const struct tegra_mc_soc tegra114_mc_soc = {
 	.smmu = &tegra114_smmu_soc,
 	.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
 		   MC_INT_DECERR_EMEM,
+	.reset_ops = &terga_mc_reset_ops_common,
+	.resets = tegra114_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra114_mc_resets),
 };
-- 
2.17.0

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

* [PATCH v4 14/15] memory: tegra: Add Tegra30 memory controller hot resets
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (12 preceding siblings ...)
  2018-04-13 11:33 ` [PATCH v4 13/15] memory: tegra: Add Tegra114 " Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-30  8:09   ` Thierry Reding
  2018-04-13 11:33 ` [PATCH v4 15/15] memory: tegra: Add Tegra20 " Dmitry Osipenko
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Define the table of memory controller hot resets for Tegra30.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra30.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index d2ba50ed0490..bee5314ed404 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -960,6 +960,36 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = {
 	.num_asids = 4,
 };
 
+#define TEGRA30_MC_RESET(_name, _control, _status, _bit)	\
+	{							\
+		.name = #_name,					\
+		.id = TEGRA30_MC_RESET_##_name,			\
+		.control = _control,				\
+		.status = _status,				\
+		.bit = _bit,					\
+	}
+
+static const struct tegra_mc_reset tegra30_mc_resets[] = {
+	TEGRA30_MC_RESET(AFI,      0x200, 0x204,  0),
+	TEGRA30_MC_RESET(AVPC,     0x200, 0x204,  1),
+	TEGRA30_MC_RESET(DC,       0x200, 0x204,  2),
+	TEGRA30_MC_RESET(DCB,      0x200, 0x204,  3),
+	TEGRA30_MC_RESET(EPP,      0x200, 0x204,  4),
+	TEGRA30_MC_RESET(2D,       0x200, 0x204,  5),
+	TEGRA30_MC_RESET(HC,       0x200, 0x204,  6),
+	TEGRA30_MC_RESET(HDA,      0x200, 0x204,  7),
+	TEGRA30_MC_RESET(ISP,      0x200, 0x204,  8),
+	TEGRA30_MC_RESET(MPCORE,   0x200, 0x204,  9),
+	TEGRA30_MC_RESET(MPCORELP, 0x200, 0x204, 10),
+	TEGRA30_MC_RESET(MPE,      0x200, 0x204, 11),
+	TEGRA30_MC_RESET(3D,       0x200, 0x204, 12),
+	TEGRA30_MC_RESET(3D2,      0x200, 0x204, 13),
+	TEGRA30_MC_RESET(PPCS,     0x200, 0x204, 14),
+	TEGRA30_MC_RESET(SATA,     0x200, 0x204, 15),
+	TEGRA30_MC_RESET(VDE,      0x200, 0x204, 16),
+	TEGRA30_MC_RESET(VI,       0x200, 0x204, 17),
+};
+
 const struct tegra_mc_soc tegra30_mc_soc = {
 	.clients = tegra30_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra30_mc_clients),
@@ -969,4 +999,7 @@ const struct tegra_mc_soc tegra30_mc_soc = {
 	.smmu = &tegra30_smmu_soc,
 	.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
 		   MC_INT_DECERR_EMEM,
+	.reset_ops = &terga_mc_reset_ops_common,
+	.resets = tegra30_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra30_mc_resets),
 };
-- 
2.17.0

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

* [PATCH v4 15/15] memory: tegra: Add Tegra20 memory controller hot resets
  2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
                   ` (13 preceding siblings ...)
  2018-04-13 11:33 ` [PATCH v4 14/15] memory: tegra: Add Tegra30 " Dmitry Osipenko
@ 2018-04-13 11:33 ` Dmitry Osipenko
  2018-04-30  8:09   ` Thierry Reding
  14 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-13 11:33 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter
  Cc: Rob Herring, devicetree, linux-tegra, linux-kernel

Define the table of memory controller hot resets for Tegra20 and add
specific to Tegra20 hot reset operations.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20.c | 118 +++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index 512a3418cb80..7119e532471c 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -6,6 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <dt-bindings/memory/tegra20-mc.h>
+
 #include "mc.h"
 
 static const struct tegra_mc_client tegra20_mc_clients[] = {
@@ -168,6 +170,119 @@ static const struct tegra_mc_client tegra20_mc_clients[] = {
 	},
 };
 
+#define TEGRA20_MC_RESET(_name, _control, _status, _reset, _bit)	\
+	{								\
+		.name = #_name,						\
+		.id = TEGRA20_MC_RESET_##_name,				\
+		.control = _control,					\
+		.status = _status,					\
+		.reset = _reset,					\
+		.bit = _bit,						\
+	}
+
+static const struct tegra_mc_reset tegra20_mc_resets[] = {
+	TEGRA20_MC_RESET(AVPC,   0x100, 0x140, 0x104,  0),
+	TEGRA20_MC_RESET(DC,     0x100, 0x144, 0x104,  1),
+	TEGRA20_MC_RESET(DCB,    0x100, 0x148, 0x104,  2),
+	TEGRA20_MC_RESET(EPP,    0x100, 0x14c, 0x104,  3),
+	TEGRA20_MC_RESET(2D,     0x100, 0x150, 0x104,  4),
+	TEGRA20_MC_RESET(HC,     0x100, 0x154, 0x104,  5),
+	TEGRA20_MC_RESET(ISP,    0x100, 0x158, 0x104,  6),
+	TEGRA20_MC_RESET(MPCORE, 0x100, 0x15c, 0x104,  7),
+	TEGRA20_MC_RESET(MPEA,   0x100, 0x160, 0x104,  8),
+	TEGRA20_MC_RESET(MPEB,   0x100, 0x164, 0x104,  9),
+	TEGRA20_MC_RESET(MPEC,   0x100, 0x168, 0x104, 10),
+	TEGRA20_MC_RESET(3D,     0x100, 0x16c, 0x104, 11),
+	TEGRA20_MC_RESET(PPCS,   0x100, 0x170, 0x104, 12),
+	TEGRA20_MC_RESET(VDE,    0x100, 0x174, 0x104, 13),
+	TEGRA20_MC_RESET(VI,     0x100, 0x178, 0x104, 14),
+};
+
+static int terga20_mc_hotreset_assert(struct tegra_mc *mc,
+				      const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->reset);
+	mc_writel(mc, value & ~BIT(rst->bit), rst->reset);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+static int terga20_mc_hotreset_deassert(struct tegra_mc *mc,
+					const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->reset);
+	mc_writel(mc, value | BIT(rst->bit), rst->reset);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+static int terga20_mc_block_dma(struct tegra_mc *mc,
+				const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
+	mc_writel(mc, value, rst->control);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+static bool terga20_mc_dma_idling(struct tegra_mc *mc,
+				  const struct tegra_mc_reset *rst)
+{
+	return mc_readl(mc, rst->status) == 0;
+}
+
+static int terga20_mc_reset_status(struct tegra_mc *mc,
+				   const struct tegra_mc_reset *rst)
+{
+	return (mc_readl(mc, rst->reset) & BIT(rst->bit)) == 0;
+}
+
+static int terga20_mc_unblock_dma(struct tegra_mc *mc,
+				  const struct tegra_mc_reset *rst)
+{
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&mc->lock, flags);
+
+	value = mc_readl(mc, rst->control) | BIT(rst->bit);
+	mc_writel(mc, value, rst->control);
+
+	spin_unlock_irqrestore(&mc->lock, flags);
+
+	return 0;
+}
+
+const struct tegra_mc_reset_ops terga20_mc_reset_ops = {
+	.hotreset_assert = terga20_mc_hotreset_assert,
+	.hotreset_deassert = terga20_mc_hotreset_deassert,
+	.block_dma = terga20_mc_block_dma,
+	.dma_idling = terga20_mc_dma_idling,
+	.unblock_dma = terga20_mc_unblock_dma,
+	.reset_status = terga20_mc_reset_status,
+};
+
 const struct tegra_mc_soc tegra20_mc_soc = {
 	.clients = tegra20_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra20_mc_clients),
@@ -175,4 +290,7 @@ const struct tegra_mc_soc tegra20_mc_soc = {
 	.client_id_mask = 0x3f,
 	.intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
 		   MC_INT_DECERR_EMEM,
+	.reset_ops = &terga20_mc_reset_ops,
+	.resets = tegra20_mc_resets,
+	.num_resets = ARRAY_SIZE(tegra20_mc_resets),
 };
-- 
2.17.0

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

* Re: [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-09 19:28 ` [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver Dmitry Osipenko
@ 2018-04-27  9:34   ` Thierry Reding
  2018-04-27 10:13     ` Dmitry Osipenko
  2018-04-30  8:07   ` Thierry Reding
  1 sibling, 1 reply; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:34 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1173 bytes --]

On Mon, Apr 09, 2018 at 10:28:31PM +0300, Dmitry Osipenko wrote:
[...]
> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
[...]
> +#define MC_GART_ERROR_REQ		0x30
> +#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
> +#define MC_SECURITY_VIOLATION_STATUS	0x74
[...]
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
[...]
> @@ -21,19 +21,30 @@
>  #define MC_INT_INVALID_SMMU_PAGE (1 << 10)
>  #define MC_INT_ARBITRATION_EMEM (1 << 9)
>  #define MC_INT_SECURITY_VIOLATION (1 << 8)
> +#define MC_INT_INVALID_GART_PAGE (1 << 7)
>  #define MC_INT_DECERR_EMEM (1 << 6)
>  
>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>  {
> +	if (mc->regs2 && offset >= 0x24)
> +		return readl(mc->regs2 + offset - 0x3c);

I'm still not sure how this is supposed to work. If we pass in
MC_GART_ERROR_REQ as offset into mc_readl(), then the condition above
will be true (0x30 >= 0x24) but then the new offset will be computed
and we end up with:

	return readl(mc->regs2 + 0x30 - 0x3c);

which means we'll be adding a negative offset (or rather a very large
offset because it will wrap around).

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding
  2018-04-09 19:28 ` [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding Dmitry Osipenko
@ 2018-04-27  9:35   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]

On Mon, Apr 09, 2018 at 10:28:23PM +0300, Dmitry Osipenko wrote:
> There are two bindings for the same Memory Controller. One of the bindings
> became obsolete long time ago and probably was left unnoticed, remove it
> for consistency.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
>  .../bindings/arm/tegra/nvidia,tegra30-mc.txt           | 18 ------------------
>  1 file changed, 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC
  2018-04-09 19:28 ` [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC Dmitry Osipenko
@ 2018-04-27  9:35   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

On Mon, Apr 09, 2018 at 10:28:24PM +0300, Dmitry Osipenko wrote:
> Memory Controller has a memory client "hot reset" functionality, which
> resets the DMA interface of a memory client. So MC is a reset controller
> in addition to IOMMU.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
>  .../devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt     | 5 +++++
>  1 file changed, 5 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC
  2018-04-09 19:28 ` [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC Dmitry Osipenko
@ 2018-04-27  9:35   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 493 bytes --]

On Mon, Apr 09, 2018 at 10:28:25PM +0300, Dmitry Osipenko wrote:
> Memory Controller has a memory client "hot reset" functionality, which
> resets the DMA interface of a memory client, so MC is a reset controller.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
>  .../devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt      | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions
  2018-04-09 19:28 ` [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions Dmitry Osipenko
@ 2018-04-27  9:36   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:36 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 745 bytes --]

On Mon, Apr 09, 2018 at 10:28:26PM +0300, Dmitry Osipenko wrote:
> Add definitions for the Tegra20+ memory controller hot resets.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
>  include/dt-bindings/memory/tegra114-mc.h | 19 +++++++++++++++++++
>  include/dt-bindings/memory/tegra124-mc.h | 25 +++++++++++++++++++++++++
>  include/dt-bindings/memory/tegra20-mc.h  | 21 +++++++++++++++++++++
>  include/dt-bindings/memory/tegra210-mc.h | 31 +++++++++++++++++++++++++++++++
>  include/dt-bindings/memory/tegra30-mc.h  | 19 +++++++++++++++++++
>  5 files changed, 115 insertions(+)
>  create mode 100644 include/dt-bindings/memory/tegra20-mc.h

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts
  2018-04-09 19:28 ` [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts Dmitry Osipenko
@ 2018-04-27  9:36   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:36 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 541 bytes --]

On Mon, Apr 09, 2018 at 10:28:27PM +0300, Dmitry Osipenko wrote:
> The ISR reads interrupts-enable mask, but doesn't utilize it. Apply the
> mask to the interrupt status and don't handle interrupts that MC driver
> haven't asked for. Kernel would disable spurious MC IRQ and report the
> error. This would happen only in a case of a very severe bug.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ
  2018-04-09 19:28 ` [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ Dmitry Osipenko
@ 2018-04-27  9:36   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:36 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 323 bytes --]

On Mon, Apr 09, 2018 at 10:28:28PM +0300, Dmitry Osipenko wrote:
> This avoids unwanted interrupt during MC driver probe.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC
  2018-04-09 19:28 ` [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC Dmitry Osipenko
@ 2018-04-27  9:36   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:36 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 917 bytes --]

On Mon, Apr 09, 2018 at 10:28:29PM +0300, Dmitry Osipenko wrote:
> Currently we are enabling handling of interrupts specific to Tegra124+
> which happen to overlap with previous generations. Let's specify
> interrupts mask per SoC generation for consistency and in a preparation
> of squashing of Tegra20 driver into the common one that will enable
> handling of GART faults which may be undesirable by newer generations.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c       | 21 +++------------------
>  drivers/memory/tegra/mc.h       |  9 +++++++++
>  drivers/memory/tegra/tegra114.c |  2 ++
>  drivers/memory/tegra/tegra124.c |  6 ++++++
>  drivers/memory/tegra/tegra210.c |  3 +++
>  drivers/memory/tegra/tegra30.c  |  2 ++
>  include/soc/tegra/mc.h          |  2 ++
>  7 files changed, 27 insertions(+), 18 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions
  2018-04-09 19:28 ` [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions Dmitry Osipenko
@ 2018-04-27  9:37   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:37 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

On Mon, Apr 09, 2018 at 10:28:30PM +0300, Dmitry Osipenko wrote:
> Tegra210 contains some unused leftover headers, remove them for
> consistency.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra210.c | 5 -----
>  1 file changed, 5 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets
  2018-04-13 11:33 ` [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets Dmitry Osipenko
@ 2018-04-27  9:39   ` Thierry Reding
  2018-04-28  8:18     ` Dmitry Osipenko
  0 siblings, 1 reply; 37+ messages in thread
From: Thierry Reding @ 2018-04-27  9:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2835 bytes --]

On Fri, Apr 13, 2018 at 02:33:50PM +0300, Dmitry Osipenko wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Define the table of memory controller hot resets for Tegra210.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/memory/tegra/tegra210.c | 45 +++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
> index b729f49ffc8f..d00a77160407 100644
> --- a/drivers/memory/tegra/tegra210.c
> +++ b/drivers/memory/tegra/tegra210.c
> @@ -1080,6 +1080,48 @@ static const struct tegra_smmu_soc tegra210_smmu_soc = {
>  	.num_asids = 128,
>  };
>  
> +#define TEGRA210_MC_RESET(_name, _control, _status, _bit)	\
> +	{							\
> +		.name = #_name,					\
> +		.id = TEGRA210_MC_RESET_##_name,		\
> +		.control = _control,				\
> +		.status = _status,				\
> +		.bit = _bit,					\
> +	}
> +
> +static const struct tegra_mc_reset tegra210_mc_resets[] = {
> +	TEGRA210_MC_RESET(AFI,       0x200, 0x204,  0),
> +	TEGRA210_MC_RESET(AVPC,      0x200, 0x204,  1),
> +	TEGRA210_MC_RESET(DC,        0x200, 0x204,  2),
> +	TEGRA210_MC_RESET(DCB,       0x200, 0x204,  3),
> +	TEGRA210_MC_RESET(HC,        0x200, 0x204,  6),
> +	TEGRA210_MC_RESET(HDA,       0x200, 0x204,  7),
> +	TEGRA210_MC_RESET(ISP2,      0x200, 0x204,  8),
> +	TEGRA210_MC_RESET(MPCORE,    0x200, 0x204,  9),
> +	TEGRA210_MC_RESET(NVENC,     0x200, 0x204, 11),
> +	TEGRA210_MC_RESET(PPCS,      0x200, 0x204, 14),
> +	TEGRA210_MC_RESET(SATA,      0x200, 0x204, 15),
> +	TEGRA210_MC_RESET(VI,        0x200, 0x204, 17),
> +	TEGRA210_MC_RESET(VIC,       0x200, 0x204, 18),
> +	TEGRA210_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
> +	TEGRA210_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
> +	TEGRA210_MC_RESET(A9AVP,     0x200, 0x204, 21),
> +	TEGRA210_MC_RESET(TSEC,      0x200, 0x204, 22),
> +	TEGRA210_MC_RESET(SDMMC1,    0x200, 0x204, 29),
> +	TEGRA210_MC_RESET(SDMMC2,    0x200, 0x204, 30),
> +	TEGRA210_MC_RESET(SDMMC3,    0x200, 0x204, 31),
> +	TEGRA210_MC_RESET(SDMMC4,    0x970, 0x974,  0),
> +	TEGRA210_MC_RESET(ISP2B,     0x970, 0x974,  1),
> +	TEGRA210_MC_RESET(GPU,       0x970, 0x974,  2),
> +	TEGRA210_MC_RESET(NVDEC,     0x970, 0x974,  5),
> +	TEGRA210_MC_RESET(APE,       0x970, 0x974,  6),
> +	TEGRA210_MC_RESET(SE,        0x970, 0x974,  7),
> +	TEGRA210_MC_RESET(NVJPG,     0x970, 0x974,  8),
> +	TEGRA210_MC_RESET(AXIAP,     0x970, 0x974, 11),
> +	TEGRA210_MC_RESET(ETR,       0x970, 0x974, 12),
> +	TEGRA210_MC_RESET(TSECB,     0x970, 0x974, 13),
> +};

Isn't this missing an include for the definitions? There is an include
for dt-bindings/memory/tegra20-mc.h for the Tegra20 driver, but none of
the others have it.

No need to respin, though, I can add that when applying.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-27  9:34   ` Thierry Reding
@ 2018-04-27 10:13     ` Dmitry Osipenko
  2018-04-27 10:24       ` Thierry Reding
  0 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-27 10:13 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

On 27.04.2018 12:34, Thierry Reding wrote:
> On Mon, Apr 09, 2018 at 10:28:31PM +0300, Dmitry Osipenko wrote:
> [...]
>> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> [...]
>> +#define MC_GART_ERROR_REQ		0x30
>> +#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
>> +#define MC_SECURITY_VIOLATION_STATUS	0x74
> [...]
>> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> [...]
>> @@ -21,19 +21,30 @@
>>  #define MC_INT_INVALID_SMMU_PAGE (1 << 10)
>>  #define MC_INT_ARBITRATION_EMEM (1 << 9)
>>  #define MC_INT_SECURITY_VIOLATION (1 << 8)
>> +#define MC_INT_INVALID_GART_PAGE (1 << 7)
>>  #define MC_INT_DECERR_EMEM (1 << 6)
>>  
>>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>>  {
>> +	if (mc->regs2 && offset >= 0x24)
>> +		return readl(mc->regs2 + offset - 0x3c);
> 
> I'm still not sure how this is supposed to work. If we pass in
> MC_GART_ERROR_REQ as offset into mc_readl(), then the condition above
> will be true (0x30 >= 0x24) but then the new offset will be computed
> and we end up with:
> 
> 	return readl(mc->regs2 + 0x30 - 0x3c);
> 
> which means we'll be adding a negative offset (or rather a very large
> offset because it will wrap around).

Indeed! Thank you for pointing at it again, now I see the issue. It probably
works because actual registers mapping is aligned to page(?) size and adding the
large offset with wraparound is equal to subtraction.

That register belongs to the GART and we can't simply move interrupt handling to
the GART driver because status register is within the MC in device tree. We can
omit reading of MC_GART_ERROR_REQ and simply report GART page fault for the
starter and then reorganize drivers by making MC driver MFD and GART its
sub-device, what do you think?

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

* Re: [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-27 10:13     ` Dmitry Osipenko
@ 2018-04-27 10:24       ` Thierry Reding
  2018-04-27 10:56         ` Dmitry Osipenko
  0 siblings, 1 reply; 37+ messages in thread
From: Thierry Reding @ 2018-04-27 10:24 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2423 bytes --]

On Fri, Apr 27, 2018 at 01:13:47PM +0300, Dmitry Osipenko wrote:
> On 27.04.2018 12:34, Thierry Reding wrote:
> > On Mon, Apr 09, 2018 at 10:28:31PM +0300, Dmitry Osipenko wrote:
> > [...]
> >> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> > [...]
> >> +#define MC_GART_ERROR_REQ		0x30
> >> +#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
> >> +#define MC_SECURITY_VIOLATION_STATUS	0x74
> > [...]
> >> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> > [...]
> >> @@ -21,19 +21,30 @@
> >>  #define MC_INT_INVALID_SMMU_PAGE (1 << 10)
> >>  #define MC_INT_ARBITRATION_EMEM (1 << 9)
> >>  #define MC_INT_SECURITY_VIOLATION (1 << 8)
> >> +#define MC_INT_INVALID_GART_PAGE (1 << 7)
> >>  #define MC_INT_DECERR_EMEM (1 << 6)
> >>  
> >>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
> >>  {
> >> +	if (mc->regs2 && offset >= 0x24)
> >> +		return readl(mc->regs2 + offset - 0x3c);
> > 
> > I'm still not sure how this is supposed to work. If we pass in
> > MC_GART_ERROR_REQ as offset into mc_readl(), then the condition above
> > will be true (0x30 >= 0x24) but then the new offset will be computed
> > and we end up with:
> > 
> > 	return readl(mc->regs2 + 0x30 - 0x3c);
> > 
> > which means we'll be adding a negative offset (or rather a very large
> > offset because it will wrap around).
> 
> Indeed! Thank you for pointing at it again, now I see the issue. It probably
> works because actual registers mapping is aligned to page(?) size and adding the
> large offset with wraparound is equal to subtraction.
> 
> That register belongs to the GART and we can't simply move interrupt handling to
> the GART driver because status register is within the MC in device tree. We can
> omit reading of MC_GART_ERROR_REQ and simply report GART page fault for the
> starter and then reorganize drivers by making MC driver MFD and GART its
> sub-device, what do you think?

Sounds like a good idea. Can you send a fix on top of this that I can
squash into this when applying?

As for integrating GART with MC, I'd prefer something that doesn't use
MFD but rather does something similar to what we have for the SMMU. I
think that's simpler to do and has less boilerplate. I think it's also
warranted because the MC and GART are very tightly coupled, so an MFD
would be slightly over-engineered, in my opinion.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-27 10:24       ` Thierry Reding
@ 2018-04-27 10:56         ` Dmitry Osipenko
  0 siblings, 0 replies; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-27 10:56 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

On 27.04.2018 13:24, Thierry Reding wrote:
> On Fri, Apr 27, 2018 at 01:13:47PM +0300, Dmitry Osipenko wrote:
>> On 27.04.2018 12:34, Thierry Reding wrote:
>>> On Mon, Apr 09, 2018 at 10:28:31PM +0300, Dmitry Osipenko wrote:
>>> [...]
>>>> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
>>> [...]
>>>> +#define MC_GART_ERROR_REQ		0x30
>>>> +#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
>>>> +#define MC_SECURITY_VIOLATION_STATUS	0x74
>>> [...]
>>>> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
>>> [...]
>>>> @@ -21,19 +21,30 @@
>>>>  #define MC_INT_INVALID_SMMU_PAGE (1 << 10)
>>>>  #define MC_INT_ARBITRATION_EMEM (1 << 9)
>>>>  #define MC_INT_SECURITY_VIOLATION (1 << 8)
>>>> +#define MC_INT_INVALID_GART_PAGE (1 << 7)
>>>>  #define MC_INT_DECERR_EMEM (1 << 6)
>>>>  
>>>>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>>>>  {
>>>> +	if (mc->regs2 && offset >= 0x24)
>>>> +		return readl(mc->regs2 + offset - 0x3c);
>>>
>>> I'm still not sure how this is supposed to work. If we pass in
>>> MC_GART_ERROR_REQ as offset into mc_readl(), then the condition above
>>> will be true (0x30 >= 0x24) but then the new offset will be computed
>>> and we end up with:
>>>
>>> 	return readl(mc->regs2 + 0x30 - 0x3c);
>>>
>>> which means we'll be adding a negative offset (or rather a very large
>>> offset because it will wrap around).
>>
>> Indeed! Thank you for pointing at it again, now I see the issue. It probably
>> works because actual registers mapping is aligned to page(?) size and adding the
>> large offset with wraparound is equal to subtraction.
>>
>> That register belongs to the GART and we can't simply move interrupt handling to
>> the GART driver because status register is within the MC in device tree. We can
>> omit reading of MC_GART_ERROR_REQ and simply report GART page fault for the
>> starter and then reorganize drivers by making MC driver MFD and GART its
>> sub-device, what do you think?
> 
> Sounds like a good idea. Can you send a fix on top of this that I can
> squash into this when applying?

Sure.

> As for integrating GART with MC, I'd prefer something that doesn't use
> MFD but rather does something similar to what we have for the SMMU. I
> think that's simpler to do and has less boilerplate. I think it's also
> warranted because the MC and GART are very tightly coupled, so an MFD
> would be slightly over-engineered, in my opinion.

Okay, I'll recap how SMMU is integrated with MC and then come up with something.

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

* Re: [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets
  2018-04-27  9:39   ` Thierry Reding
@ 2018-04-28  8:18     ` Dmitry Osipenko
  2018-04-30  8:08       ` Thierry Reding
  0 siblings, 1 reply; 37+ messages in thread
From: Dmitry Osipenko @ 2018-04-28  8:18 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

On 27.04.2018 12:39, Thierry Reding wrote:
> On Fri, Apr 13, 2018 at 02:33:50PM +0300, Dmitry Osipenko wrote:
>> From: Thierry Reding <treding@nvidia.com>
>>
>> Define the table of memory controller hot resets for Tegra210.
>>
>> Signed-off-by: Thierry Reding <treding@nvidia.com>
>> ---
>>  drivers/memory/tegra/tegra210.c | 45 +++++++++++++++++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>
>> diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
>> index b729f49ffc8f..d00a77160407 100644
>> --- a/drivers/memory/tegra/tegra210.c
>> +++ b/drivers/memory/tegra/tegra210.c
>> @@ -1080,6 +1080,48 @@ static const struct tegra_smmu_soc tegra210_smmu_soc = {
>>  	.num_asids = 128,
>>  };
>>  
>> +#define TEGRA210_MC_RESET(_name, _control, _status, _bit)	\
>> +	{							\
>> +		.name = #_name,					\
>> +		.id = TEGRA210_MC_RESET_##_name,		\
>> +		.control = _control,				\
>> +		.status = _status,				\
>> +		.bit = _bit,					\
>> +	}
>> +
>> +static const struct tegra_mc_reset tegra210_mc_resets[] = {
>> +	TEGRA210_MC_RESET(AFI,       0x200, 0x204,  0),
>> +	TEGRA210_MC_RESET(AVPC,      0x200, 0x204,  1),
>> +	TEGRA210_MC_RESET(DC,        0x200, 0x204,  2),
>> +	TEGRA210_MC_RESET(DCB,       0x200, 0x204,  3),
>> +	TEGRA210_MC_RESET(HC,        0x200, 0x204,  6),
>> +	TEGRA210_MC_RESET(HDA,       0x200, 0x204,  7),
>> +	TEGRA210_MC_RESET(ISP2,      0x200, 0x204,  8),
>> +	TEGRA210_MC_RESET(MPCORE,    0x200, 0x204,  9),
>> +	TEGRA210_MC_RESET(NVENC,     0x200, 0x204, 11),
>> +	TEGRA210_MC_RESET(PPCS,      0x200, 0x204, 14),
>> +	TEGRA210_MC_RESET(SATA,      0x200, 0x204, 15),
>> +	TEGRA210_MC_RESET(VI,        0x200, 0x204, 17),
>> +	TEGRA210_MC_RESET(VIC,       0x200, 0x204, 18),
>> +	TEGRA210_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
>> +	TEGRA210_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
>> +	TEGRA210_MC_RESET(A9AVP,     0x200, 0x204, 21),
>> +	TEGRA210_MC_RESET(TSEC,      0x200, 0x204, 22),
>> +	TEGRA210_MC_RESET(SDMMC1,    0x200, 0x204, 29),
>> +	TEGRA210_MC_RESET(SDMMC2,    0x200, 0x204, 30),
>> +	TEGRA210_MC_RESET(SDMMC3,    0x200, 0x204, 31),
>> +	TEGRA210_MC_RESET(SDMMC4,    0x970, 0x974,  0),
>> +	TEGRA210_MC_RESET(ISP2B,     0x970, 0x974,  1),
>> +	TEGRA210_MC_RESET(GPU,       0x970, 0x974,  2),
>> +	TEGRA210_MC_RESET(NVDEC,     0x970, 0x974,  5),
>> +	TEGRA210_MC_RESET(APE,       0x970, 0x974,  6),
>> +	TEGRA210_MC_RESET(SE,        0x970, 0x974,  7),
>> +	TEGRA210_MC_RESET(NVJPG,     0x970, 0x974,  8),
>> +	TEGRA210_MC_RESET(AXIAP,     0x970, 0x974, 11),
>> +	TEGRA210_MC_RESET(ETR,       0x970, 0x974, 12),
>> +	TEGRA210_MC_RESET(TSECB,     0x970, 0x974, 13),
>> +};
> 
> Isn't this missing an include for the definitions? There is an include
> for dt-bindings/memory/tegra20-mc.h for the Tegra20 driver, but none of
> the others have it.

Those drivers already have dt-bindings included.

> No need to respin, though, I can add that when applying.

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

* Re: [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver
  2018-04-09 19:28 ` [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver Dmitry Osipenko
  2018-04-27  9:34   ` Thierry Reding
@ 2018-04-30  8:07   ` Thierry Reding
  1 sibling, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:07 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1114 bytes --]

On Mon, Apr 09, 2018 at 10:28:31PM +0300, Dmitry Osipenko wrote:
> Tegra30+ has some minor differences in registers / bits layout compared
> to Tegra20. Let's squash Tegra20 driver into the common tegra-mc driver
> in a preparation for the upcoming MC hot reset controls implementation,
> avoiding code duplication.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/Kconfig         |  10 --
>  drivers/memory/Makefile        |   1 -
>  drivers/memory/tegra/Makefile  |   1 +
>  drivers/memory/tegra/mc.c      | 120 +++++++++++++++++--
>  drivers/memory/tegra/mc.h      |  11 ++
>  drivers/memory/tegra/tegra20.c | 178 +++++++++++++++++++++++++++++
>  drivers/memory/tegra20-mc.c    | 254 -----------------------------------------
>  include/soc/tegra/mc.h         |   2 +-
>  8 files changed, 299 insertions(+), 278 deletions(-)
>  create mode 100644 drivers/memory/tegra/tegra20.c
>  delete mode 100644 drivers/memory/tegra20-mc.c

I've applied this now and squashed in patch "memory: tegra: Remove
handling of MC_GART_ERROR_REQ on Tegra20".

Thanks,
Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset
  2018-04-13 11:33 ` [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset Dmitry Osipenko
@ 2018-04-30  8:08   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 617 bytes --]

On Fri, Apr 13, 2018 at 02:33:49PM +0300, Dmitry Osipenko wrote:
> In order to reset busy HW properly, memory controller needs to be
> involved, otherwise it is possible to get corrupted memory or hang machine
> if HW was reset during DMA. Introduce memory client 'hot reset' that will
> be used for resetting of busy HW.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c | 210 ++++++++++++++++++++++++++++++++++++++
>  drivers/memory/tegra/mc.h |   2 +
>  include/soc/tegra/mc.h    |  33 ++++++
>  3 files changed, 245 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets
  2018-04-28  8:18     ` Dmitry Osipenko
@ 2018-04-30  8:08       ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3174 bytes --]

On Sat, Apr 28, 2018 at 11:18:38AM +0300, Dmitry Osipenko wrote:
> On 27.04.2018 12:39, Thierry Reding wrote:
> > On Fri, Apr 13, 2018 at 02:33:50PM +0300, Dmitry Osipenko wrote:
> >> From: Thierry Reding <treding@nvidia.com>
> >>
> >> Define the table of memory controller hot resets for Tegra210.
> >>
> >> Signed-off-by: Thierry Reding <treding@nvidia.com>
> >> ---
> >>  drivers/memory/tegra/tegra210.c | 45 +++++++++++++++++++++++++++++++++
> >>  1 file changed, 45 insertions(+)
> >>
> >> diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
> >> index b729f49ffc8f..d00a77160407 100644
> >> --- a/drivers/memory/tegra/tegra210.c
> >> +++ b/drivers/memory/tegra/tegra210.c
> >> @@ -1080,6 +1080,48 @@ static const struct tegra_smmu_soc tegra210_smmu_soc = {
> >>  	.num_asids = 128,
> >>  };
> >>  
> >> +#define TEGRA210_MC_RESET(_name, _control, _status, _bit)	\
> >> +	{							\
> >> +		.name = #_name,					\
> >> +		.id = TEGRA210_MC_RESET_##_name,		\
> >> +		.control = _control,				\
> >> +		.status = _status,				\
> >> +		.bit = _bit,					\
> >> +	}
> >> +
> >> +static const struct tegra_mc_reset tegra210_mc_resets[] = {
> >> +	TEGRA210_MC_RESET(AFI,       0x200, 0x204,  0),
> >> +	TEGRA210_MC_RESET(AVPC,      0x200, 0x204,  1),
> >> +	TEGRA210_MC_RESET(DC,        0x200, 0x204,  2),
> >> +	TEGRA210_MC_RESET(DCB,       0x200, 0x204,  3),
> >> +	TEGRA210_MC_RESET(HC,        0x200, 0x204,  6),
> >> +	TEGRA210_MC_RESET(HDA,       0x200, 0x204,  7),
> >> +	TEGRA210_MC_RESET(ISP2,      0x200, 0x204,  8),
> >> +	TEGRA210_MC_RESET(MPCORE,    0x200, 0x204,  9),
> >> +	TEGRA210_MC_RESET(NVENC,     0x200, 0x204, 11),
> >> +	TEGRA210_MC_RESET(PPCS,      0x200, 0x204, 14),
> >> +	TEGRA210_MC_RESET(SATA,      0x200, 0x204, 15),
> >> +	TEGRA210_MC_RESET(VI,        0x200, 0x204, 17),
> >> +	TEGRA210_MC_RESET(VIC,       0x200, 0x204, 18),
> >> +	TEGRA210_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
> >> +	TEGRA210_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
> >> +	TEGRA210_MC_RESET(A9AVP,     0x200, 0x204, 21),
> >> +	TEGRA210_MC_RESET(TSEC,      0x200, 0x204, 22),
> >> +	TEGRA210_MC_RESET(SDMMC1,    0x200, 0x204, 29),
> >> +	TEGRA210_MC_RESET(SDMMC2,    0x200, 0x204, 30),
> >> +	TEGRA210_MC_RESET(SDMMC3,    0x200, 0x204, 31),
> >> +	TEGRA210_MC_RESET(SDMMC4,    0x970, 0x974,  0),
> >> +	TEGRA210_MC_RESET(ISP2B,     0x970, 0x974,  1),
> >> +	TEGRA210_MC_RESET(GPU,       0x970, 0x974,  2),
> >> +	TEGRA210_MC_RESET(NVDEC,     0x970, 0x974,  5),
> >> +	TEGRA210_MC_RESET(APE,       0x970, 0x974,  6),
> >> +	TEGRA210_MC_RESET(SE,        0x970, 0x974,  7),
> >> +	TEGRA210_MC_RESET(NVJPG,     0x970, 0x974,  8),
> >> +	TEGRA210_MC_RESET(AXIAP,     0x970, 0x974, 11),
> >> +	TEGRA210_MC_RESET(ETR,       0x970, 0x974, 12),
> >> +	TEGRA210_MC_RESET(TSECB,     0x970, 0x974, 13),
> >> +};
> > 
> > Isn't this missing an include for the definitions? There is an include
> > for dt-bindings/memory/tegra20-mc.h for the Tegra20 driver, but none of
> > the others have it.
> 
> Those drivers already have dt-bindings included.

You're right. Patch applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 12/15] memory: tegra: Add Tegra124 memory controller hot resets
  2018-04-13 11:33 ` [PATCH v4 12/15] memory: tegra: Add Tegra124 " Dmitry Osipenko
@ 2018-04-30  8:08   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 339 bytes --]

On Fri, Apr 13, 2018 at 02:33:51PM +0300, Dmitry Osipenko wrote:
> Define the table of memory controller hot resets for Tegra124.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra124.c | 42 +++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 13/15] memory: tegra: Add Tegra114 memory controller hot resets
  2018-04-13 11:33 ` [PATCH v4 13/15] memory: tegra: Add Tegra114 " Dmitry Osipenko
@ 2018-04-30  8:09   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 339 bytes --]

On Fri, Apr 13, 2018 at 02:33:52PM +0300, Dmitry Osipenko wrote:
> Define the table of memory controller hot resets for Tegra114.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra114.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 14/15] memory: tegra: Add Tegra30 memory controller hot resets
  2018-04-13 11:33 ` [PATCH v4 14/15] memory: tegra: Add Tegra30 " Dmitry Osipenko
@ 2018-04-30  8:09   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

On Fri, Apr 13, 2018 at 02:33:53PM +0300, Dmitry Osipenko wrote:
> Define the table of memory controller hot resets for Tegra30.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra30.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 15/15] memory: tegra: Add Tegra20 memory controller hot resets
  2018-04-13 11:33 ` [PATCH v4 15/15] memory: tegra: Add Tegra20 " Dmitry Osipenko
@ 2018-04-30  8:09   ` Thierry Reding
  0 siblings, 0 replies; 37+ messages in thread
From: Thierry Reding @ 2018-04-30  8:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Rob Herring, devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 391 bytes --]

On Fri, Apr 13, 2018 at 02:33:54PM +0300, Dmitry Osipenko wrote:
> Define the table of memory controller hot resets for Tegra20 and add
> specific to Tegra20 hot reset operations.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra20.c | 118 +++++++++++++++++++++++++++++++++
>  1 file changed, 118 insertions(+)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

end of thread, other threads:[~2018-04-30  8:09 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-09 19:28 [PATCH v4 00/15] Memory controller hot reset Dmitry Osipenko
2018-04-09 19:28 ` [PATCH v4 01/15] dt-bindings: arm: tegra: Remove duplicated Tegra30+ MC binding Dmitry Osipenko
2018-04-27  9:35   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 02/15] dt-bindings: memory: tegra: Document #reset-cells property of the Tegra30 MC Dmitry Osipenko
2018-04-27  9:35   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 03/15] dt-bindings: arm: tegra: Document #reset-cells property of the Tegra20 MC Dmitry Osipenko
2018-04-27  9:35   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 04/15] dt-bindings: memory: tegra: Add hot resets definitions Dmitry Osipenko
2018-04-27  9:36   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 05/15] memory: tegra: Do not handle spurious interrupts Dmitry Osipenko
2018-04-27  9:36   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 06/15] memory: tegra: Setup interrupts mask before requesting IRQ Dmitry Osipenko
2018-04-27  9:36   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 07/15] memory: tegra: Apply interrupts mask per SoC Dmitry Osipenko
2018-04-27  9:36   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 08/15] memory: tegra: Remove unused headers inclusions Dmitry Osipenko
2018-04-27  9:37   ` Thierry Reding
2018-04-09 19:28 ` [PATCH v4 09/15] memory: tegra: Squash tegra20-mc into common tegra-mc driver Dmitry Osipenko
2018-04-27  9:34   ` Thierry Reding
2018-04-27 10:13     ` Dmitry Osipenko
2018-04-27 10:24       ` Thierry Reding
2018-04-27 10:56         ` Dmitry Osipenko
2018-04-30  8:07   ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 10/15] memory: tegra: Introduce memory client hot reset Dmitry Osipenko
2018-04-30  8:08   ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 11/15] memory: tegra: Add Tegra210 memory controller hot resets Dmitry Osipenko
2018-04-27  9:39   ` Thierry Reding
2018-04-28  8:18     ` Dmitry Osipenko
2018-04-30  8:08       ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 12/15] memory: tegra: Add Tegra124 " Dmitry Osipenko
2018-04-30  8:08   ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 13/15] memory: tegra: Add Tegra114 " Dmitry Osipenko
2018-04-30  8:09   ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 14/15] memory: tegra: Add Tegra30 " Dmitry Osipenko
2018-04-30  8:09   ` Thierry Reding
2018-04-13 11:33 ` [PATCH v4 15/15] memory: tegra: Add Tegra20 " Dmitry Osipenko
2018-04-30  8:09   ` Thierry Reding

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.