Skip to contentSkip to conversation

tegra20-emc: Identify memory chip by LPDDR configuration

PATCH Superseded Dmitry Osipenko 1 participant 6 messages Oct 3, 2021

Subsystems (3)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover tegra20-emc: Identify memory chip by LPDDR configuration

Support memory chip identification by LPDDR2 configuration, which is needed by ASUS Transformer TF101 tablet device that doesn't store RAMCODE in Tegra's NVMEM.

Changelog:

v2: - Added separate binding for standard LPDDR2 properties, like it
was suggested by Krzysztof Kozlowski.

- Switched Tegra binding to use new lpddr2-configuration sub-node that contains the standard properties.

- Extended commit message of the "emc: Document new LPDDR2 sub-node" patch, telling how the properties are supposed to be used, which was requested by Krzysztof Kozlowski.

- Added new common helpers for parsing LPDDR2 properties and made tegra20-emc driver to use these helpers.

Dmitry Osipenko (4):
dt-bindings: memory: Add LPDDR2 binding
dt-bindings: memory: tegra20: emc: Document new LPDDR2 sub-node
memory: Add LPDDR2 configuration helpers
memory: tegra20-emc: Support matching timings by LPDDR2 configuration

 .../memory-controllers/jedec,lpddr2.yaml      |  80 ++++++++
 .../nvidia,tegra20-emc.yaml                   |  17 +-
 drivers/memory/jedec_ddr.h                    |  21 ++
 drivers/memory/jedec_ddr_data.c               |  42 ++++
 drivers/memory/of_memory.c                    |  34 ++++
 drivers/memory/of_memory.h                    |   9 +
 drivers/memory/tegra/Kconfig                  |   1 +
 drivers/memory/tegra/tegra20-emc.c            | 191 ++++++++++++++++--
 include/dt-bindings/memory/lpddr2.h           |  25 +++
 9 files changed, 404 insertions(+), 16 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/jedec,lpddr2.yaml
 create mode 100644 include/dt-bindings/memory/lpddr2.h
Signature · 1 line
2.32.0
#1 lore raw

PATCH v2 1/4 dt-bindings: memory: Add LPDDR2 binding

Add binding for standard LPDDR2 memory chip properties.

---
 .../memory-controllers/jedec,lpddr2.yaml      | 80 +++++++++++++++++++
 include/dt-bindings/memory/lpddr2.h           | 25 ++++++
 2 files changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/jedec,lpddr2.yaml
 create mode 100644 include/dt-bindings/memory/lpddr2.h
Documentation/devicetree/bindings/memory-controllers/jedec,lpddr2.yaml new file +80 -0
new file mode 100644
index 000000000000..ef227eba1e4a
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/jedec,lpddr2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: JEDEC LPDDR2 SDRAM
+
+maintainers:
+  - Krzysztof Kozlowski <[email protected]>
+
+properties:
+  jedec,lpddr2-manufacturer-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 255
+    description: |
+      Unique manufacturer ID of SDRAM chip. See MR5 description in JESD209-2.
+
+  jedec,lpddr2-revision-id1:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 255
+    description: |
+      Revision 1 value of SDRAM chip.
+      See MR6 description in chip vendor specification.
+
+  jedec,lpddr2-revision-id2:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 255
+    description: |
+      Revision 2 value of SDRAM chip.
+      See MR7 description in chip vendor specification.
+
+  jedec,lpddr2-density-mbits:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Density in megabits of SDRAM chip. See MR8 description in JESD209-2.
+    enum:
+      - 64
+      - 128
+      - 256
+      - 512
+      - 1024
+      - 2048
+      - 4096
+      - 8192
+      - 16384
+      - 32768
+
+  jedec,lpddr2-io-width-bits:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      IO bus width in bits of SDRAM chip. See MR8 description in JESD209-2.
+    enum:
+      - 32
+      - 16
+      - 8
+
+  jedec,lpddr2-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      LPDDR type which corresponds to a number of words SDRAM pre-fetches
+      per column request. See MR8 description in JESD209-2.
+    enum:
+      - 0 # S4 (4 words prefetch architecture)
+      - 1 # S2 (2 words prefetch architecture)
+      - 2 # NVM (Non-volatile memory)
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/memory/lpddr2.h>
+
+    lpddr2 {
+        jedec,lpddr2-manufacturer-id = <LPDDR2_MANID_ELPIDA>;
+        jedec,lpddr2-revision-id1 = <1>;
+        jedec,lpddr2-density-mbits = <2048>;
+        jedec,lpddr2-io-width-bits = <16>;
+        jedec,lpddr2-type = <LPDDR2_TYPE_S4>;
+    };
include/dt-bindings/memory/lpddr2.h new file +25 -0
new file mode 100644
index 000000000000..e837b0d8a11e
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+#ifndef _DT_BINDINGS_LPDDR2_H
+#define _DT_BINDINGS_LPDDR2_H
+
+#define LPDDR2_MANID_SAMSUNG		1
+#define LPDDR2_MANID_QIMONDA		2
+#define LPDDR2_MANID_ELPIDA		3
+#define LPDDR2_MANID_ETRON		4
+#define LPDDR2_MANID_NANYA		5
+#define LPDDR2_MANID_HYNIX		6
+#define LPDDR2_MANID_MOSEL		7
+#define LPDDR2_MANID_WINBOND		8
+#define LPDDR2_MANID_ESMT		9
+#define LPDDR2_MANID_SPANSION		11
+#define LPDDR2_MANID_SST		12
+#define LPDDR2_MANID_ZMOS		13
+#define LPDDR2_MANID_INTEL		14
+#define LPDDR2_MANID_NUMONYX		254
+#define LPDDR2_MANID_MICRON		255
+
+#define LPDDR2_TYPE_S4			0
+#define LPDDR2_TYPE_S2			1
+#define LPDDR2_TYPE_NVM			2
+
+#endif /*_DT_BINDINGS_LPDDR2_H */
Signature · 1 line
2.32.0
#2 lore raw

