[PATCH v5 05/10] ram: cadence: add driver for Cadence EDAC

2023-05-12 Thread Ralph Siemsen
Driver for Cadence EDAC DDR controller, as found in the Renesas RZ/N1.

Signed-off-by: Ralph Siemsen 
---

Changes in v6:
- use wait_for_bit macros instead of endless while loop

Changes in v5:
- move board-specific init out of the driver.

Changes in v3:
- assorted small cleanups
- support version 1.0 silicon (previously #if 0...)

 drivers/ram/Kconfig|   1 +
 drivers/ram/Makefile   |   2 +
 drivers/ram/cadence/Kconfig|  12 +
 drivers/ram/cadence/Makefile   |   1 +
 drivers/ram/cadence/ddr_ctrl.c | 414 +
 include/renesas/ddr_ctrl.h | 175 ++
 6 files changed, 605 insertions(+)
 create mode 100644 drivers/ram/cadence/Kconfig
 create mode 100644 drivers/ram/cadence/Makefile
 create mode 100644 drivers/ram/cadence/ddr_ctrl.c
 create mode 100644 include/renesas/ddr_ctrl.h

diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 1acf212f87..bf99964577 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -108,6 +108,7 @@ config IMXRT_SDRAM
  This driver is for the sdram memory interface with the SEMC.
 
 source "drivers/ram/aspeed/Kconfig"
+source "drivers/ram/cadence/Kconfig"
 source "drivers/ram/rockchip/Kconfig"
 source "drivers/ram/sifive/Kconfig"
 source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 2b9429cfee..b281129f89 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -24,3 +24,5 @@ ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_STARFIVE_DDR) += starfive/
 endif
 obj-$(CONFIG_ARCH_OCTEON) += octeon/
+
+obj-$(CONFIG_CADENCE_DDR_CTRL) += cadence/
diff --git a/drivers/ram/cadence/Kconfig b/drivers/ram/cadence/Kconfig
new file mode 100644
index 00..2d5469cb8e
--- /dev/null
+++ b/drivers/ram/cadence/Kconfig
@@ -0,0 +1,12 @@
+if RAM || SPL_RAM
+
+config CADENCE_DDR_CTRL
+   bool "Enable Cadence DDR controller"
+   depends on DM
+   help
+ Enable support for Cadence DDR controller, as found on
+ the Renesas RZ/N1 SoC. This controller has a large number
+ of registers which need to be programmed, mostly using values
+ obtained from Denali SOMA files via a TCL script.
+
+endif
diff --git a/drivers/ram/cadence/Makefile b/drivers/ram/cadence/Makefile
new file mode 100644
index 00..b4226cf6f2
--- /dev/null
+++ b/drivers/ram/cadence/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CADENCE_DDR_CTRL) += ddr_ctrl.o
diff --git a/drivers/ram/cadence/ddr_ctrl.c b/drivers/ram/cadence/ddr_ctrl.c
new file mode 100644
index 00..3e5959a84a
--- /dev/null
+++ b/drivers/ram/cadence/ddr_ctrl.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Cadence DDR Controller
+ *
+ * Copyright (C) 2015 Renesas Electronics Europe Ltd
+ */
+
+/*
+ * The Cadence DDR Controller has a huge number of registers that principally
+ * cover two aspects, DDR specific timing information and AXI bus interfacing.
+ * Cadence's TCL script generates all of the register values for specific
+ * DDR devices operating at a specific frequency. The TCL script uses Denali
+ * SOMA files as inputs. The tool also generates the AXI bus register values as
+ * well, however this driver assumes that users will want to modifiy these to
+ * meet a specific application's needs.
+ * Therefore, this driver is passed two arrays containing register values for
+ * the DDR device specific information, and explicity sets the AXI registers.
+ *
+ * AXI bus interfacing:
+ *  The controller has four AXI slaves connections, and each of these can be
+ * programmed to accept requests from specific AXI masters (using their IDs).
+ * The regions of DDR that can be accessed by each AXI slave can be set such
+ * as to isolate DDR used by one AXI master from another. Further, the maximum
+ * bandwidth allocated to each AXI slave can be set.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* avoid warning for real pr_debug in  */
+#ifdef pr_debug
+#undef pr_debug
+#endif
+
+#ifdef DEBUG
+   #define pr_debug(fmt, args...)  printf(fmt, ##args)
+   #define pr_debug2(fmt, args...) printf(fmt, ##args)
+#else
+   #define pr_debug(fmt, args...)
+   #define pr_debug2(fmt, args...)
+#endif
+
+#define DDR_NR_AXI_PORTS   4
+#define DDR_NR_ENTRIES 16
+
+#define DDR_START_REG  (0) /* DENALI_CTL_00 */
+#define DDR_CS0_MR1_REG(32 * 4)/* 
DENALI_CTL_32 */
+#define DDR_CS0_MR2_REG(32 * 4 + 2)/* 
DENALI_CTL_32 */
+#define DDR_CS1_MR1_REG(34 * 4 + 2)/* 
DENALI_CTL_34 */
+#define DDR_CS1_MR2_REG(35 * 4)/* 
DENALI_CTL_35 */
+#define DDR_ECC_ENABLE_REG (36 * 4 + 2)/* DENALI_CTL_36 */
+#define DDR_ECC_DISABLE_W_UC_ERR_REG   (37 * 4 + 2)/* DENALI_CTL_37 */
+#define DDR_HALF_DATAPATH_REG  (54 * 4)/* DENALI_CTL_54 */
+#define DDR_INTERRUPT_STATUS 

