devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support
@ 2019-12-22 14:10 Thierry Reding
  2019-12-22 14:10 ` [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs Thierry Reding
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Hi,

this set of patches improves the Tegra186 memory controller support and
extends it with Tegra194 support. The first three patches add the needed
device tree bindings and headers. Patches 4-10 first refactor the driver
to make it easier to support multiple SoC generations and finally add
EMC frequency scaling support (via debugfs) as well as Tegra194 support.
The last three patches enable the memory and external memory controllers
in device tree.

Thierry

Thierry Reding (13):
  dt-bindings: memory: Add Tegra186 memory client IDs
  dt-bindings: memory: Add Tegra194 memory controller header
  dt-bindings: memory: Add Tegra186 memory subsystem
  memory: tegra: Rename tegra_mc to tegra186_mc on Tegra186
  memory: tegra: Add per-SoC data for Tegra186
  memory: tegra: Extract memory client SID programming
  memory: tegra: Add system sleep support
  memory: tegra: Support DVFS on Tegra186 and later
  memory: tegra: Only include support for enabled SoCs
  memory: tegra: Add support for the Tegra194 memory controller
  arm64: tegra: Add interrupt for memory controller on Tegra186
  arm64: tegra: Add external memory controller on Tegra186
  arm64: tegra: Add the memory subsystem on Tegra194

 .../nvidia,tegra186-mc.yaml                   |  130 ++
 arch/arm64/boot/dts/nvidia/tegra186.dtsi      |   22 +
 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi |    4 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      |   43 +
 drivers/memory/tegra/Makefile                 |    3 +-
 drivers/memory/tegra/tegra186-emc.c           |  293 +++++
 drivers/memory/tegra/tegra186.c               | 1122 ++++++++++++++++-
 include/dt-bindings/memory/tegra186-mc.h      |  139 ++
 include/dt-bindings/memory/tegra194-mc.h      |  410 ++++++
 9 files changed, 2110 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
 create mode 100644 drivers/memory/tegra/tegra186-emc.c
 create mode 100644 include/dt-bindings/memory/tegra194-mc.h

-- 
2.24.1


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

* [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2020-01-08 16:14   ` Rob Herring
  2019-12-22 14:10 ` [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header Thierry Reding
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Add IDs for the memory clients found on NVIDIA Tegra186 SoCs. This will
be used to describe interconnect paths from devices to system memory.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 include/dt-bindings/memory/tegra186-mc.h | 139 +++++++++++++++++++++++
 1 file changed, 139 insertions(+)

diff --git a/include/dt-bindings/memory/tegra186-mc.h b/include/dt-bindings/memory/tegra186-mc.h
index 64813536aec9..82a1e27f7357 100644
--- a/include/dt-bindings/memory/tegra186-mc.h
+++ b/include/dt-bindings/memory/tegra186-mc.h
@@ -108,4 +108,143 @@
 #define TEGRA186_SID_SE_VM6		0x4e
 #define TEGRA186_SID_SE_VM7		0x4f
 
+/*
+ * memory client IDs
+ */
+
+/* Misses from System Memory Management Unit (SMMU) Page Table Cache (PTC) */
+#define TEGRA186_MEMORY_CLIENT_PTCR 0x00
+/* PCIE reads */
+#define TEGRA186_MEMORY_CLIENT_AFIR 0x0e
+/* High-definition audio (HDA) reads */
+#define TEGRA186_MEMORY_CLIENT_HDAR 0x15
+/* Host channel data reads */
+#define TEGRA186_MEMORY_CLIENT_HOST1XDMAR 0x16
+#define TEGRA186_MEMORY_CLIENT_NVENCSRD 0x1c
+/* SATA reads */
+#define TEGRA186_MEMORY_CLIENT_SATAR 0x1f
+/* Reads from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA186_MEMORY_CLIENT_MPCORER 0x27
+#define TEGRA186_MEMORY_CLIENT_NVENCSWR 0x2b
+/* PCIE writes */
+#define TEGRA186_MEMORY_CLIENT_AFIW 0x31
+/* High-definition audio (HDA) writes */
+#define TEGRA186_MEMORY_CLIENT_HDAW 0x35
+/* Writes from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA186_MEMORY_CLIENT_MPCOREW 0x39
+/* SATA writes */
+#define TEGRA186_MEMORY_CLIENT_SATAW 0x3d
+/* ISP Read client for Crossbar A */
+#define TEGRA186_MEMORY_CLIENT_ISPRA 0x44
+/* ISP Write client for Crossbar A */
+#define TEGRA186_MEMORY_CLIENT_ISPWA 0x46
+/* ISP Write client Crossbar B */
+#define TEGRA186_MEMORY_CLIENT_ISPWB 0x47
+/* XUSB reads */
+#define TEGRA186_MEMORY_CLIENT_XUSB_HOSTR 0x4a
+/* XUSB_HOST writes */
+#define TEGRA186_MEMORY_CLIENT_XUSB_HOSTW 0x4b
+/* XUSB reads */
+#define TEGRA186_MEMORY_CLIENT_XUSB_DEVR 0x4c
+/* XUSB_DEV writes */
+#define TEGRA186_MEMORY_CLIENT_XUSB_DEVW 0x4d
+/* TSEC Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSRD 0x54
+/* TSEC Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSWR 0x55
+/* 3D, ltcx reads instance 0 */
+#define TEGRA186_MEMORY_CLIENT_GPUSRD 0x58
+/* 3D, ltcx writes instance 0 */
+#define TEGRA186_MEMORY_CLIENT_GPUSWR 0x59
+/* sdmmca memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRA 0x60
+/* sdmmcbmemory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRAA 0x61
+/* sdmmc memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCR 0x62
+/* sdmmcd memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRAB 0x63
+/* sdmmca memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWA 0x64
+/* sdmmcb memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWAA 0x65
+/* sdmmc memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCW 0x66
+/* sdmmcd memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWAB 0x67
+#define TEGRA186_MEMORY_CLIENT_VICSRD 0x6c
+#define TEGRA186_MEMORY_CLIENT_VICSWR 0x6d
+/* VI Write client */
+#define TEGRA186_MEMORY_CLIENT_VIW 0x72
+#define TEGRA186_MEMORY_CLIENT_NVDECSRD 0x78
+#define TEGRA186_MEMORY_CLIENT_NVDECSWR 0x79
+/* Audio Processing (APE) engine reads */
+#define TEGRA186_MEMORY_CLIENT_APER 0x7a
+/* Audio Processing (APE) engine writes */
+#define TEGRA186_MEMORY_CLIENT_APEW 0x7b
+#define TEGRA186_MEMORY_CLIENT_NVJPGSRD 0x7e
+#define TEGRA186_MEMORY_CLIENT_NVJPGSWR 0x7f
+/* SE Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_SESRD 0x80
+/* SE Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_SESWR 0x81
+/* ETR reads */
+#define TEGRA186_MEMORY_CLIENT_ETRR 0x84
+/* ETR writes */
+#define TEGRA186_MEMORY_CLIENT_ETRW 0x85
+/* TSECB Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSRDB 0x86
+/* TSECB Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSWRB 0x87
+/* 3D, ltcx reads instance 1 */
+#define TEGRA186_MEMORY_CLIENT_GPUSRD2 0x88
+/* 3D, ltcx writes instance 1 */
+#define TEGRA186_MEMORY_CLIENT_GPUSWR2 0x89
+/* AXI Switch read client */
+#define TEGRA186_MEMORY_CLIENT_AXISR 0x8c
+/* AXI Switch write client */
+#define TEGRA186_MEMORY_CLIENT_AXISW 0x8d
+/* EQOS read client */
+#define TEGRA186_MEMORY_CLIENT_EQOSR 0x8e
+/* EQOS write client */
+#define TEGRA186_MEMORY_CLIENT_EQOSW 0x8f
+/* UFSHC read client */
+#define TEGRA186_MEMORY_CLIENT_UFSHCR 0x90
+/* UFSHC write client */
+#define TEGRA186_MEMORY_CLIENT_UFSHCW 0x91
+/* NVDISPLAY read client */
+#define TEGRA186_MEMORY_CLIENT_NVDISPLAYR 0x92
+/* BPMP read client */
+#define TEGRA186_MEMORY_CLIENT_BPMPR 0x93
+/* BPMP write client */
+#define TEGRA186_MEMORY_CLIENT_BPMPW 0x94
+/* BPMPDMA read client */
+#define TEGRA186_MEMORY_CLIENT_BPMPDMAR 0x95
+/* BPMPDMA write client */
+#define TEGRA186_MEMORY_CLIENT_BPMPDMAW 0x96
+/* AON read client */
+#define TEGRA186_MEMORY_CLIENT_AONR 0x97
+/* AON write client */
+#define TEGRA186_MEMORY_CLIENT_AONW 0x98
+/* AONDMA read client */
+#define TEGRA186_MEMORY_CLIENT_AONDMAR 0x99
+/* AONDMA write client */
+#define TEGRA186_MEMORY_CLIENT_AONDMAW 0x9a
+/* SCE read client */
+#define TEGRA186_MEMORY_CLIENT_SCER 0x9b
+/* SCE write client */
+#define TEGRA186_MEMORY_CLIENT_SCEW 0x9c
+/* SCEDMA read client */
+#define TEGRA186_MEMORY_CLIENT_SCEDMAR 0x9d
+/* SCEDMA write client */
+#define TEGRA186_MEMORY_CLIENT_SCEDMAW 0x9e
+/* APEDMA read client */
+#define TEGRA186_MEMORY_CLIENT_APEDMAR 0x9f
+/* APEDMA write client */
+#define TEGRA186_MEMORY_CLIENT_APEDMAW 0xa0
+/* NVDISPLAY read client instance 2 */
+#define TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 0xa1
+#define TEGRA186_MEMORY_CLIENT_VICSRD1 0xa2
+#define TEGRA186_MEMORY_CLIENT_NVDECSRD1 0xa3
+
 #endif
-- 
2.24.1


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

* [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
  2019-12-22 14:10 ` [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2020-01-08 16:15   ` Rob Herring
  2019-12-22 14:10 ` [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem Thierry Reding
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

This header contains definitions for the memory controller found on
NVIDIA Tegra194 SoCs, such as the stream IDs used for the ARM SMMU and
the IDs used to identify the various memory clients.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 include/dt-bindings/memory/tegra194-mc.h | 410 +++++++++++++++++++++++
 1 file changed, 410 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra194-mc.h

diff --git a/include/dt-bindings/memory/tegra194-mc.h b/include/dt-bindings/memory/tegra194-mc.h
new file mode 100644
index 000000000000..eed48b746bc9
--- /dev/null
+++ b/include/dt-bindings/memory/tegra194-mc.h
@@ -0,0 +1,410 @@
+#ifndef DT_BINDINGS_MEMORY_TEGRA194_MC_H
+#define DT_BINDINGS_MEMORY_TEGRA194_MC_H
+
+/* special clients */
+#define TEGRA194_SID_INVALID		0x00
+#define TEGRA194_SID_PASSTHROUGH	0x7f
+
+/* host1x clients */
+#define TEGRA194_SID_HOST1X		0x01
+#define TEGRA194_SID_CSI		0x02
+#define TEGRA194_SID_VIC		0x03
+#define TEGRA194_SID_VI			0x04
+#define TEGRA194_SID_ISP		0x05
+#define TEGRA194_SID_NVDEC		0x06
+#define TEGRA194_SID_NVENC		0x07
+#define TEGRA194_SID_NVJPG		0x08
+#define TEGRA194_SID_NVDISPLAY		0x09
+#define TEGRA194_SID_TSEC		0x0a
+#define TEGRA194_SID_TSECB		0x0b
+#define TEGRA194_SID_SE			0x0c
+#define TEGRA194_SID_SE1		0x0d
+#define TEGRA194_SID_SE2		0x0e
+#define TEGRA194_SID_SE3		0x0f
+
+/* GPU clients */
+#define TEGRA194_SID_GPU		0x10
+
+/* other SoC clients */
+#define TEGRA194_SID_AFI		0x11
+#define TEGRA194_SID_HDA		0x12
+#define TEGRA194_SID_ETR		0x13
+#define TEGRA194_SID_EQOS		0x14
+#define TEGRA194_SID_UFSHC		0x15
+#define TEGRA194_SID_AON		0x16
+#define TEGRA194_SID_SDMMC4		0x17
+#define TEGRA194_SID_SDMMC3		0x18
+#define TEGRA194_SID_SDMMC2		0x19
+#define TEGRA194_SID_SDMMC1		0x1a
+#define TEGRA194_SID_XUSB_HOST		0x1b
+#define TEGRA194_SID_XUSB_DEV		0x1c
+#define TEGRA194_SID_SATA		0x1d
+#define TEGRA194_SID_APE		0x1e
+#define TEGRA194_SID_SCE		0x1f
+
+/* GPC DMA clients */
+#define TEGRA194_SID_GPCDMA_0		0x20
+#define TEGRA194_SID_GPCDMA_1		0x21
+#define TEGRA194_SID_GPCDMA_2		0x22
+#define TEGRA194_SID_GPCDMA_3		0x23
+#define TEGRA194_SID_GPCDMA_4		0x24
+#define TEGRA194_SID_GPCDMA_5		0x25
+#define TEGRA194_SID_GPCDMA_6		0x26
+#define TEGRA194_SID_GPCDMA_7		0x27
+
+/* APE DMA clients */
+#define TEGRA194_SID_APE_1		0x28
+#define TEGRA194_SID_APE_2		0x29
+
+/* camera RTCPU */
+#define TEGRA194_SID_RCE		0x2a
+
+/* camera RTCPU on host1x address space */
+#define TEGRA194_SID_RCE_1X		0x2b
+
+/* APE DMA clients */
+#define TEGRA194_SID_APE_3		0x2c
+
+/* camera RTCPU running on APE */
+#define TEGRA194_SID_APE_CAM		0x2d
+#define TEGRA194_SID_APE_CAM_1X		0x2e
+
+#define TEGRA194_SID_RCE_RM		0x2f
+#define TEGRA194_SID_VI_FALCON		0x30
+#define TEGRA194_SID_ISP_FALCON		0x31
+
+/*
+ * The BPMP has its SID value hardcoded in the firmware. Changing it requires
+ * considerable effort.
+ */
+#define TEGRA194_SID_BPMP		0x32
+
+/* for SMMU tests */
+#define TEGRA194_SID_SMMU_TEST		0x33
+
+/* host1x virtualization channels */
+#define TEGRA194_SID_HOST1X_CTX0	0x38
+#define TEGRA194_SID_HOST1X_CTX1	0x39
+#define TEGRA194_SID_HOST1X_CTX2	0x3a
+#define TEGRA194_SID_HOST1X_CTX3	0x3b
+#define TEGRA194_SID_HOST1X_CTX4	0x3c
+#define TEGRA194_SID_HOST1X_CTX5	0x3d
+#define TEGRA194_SID_HOST1X_CTX6	0x3e
+#define TEGRA194_SID_HOST1X_CTX7	0x3f
+
+/* host1x command buffers */
+#define TEGRA194_SID_HOST1X_VM0		0x40
+#define TEGRA194_SID_HOST1X_VM1		0x41
+#define TEGRA194_SID_HOST1X_VM2		0x42
+#define TEGRA194_SID_HOST1X_VM3		0x43
+#define TEGRA194_SID_HOST1X_VM4		0x44
+#define TEGRA194_SID_HOST1X_VM5		0x45
+#define TEGRA194_SID_HOST1X_VM6		0x46
+#define TEGRA194_SID_HOST1X_VM7		0x47
+
+/* SE data buffers */
+#define TEGRA194_SID_SE_VM0		0x48
+#define TEGRA194_SID_SE_VM1		0x49
+#define TEGRA194_SID_SE_VM2		0x4a
+#define TEGRA194_SID_SE_VM3		0x4b
+#define TEGRA194_SID_SE_VM4		0x4c
+#define TEGRA194_SID_SE_VM5		0x4d
+#define TEGRA194_SID_SE_VM6		0x4e
+#define TEGRA194_SID_SE_VM7		0x4f
+
+#define TEGRA194_SID_MIU		0x50
+
+#define TEGRA194_SID_NVDLA0		0x51
+#define TEGRA194_SID_NVDLA1		0x52
+
+#define TEGRA194_SID_PVA0		0x53
+#define TEGRA194_SID_PVA1		0x54
+#define TEGRA194_SID_NVENC1		0x55
+#define TEGRA194_SID_PCIE0		0x56
+#define TEGRA194_SID_PCIE1		0x57
+#define TEGRA194_SID_PCIE2		0x58
+#define TEGRA194_SID_PCIE3		0x59
+#define TEGRA194_SID_PCIE4		0x5a
+#define TEGRA194_SID_PCIE5		0x5b
+#define TEGRA194_SID_NVDEC1		0x5c
+
+#define TEGRA194_SID_XUSB_VF0		0x5d
+#define TEGRA194_SID_XUSB_VF1		0x5e
+#define TEGRA194_SID_XUSB_VF2		0x5f
+#define TEGRA194_SID_XUSB_VF3		0x60
+
+#define TEGRA194_SID_RCE_VM3		0x61
+#define TEGRA194_SID_VI_VM2		0x62
+#define TEGRA194_SID_VI_VM3		0x63
+#define TEGRA194_SID_RCE_SERVER		0x64
+
+/*
+ * memory client IDs
+ */
+
+/* Misses from System Memory Management Unit (SMMU) Page Table Cache (PTC) */
+#define TEGRA194_MEMORY_CLIENT_PTCR 0x00
+/* MSS internal memqual MIU7 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU7R 0x01
+/* MSS internal memqual MIU7 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU7W 0x02
+/* High-definition audio (HDA) read clients */
+#define TEGRA194_MEMORY_CLIENT_HDAR 0x15
+/* Host channel data read clients */
+#define TEGRA194_MEMORY_CLIENT_HOST1XDMAR 0x16
+#define TEGRA194_MEMORY_CLIENT_NVENCSRD 0x1c
+/* SATA read clients */
+#define TEGRA194_MEMORY_CLIENT_SATAR 0x1f
+/* Reads from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA194_MEMORY_CLIENT_MPCORER 0x27
+#define TEGRA194_MEMORY_CLIENT_NVENCSWR 0x2b
+/* High-definition audio (HDA) write clients */
+#define TEGRA194_MEMORY_CLIENT_HDAW 0x35
+/* Writes from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA194_MEMORY_CLIENT_MPCOREW 0x39
+/* SATA write clients */
+#define TEGRA194_MEMORY_CLIENT_SATAW 0x3d
+/* ISP read client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPRA 0x44
+/* ISP read client 1 for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPFALR 0x45
+/* ISP Write client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPWA 0x46
+/* ISP Write client Crossbar B */
+#define TEGRA194_MEMORY_CLIENT_ISPWB 0x47
+/* XUSB_HOST read clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_HOSTR 0x4a
+/* XUSB_HOST write clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_HOSTW 0x4b
+/* XUSB read clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_DEVR 0x4c
+/* XUSB_DEV write clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_DEVW 0x4d
+/* sdmmca memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCRA 0x60
+/* sdmmc memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCR 0x62
+/* sdmmcd memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCRAB 0x63
+/* sdmmca memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCWA 0x64
+/* sdmmc memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCW 0x66
+/* sdmmcd memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCWAB 0x67
+#define TEGRA194_MEMORY_CLIENT_VICSRD 0x6c
+#define TEGRA194_MEMORY_CLIENT_VICSWR 0x6d
+/* VI Write client */
+#define TEGRA194_MEMORY_CLIENT_VIW 0x72
+#define TEGRA194_MEMORY_CLIENT_NVDECSRD 0x78
+#define TEGRA194_MEMORY_CLIENT_NVDECSWR 0x79
+/* Audio Processing (APE) engine read clients */
+#define TEGRA194_MEMORY_CLIENT_APER 0x7a
+/* Audio Processing (APE) engine write clients */
+#define TEGRA194_MEMORY_CLIENT_APEW 0x7b
+#define TEGRA194_MEMORY_CLIENT_NVJPGSRD 0x7e
+#define TEGRA194_MEMORY_CLIENT_NVJPGSWR 0x7f
+/* AXI AP and DFD-AUX0/1 read clients Both share the same interface on the on MSS */
+#define TEGRA194_MEMORY_CLIENT_AXIAPR 0x82
+/* AXI AP and DFD-AUX0/1 write clients Both sahre the same interface on MSS */
+#define TEGRA194_MEMORY_CLIENT_AXIAPW 0x83
+/* ETR read clients */
+#define TEGRA194_MEMORY_CLIENT_ETRR 0x84
+/* ETR write clients */
+#define TEGRA194_MEMORY_CLIENT_ETRW 0x85
+/* AXI Switch read client */
+#define TEGRA194_MEMORY_CLIENT_AXISR 0x8c
+/* AXI Switch write client */
+#define TEGRA194_MEMORY_CLIENT_AXISW 0x8d
+/* EQOS read client */
+#define TEGRA194_MEMORY_CLIENT_EQOSR 0x8e
+/* EQOS write client */
+#define TEGRA194_MEMORY_CLIENT_EQOSW 0x8f
+/* UFSHC read client */
+#define TEGRA194_MEMORY_CLIENT_UFSHCR 0x90
+/* UFSHC write client */
+#define TEGRA194_MEMORY_CLIENT_UFSHCW 0x91
+/* NVDISPLAY read client */
+#define TEGRA194_MEMORY_CLIENT_NVDISPLAYR 0x92
+/* BPMP read client */
+#define TEGRA194_MEMORY_CLIENT_BPMPR 0x93
+/* BPMP write client */
+#define TEGRA194_MEMORY_CLIENT_BPMPW 0x94
+/* BPMPDMA read client */
+#define TEGRA194_MEMORY_CLIENT_BPMPDMAR 0x95
+/* BPMPDMA write client */
+#define TEGRA194_MEMORY_CLIENT_BPMPDMAW 0x96
+/* AON read client */
+#define TEGRA194_MEMORY_CLIENT_AONR 0x97
+/* AON write client */
+#define TEGRA194_MEMORY_CLIENT_AONW 0x98
+/* AONDMA read client */
+#define TEGRA194_MEMORY_CLIENT_AONDMAR 0x99
+/* AONDMA write client */
+#define TEGRA194_MEMORY_CLIENT_AONDMAW 0x9a
+/* SCE read client */
+#define TEGRA194_MEMORY_CLIENT_SCER 0x9b
+/* SCE write client */
+#define TEGRA194_MEMORY_CLIENT_SCEW 0x9c
+/* SCEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_SCEDMAR 0x9d
+/* SCEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_SCEDMAW 0x9e
+/* APEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_APEDMAR 0x9f
+/* APEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_APEDMAW 0xa0
+/* NVDISPLAY read client instance 2 */
+#define TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 0xa1
+#define TEGRA194_MEMORY_CLIENT_VICSRD1 0xa2
+#define TEGRA194_MEMORY_CLIENT_NVDECSRD1 0xa3
+/* MSS internal memqual MIU0 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU0R 0xa6
+/* MSS internal memqual MIU0 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU0W 0xa7
+/* MSS internal memqual MIU1 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU1R 0xa8
+/* MSS internal memqual MIU1 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU1W 0xa9
+/* MSS internal memqual MIU2 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU2R 0xae
+/* MSS internal memqual MIU2 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU2W 0xaf
+/* MSS internal memqual MIU3 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU3R 0xb0
+/* MSS internal memqual MIU3 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU3W 0xb1
+/* MSS internal memqual MIU4 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU4R 0xb2
+/* MSS internal memqual MIU4 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU4W 0xb3
+#define TEGRA194_MEMORY_CLIENT_DPMUR 0xb4
+#define TEGRA194_MEMORY_CLIENT_DPMUW 0xb5
+#define TEGRA194_MEMORY_CLIENT_NVL0R 0xb6
+#define TEGRA194_MEMORY_CLIENT_NVL0W 0xb7
+#define TEGRA194_MEMORY_CLIENT_NVL1R 0xb8
+#define TEGRA194_MEMORY_CLIENT_NVL1W 0xb9
+#define TEGRA194_MEMORY_CLIENT_NVL2R 0xba
+#define TEGRA194_MEMORY_CLIENT_NVL2W 0xbb
+/* VI FLACON read clients */
+#define TEGRA194_MEMORY_CLIENT_VIFALR 0xbc
+/* VIFAL write clients */
+#define TEGRA194_MEMORY_CLIENT_VIFALW 0xbd
+/* DLA0ARDA read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0RDA 0xbe
+/* DLA0 Falcon read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0FALRDB 0xbf
+/* DLA0 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0WRA 0xc0
+/* DLA0 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0FALWRB 0xc1
+/* DLA1ARDA read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1RDA 0xc2
+/* DLA1 Falcon read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1FALRDB 0xc3
+/* DLA1 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1WRA 0xc4
+/* DLA1 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1FALWRB 0xc5
+/* PVA0RDA read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDA 0xc6
+/* PVA0RDB read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDB 0xc7
+/* PVA0RDC read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDC 0xc8
+/* PVA0WRA write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRA 0xc9
+/* PVA0WRB write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRB 0xca
+/* PVA0WRC write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRC 0xcb
+/* PVA1RDA read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDA 0xcc
+/* PVA1RDB read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDB 0xcd
+/* PVA1RDC read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDC 0xce
+/* PVA1WRA write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRA 0xcf
+/* PVA1WRB write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRB 0xd0
+/* PVA1WRC write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRC 0xd1
+/* RCE read client */
+#define TEGRA194_MEMORY_CLIENT_RCER 0xd2
+/* RCE write client */
+#define TEGRA194_MEMORY_CLIENT_RCEW 0xd3
+/* RCEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_RCEDMAR 0xd4
+/* RCEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_RCEDMAW 0xd5
+#define TEGRA194_MEMORY_CLIENT_NVENC1SRD 0xd6
+#define TEGRA194_MEMORY_CLIENT_NVENC1SWR 0xd7
+/* PCIE0 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0R 0xd8
+/* PCIE0 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0W 0xd9
+/* PCIE1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE1R 0xda
+/* PCIE1 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE1W 0xdb
+/* PCIE2 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE2AR 0xdc
+/* PCIE2 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE2AW 0xdd
+/* PCIE3 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE3R 0xde
+/* PCIE3 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE3W 0xdf
+/* PCIE4 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE4R 0xe0
+/* PCIE4 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE4W 0xe1
+/* PCIE5 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5R 0xe2
+/* PCIE5 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5W 0xe3
+/* ISP read client 1 for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPFALW 0xe4
+#define TEGRA194_MEMORY_CLIENT_NVL3R 0xe5
+#define TEGRA194_MEMORY_CLIENT_NVL3W 0xe6
+#define TEGRA194_MEMORY_CLIENT_NVL4R 0xe7
+#define TEGRA194_MEMORY_CLIENT_NVL4W 0xe8
+/* DLA0ARDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0RDA1 0xe9
+/* DLA1ARDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1RDA1 0xea
+/* PVA0RDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDA1 0xeb
+/* PVA0RDB1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDB1 0xec
+/* PVA1RDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDA1 0xed
+/* PVA1RDB1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDB1 0xee
+/* PCIE5r1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5R1 0xef
+#define TEGRA194_MEMORY_CLIENT_NVENCSRD1 0xf0
+#define TEGRA194_MEMORY_CLIENT_NVENC1SRD1 0xf1
+/* ISP read client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPRA1 0xf2
+/* PCIE0 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0R1 0xf3
+#define TEGRA194_MEMORY_CLIENT_NVL0RHP 0xf4
+#define TEGRA194_MEMORY_CLIENT_NVL1RHP 0xf5
+#define TEGRA194_MEMORY_CLIENT_NVL2RHP 0xf6
+#define TEGRA194_MEMORY_CLIENT_NVL3RHP 0xf7
+#define TEGRA194_MEMORY_CLIENT_NVL4RHP 0xf8
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SRD 0xf9
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SRD1 0xfa
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SWR 0xfb
+/* MSS internal memqual MIU5 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU5R 0xfc
+/* MSS internal memqual MIU5 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU5W 0xfd
+/* MSS internal memqual MIU6 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU6R 0xfe
+/* MSS internal memqual MIU6 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU6W 0xff
+
+#endif
-- 
2.24.1


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

* [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
  2019-12-22 14:10 ` [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs Thierry Reding
  2019-12-22 14:10 ` [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2020-01-08 16:19   ` Rob Herring
  2019-12-22 14:10 ` [PATCH 04/13] memory: tegra: Rename tegra_mc to tegra186_mc on Tegra186 Thierry Reding
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

The NVIDIA Tegra186 SoC contains a memory subsystem composed of the
memory controller and the external memory controller. The memory
controller provides interfaces for the memory clients to access the
memory. Accesses can be either bounced through the SMMU for IOVA
translation or directly to the EMC.

The bulk of the programming of the external memory controller happens
through interfaces exposed by the BPMP. Describe this relationship by
adding a phandle reference to the BPMP to the EMC node.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 .../nvidia,tegra186-mc.yaml                   | 130 ++++++++++++++++++
 1 file changed, 130 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
new file mode 100644
index 000000000000..b98a1d03410b
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 (and later) SoC Memory Controller
+
+maintainers:
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  The NVIDIA Tegra186 SoC features a 128 bit memory controller that is split
+  into four 32 bit channels to support LPDDR4 with x16 subpartitions. The MC
+  handles memory requests for 40-bit virtual addresses from internal clients
+  and arbitrates among them to allocate memory bandwidth.
+
+  Up to 15 GiB of physical memory can be supported. Security features such as
+  encryption of traffic to and from DRAM via general security apertures are
+  available for video and other secure applications, as well as DRAM ECC for
+  automotive safety applications (single bit error correction and double bit
+  error detection).
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    items:
+      - enum:
+          - nvidia,tegra186-mc
+          - nvidia,tegra194-mc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges: true
+
+  dma-ranges: true
+
+patternProperties:
+  "^external-memory-controller@[0-9a-f]+$":
+    description:
+      The bulk of the work involved in controlling the external memory
+      controller on NVIDIA Tegra186 and later is performed on the BPMP. This
+      coprocessor exposes the EMC clock that is used to set the frequency at
+      which the external memory is clocked and a remote procedure call that
+      can be used to obtain the set of available frequencies.
+    type: object
+    properties:
+      compatible:
+        items:
+          - enum:
+              - nvidia,tegra186-emc
+              - nvidia,tegra194-emc
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        items:
+          - description: external memory clock
+
+      clock-names:
+        items:
+          - const: emc
+
+      nvidia,bpmp:
+        $ref: /schemas/types.yaml#/definitions/phandle
+        description:
+          phandle of the node representing the BPMP
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/tegra186-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    memory-controller@2c00000 {
+        compatible = "nvidia,tegra186-mc";
+        reg = <0x0 0x02c00000 0x0 0xb0000>;
+        interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        ranges = <0x0 0x02c00000 0x02c00000 0x0 0xb0000>;
+
+        /*
+         * Memory clients have access to all 40 bits that the memory
+         * controller can address.
+         */
+        dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
+
+        external-memory-controller@2c60000 {
+            compatible = "nvidia,tegra186-emc";
+            reg = <0x0 0x02c60000 0x0 0x50000>;
+            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&bpmp TEGRA186_CLK_EMC>;
+            clock-names = "emc";
+
+            nvidia,bpmp = <&bpmp>;
+        };
+    };
+
+    bpmp: bpmp {
+        compatible = "nvidia,tegra186-bpmp";
+        #clock-cells = <1>;
+    };
-- 
2.24.1


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

* [PATCH 04/13] memory: tegra: Rename tegra_mc to tegra186_mc on Tegra186
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (2 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 05/13] memory: tegra: Add per-SoC data for Tegra186 Thierry Reding
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

This is just for consistency with the rest of the driver.

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

diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 441213a35930..f72e89877295 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -15,7 +15,7 @@ struct tegra_mc {
 	void __iomem *regs;
 };
 
-struct tegra_mc_client {
+struct tegra186_mc_client {
 	const char *name;
 	unsigned int sid;
 	struct {
@@ -24,7 +24,13 @@ struct tegra_mc_client {
 	} regs;
 };
 
-static const struct tegra_mc_client tegra186_mc_clients[] = {
+struct tegra186_mc {
+	struct memory_controller base;
+	struct device *dev;
+	void __iomem *regs;
+};
+
+static const struct tegra186_mc_client tegra186_mc_clients[] = {
 	{
 		.name = "ptcr",
 		.sid = TEGRA186_SID_PASSTHROUGH,
@@ -534,8 +540,8 @@ static const struct tegra_mc_client tegra186_mc_clients[] = {
 
 static int tegra186_mc_probe(struct platform_device *pdev)
 {
+	struct tegra186_mc *mc;
 	struct resource *res;
-	struct tegra_mc *mc;
 	unsigned int i;
 	int err = 0;
 
@@ -551,7 +557,7 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 	mc->dev = &pdev->dev;
 
 	for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
-		const struct tegra_mc_client *client = &tegra186_mc_clients[i];
+		const struct tegra186_mc_client *client = &tegra186_mc_clients[i];
 		u32 override, security;
 
 		override = readl(mc->regs + client->regs.override);
-- 
2.24.1


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

* [PATCH 05/13] memory: tegra: Add per-SoC data for Tegra186
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (3 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 04/13] memory: tegra: Rename tegra_mc to tegra186_mc on Tegra186 Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 06/13] memory: tegra: Extract memory client SID programming Thierry Reding
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Instead of hard-coding the memory client table, use per-SoC data in
preparation for adding support for other SoCs.

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

diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index f72e89877295..ad5c353dba6e 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -6,15 +6,11 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include <dt-bindings/memory/tegra186-mc.h>
 
-struct tegra_mc {
-	struct device *dev;
-	void __iomem *regs;
-};
-
 struct tegra186_mc_client {
 	const char *name;
 	unsigned int sid;
@@ -24,10 +20,16 @@ struct tegra186_mc_client {
 	} regs;
 };
 
+struct tegra186_mc_soc {
+	const struct tegra186_mc_client *clients;
+	unsigned int num_clients;
+};
+
 struct tegra186_mc {
-	struct memory_controller base;
 	struct device *dev;
 	void __iomem *regs;
+
+	const struct tegra186_mc_soc *soc;
 };
 
 static const struct tegra186_mc_client tegra186_mc_clients[] = {
@@ -538,17 +540,24 @@ static const struct tegra186_mc_client tegra186_mc_clients[] = {
 	},
 };
 
+static const struct tegra186_mc_soc tegra186_mc_soc = {
+	.num_clients = ARRAY_SIZE(tegra186_mc_clients),
+	.clients = tegra186_mc_clients,
+};
+
 static int tegra186_mc_probe(struct platform_device *pdev)
 {
 	struct tegra186_mc *mc;
 	struct resource *res;
 	unsigned int i;
-	int err = 0;
+	int err;
 
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
 		return -ENOMEM;
 
+	mc->soc = of_device_get_match_data(&pdev->dev);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mc->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(mc->regs))
@@ -556,8 +565,8 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 
 	mc->dev = &pdev->dev;
 
-	for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
-		const struct tegra186_mc_client *client = &tegra186_mc_clients[i];
+	for (i = 0; i < mc->soc->num_clients; i++) {
+		const struct tegra186_mc_client *client = &mc->soc->clients[i];
 		u32 override, security;
 
 		override = readl(mc->regs + client->regs.override);
@@ -583,7 +592,7 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id tegra186_mc_of_match[] = {
-	{ .compatible = "nvidia,tegra186-mc", },
+	{ .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
-- 
2.24.1


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

* [PATCH 06/13] memory: tegra: Extract memory client SID programming
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (4 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 05/13] memory: tegra: Add per-SoC data for Tegra186 Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 07/13] memory: tegra: Add system sleep support Thierry Reding
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Move programming of the memory client to SID mapping into a separate
function so that it can be reused from multiple call sites.

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

diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index ad5c353dba6e..57895116c8e5 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -32,6 +32,32 @@ struct tegra186_mc {
 	const struct tegra186_mc_soc *soc;
 };
 
+static void tegra186_mc_program_sid(struct tegra186_mc *mc)
+{
+	unsigned int i;
+
+	for (i = 0; i < mc->soc->num_clients; i++) {
+		const struct tegra186_mc_client *client = &mc->soc->clients[i];
+		u32 override, security;
+
+		override = readl(mc->regs + client->regs.override);
+		security = readl(mc->regs + client->regs.security);
+
+		dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+			client->name, override, security);
+
+		dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid,
+			client->name);
+		writel(client->sid, mc->regs + client->regs.override);
+
+		override = readl(mc->regs + client->regs.override);
+		security = readl(mc->regs + client->regs.security);
+
+		dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+			client->name, override, security);
+	}
+}
+
 static const struct tegra186_mc_client tegra186_mc_clients[] = {
 	{
 		.name = "ptcr",
@@ -549,7 +575,6 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 {
 	struct tegra186_mc *mc;
 	struct resource *res;
-	unsigned int i;
 	int err;
 
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
@@ -565,28 +590,8 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 
 	mc->dev = &pdev->dev;
 
-	for (i = 0; i < mc->soc->num_clients; i++) {
-		const struct tegra186_mc_client *client = &mc->soc->clients[i];
-		u32 override, security;
-
-		override = readl(mc->regs + client->regs.override);
-		security = readl(mc->regs + client->regs.security);
-
-		dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
-			client->name, override, security);
-
-		dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid,
-			client->name);
-		writel(client->sid, mc->regs + client->regs.override);
-
-		override = readl(mc->regs + client->regs.override);
-		security = readl(mc->regs + client->regs.security);
-
-		dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
-			client->name, override, security);
-	}
-
 	platform_set_drvdata(pdev, mc);
+	tegra186_mc_program_sid(mc);
 
 	return err;
 }
-- 
2.24.1


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

* [PATCH 07/13] memory: tegra: Add system sleep support
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (5 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 06/13] memory: tegra: Extract memory client SID programming Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 08/13] memory: tegra: Support DVFS on Tegra186 and later Thierry Reding
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Add system suspend/resume support for the memory controller found on
Tegra186 and later. This is required so that the SID registers can be
reprogrammed after their content was lost during system sleep.

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

diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 57895116c8e5..77a313f1bf0e 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -602,10 +602,29 @@ static const struct of_device_id tegra186_mc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
 
+static int tegra186_mc_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int tegra186_mc_resume(struct device *dev)
+{
+	struct tegra186_mc *mc = dev_get_drvdata(dev);
+
+	tegra186_mc_program_sid(mc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra186_mc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(tegra186_mc_suspend, tegra186_mc_resume)
+};
+
 static struct platform_driver tegra186_mc_driver = {
 	.driver = {
 		.name = "tegra186-mc",
 		.of_match_table = tegra186_mc_of_match,
+		.pm = &tegra186_mc_pm_ops,
 		.suppress_bind_attrs = true,
 	},
 	.prevent_deferred_probe = true,
-- 
2.24.1


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

* [PATCH 08/13] memory: tegra: Support DVFS on Tegra186 and later
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (6 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 07/13] memory: tegra: Add system sleep support Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 09/13] memory: tegra: Only include support for enabled SoCs Thierry Reding
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Add a Tegra186 (and later) EMC driver that reads the EMC DVFS tables
from BPMP and uses the EMC clock to change the external memory clock.

This currently only provides a debugfs interface to show the available
frequencies and set lower and upper limits of the allowed range. This
can be used for testing the various frequencies. The goal is to
eventually integrate this with the interconnect framework so that the
EMC frequency can be scaled based on demand from memory clients.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/memory/tegra/Makefile       |   2 +-
 drivers/memory/tegra/tegra186-emc.c | 288 ++++++++++++++++++++++++++++
 drivers/memory/tegra/tegra186.c     |  20 +-
 3 files changed, 308 insertions(+), 2 deletions(-)
 create mode 100644 drivers/memory/tegra/tegra186-emc.c

diff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile
index 3d23c4261104..1a5e112f6196 100644
--- a/drivers/memory/tegra/Makefile
+++ b/drivers/memory/tegra/Makefile
@@ -13,4 +13,4 @@ obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
 obj-$(CONFIG_TEGRA20_EMC)  += tegra20-emc.o
 obj-$(CONFIG_TEGRA30_EMC)  += tegra30-emc.o
 obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
-obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
+obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o tegra186-emc.o
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
new file mode 100644
index 000000000000..a3f275a7b4d6
--- /dev/null
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+
+#include <soc/tegra/bpmp.h>
+
+struct tegra186_emc_dvfs {
+	unsigned long latency;
+	unsigned long rate;
+};
+
+struct tegra186_emc {
+	struct tegra_bpmp *bpmp;
+	struct device *dev;
+	struct clk *clk;
+
+	struct tegra186_emc_dvfs *dvfs;
+	unsigned int num_dvfs;
+
+	struct {
+		struct dentry *root;
+		unsigned long min_rate;
+		unsigned long max_rate;
+	} debugfs;
+};
+
+/*
+ * debugfs interface
+ *
+ * The memory controller driver exposes some files in debugfs that can be used
+ * to control the EMC frequency. The top-level directory can be found here:
+ *
+ *   /sys/kernel/debug/emc
+ *
+ * It contains the following files:
+ *
+ *   - available_rates: This file contains a list of valid, space-separated
+ *     EMC frequencies.
+ *
+ *   - min_rate: Writing a value to this file sets the given frequency as the
+ *       floor of the permitted range. If this is higher than the currently
+ *       configured EMC frequency, this will cause the frequency to be
+ *       increased so that it stays within the valid range.
+ *
+ *   - max_rate: Similarily to the min_rate file, writing a value to this file
+ *       sets the given frequency as the ceiling of the permitted range. If
+ *       the value is lower than the currently configured EMC frequency, this
+ *       will cause the frequency to be decreased so that it stays within the
+ *       valid range.
+ */
+
+static bool tegra186_emc_validate_rate(struct tegra186_emc *emc,
+				       unsigned long rate)
+{
+	unsigned int i;
+
+	for (i = 0; i < emc->num_dvfs; i++)
+		if (rate == emc->dvfs[i].rate)
+			return true;
+
+	return false;
+}
+
+static int tegra186_emc_debug_available_rates_show(struct seq_file *s,
+						   void *data)
+{
+	struct tegra186_emc *emc = s->private;
+	const char *prefix = "";
+	unsigned int i;
+
+	for (i = 0; i < emc->num_dvfs; i++) {
+		seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate);
+		prefix = " ";
+	}
+
+	seq_puts(s, "\n");
+
+	return 0;
+}
+
+static int tegra186_emc_debug_available_rates_open(struct inode *inode,
+						   struct file *file)
+{
+	return single_open(file, tegra186_emc_debug_available_rates_show,
+			   inode->i_private);
+}
+
+static const struct file_operations tegra186_emc_debug_available_rates_fops = {
+	.open = tegra186_emc_debug_available_rates_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate)
+{
+	struct tegra186_emc *emc = data;
+
+	*rate = emc->debugfs.min_rate;
+
+	return 0;
+}
+
+static int tegra186_emc_debug_min_rate_set(void *data, u64 rate)
+{
+	struct tegra186_emc *emc = data;
+	int err;
+
+	if (!tegra186_emc_validate_rate(emc, rate))
+		return -EINVAL;
+
+	err = clk_set_min_rate(emc->clk, rate);
+	if (err < 0)
+		return err;
+
+	emc->debugfs.min_rate = rate;
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_min_rate_fops,
+			tegra186_emc_debug_min_rate_get,
+			tegra186_emc_debug_min_rate_set, "%llu\n");
+
+static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate)
+{
+	struct tegra186_emc *emc = data;
+
+	*rate = emc->debugfs.max_rate;
+
+	return 0;
+}
+
+static int tegra186_emc_debug_max_rate_set(void *data, u64 rate)
+{
+	struct tegra186_emc *emc = data;
+	int err;
+
+	if (!tegra186_emc_validate_rate(emc, rate))
+		return -EINVAL;
+
+	err = clk_set_max_rate(emc->clk, rate);
+	if (err < 0)
+		return err;
+
+	emc->debugfs.max_rate = rate;
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_max_rate_fops,
+			tegra186_emc_debug_max_rate_get,
+			tegra186_emc_debug_max_rate_set, "%llu\n");
+
+static int tegra186_emc_probe(struct platform_device *pdev)
+{
+	struct mrq_emc_dvfs_latency_response response;
+	struct tegra_bpmp_message msg;
+	struct tegra186_emc *emc;
+	unsigned int i;
+	int err;
+
+	emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
+	if (!emc)
+		return -ENOMEM;
+
+	emc->bpmp = tegra_bpmp_get(&pdev->dev);
+	if (IS_ERR(emc->bpmp)) {
+		err = PTR_ERR(emc->bpmp);
+
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "failed to get BPMP: %d\n", err);
+
+		return err;
+	}
+
+	emc->clk = devm_clk_get(&pdev->dev, "emc");
+	if (IS_ERR(emc->clk)) {
+		err = PTR_ERR(emc->clk);
+		dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, emc);
+	emc->dev = &pdev->dev;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.mrq = MRQ_EMC_DVFS_LATENCY;
+	msg.tx.data = NULL;
+	msg.tx.size = 0;
+	msg.rx.data = &response;
+	msg.rx.size = sizeof(response);
+
+	err = tegra_bpmp_transfer(emc->bpmp, &msg);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err);
+		return err;
+	}
+
+	emc->debugfs.min_rate = ULONG_MAX;
+	emc->debugfs.max_rate = 0;
+
+	emc->num_dvfs = response.num_pairs;
+
+	emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs,
+				       sizeof(*emc->dvfs), GFP_KERNEL);
+	if (!emc->dvfs)
+		return -ENOMEM;
+
+	dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs);
+
+	for (i = 0; i < emc->num_dvfs; i++) {
+		emc->dvfs[i].rate = response.pairs[i].freq * 1000;
+		emc->dvfs[i].latency = response.pairs[i].latency;
+
+		if (emc->dvfs[i].rate < emc->debugfs.min_rate)
+			emc->debugfs.min_rate = emc->dvfs[i].rate;
+
+		if (emc->dvfs[i].rate > emc->debugfs.max_rate)
+			emc->debugfs.max_rate = emc->dvfs[i].rate;
+
+		dev_dbg(&pdev->dev, "  %2u: %lu Hz -> %lu us\n", i,
+			emc->dvfs[i].rate, emc->dvfs[i].latency);
+	}
+
+	err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
+				 emc->debugfs.max_rate);
+	if (err < 0) {
+		dev_err(&pdev->dev,
+			"failed to set rate range [%lu-%lu] for %pC\n",
+			emc->debugfs.min_rate, emc->debugfs.max_rate,
+			emc->clk);
+		return err;
+	}
+
+	emc->debugfs.root = debugfs_create_dir("emc", NULL);
+	if (!emc->debugfs.root) {
+		dev_err(&pdev->dev, "failed to create debugfs directory\n");
+		return 0;
+	}
+
+	debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
+			    emc, &tegra186_emc_debug_available_rates_fops);
+	debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+			    emc, &tegra186_emc_debug_min_rate_fops);
+	debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+			    emc, &tegra186_emc_debug_max_rate_fops);
+
+	return 0;
+}
+
+static int tegra186_emc_remove(struct platform_device *pdev)
+{
+	struct tegra186_emc *emc = platform_get_drvdata(pdev);
+
+	debugfs_remove_recursive(emc->debugfs.root);
+	tegra_bpmp_put(emc->bpmp);
+
+	return 0;
+}
+
+static const struct of_device_id tegra186_emc_of_match[] = {
+	{ .compatible = "nvidia,tegra186-emc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tegra186_emc_of_match);
+
+static struct platform_driver tegra186_emc_driver = {
+	.driver = {
+		.name = "tegra186-emc",
+		.of_match_table = tegra186_emc_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = tegra186_emc_probe,
+	.remove = tegra186_emc_remove,
+};
+module_platform_driver(tegra186_emc_driver);
+
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 77a313f1bf0e..a727f0925276 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -590,12 +590,30 @@ static int tegra186_mc_probe(struct platform_device *pdev)
 
 	mc->dev = &pdev->dev;
 
+	err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (err < 0)
+		goto unregister;
+
 	platform_set_drvdata(pdev, mc);
 	tegra186_mc_program_sid(mc);
 
+	return 0;
+
+unregister:
+	memory_controller_unregister(&mc->base);
 	return err;
 }
 
+static int tegra186_mc_remove(struct platform_device *pdev)
+{
+	struct tegra186_mc *mc = platform_get_drvdata(pdev);
+
+	of_platform_depopulate(mc->dev);
+	memory_controller_unregister(&mc->base);
+
+	return 0;
+}
+
 static const struct of_device_id tegra186_mc_of_match[] = {
 	{ .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
 	{ /* sentinel */ }
@@ -627,8 +645,8 @@ static struct platform_driver tegra186_mc_driver = {
 		.pm = &tegra186_mc_pm_ops,
 		.suppress_bind_attrs = true,
 	},
-	.prevent_deferred_probe = true,
 	.probe = tegra186_mc_probe,
+	.remove = tegra186_mc_remove,
 };
 module_platform_driver(tegra186_mc_driver);
 
-- 
2.24.1


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

* [PATCH 09/13] memory: tegra: Only include support for enabled SoCs
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (7 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 08/13] memory: tegra: Support DVFS on Tegra186 and later Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 10/13] memory: tegra: Add support for the Tegra194 memory controller Thierry Reding
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

The memory client tables can be fairly large and they can easily be
omitted if support for the corresponding SoC is not enabled.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/memory/tegra/tegra186-emc.c | 2 ++
 drivers/memory/tegra/tegra186.c     | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index a3f275a7b4d6..812a4e152dcb 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -267,7 +267,9 @@ static int tegra186_emc_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id tegra186_emc_of_match[] = {
+#if defined(CONFIG_ARCH_TEGRA186_SOC)
 	{ .compatible = "nvidia,tegra186-emc" },
+#endif
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, tegra186_emc_of_match);
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index a727f0925276..9c9a2f54b6fc 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -9,7 +9,9 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
 #include <dt-bindings/memory/tegra186-mc.h>
+#endif
 
 struct tegra186_mc_client {
 	const char *name;
@@ -58,6 +60,7 @@ static void tegra186_mc_program_sid(struct tegra186_mc *mc)
 	}
 }
 
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
 static const struct tegra186_mc_client tegra186_mc_clients[] = {
 	{
 		.name = "ptcr",
@@ -570,6 +573,7 @@ static const struct tegra186_mc_soc tegra186_mc_soc = {
 	.num_clients = ARRAY_SIZE(tegra186_mc_clients),
 	.clients = tegra186_mc_clients,
 };
+#endif
 
 static int tegra186_mc_probe(struct platform_device *pdev)
 {
@@ -615,7 +619,9 @@ static int tegra186_mc_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id tegra186_mc_of_match[] = {
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
 	{ .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
+#endif
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
-- 
2.24.1


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

* [PATCH 10/13] memory: tegra: Add support for the Tegra194 memory controller
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (8 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 09/13] memory: tegra: Only include support for enabled SoCs Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 11/13] arm64: tegra: Add interrupt for memory controller on Tegra186 Thierry Reding
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

The memory and external memory controllers on Tegra194 are very similar
to their predecessors from Tegra186. Add the necessary SoC-specific data
to support the newer versions.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/memory/tegra/Makefile       |    1 +
 drivers/memory/tegra/tegra186-emc.c |    3 +
 drivers/memory/tegra/tegra186.c     | 1041 +++++++++++++++++++++++++--
 3 files changed, 999 insertions(+), 46 deletions(-)

diff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile
index 1a5e112f6196..529d10bc5650 100644
--- a/drivers/memory/tegra/Makefile
+++ b/drivers/memory/tegra/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_TEGRA20_EMC)  += tegra20-emc.o
 obj-$(CONFIG_TEGRA30_EMC)  += tegra30-emc.o
 obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o tegra186-emc.o
+obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186.o tegra186-emc.o
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index 812a4e152dcb..97f26bc77ad4 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -269,6 +269,9 @@ static int tegra186_emc_remove(struct platform_device *pdev)
 static const struct of_device_id tegra186_emc_of_match[] = {
 #if defined(CONFIG_ARCH_TEGRA186_SOC)
 	{ .compatible = "nvidia,tegra186-emc" },
+#endif
+#if defined(CONFIG_ARCH_TEGRA194_SOC)
+	{ .compatible = "nvidia,tegra194-emc" },
 #endif
 	{ /* sentinel */ }
 };
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 9c9a2f54b6fc..8b4dcc3d02ae 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -13,6 +13,10 @@
 #include <dt-bindings/memory/tegra186-mc.h>
 #endif
 
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+#include <dt-bindings/memory/tegra194-mc.h>
+#endif
+
 struct tegra186_mc_client {
 	const char *name;
 	unsigned int sid;
@@ -575,52 +579,997 @@ static const struct tegra186_mc_soc tegra186_mc_soc = {
 };
 #endif
 
-static int tegra186_mc_probe(struct platform_device *pdev)
-{
-	struct tegra186_mc *mc;
-	struct resource *res;
-	int err;
-
-	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
-	if (!mc)
-		return -ENOMEM;
-
-	mc->soc = of_device_get_match_data(&pdev->dev);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mc->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mc->regs))
-		return PTR_ERR(mc->regs);
-
-	mc->dev = &pdev->dev;
-
-	err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-	if (err < 0)
-		goto unregister;
-
-	platform_set_drvdata(pdev, mc);
-	tegra186_mc_program_sid(mc);
-
-	return 0;
-
-unregister:
-	memory_controller_unregister(&mc->base);
-	return err;
-}
-
-static int tegra186_mc_remove(struct platform_device *pdev)
-{
-	struct tegra186_mc *mc = platform_get_drvdata(pdev);
-
-	of_platform_depopulate(mc->dev);
-	memory_controller_unregister(&mc->base);
-
-	return 0;
-}
-
-static const struct of_device_id tegra186_mc_of_match[] = {
-#if defined(CONFIG_ARCH_TEGRA_186_SOC)
-	{ .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+static const struct tegra186_mc_client tegra194_mc_clients[] = {
+	{
+		.name = "ptcr",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x000,
+			.security = 0x004,
+		},
+	}, {
+		.name = "miu7r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x008,
+			.security = 0x00c,
+		},
+	}, {
+		.name = "miu7w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x010,
+			.security = 0x014,
+		},
+	}, {
+		.name = "hdar",
+		.sid = TEGRA194_SID_HDA,
+		.regs = {
+			.override = 0x0a8,
+			.security = 0x0ac,
+		},
+	}, {
+		.name = "host1xdmar",
+		.sid = TEGRA194_SID_HOST1X,
+		.regs = {
+			.override = 0x0b0,
+			.security = 0x0b4,
+		},
+	}, {
+		.name = "nvencsrd",
+		.sid = TEGRA194_SID_NVENC,
+		.regs = {
+			.override = 0x0e0,
+			.security = 0x0e4,
+		},
+	}, {
+		.name = "satar",
+		.sid = TEGRA194_SID_SATA,
+		.regs = {
+			.override = 0x0f8,
+			.security = 0x0fc,
+		},
+	}, {
+		.name = "mpcorer",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x138,
+			.security = 0x13c,
+		},
+	}, {
+		.name = "nvencswr",
+		.sid = TEGRA194_SID_NVENC,
+		.regs = {
+			.override = 0x158,
+			.security = 0x15c,
+		},
+	}, {
+		.name = "hdaw",
+		.sid = TEGRA194_SID_HDA,
+		.regs = {
+			.override = 0x1a8,
+			.security = 0x1ac,
+		},
+	}, {
+		.name = "mpcorew",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x1c8,
+			.security = 0x1cc,
+		},
+	}, {
+		.name = "sataw",
+		.sid = TEGRA194_SID_SATA,
+		.regs = {
+			.override = 0x1e8,
+			.security = 0x1ec,
+		},
+	}, {
+		.name = "ispra",
+		.sid = TEGRA194_SID_ISP,
+		.regs = {
+			.override = 0x220,
+			.security = 0x224,
+		},
+	}, {
+		.name = "ispfalr",
+		.sid = TEGRA194_SID_ISP_FALCON,
+		.regs = {
+			.override = 0x228,
+			.security = 0x22c,
+		},
+	}, {
+		.name = "ispwa",
+		.sid = TEGRA194_SID_ISP,
+		.regs = {
+			.override = 0x230,
+			.security = 0x234,
+		},
+	}, {
+		.name = "ispwb",
+		.sid = TEGRA194_SID_ISP,
+		.regs = {
+			.override = 0x238,
+			.security = 0x23c,
+		},
+	}, {
+		.name = "xusb_hostr",
+		.sid = TEGRA194_SID_XUSB_HOST,
+		.regs = {
+			.override = 0x250,
+			.security = 0x254,
+		},
+	}, {
+		.name = "xusb_hostw",
+		.sid = TEGRA194_SID_XUSB_HOST,
+		.regs = {
+			.override = 0x258,
+			.security = 0x25c,
+		},
+	}, {
+		.name = "xusb_devr",
+		.sid = TEGRA194_SID_XUSB_DEV,
+		.regs = {
+			.override = 0x260,
+			.security = 0x264,
+		},
+	}, {
+		.name = "xusb_devw",
+		.sid = TEGRA194_SID_XUSB_DEV,
+		.regs = {
+			.override = 0x268,
+			.security = 0x26c,
+		},
+	}, {
+		.name = "sdmmcra",
+		.sid = TEGRA194_SID_SDMMC1,
+		.regs = {
+			.override = 0x300,
+			.security = 0x304,
+		},
+	}, {
+		.name = "sdmmcr",
+		.sid = TEGRA194_SID_SDMMC3,
+		.regs = {
+			.override = 0x310,
+			.security = 0x314,
+		},
+	}, {
+		.name = "sdmmcrab",
+		.sid = TEGRA194_SID_SDMMC4,
+		.regs = {
+			.override = 0x318,
+			.security = 0x31c,
+		},
+	}, {
+		.name = "sdmmcwa",
+		.sid = TEGRA194_SID_SDMMC1,
+		.regs = {
+			.override = 0x320,
+			.security = 0x324,
+		},
+	}, {
+		.name = "sdmmcw",
+		.sid = TEGRA194_SID_SDMMC3,
+		.regs = {
+			.override = 0x330,
+			.security = 0x334,
+		},
+	}, {
+		.name = "sdmmcwab",
+		.sid = TEGRA194_SID_SDMMC4,
+		.regs = {
+			.override = 0x338,
+			.security = 0x33c,
+		},
+	}, {
+		.name = "vicsrd",
+		.sid = TEGRA194_SID_VIC,
+		.regs = {
+			.override = 0x360,
+			.security = 0x364,
+		},
+	}, {
+		.name = "vicswr",
+		.sid = TEGRA194_SID_VIC,
+		.regs = {
+			.override = 0x368,
+			.security = 0x36c,
+		},
+	}, {
+		.name = "viw",
+		.sid = TEGRA194_SID_VI,
+		.regs = {
+			.override = 0x390,
+			.security = 0x394,
+		},
+	}, {
+		.name = "nvdecsrd",
+		.sid = TEGRA194_SID_NVDEC,
+		.regs = {
+			.override = 0x3c0,
+			.security = 0x3c4,
+		},
+	}, {
+		.name = "nvdecswr",
+		.sid = TEGRA194_SID_NVDEC,
+		.regs = {
+			.override = 0x3c8,
+			.security = 0x3cc,
+		},
+	}, {
+		.name = "aper",
+		.sid = TEGRA194_SID_APE,
+		.regs = {
+			.override = 0x3c0,
+			.security = 0x3c4,
+		},
+	}, {
+		.name = "apew",
+		.sid = TEGRA194_SID_APE,
+		.regs = {
+			.override = 0x3d0,
+			.security = 0x3d4,
+		},
+	}, {
+		.name = "nvjpgsrd",
+		.sid = TEGRA194_SID_NVJPG,
+		.regs = {
+			.override = 0x3f0,
+			.security = 0x3f4,
+		},
+	}, {
+		.name = "nvjpgswr",
+		.sid = TEGRA194_SID_NVJPG,
+		.regs = {
+			.override = 0x3f0,
+			.security = 0x3f4,
+		},
+	}, {
+		.name = "axiapr",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x410,
+			.security = 0x414,
+		},
+	}, {
+		.name = "axiapw",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x418,
+			.security = 0x41c,
+		},
+	}, {
+		.name = "etrr",
+		.sid = TEGRA194_SID_ETR,
+		.regs = {
+			.override = 0x420,
+			.security = 0x424,
+		},
+	}, {
+		.name = "etrw",
+		.sid = TEGRA194_SID_ETR,
+		.regs = {
+			.override = 0x428,
+			.security = 0x42c,
+		},
+	}, {
+		.name = "axisr",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x460,
+			.security = 0x464,
+		},
+	}, {
+		.name = "axisw",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x468,
+			.security = 0x46c,
+		},
+	}, {
+		.name = "eqosr",
+		.sid = TEGRA194_SID_EQOS,
+		.regs = {
+			.override = 0x470,
+			.security = 0x474,
+		},
+	}, {
+		.name = "eqosw",
+		.sid = TEGRA194_SID_EQOS,
+		.regs = {
+			.override = 0x478,
+			.security = 0x47c,
+		},
+	}, {
+		.name = "ufshcr",
+		.sid = TEGRA194_SID_UFSHC,
+		.regs = {
+			.override = 0x480,
+			.security = 0x484,
+		},
+	}, {
+		.name = "ufshcw",
+		.sid = TEGRA194_SID_UFSHC,
+		.regs = {
+			.override = 0x488,
+			.security = 0x48c,
+		},
+	}, {
+		.name = "nvdisplayr",
+		.sid = TEGRA194_SID_NVDISPLAY,
+		.regs = {
+			.override = 0x490,
+			.security = 0x494,
+		},
+	}, {
+		.name = "bpmpr",
+		.sid = TEGRA194_SID_BPMP,
+		.regs = {
+			.override = 0x498,
+			.security = 0x49c,
+		},
+	}, {
+		.name = "bpmpw",
+		.sid = TEGRA194_SID_BPMP,
+		.regs = {
+			.override = 0x4a0,
+			.security = 0x4a4,
+		},
+	}, {
+		.name = "bpmpdmar",
+		.sid = TEGRA194_SID_BPMP,
+		.regs = {
+			.override = 0x4a8,
+			.security = 0x4ac,
+		},
+	}, {
+		.name = "bpmpdmaw",
+		.sid = TEGRA194_SID_BPMP,
+		.regs = {
+			.override = 0x4b0,
+			.security = 0x4b4,
+		},
+	}, {
+		.name = "aonr",
+		.sid = TEGRA194_SID_AON,
+		.regs = {
+			.override = 0x4b8,
+			.security = 0x4bc,
+		},
+	}, {
+		.name = "aonw",
+		.sid = TEGRA194_SID_AON,
+		.regs = {
+			.override = 0x4c0,
+			.security = 0x4c4,
+		},
+	}, {
+		.name = "aondmar",
+		.sid = TEGRA194_SID_AON,
+		.regs = {
+			.override = 0x4c8,
+			.security = 0x4cc,
+		},
+	}, {
+		.name = "aondmaw",
+		.sid = TEGRA194_SID_AON,
+		.regs = {
+			.override = 0x4d0,
+			.security = 0x4d4,
+		},
+	}, {
+		.name = "scer",
+		.sid = TEGRA194_SID_SCE,
+		.regs = {
+			.override = 0x4d8,
+			.security = 0x4dc,
+		},
+	}, {
+		.name = "scew",
+		.sid = TEGRA194_SID_SCE,
+		.regs = {
+			.override = 0x4e0,
+			.security = 0x4e4,
+		},
+	}, {
+		.name = "scedmar",
+		.sid = TEGRA194_SID_SCE,
+		.regs = {
+			.override = 0x4e8,
+			.security = 0x4ec,
+		},
+	}, {
+		.name = "scedmaw",
+		.sid = TEGRA194_SID_SCE,
+		.regs = {
+			.override = 0x4f0,
+			.security = 0x4f4,
+		},
+	}, {
+		.name = "apedmar",
+		.sid = TEGRA194_SID_APE,
+		.regs = {
+			.override = 0x4f8,
+			.security = 0x4fc,
+		},
+	}, {
+		.name = "apedmaw",
+		.sid = TEGRA194_SID_APE,
+		.regs = {
+			.override = 0x500,
+			.security = 0x504,
+		},
+	}, {
+		.name = "nvdisplayr1",
+		.sid = TEGRA194_SID_NVDISPLAY,
+		.regs = {
+			.override = 0x508,
+			.security = 0x50c,
+		},
+	}, {
+		.name = "vicsrd1",
+		.sid = TEGRA194_SID_VIC,
+		.regs = {
+			.override = 0x510,
+			.security = 0x514,
+		},
+	}, {
+		.name = "nvdecsrd1",
+		.sid = TEGRA194_SID_NVDEC,
+		.regs = {
+			.override = 0x518,
+			.security = 0x51c,
+		},
+	}, {
+		.name = "miu0r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x530,
+			.security = 0x534,
+		},
+	}, {
+		.name = "miu0w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x538,
+			.security = 0x53c,
+		},
+	}, {
+		.name = "miu1r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x540,
+			.security = 0x544,
+		},
+	}, {
+		.name = "miu1w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x548,
+			.security = 0x54c,
+		},
+	}, {
+		.name = "miu2r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x570,
+			.security = 0x574,
+		},
+	}, {
+		.name = "miu2w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x578,
+			.security = 0x57c,
+		},
+	}, {
+		.name = "miu3r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x580,
+			.security = 0x584,
+		},
+	}, {
+		.name = "miu3w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x588,
+			.security = 0x58c,
+		},
+	}, {
+		.name = "miu4r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x590,
+			.security = 0x594,
+		},
+	}, {
+		.name = "miu4w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x598,
+			.security = 0x59c,
+		},
+	}, {
+		.name = "dpmur",
+		.sid = TEGRA194_SID_PASSTHROUGH,
+		.regs = {
+			.override = 0x598,
+			.security = 0x59c,
+		},
+	}, {
+		.name = "vifalr",
+		.sid = TEGRA194_SID_VI_FALCON,
+		.regs = {
+			.override = 0x5e0,
+			.security = 0x5e4,
+		},
+	}, {
+		.name = "vifalw",
+		.sid = TEGRA194_SID_VI_FALCON,
+		.regs = {
+			.override = 0x5e8,
+			.security = 0x5ec,
+		},
+	}, {
+		.name = "dla0rda",
+		.sid = TEGRA194_SID_NVDLA0,
+		.regs = {
+			.override = 0x5f0,
+			.security = 0x5f4,
+		},
+	}, {
+		.name = "dla0falrdb",
+		.sid = TEGRA194_SID_NVDLA0,
+		.regs = {
+			.override = 0x5f8,
+			.security = 0x5fc,
+		},
+	}, {
+		.name = "dla0wra",
+		.sid = TEGRA194_SID_NVDLA0,
+		.regs = {
+			.override = 0x600,
+			.security = 0x604,
+		},
+	}, {
+		.name = "dla0falwrb",
+		.sid = TEGRA194_SID_NVDLA0,
+		.regs = {
+			.override = 0x608,
+			.security = 0x60c,
+		},
+	}, {
+		.name = "dla1rda",
+		.sid = TEGRA194_SID_NVDLA1,
+		.regs = {
+			.override = 0x610,
+			.security = 0x614,
+		},
+	}, {
+		.name = "dla1falrdb",
+		.sid = TEGRA194_SID_NVDLA1,
+		.regs = {
+			.override = 0x618,
+			.security = 0x61c,
+		},
+	}, {
+		.name = "dla1wra",
+		.sid = TEGRA194_SID_NVDLA1,
+		.regs = {
+			.override = 0x620,
+			.security = 0x624,
+		},
+	}, {
+		.name = "dla1falwrb",
+		.sid = TEGRA194_SID_NVDLA1,
+		.regs = {
+			.override = 0x628,
+			.security = 0x62c,
+		},
+	}, {
+		.name = "pva0rda",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x630,
+			.security = 0x634,
+		},
+	}, {
+		.name = "pva0rdb",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x638,
+			.security = 0x63c,
+		},
+	}, {
+		.name = "pva0rdc",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x640,
+			.security = 0x644,
+		},
+	}, {
+		.name = "pva0wra",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x648,
+			.security = 0x64c,
+		},
+	}, {
+		.name = "pva0wrb",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x650,
+			.security = 0x654,
+		},
+	}, {
+		.name = "pva0wrc",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x658,
+			.security = 0x65c,
+		},
+	}, {
+		.name = "pva1rda",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x660,
+			.security = 0x664,
+		},
+	}, {
+		.name = "pva1rdb",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x668,
+			.security = 0x66c,
+		},
+	}, {
+		.name = "pva1rdc",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x670,
+			.security = 0x674,
+		},
+	}, {
+		.name = "pva1wra",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x678,
+			.security = 0x67c,
+		},
+	}, {
+		.name = "pva1wrb",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x680,
+			.security = 0x684,
+		},
+	}, {
+		.name = "pva1wrc",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x688,
+			.security = 0x68c,
+		},
+	}, {
+		.name = "rcer",
+		.sid = TEGRA194_SID_RCE,
+		.regs = {
+			.override = 0x690,
+			.security = 0x694,
+		},
+	}, {
+		.name = "rcew",
+		.sid = TEGRA194_SID_RCE,
+		.regs = {
+			.override = 0x698,
+			.security = 0x69c,
+		},
+	}, {
+		.name = "rcedmar",
+		.sid = TEGRA194_SID_RCE,
+		.regs = {
+			.override = 0x6a0,
+			.security = 0x6a4,
+		},
+	}, {
+		.name = "rcedmaw",
+		.sid = TEGRA194_SID_RCE,
+		.regs = {
+			.override = 0x6a8,
+			.security = 0x6ac,
+		},
+	}, {
+		.name = "nvenc1srd",
+		.sid = TEGRA194_SID_NVENC1,
+		.regs = {
+			.override = 0x6b0,
+			.security = 0x6b4,
+		},
+	}, {
+		.name = "nvenc1swr",
+		.sid = TEGRA194_SID_NVENC1,
+		.regs = {
+			.override = 0x6b8,
+			.security = 0x6bc,
+		},
+	}, {
+		.name = "pcie0r",
+		.sid = TEGRA194_SID_PCIE0,
+		.regs = {
+			.override = 0x6c0,
+			.security = 0x6c4,
+		},
+	}, {
+		.name = "pcie0w",
+		.sid = TEGRA194_SID_PCIE0,
+		.regs = {
+			.override = 0x6c8,
+			.security = 0x6cc,
+		},
+	}, {
+		.name = "pcie1r",
+		.sid = TEGRA194_SID_PCIE1,
+		.regs = {
+			.override = 0x6d0,
+			.security = 0x6d4,
+		},
+	}, {
+		.name = "pcie1w",
+		.sid = TEGRA194_SID_PCIE1,
+		.regs = {
+			.override = 0x6d8,
+			.security = 0x6dc,
+		},
+	}, {
+		.name = "pcie2ar",
+		.sid = TEGRA194_SID_PCIE2,
+		.regs = {
+			.override = 0x6e0,
+			.security = 0x6e4,
+		},
+	}, {
+		.name = "pcie2aw",
+		.sid = TEGRA194_SID_PCIE2,
+		.regs = {
+			.override = 0x6e8,
+			.security = 0x6ec,
+		},
+	}, {
+		.name = "pcie3r",
+		.sid = TEGRA194_SID_PCIE3,
+		.regs = {
+			.override = 0x6f0,
+			.security = 0x6f4,
+		},
+	}, {
+		.name = "pcie3w",
+		.sid = TEGRA194_SID_PCIE3,
+		.regs = {
+			.override = 0x6f8,
+			.security = 0x6fc,
+		},
+	}, {
+		.name = "pcie4r",
+		.sid = TEGRA194_SID_PCIE4,
+		.regs = {
+			.override = 0x700,
+			.security = 0x704,
+		},
+	}, {
+		.name = "pcie4w",
+		.sid = TEGRA194_SID_PCIE4,
+		.regs = {
+			.override = 0x708,
+			.security = 0x70c,
+		},
+	}, {
+		.name = "pcie5r",
+		.sid = TEGRA194_SID_PCIE5,
+		.regs = {
+			.override = 0x710,
+			.security = 0x714,
+		},
+	}, {
+		.name = "pcie5w",
+		.sid = TEGRA194_SID_PCIE5,
+		.regs = {
+			.override = 0x718,
+			.security = 0x71c,
+		},
+	}, {
+		.name = "ispfalw",
+		.sid = TEGRA194_SID_ISP_FALCON,
+		.regs = {
+			.override = 0x720,
+			.security = 0x724,
+		},
+	}, {
+		.name = "dla0rda1",
+		.sid = TEGRA194_SID_NVDLA0,
+		.regs = {
+			.override = 0x748,
+			.security = 0x74c,
+		},
+	}, {
+		.name = "dla1rda1",
+		.sid = TEGRA194_SID_NVDLA1,
+		.regs = {
+			.override = 0x750,
+			.security = 0x754,
+		},
+	}, {
+		.name = "pva0rda1",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x758,
+			.security = 0x75c,
+		},
+	}, {
+		.name = "pva0rdb1",
+		.sid = TEGRA194_SID_PVA0,
+		.regs = {
+			.override = 0x760,
+			.security = 0x764,
+		},
+	}, {
+		.name = "pva1rda1",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x768,
+			.security = 0x76c,
+		},
+	}, {
+		.name = "pva1rdb1",
+		.sid = TEGRA194_SID_PVA1,
+		.regs = {
+			.override = 0x770,
+			.security = 0x774,
+		},
+	}, {
+		.name = "pcie5r1",
+		.sid = TEGRA194_SID_PCIE5,
+		.regs = {
+			.override = 0x778,
+			.security = 0x77c,
+		},
+	}, {
+		.name = "nvencsrd1",
+		.sid = TEGRA194_SID_NVENC,
+		.regs = {
+			.override = 0x780,
+			.security = 0x784,
+		},
+	}, {
+		.name = "nvenc1srd1",
+		.sid = TEGRA194_SID_NVENC1,
+		.regs = {
+			.override = 0x788,
+			.security = 0x78c,
+		},
+	}, {
+		.name = "ispra1",
+		.sid = TEGRA194_SID_ISP,
+		.regs = {
+			.override = 0x790,
+			.security = 0x794,
+		},
+	}, {
+		.name = "pcie0r1",
+		.sid = TEGRA194_SID_PCIE0,
+		.regs = {
+			.override = 0x798,
+			.security = 0x79c,
+		},
+	}, {
+		.name = "nvdec1srd",
+		.sid = TEGRA194_SID_NVDEC1,
+		.regs = {
+			.override = 0x7c8,
+			.security = 0x7cc,
+		},
+	}, {
+		.name = "nvdec1srd1",
+		.sid = TEGRA194_SID_NVDEC1,
+		.regs = {
+			.override = 0x7d0,
+			.security = 0x7d4,
+		},
+	}, {
+		.name = "nvdec1swr",
+		.sid = TEGRA194_SID_NVDEC1,
+		.regs = {
+			.override = 0x7d8,
+			.security = 0x7dc,
+		},
+	}, {
+		.name = "miu5r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x7e0,
+			.security = 0x7e4,
+		},
+	}, {
+		.name = "miu5w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x7e8,
+			.security = 0x7ec,
+		},
+	}, {
+		.name = "miu6r",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x7f0,
+			.security = 0x7f4,
+		},
+	}, {
+		.name = "miu6w",
+		.sid = TEGRA194_SID_MIU,
+		.regs = {
+			.override = 0x7f8,
+			.security = 0x7fc,
+		},
+	},
+};
+
+static const struct tegra186_mc_soc tegra194_mc_soc = {
+	.num_clients = ARRAY_SIZE(tegra194_mc_clients),
+	.clients = tegra194_mc_clients,
+};
+#endif
+
+static int tegra186_mc_probe(struct platform_device *pdev)
+{
+	struct tegra186_mc *mc;
+	struct resource *res;
+	int err;
+
+	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
+	if (!mc)
+		return -ENOMEM;
+
+	mc->soc = of_device_get_match_data(&pdev->dev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mc->regs))
+		return PTR_ERR(mc->regs);
+
+	mc->dev = &pdev->dev;
+
+	err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (err < 0)
+		goto unregister;
+
+	platform_set_drvdata(pdev, mc);
+	tegra186_mc_program_sid(mc);
+
+	return 0;
+
+unregister:
+	memory_controller_unregister(&mc->base);
+	return err;
+}
+
+static int tegra186_mc_remove(struct platform_device *pdev)
+{
+	struct tegra186_mc *mc = platform_get_drvdata(pdev);
+
+	of_platform_depopulate(mc->dev);
+	memory_controller_unregister(&mc->base);
+
+	return 0;
+}
+
+static const struct of_device_id tegra186_mc_of_match[] = {
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
+	{ .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
+#endif
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+	{ .compatible = "nvidia,tegra194-mc", .data = &tegra194_mc_soc },
 #endif
 	{ /* sentinel */ }
 };
-- 
2.24.1


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

* [PATCH 11/13] arm64: tegra: Add interrupt for memory controller on Tegra186
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (9 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 10/13] memory: tegra: Add support for the Tegra194 memory controller Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 12/13] arm64: tegra: Add external " Thierry Reding
  2019-12-22 14:10 ` [PATCH 13/13] arm64: tegra: Add the memory subsystem on Tegra194 Thierry Reding
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

The memory controller can be interrupted by certain conditions. Add the
interrupt to the device tree node to allow drivers to trap these
conditions.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 7dc7fa8bcc39..584498a999d4 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -142,6 +142,7 @@ agic: interrupt-controller@2a40000 {
 	memory-controller@2c00000 {
 		compatible = "nvidia,tegra186-mc";
 		reg = <0x0 0x02c00000 0x0 0xb0000>;
+		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
 		status = "disabled";
 	};
 
-- 
2.24.1


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

* [PATCH 12/13] arm64: tegra: Add external memory controller on Tegra186
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (10 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 11/13] arm64: tegra: Add interrupt for memory controller on Tegra186 Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  2019-12-22 14:10 ` [PATCH 13/13] arm64: tegra: Add the memory subsystem on Tegra194 Thierry Reding
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

