linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1] memory: mediatek: add DRAM controller driver
@ 2021-03-30  5:22 Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-03-30  5:22 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	wsd_upstream, CC Hwang, Loda Chou, Po-Kai Chi

These patch series introduces the MediaTek DRAM controller driver (DRAMC)
on MT6779 SoC, and enables to be built as a module by default for the
ARM64 builds.

MediaTek DRAMC driver provides cross-platform features as below:
  - API provided to other kernel modules for querying DRAM type,
    rank count, rank size, channel count and mode register settings.
  - Sysfs interface used to pass DRAM mode register settings and current
    DRAM data rate to user-space for MediaTek ecosystem.

The API user includes MediaTek External Memory Interface (EMI) and
DVFS Resource Control (DVFSRC), which will be sent to mainline later.


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

* [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller
  2021-03-30  5:22 [PATCH v1] memory: mediatek: add DRAM controller driver Po-Kai Chi
@ 2021-03-30  5:22 ` Po-Kai Chi
  2021-03-30 13:08   ` Rob Herring
  2021-03-30 13:58   ` Rob Herring
  2021-03-30  5:22 ` [PATCH v1 2/4] memory: mediatek: add DRAM controller driver Po-Kai Chi
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-03-30  5:22 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	wsd_upstream, CC Hwang, Loda Chou, Po-Kai Chi

This patch adds the documentation of the device-tree binding for
MediaTek Common DRAM Controller.

Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
---
 .../memory-controllers/mediatek,dramc.yaml         |  155 ++++++++++++++++++++
 1 file changed, 155 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
new file mode 100644
index 0000000..0217ce0
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
@@ -0,0 +1,155 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2021 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/mediatek,dramc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek DRAM Controller
+
+maintainers:
+  - Po-Kai Chi <pk.chi@mediatek.com>
+
+description: |
+  MediaTek DRAM controller (DRAMC) provides an interface to query information
+  about DRAM which collected from bootloader and device tree.
+  This is mainly used by MediaTek Extended Memory Interface (EMI) and DVFS Resource
+  Control (DVFSRC).
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt6779-dramc
+
+  reg:
+    description:
+      Base address of MediaTek DRAM related hardware modules, each channel has
+      its own base address in order of
+      DRAMC_AO_{CH}, DRAMC_NAO_{CH}, DDRPHY_AO_{CH}.
+    minItems: 3            # 3 * N channels
+    maxItems: 6
+
+  dram_type:
+    description:
+      The DRAM type of current DRAM chip.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+
+  support_channel_cnt:
+    description:
+      The maximum DRAM channel count supported by SoC.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 4
+
+  channel_cnt:
+    description:
+      The DRAM channel count of current DRAM chip.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 4
+
+  rank_cnt:
+    description:
+      The DRAM rank count of current DRAM chip.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 2
+
+  rank_size:
+    description:
+      The size of each DRAM rank.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint64
+    minItems: 1
+    maxItems: 2
+    items:
+      minimum: 0x0
+      maximum: 0x100000000    # support up to 4GB in single rank
+
+  mr_cnt:
+    description:
+      Specifies how many sets of DRAM mode register information to provide.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 40    # total 40 MRs for JEDEC LPDDR4X
+
+  mr:
+    description:
+      Pair of DRAM mode register information.
+      This property is filled in by bootloader according to the board hardware
+      configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32-matrix
+    maxItems: 40    # align with mr_cnt
+    items:
+      items:
+        - description:
+            Mode register index
+        - description:
+            Mode register value
+
+  freq_cnt:
+    description:
+      Specifies how many sets of DRAM data clock rate supported by SoC.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  freq_step:
+    description:
+      The DRAM data clock rate may be slightly different from those defined
+      by the specification due to errors in multiples of the base frequency.
+      This describe the mapping from real data clock rate measured by
+      frequency meter to JEDEC data clock rate.
+    $ref: /schemas/types.yaml#/definitions/uint32-matrix
+    items:
+      items:
+        - description:
+            Real data rate
+        - description:
+            Spec data rate
+
+required:
+  - compatible
+  - reg
+  - dram_type
+  - support_channel_cnt
+  - channel_cnt
+  - rank_cnt
+  - mr_cnt
+  - freq_cnt
+
+additionalProperties: false
+
+examples:
+  - |
+    dramc@10230000 {
+        compatible = "mediatek,mt6779-dramc";
+        reg = <0 0x10230000 0 0x2000>, /* DRAMC AO CHA */
+            <0 0x10240000 0 0x2000>,   /* DRAMC AO CHB */
+            <0 0x10234000 0 0x1000>,   /* DRAMC NAO CHA */
+            <0 0x10244000 0 0x1000>,   /* DRAMC NAO CHB */
+            <0 0x10238000 0 0x2000>,   /* DDRPHY AO CHA */
+            <0 0x10248000 0 0x2000>;   /* DDRPHY AO CHB */
+        dram_type = <0>;
+        support_channel_cnt = <2>;
+        channel_cnt = <2>;
+        rank_cnt = <2>;
+        rank_size = <0x40000000 0x40000000>;
+        mr_cnt = <1>;
+        mr = <0x5 0xff>;
+        freq_cnt = <6>;
+        freq_step = <3718 3733>,
+                <3094 3200>,
+                <2392 2400>,
+                <1534 1600>,
+                <1196 1200>,
+                <754 800>;
+    };
-- 
1.7.9.5


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

* [PATCH v1 2/4] memory: mediatek: add DRAM controller driver
  2021-03-30  5:22 [PATCH v1] memory: mediatek: add DRAM controller driver Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
@ 2021-03-30  5:22 ` Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 3/4] arm64: dts: add DRAMC node for MT6779 Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 4/4] arm64: defconfig: Enable MediaTek DRAMC common driver Po-Kai Chi
  3 siblings, 0 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-03-30  5:22 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	wsd_upstream, CC Hwang, Loda Chou, Po-Kai Chi

MediaTek DRAM controller (DRAMC) driver provides cross-platform features
as below:
  - API provided to other kernel modules for querying DRAM type,
    rank count, rank size, channel count and mode register settings.
  - Sysfs interface used to pass DRAM mode register settings and current
    DRAM data rate to user-space for MediaTek ecosystem.

Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
---
 drivers/memory/Kconfig              |    1 +
 drivers/memory/Makefile             |    1 +
 drivers/memory/mediatek/Kconfig     |    9 +
 drivers/memory/mediatek/Makefile    |    3 +
 drivers/memory/mediatek/mtk-dramc.c |  711 +++++++++++++++++++++++++++++++++++
 include/memory/mediatek/dramc.h     |   18 +
 6 files changed, 743 insertions(+)
 create mode 100644 drivers/memory/mediatek/Kconfig
 create mode 100644 drivers/memory/mediatek/Makefile
 create mode 100644 drivers/memory/mediatek/mtk-dramc.c
 create mode 100644 include/memory/mediatek/dramc.h

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 72c0df1..056e906 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -225,6 +225,7 @@ config STM32_FMC2_EBI
 	  devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on
 	  SOCs containing the FMC2 External Bus Interface.
 
+source "drivers/memory/mediatek/Kconfig"
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index bc7663e..cd4f8cf 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_PL353_SMC)		+= pl353-smc.o
 obj-$(CONFIG_RENESAS_RPCIF)	+= renesas-rpc-if.o
 obj-$(CONFIG_STM32_FMC2_EBI)	+= stm32-fmc2-ebi.o
 
+obj-$(CONFIG_MTK_DRAMC)		+= mediatek/
 obj-$(CONFIG_SAMSUNG_MC)	+= samsung/
 obj-$(CONFIG_TEGRA_MC)		+= tegra/
 obj-$(CONFIG_TI_EMIF_SRAM)	+= ti-emif-sram.o
diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kconfig
new file mode 100644
index 0000000..a1618b0
--- /dev/null
+++ b/drivers/memory/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config MTK_DRAMC
+	tristate "MediaTek DRAMC driver"
+	help
+	  This selects the MediaTek(R) DRAMC driver.
+	  Provide the API for DRAMC low power scenario, and the interface
+	  for reporting DRAM information, e.g. DRAM mode register (MR) for
+	  DRAM vendor ID, temperature, and density.
diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Makefile
new file mode 100644
index 0000000..632be48
--- /dev/null
+++ b/drivers/memory/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_MTK_DRAMC)	+= mtk-dramc.o
diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/mtk-dramc.c
new file mode 100644
index 0000000..d81d311
--- /dev/null
+++ b/drivers/memory/mediatek/mtk-dramc.c
@@ -0,0 +1,711 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <memory/mediatek/dramc.h>
+
+#define DRAMC_DRV_NAME	"mtk-dramc"
+
+struct mr_info_t {
+	unsigned int mr_index;
+	unsigned int mr_value;
+};
+
+/*
+ * struct reg_ctrl_t - to describe the bits required in a register
+ * @offset: register address offset from a base
+ * @mask: bitmask of the target bits
+ * @shift: starting bit of the target bits
+ */
+struct reg_ctrl_t {
+	unsigned int offset;
+	unsigned int mask;
+	unsigned int shift;
+};
+
+struct fmeter_dev_t {
+	unsigned int crystal_freq;
+	unsigned int shu_of;
+	struct reg_ctrl_t shu_lv;
+	struct reg_ctrl_t pll_id;
+	struct reg_ctrl_t pll_md[2];
+	struct reg_ctrl_t sdmpcw[2];
+	struct reg_ctrl_t prediv[2];
+	struct reg_ctrl_t posdiv[2];
+	struct reg_ctrl_t ckdiv4[2];
+	struct reg_ctrl_t cldiv2[2];
+	struct reg_ctrl_t fbksel[2];
+	struct reg_ctrl_t dqopen[2];
+};
+
+struct mr4_dev_t {
+	struct reg_ctrl_t mr4_rg;
+};
+
+struct dramc_dev_t {
+	unsigned int dram_type;
+	unsigned int support_channel_cnt;
+	unsigned int channel_cnt;
+	unsigned int rank_cnt;
+	unsigned int mr_cnt;
+	unsigned int freq_cnt;
+	unsigned int *rank_size;
+	unsigned int *freq_step;
+	struct mr_info_t *mr_info_ptr;
+	void __iomem **dramc_chn_base_ao;
+	void __iomem **dramc_chn_base_nao;
+	void __iomem **ddrphy_chn_base_ao;
+	void *mr4_dev_ptr;
+	void *fmeter_dev_ptr;
+};
+
+enum DRAM_TYPE {
+	TYPE_NONE = 0,
+	TYPE_DDR1,
+	TYPE_LPDDR2,
+	TYPE_LPDDR3,
+	TYPE_PCDDR3,
+	TYPE_LPDDR4,
+	TYPE_LPDDR4X,
+	TYPE_LPDDR4P
+};
+
+static const struct fmeter_dev_t fmeter_v0_mt6779_t = {
+	.crystal_freq = 52,
+	.shu_of = 0x500,
+	.shu_lv = { .offset = 0x00e4, .mask = 0x00000006, .shift = 1 },
+	.pll_id = { .offset = 0x0510, .mask = 0x80000000, .shift = 31 },
+	.pll_md = {
+		{ .offset = 0x0d84, .mask = 0x00000100, .shift = 8 },
+		{ .offset = 0x0d84, .mask = 0x00000100, .shift = 8 },
+	},
+	.sdmpcw = {
+		{ .offset = 0x0d9c, .mask = 0xffff0000, .shift = 16 },
+		{ .offset = 0x0d94, .mask = 0xffff0000, .shift = 16 },
+	},
+	.prediv = {
+		{ .offset = 0x0da8, .mask = 0x000c0000, .shift = 18 },
+		{ .offset = 0x0da0, .mask = 0x000c0000, .shift = 18 },
+	},
+	.posdiv = {
+		{ .offset = 0x0da8, .mask = 0x00000007, .shift = 0 },
+		{ .offset = 0x0da0, .mask = 0x00000007, .shift = 0 },
+	},
+	.ckdiv4 = {
+		{ .offset = 0x0d18, .mask = 0x08000000, .shift = 27 },
+		{ .offset = 0x0d18, .mask = 0x08000000, .shift = 27 },
+	},
+	.cldiv2 = {
+		{ .offset = 0x0c38, .mask = 0x80000000, .shift = 31 },
+		{ .offset = 0x0c38, .mask = 0x80000000, .shift = 31 },
+	},
+};
+
+static const struct mr4_dev_t mr4_v1_mt6779_t = {
+	.mr4_rg = { .offset = 0x0090, .mask = 0x0000ffff, .shift = 0 },
+};
+
+struct mtk_dramc_compatible {
+	const struct fmeter_dev_t *fmeter;
+	const struct mr4_dev_t *mr4;
+};
+
+static const struct mtk_dramc_compatible mt6779_compat = {
+	.fmeter = &fmeter_v0_mt6779_t,
+	.mr4 = &mr4_v1_mt6779_t,
+};
+
+static const struct of_device_id mtk_dramc_of_ids[] = {
+	{ .compatible = "mediatek,mt6779-dramc", .data = &mt6779_compat },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mtk_dramc_of_ids);
+
+/*
+ * mtk_dramc_get_drvdata_by_ids - get the dramc driver data
+ *
+ * Return the dramc driver data
+ */
+static struct dramc_dev_t *mtk_dramc_get_drvdata_by_ids(void)
+{
+	struct device_node *np;
+	struct platform_device *dramc_pdev;
+
+	np = of_find_matching_node_and_match(NULL, mtk_dramc_of_ids, NULL);
+	dramc_pdev = of_find_device_by_node(np);
+
+	if (!dramc_pdev)
+		return NULL;
+
+	return (struct dramc_dev_t *)platform_get_drvdata(dramc_pdev);
+}
+
+static ssize_t mr_show(struct device_driver *driver, char *buf)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+	struct mr_info_t *mr_info_ptr;
+	unsigned int i;
+	ssize_t ret;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	mr_info_ptr = dramc_dev_ptr->mr_info_ptr;
+
+	for (ret = 0, i = 0; i < dramc_dev_ptr->mr_cnt; i++) {
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"mr%d: 0x%x\n",
+				mr_info_ptr[i].mr_index,
+				mr_info_ptr[i].mr_value);
+		if (ret >= PAGE_SIZE)
+			return strlen(buf);
+	}
+
+	return strlen(buf);
+}
+
+static ssize_t mr4_show(struct device_driver *driver, char *buf)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+	unsigned int i;
+	ssize_t ret;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	for (ret = 0, i = 0; i < dramc_dev_ptr->channel_cnt; i++) {
+		ret += snprintf(buf + ret, PAGE_SIZE - ret,
+				"mr4: ch%d 0x%x\n",
+				i, mtk_dramc_get_mr4(i));
+		if (ret >= PAGE_SIZE)
+			return strlen(buf);
+	}
+
+	return strlen(buf);
+}
+
+static ssize_t dram_data_rate_show(struct device_driver *driver, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "DRAM data rate = %d\n",
+			mtk_dramc_get_data_rate());
+}
+
+static DRIVER_ATTR_RO(mr);
+static DRIVER_ATTR_RO(mr4);
+static DRIVER_ATTR_RO(dram_data_rate);
+
+static int dramc_probe(struct platform_device *pdev)
+{
+	struct device_node *dramc_node = pdev->dev.of_node;
+	struct dramc_dev_t *dramc_dev_ptr;
+	const struct mtk_dramc_compatible *dev_comp;
+	struct resource *res;
+	unsigned int i, size;
+	int ret;
+
+	pr_info("%s: module probe.\n", __func__);
+
+	dramc_dev_ptr = devm_kmalloc(&pdev->dev,
+				     sizeof(struct dramc_dev_t),
+				     GFP_KERNEL);
+
+	dev_comp =
+		(struct mtk_dramc_compatible *)
+			of_device_get_match_data(&pdev->dev);
+
+	if (!dramc_dev_ptr)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(dramc_node,
+				   "dram_type",
+				   &dramc_dev_ptr->dram_type);
+	if (ret) {
+		pr_info("%s: get dram_type fail\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(dramc_node,
+				   "support_channel_cnt",
+				   &dramc_dev_ptr->support_channel_cnt);
+	if (ret) {
+		pr_info("%s: get support_channel_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(dramc_node,
+				   "channel_cnt",
+				   &dramc_dev_ptr->channel_cnt);
+	if (ret) {
+		pr_info("%s: get channel_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(dramc_node,
+				   "rank_cnt",
+				   &dramc_dev_ptr->rank_cnt);
+	if (ret) {
+		pr_info("%s: get rank_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(dramc_node,
+				   "mr_cnt",
+				   &dramc_dev_ptr->mr_cnt);
+	if (ret) {
+		pr_info("%s: get mr_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(dramc_node,
+				   "freq_cnt",
+				   &dramc_dev_ptr->freq_cnt);
+	if (ret) {
+		pr_info("%s: get freq_cnt fail\n", __func__);
+		return -EINVAL;
+	}
+
+	dramc_dev_ptr->mr4_dev_ptr = (void *)dev_comp->mr4;
+
+	pr_info("%s: %s(%d),%s(%d),%s(%d),%s(%d),%s(%d),%s(%d),%s(%s)\n",
+		__func__,
+		"dram_type", dramc_dev_ptr->dram_type,
+		"support_channel_cnt", dramc_dev_ptr->support_channel_cnt,
+		"channel_cnt", dramc_dev_ptr->channel_cnt,
+		"rank_cnt", dramc_dev_ptr->rank_cnt,
+		"mr_cnt", dramc_dev_ptr->mr_cnt,
+		"freq_cnt", dramc_dev_ptr->freq_cnt,
+		"mr4", (dramc_dev_ptr->mr4_dev_ptr) ? "true" : "false");
+
+	size = sizeof(unsigned int) * dramc_dev_ptr->rank_cnt;
+	dramc_dev_ptr->rank_size = devm_kmalloc(&pdev->dev, size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->rank_size))
+		return -ENOMEM;
+	ret = of_property_read_u32_array(dramc_node,
+					 "rank_size",
+					 dramc_dev_ptr->rank_size,
+					 dramc_dev_ptr->rank_cnt);
+	if (ret) {
+		pr_info("%s: get rank_size fail\n", __func__);
+		return -EINVAL;
+	}
+
+	if (dramc_dev_ptr->mr_cnt) {
+		size = sizeof(struct mr_info_t) * dramc_dev_ptr->mr_cnt;
+		dramc_dev_ptr->mr_info_ptr = devm_kmalloc(&pdev->dev,
+							  size,
+							  GFP_KERNEL);
+		if (!(dramc_dev_ptr->mr_info_ptr))
+			return -ENOMEM;
+		ret =
+		    of_property_read_u32_array(dramc_node,
+					       "mr",
+					       (unsigned int *)dramc_dev_ptr->mr_info_ptr,
+					       size >> 2);
+		if (ret) {
+			pr_info("%s: get mr_info fail\n", __func__);
+			return -EINVAL;
+		}
+		for (i = 0; i < dramc_dev_ptr->mr_cnt; i++)
+			pr_info("%s: mr%d(%x)\n", __func__,
+				dramc_dev_ptr->mr_info_ptr[i].mr_index,
+				dramc_dev_ptr->mr_info_ptr[i].mr_value);
+	}
+
+	if (dramc_dev_ptr->freq_cnt) {
+		size = sizeof(unsigned int) * dramc_dev_ptr->freq_cnt * 2;
+		dramc_dev_ptr->freq_step =
+			devm_kmalloc(&pdev->dev, size, GFP_KERNEL);
+		if (!(dramc_dev_ptr->freq_step))
+			return -ENOMEM;
+		ret = of_property_read_u32_array(dramc_node,
+						 "freq_step",
+						 dramc_dev_ptr->freq_step,
+						 dramc_dev_ptr->freq_cnt * 2);
+		if (ret) {
+			pr_info("%s: get freq_step fail\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	size = sizeof(phys_addr_t) * dramc_dev_ptr->support_channel_cnt;
+	dramc_dev_ptr->dramc_chn_base_ao = devm_kmalloc(&pdev->dev,
+							size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->dramc_chn_base_ao))
+		return -ENOMEM;
+	dramc_dev_ptr->dramc_chn_base_nao = devm_kmalloc(&pdev->dev,
+							 size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->dramc_chn_base_nao))
+		return -ENOMEM;
+	dramc_dev_ptr->ddrphy_chn_base_ao = devm_kmalloc(&pdev->dev,
+							 size, GFP_KERNEL);
+	if (!(dramc_dev_ptr->ddrphy_chn_base_ao))
+		return -ENOMEM;
+
+	for (i = 0; i < dramc_dev_ptr->support_channel_cnt; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		dramc_dev_ptr->dramc_chn_base_ao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_ao[i])) {
+			pr_info("%s: unable to map ch%d DRAMC AO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    i + dramc_dev_ptr->support_channel_cnt);
+		dramc_dev_ptr->dramc_chn_base_nao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->dramc_chn_base_nao[i])) {
+			pr_info("%s: unable to map ch%d DRAMC NAO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM,
+					    i + dramc_dev_ptr->support_channel_cnt * 2);
+		dramc_dev_ptr->ddrphy_chn_base_ao[i] =
+			devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(dramc_dev_ptr->ddrphy_chn_base_ao[i])) {
+			pr_info("%s: unable to map ch%d DDRPHY AO base\n",
+				__func__, i);
+			return -EINVAL;
+		}
+	}
+
+	dramc_dev_ptr->fmeter_dev_ptr = (void *)dev_comp->fmeter;
+
+	ret = driver_create_file(pdev->dev.driver,
+				 &driver_attr_dram_data_rate);
+	if (ret) {
+		pr_info("%s: fail to create dram_data_rate sysfs\n", __func__);
+		return ret;
+	}
+
+	ret = driver_create_file(pdev->dev.driver,
+				 &driver_attr_mr);
+	if (ret) {
+		pr_info("%s: fail to create mr sysfs\n", __func__);
+		return ret;
+	}
+
+	if (dramc_dev_ptr->mr4_dev_ptr) {
+		ret = driver_create_file(pdev->dev.driver,
+					 &driver_attr_mr4);
+		if (ret) {
+			pr_info("%s: fail to create mr4 sysfs\n", __func__);
+			return ret;
+		}
+	}
+
+	platform_set_drvdata(pdev, dramc_dev_ptr);
+	pr_info("%s: DRAM data type = %d\n", __func__,
+		mtk_dramc_get_ddr_type());
+
+	pr_info("%s: DRAM data clock rate = %d\n", __func__,
+		mtk_dramc_get_data_rate());
+
+	return ret;
+}
+
+/*
+ * mtk_dramc_get_steps_freq - get the data clock rate of target DVFS step
+ * @step: the step index of DVFS
+ *
+ * Return the DRAM spec data clock rate (MHz)
+ */
+int mtk_dramc_get_steps_freq(unsigned int step)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return -ENODEV;
+
+	if (step < dramc_dev_ptr->freq_cnt)
+		return dramc_dev_ptr->freq_step[step * 2 + 1];
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mtk_dramc_get_steps_freq);
+
+/*
+ * decode_freq - decode the spec data clock rate
+ * @vco_freq: real data clock rate
+ *
+ * Return the DRAM spec data clock rate (MHz)
+ */
+static unsigned int decode_freq(unsigned int vco_freq)
+{
+	int i;
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	for (i = 0; i < dramc_dev_ptr->freq_cnt * 2; i += 2)
+		if (vco_freq == dramc_dev_ptr->freq_step[i])
+			return dramc_dev_ptr->freq_step[i + 1];
+
+	return vco_freq;
+}
+
+static unsigned int fmeter_v0(struct dramc_dev_t *dramc_dev_ptr)
+{
+	struct fmeter_dev_t *fmeter_dev_ptr =
+		(struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
+	unsigned int shu_lv_val;
+	unsigned int pll_id_val;
+	unsigned int pll_md_val;
+	unsigned int sdmpcw_val;
+	unsigned int prediv_val;
+	unsigned int posdiv_val;
+	unsigned int ckdiv4_val;
+	unsigned int cldiv2_val;
+	unsigned int offset;
+	unsigned int vco_freq;
+
+	shu_lv_val = (readl(dramc_dev_ptr->dramc_chn_base_ao[0] +
+		fmeter_dev_ptr->shu_lv.offset) &
+		fmeter_dev_ptr->shu_lv.mask) >>
+		fmeter_dev_ptr->shu_lv.shift;
+
+	pll_id_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] +
+		fmeter_dev_ptr->pll_id.offset) &
+		fmeter_dev_ptr->pll_id.mask) >>
+		fmeter_dev_ptr->pll_id.shift;
+
+	offset = fmeter_dev_ptr->pll_md[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	pll_md_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->pll_md[pll_id_val].mask) >>
+		fmeter_dev_ptr->pll_md[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->sdmpcw[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	sdmpcw_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->sdmpcw[pll_id_val].mask) >>
+		fmeter_dev_ptr->sdmpcw[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->prediv[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	prediv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->prediv[pll_id_val].mask) >>
+		fmeter_dev_ptr->prediv[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->posdiv[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	posdiv_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->posdiv[pll_id_val].mask) >>
+		fmeter_dev_ptr->posdiv[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->ckdiv4[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	ckdiv4_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->ckdiv4[pll_id_val].mask) >>
+		fmeter_dev_ptr->ckdiv4[pll_id_val].shift;
+
+	offset = fmeter_dev_ptr->cldiv2[pll_id_val].offset +
+		fmeter_dev_ptr->shu_of * shu_lv_val;
+	cldiv2_val = (readl(dramc_dev_ptr->ddrphy_chn_base_ao[0] + offset) &
+		fmeter_dev_ptr->cldiv2[pll_id_val].mask) >>
+		fmeter_dev_ptr->cldiv2[pll_id_val].shift;
+
+	vco_freq = ((fmeter_dev_ptr->crystal_freq >> prediv_val) *
+		(sdmpcw_val >> 8)) >>
+		posdiv_val >> ckdiv4_val >> pll_md_val >> cldiv2_val;
+
+	return decode_freq(vco_freq);
+}
+
+/*
+ * mtk_dramc_get_data_rate - calculate DRAM data rate
+ *
+ * Return DRAM data rate (MB/s)
+ */
+unsigned int mtk_dramc_get_data_rate(void)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+	struct fmeter_dev_t *fmeter_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	fmeter_dev_ptr = (struct fmeter_dev_t *)dramc_dev_ptr->fmeter_dev_ptr;
+	if (!fmeter_dev_ptr)
+		return 0;
+
+	return fmeter_v0(dramc_dev_ptr);
+}
+EXPORT_SYMBOL(mtk_dramc_get_data_rate);
+
+static unsigned int mr4_v1(struct dramc_dev_t *dramc_dev_ptr, unsigned int ch)
+{
+	struct mr4_dev_t *mr4_dev_ptr =
+		(struct mr4_dev_t *)dramc_dev_ptr->mr4_dev_ptr;
+
+	return (readl(dramc_dev_ptr->dramc_chn_base_nao[ch] +
+		mr4_dev_ptr->mr4_rg.offset) & mr4_dev_ptr->mr4_rg.mask) >>
+		mr4_dev_ptr->mr4_rg.shift;
+}
+
+/*
+ * mtk_dramc_get_mr4 - get the DRAM MR4 value of specific DRAM channel
+ * @ch:	the channel index
+ *
+ * Return the MR4 value
+ */
+unsigned int mtk_dramc_get_mr4(unsigned int ch)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+	struct mr4_dev_t *mr4_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	mr4_dev_ptr = (struct mr4_dev_t *)dramc_dev_ptr->mr4_dev_ptr;
+	if (!mr4_dev_ptr)
+		return 0;
+
+	if (ch >= dramc_dev_ptr->channel_cnt)
+		return 0;
+
+	return mr4_v1(dramc_dev_ptr, ch);
+}
+EXPORT_SYMBOL(mtk_dramc_get_mr4);
+
+/*
+ * mtk_dramc_get_ddr_type - get DRAM type
+ *
+ * Return the DRAM type
+ */
+unsigned int mtk_dramc_get_ddr_type(void)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	return dramc_dev_ptr->dram_type;
+}
+EXPORT_SYMBOL(mtk_dramc_get_ddr_type);
+
+/*
+ * mtk_dramc_get_channel_count - get DRAM channel count
+ *
+ * Return the DRAM channel count
+ */
+unsigned int mtk_dramc_get_channel_count(void)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	return dramc_dev_ptr->channel_cnt;
+}
+EXPORT_SYMBOL(mtk_dramc_get_channel_count);
+
+/*
+ * mtk_dramc_get_rank_count - get DRAM rank count
+ *
+ * Return the DRAM rank count
+ */
+unsigned int mtk_dramc_get_rank_count(void)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	return dramc_dev_ptr->rank_cnt;
+}
+EXPORT_SYMBOL(mtk_dramc_get_rank_count);
+
+/*
+ * mtk_dramc_get_rank_size - get size of DRAM rank
+ *
+ * Return the size of specific DRAM rank
+ */
+unsigned int mtk_dramc_get_rank_size(unsigned int rank)
+{
+	struct dramc_dev_t *dramc_dev_ptr;
+
+	dramc_dev_ptr = mtk_dramc_get_drvdata_by_ids();
+
+	if (!dramc_dev_ptr)
+		return 0;
+
+	if (rank < dramc_dev_ptr->rank_cnt)
+		return dramc_dev_ptr->rank_size[rank];
+	else
+		return 0;
+}
+EXPORT_SYMBOL(mtk_dramc_get_rank_size);
+
+static int dramc_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver dramc_drv = {
+	.probe = dramc_probe,
+	.remove = dramc_remove,
+	.driver = {
+		.name = DRAMC_DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_dramc_of_ids,
+	},
+};
+
+static int __init dramc_drv_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&dramc_drv);
+	if (ret) {
+		pr_info("%s: init fail, ret 0x%x\n", __func__, ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void __exit dramc_drv_exit(void)
+{
+	platform_driver_unregister(&dramc_drv);
+}
+
+module_init(dramc_drv_init);
+module_exit(dramc_drv_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek DRAMC Driver");
+MODULE_AUTHOR("Po-Kai Chi <pk.chi@mediatek.com>");
diff --git a/include/memory/mediatek/dramc.h b/include/memory/mediatek/dramc.h
new file mode 100644
index 0000000..c8d200f
--- /dev/null
+++ b/include/memory/mediatek/dramc.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __DRAMC_H__
+#define __DRAMC_H__
+
+int mtk_dramc_get_steps_freq(unsigned int step);
+unsigned int mtk_dramc_get_ddr_type(void);
+unsigned int mtk_dramc_get_data_rate(void);
+unsigned int mtk_dramc_get_mr4(unsigned int ch);
+unsigned int mtk_dramc_get_channel_count(void);
+unsigned int mtk_dramc_get_rank_count(void);
+unsigned int mtk_dramc_get_rank_size(unsigned int rk);
+
+#endif /* __DRAMC_H__ */
+
-- 
1.7.9.5


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

* [PATCH v1 3/4] arm64: dts: add DRAMC node for MT6779
  2021-03-30  5:22 [PATCH v1] memory: mediatek: add DRAM controller driver Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 2/4] memory: mediatek: add DRAM controller driver Po-Kai Chi
@ 2021-03-30  5:22 ` Po-Kai Chi
  2021-03-30  5:22 ` [PATCH v1 4/4] arm64: defconfig: Enable MediaTek DRAMC common driver Po-Kai Chi
  3 siblings, 0 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-03-30  5:22 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	wsd_upstream, CC Hwang, Loda Chou, Po-Kai Chi

Add the DRAMC node for the DRAMC kernel driver.

Properties are divided into three categories:
  - Platform DTS:
      MediaTek DRAMC platform common part.

  - Project DTS:
      Runtime filled in by bootloader according to the board
      hardware configuration.

  - Driver level:
      Hardware-specific register settings, encapsulated as
      compatible data for better DTS compatibility.

Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt6779-evb.dts |    9 +++++++++
 arch/arm64/boot/dts/mediatek/mt6779.dtsi    |   18 ++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6779-evb.dts b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
index 164f5cb..9a556ad 100644
--- a/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
@@ -29,3 +29,12 @@
 &uart0 {
 	status = "okay";
 };
+
+&dramc {
+	dram_type = <0>;
+	channel_cnt = <2>;
+	rank_cnt = <2>;
+	rank_size = <0x0 0x0>;
+	mr_cnt = <1>;
+	mr = <0x5 0xff>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
index 9bdf514..332d48d 100644
--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
@@ -206,6 +206,24 @@
 			clock-names = "devapc-infra-clock";
 		};
 
+		dramc: dramc@10230000 {
+			compatible = "mediatek,mt6779-dramc";
+			reg = <0 0x10230000 0 0x2000>, /* DRAMC AO CHA */
+				<0 0x10240000 0 0x2000>, /* DRAMC AO CHB */
+				<0 0x10234000 0 0x1000>, /* DRAMC NAO CHA */
+				<0 0x10244000 0 0x1000>, /* DRAMC NAO CHB */
+				<0 0x10238000 0 0x2000>, /* DDRPHY AO CHA */
+				<0 0x10248000 0 0x2000>; /* DDRPHY AO CHB */
+			support_channel_cnt = <2>;
+			freq_cnt = <6>;
+			freq_step = <3718 3733>,
+				<3094 3200>,
+				<2392 2400>,
+				<1534 1600>,
+				<1196 1200>,
+				<754 800>;
+		};
+
 		uart0: serial@11002000 {
 			compatible = "mediatek,mt6779-uart",
 				     "mediatek,mt6577-uart";
-- 
1.7.9.5


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

* [PATCH v1 4/4] arm64: defconfig: Enable MediaTek DRAMC common driver
  2021-03-30  5:22 [PATCH v1] memory: mediatek: add DRAM controller driver Po-Kai Chi
                   ` (2 preceding siblings ...)
  2021-03-30  5:22 ` [PATCH v1 3/4] arm64: dts: add DRAMC node for MT6779 Po-Kai Chi
@ 2021-03-30  5:22 ` Po-Kai Chi
  3 siblings, 0 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-03-30  5:22 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	wsd_upstream, CC Hwang, Loda Chou, Po-Kai Chi

This commit enables MediaTek DRAMC common driver to be built
as a module by default for the ARM64 builds.

Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
---
 arch/arm64/configs/defconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d612f63..49d7464 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1163,3 +1163,4 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_MEMTEST=y
+CONFIG_MTK_DRAMC=m
-- 
1.7.9.5


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

* Re: [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller
  2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
@ 2021-03-30 13:08   ` Rob Herring
  2021-03-30 13:58   ` Rob Herring
  1 sibling, 0 replies; 8+ messages in thread
From: Rob Herring @ 2021-03-30 13:08 UTC (permalink / raw)
  To: Po-Kai Chi
  Cc: wsd_upstream, CC Hwang, linux-kernel, Matthias Brugger,
	linux-arm-kernel, linux-mediatek, devicetree, Loda Chou

On Tue, 30 Mar 2021 13:22:08 +0800, Po-Kai Chi wrote:
> This patch adds the documentation of the device-tree binding for
> MediaTek Common DRAM Controller.
> 
> Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
> ---
>  .../memory-controllers/mediatek,dramc.yaml         |  155 ++++++++++++++++++++
>  1 file changed, 155 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.example.dts:43.3-44.1 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:377: Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1414: dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1459879

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


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

* Re: [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller
  2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
  2021-03-30 13:08   ` Rob Herring
@ 2021-03-30 13:58   ` Rob Herring
  2021-04-01  8:52     ` Po-Kai Chi
  1 sibling, 1 reply; 8+ messages in thread
From: Rob Herring @ 2021-03-30 13:58 UTC (permalink / raw)
  To: Po-Kai Chi
  Cc: Matthias Brugger, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, wsd_upstream, CC Hwang, Loda Chou

On Tue, Mar 30, 2021 at 01:22:08PM +0800, Po-Kai Chi wrote:
> This patch adds the documentation of the device-tree binding for
> MediaTek Common DRAM Controller.
> 
> Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
> ---
>  .../memory-controllers/mediatek,dramc.yaml         |  155 ++++++++++++++++++++
>  1 file changed, 155 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> new file mode 100644
> index 0000000..0217ce0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> @@ -0,0 +1,155 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (c) 2021 MediaTek Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/mediatek,dramc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek DRAM Controller
> +
> +maintainers:
> +  - Po-Kai Chi <pk.chi@mediatek.com>
> +
> +description: |
> +  MediaTek DRAM controller (DRAMC) provides an interface to query information
> +  about DRAM which collected from bootloader and device tree.
> +  This is mainly used by MediaTek Extended Memory Interface (EMI) and DVFS Resource
> +  Control (DVFSRC).
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt6779-dramc
> +
> +  reg:
> +    description:
> +      Base address of MediaTek DRAM related hardware modules, each channel has
> +      its own base address in order of
> +      DRAMC_AO_{CH}, DRAMC_NAO_{CH}, DDRPHY_AO_{CH}.
> +    minItems: 3            # 3 * N channels
> +    maxItems: 6
> +
> +  dram_type:

These need to be either common or have a vendor prefix.

Also, s/_/-/

> +    description:
> +      The DRAM type of current DRAM chip.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 7
> +
> +  support_channel_cnt:
> +    description:
> +      The maximum DRAM channel count supported by SoC.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 1
> +    maximum: 4
> +
> +  channel_cnt:
> +    description:
> +      The DRAM channel count of current DRAM chip.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 1
> +    maximum: 4
> +
> +  rank_cnt:
> +    description:
> +      The DRAM rank count of current DRAM chip.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 1
> +    maximum: 2
> +
> +  rank_size:
> +    description:
> +      The size of each DRAM rank.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint64
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      minimum: 0x0
> +      maximum: 0x100000000    # support up to 4GB in single rank
> +
> +  mr_cnt:
> +    description:
> +      Specifies how many sets of DRAM mode register information to provide.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    maximum: 40    # total 40 MRs for JEDEC LPDDR4X
> +
> +  mr:
> +    description:
> +      Pair of DRAM mode register information.
> +      This property is filled in by bootloader according to the board hardware
> +      configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> +    maxItems: 40    # align with mr_cnt
> +    items:
> +      items:
> +        - description:
> +            Mode register index
> +        - description:
> +            Mode register value
> +
> +  freq_cnt:
> +    description:
> +      Specifies how many sets of DRAM data clock rate supported by SoC.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  freq_step:
> +    description:
> +      The DRAM data clock rate may be slightly different from those defined
> +      by the specification due to errors in multiples of the base frequency.
> +      This describe the mapping from real data clock rate measured by
> +      frequency meter to JEDEC data clock rate.
> +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> +    items:
> +      items:
> +        - description:
> +            Real data rate
> +        - description:
> +            Spec data rate

Looks like an OPP table.

> +
> +required:
> +  - compatible
> +  - reg
> +  - dram_type
> +  - support_channel_cnt
> +  - channel_cnt
> +  - rank_cnt
> +  - mr_cnt
> +  - freq_cnt
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dramc@10230000 {
> +        compatible = "mediatek,mt6779-dramc";
> +        reg = <0 0x10230000 0 0x2000>, /* DRAMC AO CHA */
> +            <0 0x10240000 0 0x2000>,   /* DRAMC AO CHB */
> +            <0 0x10234000 0 0x1000>,   /* DRAMC NAO CHA */
> +            <0 0x10244000 0 0x1000>,   /* DRAMC NAO CHB */
> +            <0 0x10238000 0 0x2000>,   /* DDRPHY AO CHA */
> +            <0 0x10248000 0 0x2000>;   /* DDRPHY AO CHB */
> +        dram_type = <0>;
> +        support_channel_cnt = <2>;
> +        channel_cnt = <2>;
> +        rank_cnt = <2>;
> +        rank_size = <0x40000000 0x40000000>;

You defined this as 64-bit, so this is a single value?

> +        mr_cnt = <1>;
> +        mr = <0x5 0xff>;
> +        freq_cnt = <6>;
> +        freq_step = <3718 3733>,
> +                <3094 3200>,
> +                <2392 2400>,
> +                <1534 1600>,
> +                <1196 1200>,
> +                <754 800>;
> +    };
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller
  2021-03-30 13:58   ` Rob Herring
@ 2021-04-01  8:52     ` Po-Kai Chi
  0 siblings, 0 replies; 8+ messages in thread
From: Po-Kai Chi @ 2021-04-01  8:52 UTC (permalink / raw)
  To: Rob Herring
  Cc: Matthias Brugger, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, wsd_upstream, CC Hwang (黃致銓),
	Loda Chou (周宏霖)

Hello Rob,

Thanks for the remind about dt_binding_check fail and the comments, my
reply is as follows and will fix it in the next version (v2).


Po-Kai

On Tue, 2021-03-30 at 21:58 +0800, Rob Herring wrote:
> On Tue, Mar 30, 2021 at 01:22:08PM +0800, Po-Kai Chi wrote:
> > This patch adds the documentation of the device-tree binding for
> > MediaTek Common DRAM Controller.
> > 
> > Signed-off-by: Po-Kai Chi <pk.chi@mediatek.com>
> > ---
> >  .../memory-controllers/mediatek,dramc.yaml         |  155 ++++++++++++++++++++
> >  1 file changed, 155 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> > new file mode 100644
> > index 0000000..0217ce0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,dramc.yaml
> > @@ -0,0 +1,155 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +# Copyright (c) 2021 MediaTek Inc.
> > +%YAML 1.2
> > +---
> > +$id: https://urldefense.com/v3/__http://devicetree.org/schemas/memory-controllers/mediatek,dramc.yaml*__;Iw!!CTRNKA9wMg0ARbw!y9zM5d-aNLK99Y_ag2yvqq3TI1Xvm6TV_Vu03VVD3Qbe69N1qZXFFk2DUFb6CG0$ 
> > +$schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!y9zM5d-aNLK99Y_ag2yvqq3TI1Xvm6TV_Vu03VVD3Qbe69N1qZXFFk2DiMad89A$ 
> > +
> > +title: MediaTek DRAM Controller
> > +
> > +maintainers:
> > +  - Po-Kai Chi <pk.chi@mediatek.com>
> > +
> > +description: |
> > +  MediaTek DRAM controller (DRAMC) provides an interface to query information
> > +  about DRAM which collected from bootloader and device tree.
> > +  This is mainly used by MediaTek Extended Memory Interface (EMI) and DVFS Resource
> > +  Control (DVFSRC).
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - mediatek,mt6779-dramc
> > +
> > +  reg:
> > +    description:
> > +      Base address of MediaTek DRAM related hardware modules, each channel has
> > +      its own base address in order of
> > +      DRAMC_AO_{CH}, DRAMC_NAO_{CH}, DDRPHY_AO_{CH}.
> > +    minItems: 3            # 3 * N channels
> > +    maxItems: 6
> > +
> > +  dram_type:
> 
> These need to be either common or have a vendor prefix.
> 
> Also, s/_/-/

Okay, I have revised the naming rule according to writing-schema.rst.

> > +    description:
> > +      The DRAM type of current DRAM chip.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    minimum: 0
> > +    maximum: 7
> > +
> > +  support_channel_cnt:
> > +    description:
> > +      The maximum DRAM channel count supported by SoC.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    minimum: 1
> > +    maximum: 4
> > +
> > +  channel_cnt:
> > +    description:
> > +      The DRAM channel count of current DRAM chip.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    minimum: 1
> > +    maximum: 4
> > +
> > +  rank_cnt:
> > +    description:
> > +      The DRAM rank count of current DRAM chip.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    minimum: 1
> > +    maximum: 2
> > +
> > +  rank_size:
> > +    description:
> > +      The size of each DRAM rank.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint64

There may be some misunderstanding.
rank_size uses the full 64 bits to describe the size of each DRAM rank.
So the type of rank_size should be uint64-array, instead of uint64.

> > +    minItems: 1
> > +    maxItems: 2
> > +    items:
> > +      minimum: 0x0
> > +      maximum: 0x100000000    # support up to 4GB in single rank
> > +
> > +  mr_cnt:
> > +    description:
> > +      Specifies how many sets of DRAM mode register information to provide.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    maximum: 40    # total 40 MRs for JEDEC LPDDR4X
> > +
> > +  mr:
> > +    description:
> > +      Pair of DRAM mode register information.
> > +      This property is filled in by bootloader according to the board hardware
> > +      configuration.
> > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > +    maxItems: 40    # align with mr_cnt
> > +    items:
> > +      items:
> > +        - description:
> > +            Mode register index
> > +        - description:
> > +            Mode register value
> > +
> > +  freq_cnt:
> > +    description:
> > +      Specifies how many sets of DRAM data clock rate supported by SoC.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +
> > +  freq_step:
> > +    description:
> > +      The DRAM data clock rate may be slightly different from those defined
> > +      by the specification due to errors in multiples of the base frequency.
> > +      This describe the mapping from real data clock rate measured by
> > +      frequency meter to JEDEC data clock rate.
> > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > +    items:
> > +      items:
> > +        - description:
> > +            Real data rate
> > +        - description:
> > +            Spec data rate
> 
> Looks like an OPP table.

Yes, It's essentially an OPP table, but also records the relationship
between real data rate and spec data rate.

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - dram_type
> > +  - support_channel_cnt
> > +  - channel_cnt
> > +  - rank_cnt
> > +  - mr_cnt
> > +  - freq_cnt
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    dramc@10230000 {
> > +        compatible = "mediatek,mt6779-dramc";
> > +        reg = <0 0x10230000 0 0x2000>, /* DRAMC AO CHA */
> > +            <0 0x10240000 0 0x2000>,   /* DRAMC AO CHB */
> > +            <0 0x10234000 0 0x1000>,   /* DRAMC NAO CHA */
> > +            <0 0x10244000 0 0x1000>,   /* DRAMC NAO CHB */
> > +            <0 0x10238000 0 0x2000>,   /* DDRPHY AO CHA */
> > +            <0 0x10248000 0 0x2000>;   /* DDRPHY AO CHB */
> > +        dram_type = <0>;
> > +        support_channel_cnt = <2>;
> > +        channel_cnt = <2>;
> > +        rank_cnt = <2>;
> > +        rank_size = <0x40000000 0x40000000>;
> 
> You defined this as 64-bit, so this is a single value?

No, these are independent values.I have updated the description of this
property in the previous paragraph.

And the sample will be updated to
mediatek,rank-size = <0x40000000>, <0x40000000>;

> 
> > +        mr_cnt = <1>;
> > +        mr = <0x5 0xff>;
> > +        freq_cnt = <6>;
> > +        freq_step = <3718 3733>,
> > +                <3094 3200>,
> > +                <2392 2400>,
> > +                <1534 1600>,
> > +                <1196 1200>,
> > +                <754 800>;
> > +    };
> > -- 
> > 1.7.9.5
> > 


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

end of thread, other threads:[~2021-04-01  8:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-30  5:22 [PATCH v1] memory: mediatek: add DRAM controller driver Po-Kai Chi
2021-03-30  5:22 ` [PATCH v1 1/4] dt-bindings: memory: Add binding for MediaTek Common DRAM Controller Po-Kai Chi
2021-03-30 13:08   ` Rob Herring
2021-03-30 13:58   ` Rob Herring
2021-04-01  8:52     ` Po-Kai Chi
2021-03-30  5:22 ` [PATCH v1 2/4] memory: mediatek: add DRAM controller driver Po-Kai Chi
2021-03-30  5:22 ` [PATCH v1 3/4] arm64: dts: add DRAMC node for MT6779 Po-Kai Chi
2021-03-30  5:22 ` [PATCH v1 4/4] arm64: defconfig: Enable MediaTek DRAMC common driver Po-Kai Chi

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).