Re: [PATCH v5 05/10] ram: cadence: add driver for Cadence EDAC

2023-05-07 Thread Marek Vasut

On 4/24/23 03:15, Ralph Siemsen wrote:

[...]


diff --git a/drivers/ram/cadence/ddr_ctrl.c b/drivers/ram/cadence/ddr_ctrl.c
new file mode 100644
index 00..35544fbb95
--- /dev/null
+++ b/drivers/ram/cadence/ddr_ctrl.c


[...]


+void cdns_ddr_ctrl_start(void *ddr_ctrl_basex)
+{
+   u32 *ddr_ctrl_base = (u32 *)ddr_ctrl_basex;
+   u8 *base8 = (u8 *)ddr_ctrl_basex;
+
+   /* Start */
+   ddrc_writeb(1, base8 + DDR_START_REG);
+
+   /* Wait for controller to be ready (interrupt status) */
+   while (!(readl(base8 + DDR_INTERRUPT_STATUS) & 0x100))
+   ;


If you can, use readl_poll_timeout() or wait_for_bit*() to avoid endless 
loops .


[PATCH v5 05/10] ram: cadence: add driver for Cadence EDAC

2023-04-23 Thread Ralph Siemsen
Driver for Cadence EDAC DDR controller, as found in the Renesas RZ/N1.

Signed-off-by: Ralph Siemsen 
---

Changes in v5:
- move board-specific init out of the driver.

Changes in v3:
- assorted small cleanups
- support version 1.0 silicon (previously #if 0...)

 drivers/ram/Kconfig|   1 +
 drivers/ram/Makefile   |   2 +
 drivers/ram/cadence/Kconfig|  12 +
 drivers/ram/cadence/Makefile   |   1 +
 drivers/ram/cadence/ddr_ctrl.c | 414 +
 include/renesas/ddr_ctrl.h | 175 ++
 6 files changed, 605 insertions(+)
 create mode 100644 drivers/ram/cadence/Kconfig
 create mode 100644 drivers/ram/cadence/Makefile
 create mode 100644 drivers/ram/cadence/ddr_ctrl.c
 create mode 100644 include/renesas/ddr_ctrl.h

diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 1acf212f87..bf99964577 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -108,6 +108,7 @@ config IMXRT_SDRAM
  This driver is for the sdram memory interface with the SEMC.
 
 source "drivers/ram/aspeed/Kconfig"
+source "drivers/ram/cadence/Kconfig"
 source "drivers/ram/rockchip/Kconfig"
 source "drivers/ram/sifive/Kconfig"
 source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 2b9429cfee..b281129f89 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -24,3 +24,5 @@ ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_STARFIVE_DDR) += starfive/
 endif
 obj-$(CONFIG_ARCH_OCTEON) += octeon/
+
+obj-$(CONFIG_CADENCE_DDR_CTRL) += cadence/
diff --git a/drivers/ram/cadence/Kconfig b/drivers/ram/cadence/Kconfig
new file mode 100644
index 00..2d5469cb8e
--- /dev/null
+++ b/drivers/ram/cadence/Kconfig
@@ -0,0 +1,12 @@
+if RAM || SPL_RAM
+
+config CADENCE_DDR_CTRL
+   bool "Enable Cadence DDR controller"
+   depends on DM
+   help
+ Enable support for Cadence DDR controller, as found on
+ the Renesas RZ/N1 SoC. This controller has a large number
+ of registers which need to be programmed, mostly using values
+ obtained from Denali SOMA files via a TCL script.
+
+endif
diff --git a/drivers/ram/cadence/Makefile b/drivers/ram/cadence/Makefile
new file mode 100644
index 00..b4226cf6f2
--- /dev/null
+++ b/drivers/ram/cadence/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CADENCE_DDR_CTRL) += ddr_ctrl.o
diff --git a/drivers/ram/cadence/ddr_ctrl.c b/drivers/ram/cadence/ddr_ctrl.c
new file mode 100644
index 00..35544fbb95
--- /dev/null
+++ b/drivers/ram/cadence/ddr_ctrl.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Cadence DDR Controller
+ *
+ * Copyright (C) 2015 Renesas Electronics Europe Ltd
+ */
+
+/*
+ * The Cadence DDR Controller has a huge number of registers that principally
+ * cover two aspects, DDR specific timing information and AXI bus interfacing.
+ * Cadence's TCL script generates all of the register values for specific
+ * DDR devices operating at a specific frequency. The TCL script uses Denali
+ * SOMA files as inputs. The tool also generates the AXI bus register values as
+ * well, however this driver assumes that users will want to modifiy these to
+ * meet a specific application's needs.
+ * Therefore, this driver is passed two arrays containing register values for
+ * the DDR device specific information, and explicity sets the AXI registers.
+ *
+ * AXI bus interfacing:
+ *  The controller has four AXI slaves connections, and each of these can be
+ * programmed to accept requests from specific AXI masters (using their IDs).
+ * The regions of DDR that can be accessed by each AXI slave can be set such
+ * as to isolate DDR used by one AXI master from another. Further, the maximum
+ * bandwidth allocated to each AXI slave can be set.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* avoid warning for real pr_debug in  */
+#ifdef pr_debug
+#undef pr_debug
+#endif
+
+#ifdef DEBUG
+   #define pr_debug(fmt, args...)  printf(fmt, ##args)
+   #define pr_debug2(fmt, args...) printf(fmt, ##args)
+#else
+   #define pr_debug(fmt, args...)
+   #define pr_debug2(fmt, args...)
+#endif
+
+#define DDR_NR_AXI_PORTS   4
+#define DDR_NR_ENTRIES 16
+
+#define DDR_START_REG  (0) /* DENALI_CTL_00 */
+#define DDR_CS0_MR1_REG(32 * 4)/* 
DENALI_CTL_32 */
+#define DDR_CS0_MR2_REG(32 * 4 + 2)/* 
DENALI_CTL_32 */
+#define DDR_CS1_MR1_REG(34 * 4 + 2)/* 
DENALI_CTL_34 */
+#define DDR_CS1_MR2_REG(35 * 4)/* 
DENALI_CTL_35 */
+#define DDR_ECC_ENABLE_REG (36 * 4 + 2)/* DENALI_CTL_36 */
+#define DDR_ECC_DISABLE_W_UC_ERR_REG   (37 * 4 + 2)/* DENALI_CTL_37 */
+#define DDR_HALF_DATAPATH_REG  (54 * 4)/* DENALI_CTL_54 */
+#define DDR_INTERRUPT_STATUS   (56 * 4)/* DENALI_CTL_56 */
+#define DDR_INTERRUPT_ACK