Add the external memory controller as a child device of the memory
controller on Tegra186. The memory controller really represents the
memory subsystem that encompasses both the memory and external memory
controllers. The external memory controller uses the BPMP to obtain the
list of supported EMC frequencies and set the EMC frequency.

Also set up the dma-ranges property to describe that all memory clients
can address up to 40 bits using the memory controller client interface
(MCCIF), unless otherwise limited by the DMA engines of the hardware.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 584498a999d4..dba7f57469c5 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -144,6 +144,27 @@ memory-controller@2c00000 {
 		reg = <0x0 0x02c00000 0x0 0xb0000>;
 		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
 		status = "disabled";
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x02c00000 0x0 0x02c00000 0x0 0xb0000>;
+
+		/*
+		 * Memory clients have access to all 40 bits that the memory
+		 * controller can address.
+		 */
+		dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
+
+		emc: external-memory-controller@2c60000 {
+			compatible = "nvidia,tegra186-emc";
+			reg = <0x0 0x02c60000 0x0 0x50000>;
+			interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&bpmp TEGRA186_CLK_EMC>;
+			clock-names = "emc";
+
+			nvidia,bpmp = <&bpmp>;
+		};
 	};
 
 	timer@3010000 {
-- 
2.24.1


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

* [PATCH 13/13] arm64: tegra: Add the memory subsystem on Tegra194
  2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
                   ` (11 preceding siblings ...)
  2019-12-22 14:10 ` [PATCH 12/13] arm64: tegra: Add external " Thierry Reding
@ 2019-12-22 14:10 ` Thierry Reding
  12 siblings, 0 replies; 17+ messages in thread
From: Thierry Reding @ 2019-12-22 14:10 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

From: Thierry Reding <treding@nvidia.com>

The memory subsystem on Tegra194 encompasses both the memory and
external memory controllers. The EMC is represented as a subnode of the
MC and a ranges property is used to describe the register ranges.

A dma-ranges property is also added to describe that all memory clients
can address up to 39 bits using the memory controller client interface
(MCCIF), unless otherwise limited by the DMA engines of the hardware. A
memory client can technically use 40 bits of addresses, but the memory
controller on Tegra194 uses bit 39 to determine the XBAR format used to
access memory. Use of this bit needs to be explicitly controlled by the
operating system drivers for devices that can use this on-the-fly format
conversion. Using the dma-ranges property prevents the operating system
from using the bit implicitly, for example in I/O virtual address
mappings.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi |  4 ++
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      | 43 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index b6ffd5dde20d..cc23d59240ac 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -48,6 +48,10 @@ phy: phy@0 {
 			};
 		};
 
+		memory-controller@2c00000 {
+			status = "okay";
+		};
+
 		serial@3110000 {
 			status = "okay";
 		};
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 9f000bb7fca7..73e23ca158dc 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -7,6 +7,7 @@
 #include <dt-bindings/power/tegra194-powergate.h>
 #include <dt-bindings/reset/tegra194-reset.h>
 #include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
+#include <dt-bindings/memory/tegra194-mc.h>
 
 / {
 	compatible = "nvidia,tegra194";
@@ -166,6 +167,48 @@ clkreq {
 			};
 		};
 
+		mc: memory-controller@2c00000 {
+			compatible = "nvidia,tegra194-mc";
+			reg = <0x02c00000 0x100000>,
+			      <0x02b80000 0x040000>,
+			      <0x01700000 0x100000>;
+			status = "disabled";
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			ranges = <0x01700000 0x0 0x01700000 0x0 0x100000>,
+				 <0x02b80000 0x0 0x02b80000 0x0 0x040000>,
+				 <0x02c00000 0x0 0x02c00000 0x0 0x100000>;
+
+			/*
+			 * Bit 39 of addresses passing through the memory
+			 * controller selects the XBAR format used when memory
+			 * is accessed. This is used to transparently access
+			 * memory in the XBAR format used by the discrete GPU
+			 * (bit 39 set) or Tegra (bit 39 clear).
+			 *
+			 * As a consequence, the operating system must ensure
+			 * that bit 39 is never used implicitly, for example
+			 * via an I/O virtual address mapping of an IOMMU. If
+			 * devices require access to the XBAR switch, their
+			 * drivers must set this bit explicitly.
+			 *
+			 * Limit the DMA range for memory clients to [38:0].
+			 */
+			dma-ranges = <0x0 0x0 0x0 0x80 0x0>;
+
+			emc: external-memory-controller@2c60000 {
+				compatible = "nvidia,tegra194-emc";
+				reg = <0x0 0x02c60000 0x0 0x90000>,
+				      <0x0 0x01780000 0x0 0x80000>;
+				clocks = <&bpmp TEGRA194_CLK_EMC>;
+				clock-names = "emc";
+
+				nvidia,bpmp = <&bpmp>;
+			};
+		};
+
 		uarta: serial@3100000 {
 			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
 			reg = <0x03100000 0x40>;
-- 
2.24.1


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

* Re: [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs
  2019-12-22 14:10 ` [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs Thierry Reding
@ 2020-01-08 16:14   ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2020-01-08 16:14 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Thierry Reding, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

On Sun, 22 Dec 2019 15:10:23 +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Add IDs for the memory clients found on NVIDIA Tegra186 SoCs. This will
> be used to describe interconnect paths from devices to system memory.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  include/dt-bindings/memory/tegra186-mc.h | 139 +++++++++++++++++++++++
>  1 file changed, 139 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header
  2019-12-22 14:10 ` [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header Thierry Reding
@ 2020-01-08 16:15   ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2020-01-08 16:15 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Thierry Reding, Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

On Sun, 22 Dec 2019 15:10:24 +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> This header contains definitions for the memory controller found on
> NVIDIA Tegra194 SoCs, such as the stream IDs used for the ARM SMMU and
> the IDs used to identify the various memory clients.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  include/dt-bindings/memory/tegra194-mc.h | 410 +++++++++++++++++++++++
>  1 file changed, 410 insertions(+)
>  create mode 100644 include/dt-bindings/memory/tegra194-mc.h
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem
  2019-12-22 14:10 ` [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem Thierry Reding
@ 2020-01-08 16:19   ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2020-01-08 16:19 UTC (permalink / raw)
  To: Thierry Reding; +Cc: Jon Hunter, linux-tegra, devicetree, linux-arm-kernel

On Sun, Dec 22, 2019 at 03:10:25PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> The NVIDIA Tegra186 SoC contains a memory subsystem composed of the
> memory controller and the external memory controller. The memory
> controller provides interfaces for the memory clients to access the
> memory. Accesses can be either bounced through the SMMU for IOVA
> translation or directly to the EMC.
> 
> The bulk of the programming of the external memory controller happens
> through interfaces exposed by the BPMP. Describe this relationship by
> adding a phandle reference to the BPMP to the EMC node.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  .../nvidia,tegra186-mc.yaml                   | 130 ++++++++++++++++++
>  1 file changed, 130 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
> new file mode 100644
> index 000000000000..b98a1d03410b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
> @@ -0,0 +1,130 @@
> +# SPDX-License-Identifier: (GPL-2.0)

Dual license new bindings:

(GPL-2.0-only OR BSD-2-Clause)

Though maybe this is a copy-n-paste of the other Tegra MC bindings?

With that sorted,

Reviewed-by: Rob Herring <robh@kernel.org>

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVIDIA Tegra186 (and later) SoC Memory Controller
> +
> +maintainers:
> +  - Jon Hunter <jonathanh@nvidia.com>
> +  - Thierry Reding <thierry.reding@gmail.com>
> +
> +description: |
> +  The NVIDIA Tegra186 SoC features a 128 bit memory controller that is split
> +  into four 32 bit channels to support LPDDR4 with x16 subpartitions. The MC
> +  handles memory requests for 40-bit virtual addresses from internal clients
> +  and arbitrates among them to allocate memory bandwidth.
> +
> +  Up to 15 GiB of physical memory can be supported. Security features such as
> +  encryption of traffic to and from DRAM via general security apertures are
> +  available for video and other secure applications, as well as DRAM ECC for
> +  automotive safety applications (single bit error correction and double bit
> +  error detection).
> +
> +properties:
> +  $nodename:
> +    pattern: "^memory-controller@[0-9a-f]+$"
> +
> +  compatible:
> +    items:
> +      - enum:
> +          - nvidia,tegra186-mc
> +          - nvidia,tegra194-mc
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 2
> +
> +  ranges: true
> +
> +  dma-ranges: true
> +
> +patternProperties:
> +  "^external-memory-controller@[0-9a-f]+$":
> +    description:
> +      The bulk of the work involved in controlling the external memory
> +      controller on NVIDIA Tegra186 and later is performed on the BPMP. This
> +      coprocessor exposes the EMC clock that is used to set the frequency at
> +      which the external memory is clocked and a remote procedure call that
> +      can be used to obtain the set of available frequencies.
> +    type: object
> +    properties:
> +      compatible:
> +        items:
> +          - enum:
> +              - nvidia,tegra186-emc
> +              - nvidia,tegra194-emc
> +
> +      reg:
> +        maxItems: 1
> +
> +      interrupts:
> +        maxItems: 1
> +
> +      clocks:
> +        items:
> +          - description: external memory clock
> +
> +      clock-names:
> +        items:
> +          - const: emc
> +
> +      nvidia,bpmp:
> +        $ref: /schemas/types.yaml#/definitions/phandle
> +        description:
> +          phandle of the node representing the BPMP
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#address-cells"
> +  - "#size-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/tegra186-clock.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    memory-controller@2c00000 {
> +        compatible = "nvidia,tegra186-mc";
> +        reg = <0x0 0x02c00000 0x0 0xb0000>;
> +        interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        ranges = <0x0 0x02c00000 0x02c00000 0x0 0xb0000>;
> +
> +        /*
> +         * Memory clients have access to all 40 bits that the memory
> +         * controller can address.
> +         */
> +        dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
> +
> +        external-memory-controller@2c60000 {
> +            compatible = "nvidia,tegra186-emc";
> +            reg = <0x0 0x02c60000 0x0 0x50000>;
> +            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&bpmp TEGRA186_CLK_EMC>;
> +            clock-names = "emc";
> +
> +            nvidia,bpmp = <&bpmp>;
> +        };
> +    };
> +
> +    bpmp: bpmp {
> +        compatible = "nvidia,tegra186-bpmp";
> +        #clock-cells = <1>;
> +    };
> -- 
> 2.24.1
> 

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

end of thread, other threads:[~2020-01-08 16:19 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-22 14:10 [PATCH 00/13] memory: tegra: Add Tegra186/Tegra194 support Thierry Reding
2019-12-22 14:10 ` [PATCH 01/13] dt-bindings: memory: Add Tegra186 memory client IDs Thierry Reding
2020-01-08 16:14   ` Rob Herring
2019-12-22 14:10 ` [PATCH 02/13] dt-bindings: memory: Add Tegra194 memory controller header Thierry Reding
2020-01-08 16:15   ` Rob Herring
2019-12-22 14:10 ` [PATCH 03/13] dt-bindings: memory: Add Tegra186 memory subsystem Thierry Reding
2020-01-08 16:19   ` Rob Herring
2019-12-22 14:10 ` [PATCH 04/13] memory: tegra: Rename tegra_mc to tegra186_mc on Tegra186 Thierry Reding
2019-12-22 14:10 ` [PATCH 05/13] memory: tegra: Add per-SoC data for Tegra186 Thierry Reding
2019-12-22 14:10 ` [PATCH 06/13] memory: tegra: Extract memory client SID programming Thierry Reding
2019-12-22 14:10 ` [PATCH 07/13] memory: tegra: Add system sleep support Thierry Reding
2019-12-22 14:10 ` [PATCH 08/13] memory: tegra: Support DVFS on Tegra186 and later Thierry Reding
2019-12-22 14:10 ` [PATCH 09/13] memory: tegra: Only include support for enabled SoCs Thierry Reding
2019-12-22 14:10 ` [PATCH 10/13] memory: tegra: Add support for the Tegra194 memory controller Thierry Reding
2019-12-22 14:10 ` [PATCH 11/13] arm64: tegra: Add interrupt for memory controller on Tegra186 Thierry Reding
2019-12-22 14:10 ` [PATCH 12/13] arm64: tegra: Add external " Thierry Reding
2019-12-22 14:10 ` [PATCH 13/13] arm64: tegra: Add the memory subsystem on Tegra194 Thierry Reding

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