PATCH v2 2/4 dt-bindings: memory: tegra20: emc: Document new LPDDR2 sub-node

In reply to Dmitry Osipenko

Some Tegra20 boards don't have RAM code stored in NVMEM, which is used for the memory chip identification and the identity information should be read out from LPDDR2 chip in this case. Document new sub-node containing generic LPDDR2 properties that will be used for the memory chip identification if RAM code isn't available. The identification is done by reading out memory configuration values from generic LPDDR2 mode registers of SDRAM chip and comparing them with the values of device-tree sub-node's.

---
 .../memory-controllers/nvidia,tegra20-emc.yaml  | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.yaml +14 -3
index cac6842dc8f1..2741333591bf 100644
@@ -164,13 +164,14 @@ patternProperties:
       "#size-cells":
         const: 0
 
+      lpddr2-configuration:
+        $ref: "jedec,lpddr2.yaml#"
+        type: object
+
     patternProperties:
       "^emc-table@[0-9]+$":
         $ref: "#/$defs/emc-table"
 
-    required:
-      - nvidia,ram-code
-
     additionalProperties: false
 
 required:
@@ -186,6 +187,8 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/memory/lpddr2.h>
+
     external-memory-controller@7000f400 {
         compatible = "nvidia,tegra20-emc";
         reg = <0x7000f400 0x400>;
@@ -226,5 +229,13 @@ examples:
                         0x007fe010 0x00001414 0x00000000 0x00000000
                         0x00000000 0x00000000 0x00000000 0x00000000>;
             };
+
+            lpddr2-config {
+                jedec,lpddr2-manufacturer-id = <LPDDR2_MANID_ELPIDA>;
+                jedec,lpddr2-revision-id1 = <1>;
+                jedec,lpddr2-density-mbits = <2048>;
+                jedec,lpddr2-io-width-bits = <16>;
+                jedec,lpddr2-type = <LPDDR2_TYPE_S4>;
+            };
         };
     };
Signature · 1 line
2.32.0
#3 lore raw

Re: [PATCH v2 2/4] dt-bindings: memory: tegra20: emc: Document new LPDDR2 sub-node

03.10.2021 03:35, Dmitry Osipenko пишет:

Quoted 3 lines
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.yaml +3 -0
+      lpddr2-configuration:
+        $ref: "jedec,lpddr2.yaml#"
+        type: object

...

Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.yaml examples: · line 239

Quoted 8 lines
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.yaml +8 -0
+
+            lpddr2-config {
+                jedec,lpddr2-manufacturer-id = <LPDDR2_MANID_ELPIDA>;
+                jedec,lpddr2-revision-id1 = <1>;
+                jedec,lpddr2-density-mbits = <2048>;
+                jedec,lpddr2-io-width-bits = <16>;
+                jedec,lpddr2-type = <LPDDR2_TYPE_S4>;
+            };

I just noticed that this is a wrong node name and I missed to run dt_binding_check after the last edit. I'll send v3 with the corrected name shortly.

#4 lore raw

PATCH v2 3/4 memory: Add LPDDR2 configuration helpers

In reply to Dmitry Osipenko

Add helpers for reading and parsing standard LPDDR2 properties.

---
 drivers/memory/jedec_ddr.h      | 21 +++++++++++++++++
 drivers/memory/jedec_ddr_data.c | 42 +++++++++++++++++++++++++++++++++
 drivers/memory/of_memory.c      | 34 ++++++++++++++++++++++++++
 drivers/memory/of_memory.h      |  9 +++++++
 4 files changed, 106 insertions(+)
drivers/memory/jedec_ddr.h +21 -0
index e59ccbd982d0..14cef272559e 100644
@@ -230,4 +230,25 @@ struct lpddr3_min_tck {
 	u32 tMRD;
 };
 
+union lpddr2_basic_config4 {
+	u32 value;
+
+	struct {
+		unsigned int arch_type : 2;
+		unsigned int density : 4;
+		unsigned int io_width : 2;
+	} __packed;
+};
+
+struct lpddr2_configuration {
+	int arch_type;
+	int density;
+	int io_width;
+	int manufacturer_id;
+	int revision_id1;
+	int revision_id2;
+};
+
+const char *lpddr2_jedec_manufacturer(unsigned int manufacturer_id);
+
 #endif /* __JEDEC_DDR_H */
drivers/memory/jedec_ddr_data.c +42 -0

51 lines not on this page · raw message

drivers/memory/of_memory.c +34 -0
index d9f5437d3bce..8aa777f2a090 100644
@@ -298,3 +298,37 @@ const struct lpddr3_timings
 	return NULL;
 }
 EXPORT_SYMBOL(of_lpddr3_get_ddr_timings);
+
+/**
+ * of_lpddr2_get_config() - extracts the lpddr2 chip configuration.
+ * @np: Pointer to device tree node containing configuration
+ * @conf: Configuration updated by this function
+ *
+ * Populates lpddr2_configuration structure by extracting data from device
+ * tree node. Returns 0 on success or error code on failure. If property
+ * is missing in device-tree, then the corresponding @conf value is set to
+ * -ENOENT.
+ */
+int of_lpddr2_get_config(struct device_node *np,
+			 struct lpddr2_configuration *conf)
+{
+	int err, ret = -ENOENT;
+
+#define OF_LPDDR2_READ_U32(prop, dtprop) \
+	err = of_property_read_u32(np, dtprop, &conf->prop); \
+	if (err) \
+		conf->prop = -ENOENT; \
+	else \
+		ret = 0
+
+	/* at least one property should be parsed */
+	OF_LPDDR2_READ_U32(manufacturer_id, "jedec,lpddr2-manufacturer-id");
+	OF_LPDDR2_READ_U32(revision_id1, "jedec,lpddr2-revision-id1");
+	OF_LPDDR2_READ_U32(revision_id2, "jedec,lpddr2-revision-id2");
+	OF_LPDDR2_READ_U32(io_width, "jedec,lpddr2-io-width-bits");
+	OF_LPDDR2_READ_U32(density, "jedec,lpddr2-density-mbits");
+	OF_LPDDR2_READ_U32(arch_type, "jedec,lpddr2-type");
+
+	return ret;
+}
+EXPORT_SYMBOL(of_lpddr2_get_config);
drivers/memory/of_memory.h +9 -0
index 4a99b232ab0a..95eccc251b04 100644
@@ -20,6 +20,9 @@ const struct lpddr3_min_tck *of_lpddr3_get_min_tck(struct device_node *np,
 const struct lpddr3_timings *
 of_lpddr3_get_ddr_timings(struct device_node *np_ddr,
 			  struct device *dev, u32 device_type, u32 *nr_frequencies);
+
+int of_lpddr2_get_config(struct device_node *np,
+			 struct lpddr2_configuration *conf);
 #else
 static inline const struct lpddr2_min_tck
 	*of_get_min_tck(struct device_node *np, struct device *dev)
@@ -46,6 +49,12 @@ static inline const struct lpddr3_timings
 {
 	return NULL;
 }
+
+static int of_lpddr2_get_config(struct device_node *np,
+				struct lpddr2_configuration *conf)
+{
+	return -ENOENT;
+}
 #endif /* CONFIG_OF && CONFIG_DDR */
 
 #endif /* __LINUX_MEMORY_OF_REG_ */
Signature · 1 line
2.32.0
#5 lore raw

PATCH v2 4/4 memory: tegra20-emc: Support matching timings by LPDDR2 configuration

In reply to Dmitry Osipenko

Asus Transformer TF101 doesn't provide RAM code and in this case memory timings should be selected based on identity information read out from SDRAM chip. Support matching timings by LPDDR2 configuration.

---
 drivers/memory/tegra/Kconfig       |   1 +
 drivers/memory/tegra/tegra20-emc.c | 191 +++++++++++++++++++++++++++--
 2 files changed, 179 insertions(+), 13 deletions(-)
drivers/memory/tegra/Kconfig +1 -0
index f9bae36c03a3..7951764b4efe 100644
@@ -16,6 +16,7 @@ config TEGRA20_EMC
 	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	select PM_DEVFREQ
+	select DDR
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra20 chips. The EMC controls the external DRAM on the board.
drivers/memory/tegra/tegra20-emc.c +178 -13

283 lines not on this page · raw message

Signature · 1 line
2.32.0