ram: renesas: Add Renesas R-Car Gen4 DBSC5 driver
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Thu, 12 Dec 2024 13:34:30 +0000 (14:34 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 29 Dec 2024 15:55:31 +0000 (16:55 +0100)
Add Renesas R-Car Gen4 DBSC5 DRAM controller driver. This driver is currently
capable of bringing LPDDR5 DRAM on Renesas R-Car V4H Whitehawk board. Further
boards can be supported by supplying board specific DRAM configuration data
via dbsc5_get_board_data(). Support for R-Car V4M is not implemented, however
the driver is already mostly prepared to support this SoC.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
drivers/ram/Kconfig
drivers/ram/renesas/Kconfig [new file with mode: 0644]
drivers/ram/renesas/Makefile
drivers/ram/renesas/dbsc5/Makefile [new file with mode: 0644]
drivers/ram/renesas/dbsc5/dbsc5.c [new file with mode: 0644]
drivers/ram/renesas/dbsc5/dbsc5.h [new file with mode: 0644]
drivers/ram/renesas/dbsc5/dram.c [new file with mode: 0644]
drivers/ram/renesas/dbsc5/qos.c [new file with mode: 0644]
drivers/ram/renesas/dbsc5/rtvram.c [new file with mode: 0644]

index f7e357f..2b0cd31 100644 (file)
@@ -119,6 +119,7 @@ config IMXRT_SDRAM
 source "drivers/ram/aspeed/Kconfig"
 source "drivers/ram/cadence/Kconfig"
 source "drivers/ram/octeon/Kconfig"
+source "drivers/ram/renesas/Kconfig"
 source "drivers/ram/rockchip/Kconfig"
 source "drivers/ram/sifive/Kconfig"
 source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/renesas/Kconfig b/drivers/ram/renesas/Kconfig
new file mode 100644 (file)
index 0000000..6a1ef2a
--- /dev/null
@@ -0,0 +1,7 @@
+config RAM_RENESAS_DBSC5
+       bool "Renesas R-Car V4H/V4M DBSC5 controller driver"
+       depends on SPL && RAM && (R8A779G0 || R8A779H0)
+       default n
+       help
+         Enable this to support the DBSC5 DRAM controller initialization
+         on Renesas R8A779G0/R8A779H0 SoCs.
index 705cc4b..578d056 100644 (file)
@@ -1,3 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+ifdef CONFIG_XPL_BUILD
+obj-$(CONFIG_RAM_RENESAS_DBSC5)        += dbsc5/
+endif
 obj-$(CONFIG_RZN1)     += rzn1/
diff --git a/drivers/ram/renesas/dbsc5/Makefile b/drivers/ram/renesas/dbsc5/Makefile
new file mode 100644 (file)
index 0000000..177be89
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y  += dbsc5.o dram.o qos.o rtvram.o
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.c b/drivers/ram/renesas/dbsc5/dbsc5.c
new file mode 100644 (file)
index 0000000..d24b7c5
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <linux/sizes.h>
+#include <ram.h>
+#include "dbsc5.h"
+
+static int renesas_dbsc5_probe(struct udevice *dev)
+{
+       struct udevice *pdev;
+       int ret;
+
+       ret = uclass_get_device_by_name(UCLASS_RAM, "dbsc5_dram", &pdev);
+       if (ret)
+               return ret;
+
+       ret = uclass_get_device_by_name(UCLASS_NOP, "dbsc5_qos", &pdev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+int renesas_dbsc5_bind(struct udevice *dev)
+{
+       struct udevice *ramdev, *qosdev;
+       struct driver *ramdrv, *qosdrv;
+       int ret;
+
+       ramdrv = lists_driver_lookup_name("dbsc5_dram");
+       if (!ramdrv)
+               return -ENOENT;
+
+
+       qosdrv = lists_driver_lookup_name("dbsc5_qos");
+       if (!qosdrv)
+               return -ENOENT;
+
+       ret = device_bind_with_driver_data(dev, ramdrv, "dbsc5_dram",
+                                          dev_get_driver_data(dev),
+                                          dev_ofnode(dev), &ramdev);
+       if (ret)
+               return ret;
+
+       ret = device_bind_with_driver_data(dev, qosdrv, "dbsc5_qos", 0,
+                                          dev_ofnode(dev), &qosdev);
+       if (ret)
+               device_unbind(ramdev);
+
+       return ret;
+}
+
+struct renesas_dbsc5_data r8a779g0_dbsc5_data = {
+       .clock_node = "renesas,r8a779g0-cpg-mssr",
+       .reset_node = "renesas,r8a779g0-rst"
+};
+
+static const struct udevice_id renesas_dbsc5_ids[] = {
+       {
+               .compatible = "renesas,r8a779g0-dbsc",
+               .data = (ulong)&r8a779g0_dbsc5_data
+       },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(renesas_dbsc5) = {
+       .name           = "dbsc5",
+       .id             = UCLASS_NOP,
+       .of_match       = renesas_dbsc5_ids,
+       .bind           = renesas_dbsc5_bind,
+       .probe          = renesas_dbsc5_probe,
+};
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.h b/drivers/ram/renesas/dbsc5/dbsc5.h
new file mode 100644 (file)
index 0000000..c410eb0
--- /dev/null
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#ifndef __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__
+#define __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__
+
+/*
+ * DBSC5 ... 0xe678_0000..0xe67fffff
+ * - AXMM_BASE         0xe6780000      MM (DDR Hier) MM AXI Router - Region 0
+ * - DBSC_A_BASE       0xe6790000      MM (DDR Hier) DBSC0A - Region 0
+ * - CCI_BASE          0xe67A0000      MM (DDR Hier) FBA for MM
+ * - DBSC_D_BASE       0xE67A4000      MM (DDR Hier) DBSC0D - Region 0
+ * - QOS_BASE          0xe67E0000      MM (DDR Hier) M-STATQ (64kiB)
+ */
+#define DBSC5_AXMM_OFFSET                      0x00000
+#define DBSC5_DBSC_A_OFFSET                    0x10000
+#define DBSC5_CCI_OFFSET                       0x20000
+#define DBSC5_DBSC_D_OFFSET                    0x24000
+#define DBSC5_QOS_OFFSET                       0x60000
+
+struct renesas_dbsc5_data {
+       const char              *clock_node;
+       const char              *reset_node;
+};
+
+#endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c
new file mode 100644 (file)
index 0000000..210a68f
--- /dev/null
@@ -0,0 +1,4532 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <hang.h>
+#include <ram.h>
+#include <linux/iopoll.h>
+#include <linux/sizes.h>
+#include "dbsc5.h"
+
+/* The number of channels V4H has */
+#define DRAM_CH_CNT                    4
+/* The number of slices V4H has */
+#define SLICE_CNT                      2
+/* The number of chip select V4H has */
+#define CS_CNT                         2
+
+/* Number of array elements in Data Slice */
+#define DDR_PHY_SLICE_REGSET_SIZE_V4H  0x100
+/* Number of array elements in Data Slice */
+#define DDR_PHY_SLICE_REGSET_NUM_V4H   153
+/* Number of array elements in Address Slice */
+#define DDR_PHY_ADR_V_REGSET_NUM_V4H   61
+/* Number of array elements in Address Control Slice */
+#define DDR_PHY_ADR_G_REGSET_NUM_V4H   97
+/* Number of array elements in PI Register */
+#define DDR_PI_REGSET_NUM_V4H          1381
+
+/* Minimum value table for JS1 configuration table that can be taken */
+#define JS1_USABLEC_SPEC_LO            5
+/* Maximum value table for JS1 configuration table that can be taken */
+#define JS1_USABLEC_SPEC_HI            11
+/* The number of JS1 setting table */
+#define JS1_FREQ_TBL_NUM               12
+/* Macro to set the value of MR1 */
+#define JS1_MR1(f)                     (((f) << 4) | 0x00) /* CK mode = 0B */
+/* Macro to set the value of MR2 */
+#define JS1_MR2(f)                     (((f) << 4) | (f))
+
+#define JS2_tSR                0       /* Element for self refresh */
+#define JS2_tXP                1       /* Exit power-down mode to first valid command */
+#define JS2_tRCD       2       /* Active to read or write delay */
+#define JS2_tRPpb      3       /* Minimum Row Precharge Delay Time */
+#define JS2_tRPab      4       /* Minimum Row Precharge Delay Time */
+#define JS2_tRAS       5       /* ACTIVE-to-PRECHARGE command */
+#define JS2_tWTR_S     6       /* Internal WRITE-to-READ command delay */
+#define JS2_tWTR_L     7       /* Internal WRITE-to-READ command delay */
+#define JS2_tRRD       8       /* Active bank a to active bank b command */
+#define JS2_tPPD       9       /* Precharge Power Down */
+#define JS2_tFAW       10      /* Four bank ACT window */
+#define JS2_tMRR       11      /* Mode Register Read */
+#define JS2_tMRW       12      /* Mode Register Write */
+#define JS2_tMRD       13      /* LOAD MODE REGISTER command cycle time */
+#define JS2_tZQCALns   14      /* ZQ Calibration */
+#define JS2_tZQLAT     15      /* ZQ Latency */
+#define JS2_tODTon_min 16      /* Minimum time on die termination */
+#define JS2_tPDN_DSM   17      /* Recommended minimum time for Deep Sleep Mode duration */
+#define JS2_tXSR_DSM   18      /* Required time to be fully re-powered up from Deep Sleep Mode */
+#define JS2_tXDSM_XP   19      /* Delay from Deep Sleep Mode Exit to Power-Down Exit */
+#define JS2_tWCK2DQI_HF        20      /* Setting value of DQ to WCK input offset */
+#define JS2_tWCK2DQO_HF        21      /* Setting value of WCK to DQ output offset */
+#define JS2_tWCK2DQI_LF        22      /* Setting value of DQ to WCK input offset */
+#define JS2_tWCK2DQO_LF        23      /* Setting value of WCK to DQ output offset */
+#define JS2_tOSCODQI   24      /* Delay time from Stop WCK2DQI Interval Oscillator command to Mode Register Readout */
+#define JS2_tDQ72DQns  25      /* Reception time to change the value fof REF(CA) for Command Bus Training Mode2 */
+#define JS2_tCAENTns   26      /* Reception time to change the value fof REF(CA) for Command Bus Training Mode1 */
+#define JS2_tCSCAL     27      /* Minimum CA Low Duration time */
+#define JS2_TBLCNT     28      /* The number of table */
+
+#define JS2_tRCpb      JS2_TBLCNT              /* ACTIVATE-to-ACTIVATE command period with per bank precharge */
+#define JS2_tRCab      (JS2_TBLCNT + 1)        /* ACTIVATE-to-ACTIVATE command period with all bank precharge */
+#define JS2_tRFCab     (JS2_TBLCNT + 2)        /* Refresh Cycle Time with All Banks */
+#define JS2_tRBTP      (JS2_TBLCNT + 3)        /* READ Burst end to PRECHARGE command delay */
+#define JS2_tXSR       (JS2_TBLCNT + 4)        /* Exit Self Refresh to Valid commands */
+#define JS2_tPDN       (JS2_TBLCNT + 5)
+#define JS2_tWLWCKOFF  (JS2_TBLCNT + 6)
+#define JS2_CNT                (JS2_TBLCNT + 7)
+
+struct jedec_spec1 {
+       u32 fx3;        /* Frequency */
+       u8 RLset1;      /* setting value of Read Latency */
+       u8 RLset2;      /* setting value of Read Latency */
+       u8 WLsetA;      /* setting value of Write Latency */
+       u8 WLsetB;      /* setting value of Write Latency */
+       u32 nWR;        /* Write-Recovery for Auto-Precharge commands */
+       u32 nRBTP;      /* the minimum interval from a READ command to a PRE command */
+       u32 ODTLon;     /* On Die Termination */
+       u8 MR1;         /* Mode Register 1 */
+       u8 MR2;         /* Mode Register 2 */
+       u32 WCKENLR;    /* The setting time from CAS command to the Start-up of WCK in READ operation */
+       u32 WCKENLW;    /* The setting time from CAS command to the Start-up of WCK in WRITE operation */
+       u32 WCKENLF;    /* The setting time from CAS command to the Start-up of WCK in FAST-sync operation */
+       u32 WCKPRESTA;  /* The setting time from the Start-up of WCK to WCK Clocling Start */
+       u32 WCKPRETGLR; /* The setting time from WCK Clocling Start to Reflecting frequency of WCK */
+};
+
+static const struct jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
+       /* fx3, RL1, RL2, WLA.WLB.nWR.nRBTP, ODTLon    */
+       {  800,  3,  3,  2,  2,  3, 0, 1, JS1_MR1(0),  JS1_MR2(0),  0, 0, 0, 1, 3 }, /*  533.333Mbps*/
+       { 1600,  4,  4,  2,  3,  5, 0, 1, JS1_MR1(1),  JS1_MR2(1),  0, 0, 0, 1, 4 }, /* 1066.666Mbps*/
+       { 2400,  5,  6,  3,  4,  7, 0, 2, JS1_MR1(2),  JS1_MR2(2),  1, 1, 1, 1, 4 }, /* 1600.000Mbps*/
+       { 3200,  7,  7,  4,  5, 10, 0, 2, JS1_MR1(3),  JS1_MR2(3),  2, 1, 1, 2, 4 }, /* 2133.333Mbps*/
+       { 4000,  8,  9,  4,  7, 12, 1, 2, JS1_MR1(4),  JS1_MR2(4),  2, 1, 1, 2, 5 }, /* 2666.666Mbps*/
+       { 4800, 10, 10,  5,  8, 14, 1, 3, JS1_MR1(5),  JS1_MR2(5),  4, 2, 1, 2, 5 }, /* 3200.000Mbps*/
+       { 5600, 11, 12,  6,  9, 16, 2, 4, JS1_MR1(6),  JS1_MR2(6),  4, 2, 1, 3, 5 }, /* 3733.333Mbps*/
+       { 6400, 13, 14,  6, 11, 19, 2, 3, JS1_MR1(7),  JS1_MR2(7),  5, 2, 1, 3, 6 }, /* 4266.666Mbps*/
+       { 7200, 14, 15,  7, 12, 21, 3, 4, JS1_MR1(8),  JS1_MR2(8),  6, 3, 2, 3, 6 }, /* 4800.000Mbps*/
+       { 8250, 16, 17,  8, 14, 24, 4, 5, JS1_MR1(9),  JS1_MR2(9),  7, 3, 2, 4, 6 }, /* 5500.000Mbps*/
+       { 9000, 17, 19,  9, 15, 26, 4, 6, JS1_MR1(10), JS1_MR2(10), 7, 4, 2, 4, 7 }, /* 6000.000Mbps*/
+       { 9600, 18, 20,  9, 16, 28, 4, 6, JS1_MR1(11), JS1_MR2(11), 8, 4, 2, 4, 7 }  /* 6400.000Mbps*/
+};
+
+struct jedec_spec2 {
+       u16 ps;         /* Value in pico seconds */
+       u16 cyc;        /* Value in cycle count */
+};
+
+static const struct jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = {
+       {
+               { 15000, 2 },   /* tSR */
+               { 7000, 3 },    /* tXP */
+               { 18000, 2 },   /* tRCD */
+               { 18000, 2 },   /* tRPpb */
+               { 21000, 2 },   /* tRPab */
+               { 42000, 3 },   /* tRAS */
+               { 6250, 4 },    /* tWTR_S */
+               { 12000, 4 },   /* tWTR_L */
+               { 5000, 2 },    /* tRRD */
+               { 0, 2 },       /* tPPD */
+               { 20000, 0 },   /* tFAW */
+               { 0, 4 },       /* tMRR */
+               { 10000, 5 },   /* tMRW */
+               { 14000, 5 },   /* tMRD */
+               { 1500, 0 },    /* tZQCALns */
+               { 30000, 4 },   /* tZQLAT */
+               { 1500, 0 },    /* tODTon_min */
+               { 4000, 0 },    /* tPDN_DSMus */
+               { 200, 0 },     /* tXSR_DSMus */
+               { 190, 0 },     /* tXDSM_XPus */
+               { 700, 0 },     /* tWCK2DQI_HF */
+               { 1600, 0 },    /* tWCK2DQO_HF */
+               { 900, 0 },     /* tWCK2DQI_LF */
+               { 1900, 0 },    /* tWCK2DQO_LF */
+               { 40000, 8 },   /* tOSCODQI */
+               { 125, 0 },     /* tDQ72DQns */
+               { 250, 0 },     /* tCAENTns */
+               { 1750, 0 }     /* tCSCAL */
+       }, {
+               { 15000, 2 },   /* tSR */
+               { 7000, 3 },    /* tXP */
+               { 19875, 2 },   /* tRCD */
+               { 19875, 2 },   /* tRPpb */
+               { 22875, 2 },   /* tRPab */
+               { 43875, 3 },   /* tRAS */
+               { 6250, 4 },    /* tWTR_S */
+               { 12000, 4 },   /* tWTR_L */
+               { 5000, 2 },    /* tRRD */
+               { 0, 2 },       /* tPPD */
+               { 20000, 0 },   /* tFAW */
+               { 0, 4 },       /* tMRR */
+               { 10000, 5 },   /* tMRW */
+               { 14000, 5 },   /* tMRD */
+               { 1500, 0 },    /* tZQCALns */
+               { 30000, 4 },   /* tZQLAT */
+               { 1500, 0 },    /* tODTon_min */
+               { 4000, 0 },    /* tPDN_DSMus */
+               { 200, 0 },     /* tXSR_DSMus */
+               { 190, 0 },     /* tXDSM_XPus */
+               { 715, 0 },     /* tWCK2DQI_HF */
+               { 1635, 0 },    /* tWCK2DQO_HF */
+               { 920, 0 },     /* tWCK2DQI_LF */
+               { 1940, 0 },    /* tWCK2DQO_LF */
+               { 40000, 8 },   /* tOSCODQI */
+               { 125, 0 },     /* tDQ72DQns */
+               { 250, 0 },     /* tCAENTns */
+               { 1750, 0 }     /* tCSCAL */
+       }
+};
+
+static const u16 jedec_spec2_tRFC_ab[] = {
+       /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+       130, 180, 180, 210, 210, 280, 280, 380, 380
+};
+
+/* The address offsets of PI Register */
+#define DDR_PI_REGSET_OFS_V4H                  0x0800
+/* The address offsets of Data Slice */
+#define DDR_PHY_SLICE_REGSET_OFS_V4H           0x1000
+/* The address offsets of Address Slice */
+#define DDR_PHY_ADR_V_REGSET_OFS_V4H           0x1200
+/* The address offsets of Address Control Slice */
+#define DDR_PHY_ADR_G_REGSET_OFS_V4H           0x1300
+
+#define DDR_REGDEF_ADR(regdef)                 ((regdef) & 0xFFFF)
+#define DDR_REGDEF_LEN(regdef)                 (((regdef) >> 16) & 0xFF)
+#define DDR_REGDEF_LSB(regdef)                 (((regdef) >> 24) & 0xFF)
+
+#define DDR_REGDEF(lsb, len, adr)                                      \
+       (((lsb) << 24) | ((len) << 16) | (adr))
+
+#define PHY_LP4_BOOT_RX_PCLK_CLK_SEL           DDR_REGDEF(0x10, 0x03, 0x1000)
+#define PHY_PER_CS_TRAINING_MULTICAST_EN       DDR_REGDEF(0x10, 0x01, 0x1006)
+#define PHY_PER_CS_TRAINING_INDEX              DDR_REGDEF(0x18, 0x01, 0x1006)
+#define PHY_VREF_INITIAL_STEPSIZE              DDR_REGDEF(0x18, 0x08, 0x100D)
+#define PHY_RDLVL_BEST_THRSHLD                 DDR_REGDEF(0x00, 0x04, 0x100E)
+#define PHY_RDLVL_VREF_OUTLIER                 DDR_REGDEF(0x10, 0x03, 0x100E)
+#define SC_PHY_WCK_CALC                                DDR_REGDEF(0x18, 0x01, 0x101A)
+#define PHY_RDLVL_RDDQS_DQ_OBS_SELECT          DDR_REGDEF(0x10, 0x05, 0x102C)
+#define PHY_CALVL_VREF_DRIVING_SLICE           DDR_REGDEF(0x18, 0x01, 0x1030)
+#define PHY_WRLVL_HARD0_DELAY_OBS              DDR_REGDEF(0x00, 0x0A, 0x1038)
+#define PHY_WRLVL_HARD1_DELAY_OBS              DDR_REGDEF(0x10, 0x0A, 0x1038)
+#define PHY_WRLVL_STATUS_OBS                   DDR_REGDEF(0x00, 0x1C, 0x1039)
+#define PHY_WRLVL_ERROR_OBS                    DDR_REGDEF(0x00, 0x10, 0x103B)
+#define PHY_GTLVL_STATUS_OBS                   DDR_REGDEF(0x00, 0x12, 0x103D)
+#define PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS          DDR_REGDEF(0x10, 0x09, 0x103E)
+#define PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS          DDR_REGDEF(0x00, 0x09, 0x103F)
+#define PHY_WDQLVL_STATUS_OBS                  DDR_REGDEF(0x00, 0x20, 0x1043)
+#define PHY_DATA_DC_CAL_START                  DDR_REGDEF(0x18, 0x01, 0x104D)
+#define PHY_REGULATOR_EN_CNT                   DDR_REGDEF(0x18, 0x06, 0x1050)
+#define PHY_VREF_INITIAL_START_POINT           DDR_REGDEF(0x00, 0x09, 0x1055)
+#define PHY_VREF_INITIAL_STOP_POINT            DDR_REGDEF(0x10, 0x09, 0x1055)
+#define PHY_VREF_TRAINING_CTRL                 DDR_REGDEF(0x00, 0x02, 0x1056)
+#define PHY_RDDQ0_SLAVE_DELAY                  DDR_REGDEF(0x00, 0x09, 0x105D)
+#define PHY_RDDQ1_SLAVE_DELAY                  DDR_REGDEF(0x10, 0x09, 0x105D)
+#define PHY_RDDQ2_SLAVE_DELAY                  DDR_REGDEF(0x00, 0x09, 0x105E)
+#define PHY_RDDQ3_SLAVE_DELAY                  DDR_REGDEF(0x10, 0x09, 0x105E)
+#define PHY_RDDQ4_SLAVE_DELAY                  DDR_REGDEF(0x00, 0x09, 0x105F)
+#define PHY_RDDQ5_SLAVE_DELAY                  DDR_REGDEF(0x10, 0x09, 0x105F)
+#define PHY_RDDQ6_SLAVE_DELAY                  DDR_REGDEF(0x00, 0x09, 0x1060)
+#define PHY_RDDQ7_SLAVE_DELAY                  DDR_REGDEF(0x10, 0x09, 0x1060)
+#define PHY_RDDM_SLAVE_DELAY                   DDR_REGDEF(0x00, 0x09, 0x1061)
+#define PHY_RX_CAL_ALL_DLY                     DDR_REGDEF(0x18, 0x06, 0x1061)
+#define PHY_RX_PCLK_CLK_SEL                    DDR_REGDEF(0x00, 0x03, 0x1062)
+#define PHY_DATA_DC_CAL_CLK_SEL                        DDR_REGDEF(0x18, 0x03, 0x1063)
+#define PHY_PAD_VREF_CTRL_DQ                   DDR_REGDEF(0x00, 0x0E, 0x1067)
+#define PHY_PER_CS_TRAINING_EN                 DDR_REGDEF(0x00, 0x01, 0x1068)
+#define PHY_RDDATA_EN_TSEL_DLY                 DDR_REGDEF(0x18, 0x05, 0x1069)
+#define PHY_RDDATA_EN_OE_DLY                   DDR_REGDEF(0x00, 0x05, 0x106A)
+#define PHY_RPTR_UPDATE                                DDR_REGDEF(0x10, 0x04, 0x106C)
+#define PHY_WRLVL_RESP_WAIT_CNT                        DDR_REGDEF(0x08, 0x06, 0x106D)
+#define PHY_RDLVL_DLY_STEP                     DDR_REGDEF(0x08, 0x04, 0x1070)
+#define PHY_RDLVL_MAX_EDGE                     DDR_REGDEF(0x00, 0x09, 0x1071)
+#define PHY_DATA_DC_WDQLVL_ENABLE              DDR_REGDEF(0x08, 0x02, 0x1075)
+#define PHY_RDDATA_EN_DLY                      DDR_REGDEF(0x10, 0x05, 0x1076)
+#define PHY_MEAS_DLY_STEP_ENABLE               DDR_REGDEF(0x08, 0x06, 0x1076)
+#define PHY_DQ_DM_SWIZZLE0                     DDR_REGDEF(0x00, 0x20, 0x1077)
+#define PHY_DQ_DM_SWIZZLE1                     DDR_REGDEF(0x00, 0x04, 0x1078)
+#define PHY_CLK_WRDQS_SLAVE_DELAY              DDR_REGDEF(0x00, 0x09, 0x107E)
+#define PHY_WRITE_PATH_LAT_DEC                 DDR_REGDEF(0x10, 0x01, 0x107E)
+#define PHY_RDDQS_GATE_SLAVE_DELAY             DDR_REGDEF(0x00, 0x09, 0x1088)
+#define PHY_RDDQS_LATENCY_ADJUST               DDR_REGDEF(0x10, 0x05, 0x1088)
+#define PHY_WRITE_PATH_LAT_ADD                 DDR_REGDEF(0x18, 0x03, 0x1088)
+#define PHY_WRITE_PATH_LAT_FRAC                        DDR_REGDEF(0x00, 0x08, 0x1089)
+#define PHY_GTLVL_LAT_ADJ_START                        DDR_REGDEF(0x00, 0x05, 0x108A)
+#define PHY_DATA_DC_DQS_CLK_ADJUST             DDR_REGDEF(0x00, 0x08, 0x108C)
+#define PHY_ADR_CALVL_SWIZZLE0                 DDR_REGDEF(0x00, 0x20, 0x1202)
+#define PHY_ADR_MEAS_DLY_STEP_ENABLE           DDR_REGDEF(0x10, 0x01, 0x1203)
+#define PHY_ADR_CALVL_RANK_CTRL                        DDR_REGDEF(0x18, 0x02, 0x1205)
+#define PHY_ADR_CALVL_OBS1                     DDR_REGDEF(0x00, 0x20, 0x120A)
+#define PHY_ADR_CALVL_OBS2                     DDR_REGDEF(0x00, 0x20, 0x120B)
+#define PHY_ADR_CALVL_DLY_STEP                 DDR_REGDEF(0x00, 0x04, 0x1210)
+#define PHY_CS_ACS_ALLOCATION_BIT2_2           DDR_REGDEF(0x08, 0x02, 0x1215)
+#define PHY_CS_ACS_ALLOCATION_BIT3_2           DDR_REGDEF(0x10, 0x02, 0x1215)
+#define PHY_CSLVL_OBS1                         DDR_REGDEF(0x00, 0x20, 0x1221)
+#define PHY_CLK_DC_CAL_CLK_SEL                 DDR_REGDEF(0x08, 0x03, 0x123A)
+#define PHY_FREQ_SEL_MULTICAST_EN              DDR_REGDEF(0x08, 0x01, 0x1301)
+#define PHY_FREQ_SEL_INDEX                     DDR_REGDEF(0x10, 0x02, 0x1301)
+#define SC_PHY_MANUAL_UPDATE                   DDR_REGDEF(0x18, 0x01, 0x1304)
+#define PHY_SET_DFI_INPUT_RST_PAD              DDR_REGDEF(0x18, 0x01, 0x1311)
+#define PHY_CAL_MODE_0                         DDR_REGDEF(0x00, 0x0D, 0x132C)
+#define PHY_CAL_INTERVAL_COUNT_0               DDR_REGDEF(0x00, 0x20, 0x132D)
+#define PHY_DATA_BYTE_ORDER_SEL                        DDR_REGDEF(0x00, 0x20, 0x133E)
+#define PHY_PAD_ACS_RX_PCLK_CLK_SEL            DDR_REGDEF(0x10, 0x03, 0x1348)
+#define PHY_PLL_CTRL                           DDR_REGDEF(0x00, 0x0E, 0x134B)
+#define PHY_PLL_CTRL_8X                                DDR_REGDEF(0x10, 0x0E, 0x134B)
+#define PHY_CAL_CLK_SELECT_0                   DDR_REGDEF(0x00, 0x03, 0x1360)
+
+#define PI_START                               DDR_REGDEF(0x00, 0x01, 0x0800)
+#define PI_TRAIN_ALL_FREQ_REQ                  DDR_REGDEF(0x18, 0x01, 0x0802)
+#define PI_CS_MAP                              DDR_REGDEF(0x08, 0x02, 0x0813)
+#define PI_WRLVL_REQ                           DDR_REGDEF(0x10, 0x01, 0x081C)
+#define PI_WRLVL_CS_SW                         DDR_REGDEF(0x18, 0x02, 0x081C)
+#define PI_RDLVL_REQ                           DDR_REGDEF(0x18, 0x01, 0x0824)
+#define PI_RDLVL_GATE_REQ                      DDR_REGDEF(0x00, 0x01, 0x0825)
+#define PI_RDLVL_CS_SW                         DDR_REGDEF(0x08, 0x02, 0x0825)
+#define PI_RDLVL_PERIODIC                      DDR_REGDEF(0x08, 0x01, 0x082E)
+#define PI_RDLVL_INTERVAL                      DDR_REGDEF(0x08, 0x10, 0x0835)
+#define PI_DRAMDCA_FLIP_MASK                   DDR_REGDEF(0x08, 0x02, 0x083B)
+#define PI_DRAMDCA_LVL_REQ                     DDR_REGDEF(0x10, 0x01, 0x083D)
+#define PI_DCMLVL_CS_SW                                DDR_REGDEF(0x18, 0x02, 0x083D)
+#define PI_WRDCM_LVL_EN_F1                     DDR_REGDEF(0x00, 0x02, 0x083F)
+#define PI_DRAMDCA_LVL_EN_F1                   DDR_REGDEF(0x08, 0x02, 0x083F)
+#define PI_WRDCM_LVL_EN_F2                     DDR_REGDEF(0x18, 0x02, 0x083F)
+#define PI_DRAMDCA_LVL_EN_F2                   DDR_REGDEF(0x00, 0x02, 0x0840)
+#define PI_DRAMDCA_LVL_ACTIVE_SEQ_2            DDR_REGDEF(0x00, 0x1B, 0x0868)
+#define PI_DRAMDCA_LVL_ACTIVE_SEQ_3            DDR_REGDEF(0x00, 0x1B, 0x0869)
+#define PI_DRAMDCA_LVL_ACTIVE_SEQ_4            DDR_REGDEF(0x00, 0x1B, 0x086A)
+#define PI_TCKCKEL_F2                          DDR_REGDEF(0x18, 0x04, 0x089D)
+#define PI_WDQLVL_VREF_EN                      DDR_REGDEF(0x08, 0x04, 0x089E)
+#define PI_WDQLVL_PERIODIC                     DDR_REGDEF(0x00, 0x01, 0x08A0)
+#define PI_WDQLVL_INTERVAL                     DDR_REGDEF(0x00, 0x10, 0x08A4)
+#define PI_INT_STATUS                          DDR_REGDEF(0x00, 0x20, 0x0900)
+#define PI_INT_ACK_0                           DDR_REGDEF(0x00, 0x20, 0x0902)
+#define PI_INT_ACK_1                           DDR_REGDEF(0x00, 0x03, 0x0903)
+#define PI_LONG_COUNT_MASK                     DDR_REGDEF(0x10, 0x05, 0x090F)
+#define PI_ADDR_MUX_0                          DDR_REGDEF(0x00, 0x03, 0x0910)
+#define PI_ADDR_MUX_1                          DDR_REGDEF(0x08, 0x03, 0x0910)
+#define PI_ADDR_MUX_2                          DDR_REGDEF(0x10, 0x03, 0x0910)
+#define PI_ADDR_MUX_3                          DDR_REGDEF(0x18, 0x03, 0x0910)
+#define PI_ADDR_MUX_4                          DDR_REGDEF(0x00, 0x03, 0x0911)
+#define PI_ADDR_MUX_5                          DDR_REGDEF(0x08, 0x03, 0x0911)
+#define PI_ADDR_MUX_6                          DDR_REGDEF(0x10, 0x03, 0x0911)
+#define PI_DATA_BYTE_SWAP_EN                   DDR_REGDEF(0x18, 0x01, 0x0911)
+#define PI_DATA_BYTE_SWAP_SLICE0               DDR_REGDEF(0x00, 0x01, 0x0912)
+#define PI_DATA_BYTE_SWAP_SLICE1               DDR_REGDEF(0x08, 0x01, 0x0912)
+#define PI_PWRUP_SREFRESH_EXIT                 DDR_REGDEF(0x18, 0x01, 0x093D)
+#define PI_PWRUP_SREFRESH_EXIT                 DDR_REGDEF(0x18, 0x01, 0x093D)
+#define PI_DLL_RST                             DDR_REGDEF(0x00, 0x01, 0x0941)
+#define PI_TDELAY_RDWR_2_BUS_IDLE_F2           DDR_REGDEF(0x00, 0x08, 0x0964)
+#define PI_WRLAT_F2                            DDR_REGDEF(0x10, 0x07, 0x096A)
+#define PI_TWCKENL_WR_ADJ_F2                   DDR_REGDEF(0x18, 0x06, 0x096A)
+#define PI_TWCKENL_RD_ADJ_F2                   DDR_REGDEF(0x00, 0x06, 0x096B)
+#define PI_TWCKPRE_STATIC_F2                   DDR_REGDEF(0x08, 0x06, 0x096B)
+#define PI_TWCKPRE_TOGGLE_RD_F2                        DDR_REGDEF(0x18, 0x06, 0x096B)
+#define PI_TWCKENL_FS_ADJ_F2                   DDR_REGDEF(0x00, 0x06, 0x096C)
+#define PI_CASLAT_F2                           DDR_REGDEF(0x08, 0x07, 0x096C)
+#define PI_TRFC_F2                             DDR_REGDEF(0x00, 0x0A, 0x0971)
+#define PI_TREF_F2                             DDR_REGDEF(0x00, 0x14, 0x0972)
+#define PI_TDFI_WRLVL_WW_F0                    DDR_REGDEF(0x00, 0x0A, 0x0974)
+#define PI_TDFI_WRLVL_WW_F1                    DDR_REGDEF(0x00, 0x0A, 0x0975)
+#define PI_WRLVL_EN_F2                         DDR_REGDEF(0x18, 0x02, 0x0975)
+#define PI_TDFI_WRLVL_WW_F2                    DDR_REGDEF(0x00, 0x0A, 0x0976)
+#define PI_WRLVL_WCKOFF_F2                     DDR_REGDEF(0x10, 0x08, 0x0976)
+#define PI_RDLVL_EN_F2                         DDR_REGDEF(0x18, 0x02, 0x097A)
+#define PI_RDLVL_GATE_EN_F2                    DDR_REGDEF(0x00, 0x02, 0x097B)
+#define PI_RDLVL_VREF_EN_F0                    DDR_REGDEF(0x10, 0x04, 0x097B)
+#define PI_RDLVL_VREF_EN_F1                    DDR_REGDEF(0x00, 0x04, 0x097D)
+#define PI_RDLVL_VREF_EN_F2                    DDR_REGDEF(0x10, 0x04, 0x097E)
+#define PI_RDLAT_ADJ_F2                                DDR_REGDEF(0x00, 0x09, 0x0981)
+#define PI_WRLAT_ADJ_F2                                DDR_REGDEF(0x00, 0x07, 0x0982)
+#define PI_TDFI_CALVL_CC_F2                    DDR_REGDEF(0x00, 0x0A, 0x0985)
+#define PI_TDFI_CALVL_CAPTURE_F2               DDR_REGDEF(0x10, 0x0A, 0x0985)
+#define PI_CALVL_EN_F2                         DDR_REGDEF(0x10, 0x02, 0x0986)
+#define PI_TCAENT_F2                           DDR_REGDEF(0x00, 0x0E, 0x0989)
+#define PI_TVREF_SHORT_F2                      DDR_REGDEF(0x00, 0x0A, 0x098F)
+#define PI_TVREF_LONG_F2                       DDR_REGDEF(0x10, 0x0A, 0x098F)
+#define PI_TVRCG_ENABLE_F2                     DDR_REGDEF(0x00, 0x0A, 0x0990)
+#define PI_TVRCG_DISABLE_F2                    DDR_REGDEF(0x10, 0x0A, 0x0990)
+#define PI_CALVL_VREF_INITIAL_START_POINT_F0   DDR_REGDEF(0x00, 0x07, 0x0991)
+#define PI_CALVL_VREF_INITIAL_STOP_POINT_F0    DDR_REGDEF(0x08, 0x07, 0x0991)
+#define PI_CALVL_VREF_INITIAL_START_POINT_F1   DDR_REGDEF(0x18, 0x07, 0x0991)
+#define PI_CALVL_VREF_INITIAL_STOP_POINT_F1    DDR_REGDEF(0x00, 0x07, 0x0992)
+#define PI_CALVL_VREF_INITIAL_START_POINT_F2   DDR_REGDEF(0x10, 0x07, 0x0992)
+#define PI_CALVL_VREF_INITIAL_STOP_POINT_F2    DDR_REGDEF(0x18, 0x07, 0x0992)
+#define PI_TDFI_CALVL_STROBE_F2                        DDR_REGDEF(0x08, 0x04, 0x0995)
+#define PI_TXP_F2                              DDR_REGDEF(0x10, 0x05, 0x0995)
+#define PI_TMRWCKEL_F2                         DDR_REGDEF(0x18, 0x08, 0x0995)
+#define PI_TCKEHDQS_F2                         DDR_REGDEF(0x10, 0x06, 0x099D)
+#define PI_TFC_F2                              DDR_REGDEF(0x00, 0x0A, 0x099E)
+#define PI_WDQLVL_VREF_INITIAL_START_POINT_F0  DDR_REGDEF(0x10, 0x07, 0x09A0)
+#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0   DDR_REGDEF(0x18, 0x07, 0x09A0)
+#define PI_WDQLVL_VREF_INITIAL_START_POINT_F1  DDR_REGDEF(0x00, 0x07, 0x09A4)
+#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1   DDR_REGDEF(0x08, 0x07, 0x09A4)
+#define PI_TDFI_WDQLVL_WR_F2                   DDR_REGDEF(0x00, 0x0A, 0x09A6)
+#define PI_TDFI_WDQLVL_RW_F2                   DDR_REGDEF(0x10, 0x0A, 0x09A6)
+#define PI_WDQLVL_VREF_INITIAL_START_POINT_F2  DDR_REGDEF(0x00, 0x07, 0x09A7)
+#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2   DDR_REGDEF(0x08, 0x07, 0x09A7)
+#define PI_WDQLVL_EN_F2                                DDR_REGDEF(0x18, 0x02, 0x09A7)
+#define PI_MBIST_RDLAT_ADJ_F2                  DDR_REGDEF(0x08, 0x09, 0x09A8)
+#define PI_MBIST_TWCKENL_RD_ADJ_F2             DDR_REGDEF(0x18, 0x06, 0x09A8)
+#define PI_TRTP_F2                             DDR_REGDEF(0x18, 0x08, 0x09B3)
+#define PI_TRP_F2                              DDR_REGDEF(0x00, 0x08, 0x09B4)
+#define PI_TRCD_F2                             DDR_REGDEF(0x08, 0x08, 0x09B4)
+#define PI_TWTR_S_F2                           DDR_REGDEF(0x18, 0x06, 0x09B4)
+#define PI_TWTR_L_F2                           DDR_REGDEF(0x00, 0x06, 0x09B5)
+#define PI_TWTR_F2                             DDR_REGDEF(0x10, 0x06, 0x09B5)
+#define PI_TWR_F2                              DDR_REGDEF(0x18, 0x08, 0x09B5)
+#define PI_TRAS_MIN_F2                         DDR_REGDEF(0x10, 0x09, 0x09B6)
+#define PI_TDQSCK_MAX_F2                       DDR_REGDEF(0x00, 0x04, 0x09B7)
+#define PI_TSR_F2                              DDR_REGDEF(0x10, 0x08, 0x09B7)
+#define PI_TMRD_F2                             DDR_REGDEF(0x18, 0x08, 0x09B7)
+#define PI_TDFI_CTRLUPD_MAX_F2                 DDR_REGDEF(0x00, 0x15, 0x09BC)
+#define PI_TDFI_CTRLUPD_INTERVAL_F2            DDR_REGDEF(0x00, 0x20, 0x09BD)
+#define PI_TINIT_F2                            DDR_REGDEF(0x00, 0x18, 0x09CC)
+#define PI_TINIT1_F2                           DDR_REGDEF(0x00, 0x18, 0x09CD)
+#define PI_TINIT3_F2                           DDR_REGDEF(0x00, 0x18, 0x09CE)
+#define PI_TINIT4_F2                           DDR_REGDEF(0x00, 0x18, 0x09CF)
+#define PI_TINIT5_F2                           DDR_REGDEF(0x00, 0x18, 0x09D0)
+#define PI_TXSNR_F2                            DDR_REGDEF(0x00, 0x10, 0x09D1)
+#define PI_TZQCAL_F2                           DDR_REGDEF(0x10, 0x0C, 0x09D6)
+#define PI_TZQLAT_F2                           DDR_REGDEF(0x00, 0x07, 0x09D7)
+#define PI_ZQRESET_F2                          DDR_REGDEF(0x10, 0x0C, 0x09D8)
+#define PI_TDQ72DQ_F2                          DDR_REGDEF(0x10, 0x0A, 0x09DD)
+#define PI_TCBTRTW_F2                          DDR_REGDEF(0x00, 0x06, 0x09DE)
+#define PI_MC_TRFC_F2                          DDR_REGDEF(0x00, 0x0A, 0x09E1)
+#define PI_CKE_MUX_0                           DDR_REGDEF(0x00, 0x03, 0x09E6)
+#define PI_CKE_MUX_1                           DDR_REGDEF(0x08, 0x03, 0x09E6)
+#define PI_SEQ_DEC_SW_CS                       DDR_REGDEF(0x00, 0x02, 0x0A4E)
+#define PI_SW_SEQ_START                                DDR_REGDEF(0x10, 0x01, 0x0A4E)
+#define PI_SW_SEQ_0                            DDR_REGDEF(0x00, 0x1B, 0x0BF1)
+#define PI_SW_SEQ_1                            DDR_REGDEF(0x00, 0x1B, 0x0BF2)
+#define PI_DFS_ENTRY_SEQ_0                     DDR_REGDEF(0x00, 0x1D, 0x0BFB)
+#define PI_DFS_INITIALIZATION_SEQ_1            DDR_REGDEF(0x00, 0x1D, 0x0C24)
+#define PI_DFS_INITIALIZATION_SEQ_9            DDR_REGDEF(0x00, 0x1D, 0x0C2C)
+#define PI_DFS_INITIALIZATION_SEQ_10           DDR_REGDEF(0x00, 0x1D, 0x0C2D)
+#define PI_RDLVL_TRAIN_SEQ_1                   DDR_REGDEF(0x00, 0x1B, 0x0C42)
+#define PI_RDLVL_TRAIN_SEQ_2                   DDR_REGDEF(0x00, 0x1B, 0x0C43)
+#define PI_RDLVL_TRAIN_SEQ_3                   DDR_REGDEF(0x00, 0x1B, 0x0C44)
+#define PI_RDLVL_TRAIN_SEQ_4                   DDR_REGDEF(0x00, 0x1B, 0x0C45)
+#define PI_RDLVL_TRAIN_SEQ_5                   DDR_REGDEF(0x00, 0x1B, 0x0C46)
+#define PI_SEQ_WAIT_16_F2                      DDR_REGDEF(0x00, 0x18, 0x0C77)
+#define PI_SEQ_WAIT_17_F2                      DDR_REGDEF(0x00, 0x18, 0x0C7A)
+#define PI_SEQ_WAIT_18_F2                      DDR_REGDEF(0x00, 0x18, 0x0C7D)
+#define PI_SEQ_WAIT_19_F2                      DDR_REGDEF(0x00, 0x18, 0x0C80)
+#define PI_SEQ_WAIT_20_F2                      DDR_REGDEF(0x00, 0x18, 0x0C83)
+#define PI_SEQ_WAIT_21_F2                      DDR_REGDEF(0x00, 0x18, 0x0C86)
+#define PI_SEQ_WAIT_22_F2                      DDR_REGDEF(0x00, 0x18, 0x0C89)
+#define PI_SEQ_WAIT_23_F2                      DDR_REGDEF(0x00, 0x18, 0x0C8C)
+#define PI_SEQ_WAIT_24_F2                      DDR_REGDEF(0x00, 0x18, 0x0C8F)
+#define PI_SEQ_WAIT_25_F2                      DDR_REGDEF(0x00, 0x18, 0x0C92)
+#define PI_SEQ_WAIT_26_F2                      DDR_REGDEF(0x00, 0x18, 0x0C95)
+#define PI_SEQ_WAIT_30_F2                      DDR_REGDEF(0x00, 0x18, 0x0CA1)
+#define PI_DARRAY3_0_CS0_F0                    DDR_REGDEF(0x00, 0x08, 0x0D0B)
+#define PI_DARRAY3_1_CS0_F0                    DDR_REGDEF(0x08, 0x08, 0x0D0B)
+#define PI_DARRAY3_0_CS0_F1                    DDR_REGDEF(0x00, 0x08, 0x0D15)
+#define PI_DARRAY3_1_CS0_F1                    DDR_REGDEF(0x08, 0x08, 0x0D15)
+#define PI_DARRAY3_0_CS0_F2                    DDR_REGDEF(0x00, 0x08, 0x0D1F)
+#define PI_DARRAY3_1_CS0_F2                    DDR_REGDEF(0x08, 0x08, 0x0D1F)
+#define PI_DARRAY3_4_CS0_F2                    DDR_REGDEF(0x00, 0x08, 0x0D20)
+#define PI_DARRAY3_20_CS0_F2                   DDR_REGDEF(0x00, 0x08, 0x0D24)
+#define PI_DARRAY3_0_CS1_F0                    DDR_REGDEF(0x00, 0x08, 0x0D29)
+#define PI_DARRAY3_1_CS1_F0                    DDR_REGDEF(0x08, 0x08, 0x0D29)
+#define PI_DARRAY3_0_CS1_F1                    DDR_REGDEF(0x00, 0x08, 0x0D33)
+#define PI_DARRAY3_1_CS1_F1                    DDR_REGDEF(0x08, 0x08, 0x0D33)
+#define PI_DARRAY3_0_CS1_F2                    DDR_REGDEF(0x00, 0x08, 0x0D3D)
+#define PI_DARRAY3_1_CS1_F2                    DDR_REGDEF(0x08, 0x08, 0x0D3D)
+#define PI_DARRAY3_4_CS1_F2                    DDR_REGDEF(0x00, 0x08, 0x0D3E)
+#define PI_DARRAY3_20_CS1_F2                   DDR_REGDEF(0x00, 0x08, 0x0D42)
+
+/* The setting table of Data Slice for V4H */
+static const u32 DDR_PHY_SLICE_REGSET_V4H[DDR_PHY_SLICE_REGSET_NUM_V4H] = {
+       0x30020370, 0x00000000, 0x01000002, 0x00000000,
+       0x00000000, 0x00000000, 0x00010300, 0x04000100,
+       0x00010000, 0x01000000, 0x00000000, 0x00000000,
+       0x00010000, 0x08010000, 0x00022003, 0x00000000,
+       0x040F0100, 0x1404034F, 0x04040102, 0x04040404,
+       0x00000100, 0x00000000, 0x00000000, 0x000800C0,
+       0x000F18FF, 0x00000000, 0x00000001, 0x00070000,
+       0x0000AAAA, 0x00005555, 0x0000B5B5, 0x00004A4A,
+       0x00005656, 0x0000A9A9, 0x0000A9A9, 0x0000B5B5,
+       0x00000000, 0xBFBF0000, 0xCCCCF7F7, 0x00000000,
+       0x00000000, 0x00000000, 0x00080815, 0x08040000,
+       0x00000004, 0x00103000, 0x000C0040, 0x00200200,
+       0x01010000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000020, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000004, 0x001F07FF, 0x08000303,
+       0x10200080, 0x00000006, 0x00000401, 0x00000000,
+       0x20CEC201, 0x00000001, 0x00017706, 0x01007706,
+       0x00000000, 0x008D006D, 0x00100001, 0x03FF0100,
+       0x00006E01, 0x00000301, 0x00000000, 0x00000000,
+       0x00000000, 0x00500050, 0x00500050, 0x00500050,
+       0x00500050, 0x0D000050, 0x10100004, 0x06102010,
+       0x61619041, 0x07097000, 0x00644180, 0x00803280,
+       0x00808001, 0x13010100, 0x02000016, 0x10001003,
+       0x06093E42, 0x0F063D01, 0x011700C8, 0x04100140,
+       0x00000100, 0x000001D1, 0x05000068, 0x00030402,
+       0x01400000, 0x80800300, 0x00160010, 0x76543210,
+       0x00000008, 0x03010301, 0x03010301, 0x03010301,
+       0x03010301, 0x03010301, 0x00000000, 0x00500050,
+       0x00500050, 0x00500050, 0x00500050, 0x00500050,
+       0x00500050, 0x00500050, 0x00500050, 0x00500050,
+       0x00070087, 0x00000000, 0x08010007, 0x00000000,
+       0x20202020, 0x20202020, 0x20202020, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000
+};
+
+/* The setting table of Address Slice for V4H */
+static const u32 DDR_PHY_ADR_V_REGSET_V4H[DDR_PHY_ADR_V_REGSET_NUM_V4H] = {
+       0x00200030, 0x00200002, 0x76543210, 0x00010001,
+       0x06543210, 0x03070000, 0x00001000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x0000807F,
+       0x00000001, 0x00000003, 0x00000000, 0x000F0000,
+       0x030C000F, 0x00020103, 0x0000000F, 0x00000100,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x02000400, 0x0000002A, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00200101,
+       0x10002C03, 0x00000003, 0x00030240, 0x00008008,
+       0x00081020, 0x01200000, 0x00010001, 0x00000000,
+       0x00100302, 0x003E4208, 0x01400140, 0x01400140,
+       0x01400140, 0x01400140, 0x00000100, 0x00000100,
+       0x00000100, 0x00000100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00020580, 0x03000040,
+       0x00000000
+};
+
+/* The setting table of Address Control Slice for V4H */
+static const u32 DDR_PHY_ADR_G_REGSET_V4H[DDR_PHY_ADR_G_REGSET_NUM_V4H] = {
+       0x00000000, 0x00000100, 0x00000001, 0x23800000,
+       0x00000000, 0x01000101, 0x00000000, 0x00000001,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00040101, 0x00000000, 0x00000000, 0x00000064,
+       0x00000000, 0x00000000, 0x39421B42, 0x00010124,
+       0x00520052, 0x00000052, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x07030102,
+       0x01030307, 0x00000054, 0x00004096, 0x08200820,
+       0x08200820, 0x08200820, 0x08200820, 0x00000820,
+       0x004103B8, 0x0000003F, 0x000C0006, 0x00000000,
+       0x000004C0, 0x00007A12, 0x00000208, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x03000000, 0x00000000, 0x00000000, 0x04102002,
+       0x00041020, 0x01C98C98, 0x3F400000, 0x003F3F3F,
+       0x00000000, 0x00000000, 0x76543210, 0x00010198,
+       0x00000007, 0x00000000, 0x00000000, 0x00000000,
+       0x00000002, 0x00000000, 0x00000000, 0x00000000,
+       0x01032380, 0x00000100, 0x00000000, 0x31421342,
+       0x00308000, 0x00000080, 0x00063F77, 0x00000006,
+       0x0000033F, 0x00000000, 0x0000033F, 0x00000000,
+       0x0000033F, 0x00000000, 0x00033F00, 0x00CC0000,
+       0x00033F77, 0x00000000, 0x00033F00, 0x00EE0000,
+       0x00033F00, 0x00EE0000, 0x00033F00, 0x00EE0000,
+       0x00200106
+};
+
+/* The setting table of PI Register for V4H */
+static const u32 DDR_PI_REGSET_V4H[DDR_PI_REGSET_NUM_V4H] = {
+       0x00000D00, 0x00010100, 0x00640004, 0x00000001,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0xFFFFFFFF, 0x02010000, 0x00000003, 0x00000005,
+       0x00000002, 0x00000000, 0x00000101, 0x0012080E,
+       0x00000000, 0x001E2C0E, 0x00000000, 0x00030300,
+       0x01010700, 0x00000001, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x01000000, 0x00002807, 0x00000000, 0x32000300,
+       0x00000000, 0x00000000, 0x04022004, 0x01040100,
+       0x00010000, 0x00000100, 0x000000AA, 0x00000055,
+       0x000000B5, 0x0000004A, 0x00000056, 0x000000A9,
+       0x000000A9, 0x000000B5, 0x00000000, 0x01000000,
+       0x00030300, 0x0000001A, 0x000007D0, 0x00000300,
+       0x00000000, 0x00000000, 0x01000000, 0x00000101,
+       0x00000000, 0x00000000, 0x00000000, 0x00000200,
+       0x03030300, 0x01000000, 0x00000000, 0x00000100,
+       0x00000003, 0x001100EF, 0x01A1120B, 0x00051400,
+       0x001A0700, 0x001101FC, 0x00011A00, 0x00000000,
+       0x001F0000, 0x00000000, 0x00000000, 0x00051500,
+       0x001103FC, 0x00011A00, 0x00051500, 0x001102FC,
+       0x00011A00, 0x00001A00, 0x00000000, 0x001F0000,
+       0x001100FC, 0x00011A00, 0x01A1120B, 0x001A0701,
+       0x00000000, 0x001F0000, 0x00000000, 0x00000000,
+       0x001100EF, 0x01A1120B, 0x00051400, 0x01910480,
+       0x01821009, 0x001F0000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x001A0700, 0x01A11E14,
+       0x001101FC, 0x00211A00, 0x00051500, 0x001103FC,
+       0x00011A00, 0x00051500, 0x001102FC, 0x00011A00,
+       0x00031A00, 0x001A0701, 0x00000000, 0x001F0000,
+       0x00000000, 0x00000000, 0x01A11E14, 0x01A1120B,
+       0x00000000, 0x001F0000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x001100FD, 0x00012E00,
+       0x00051700, 0x01A1120B, 0x001A0701, 0x001F0000,
+       0x00000000, 0x00000000, 0x001100EF, 0x01A1120B,
+       0x00051400, 0x001A0700, 0x001102FD, 0x00012E00,
+       0x00000000, 0x001F0000, 0x00000000, 0x00000000,
+       0x00070700, 0x00000000, 0x01000000, 0x00000300,
+       0x17030000, 0x00000000, 0x00000000, 0x00000000,
+       0x0A0A140A, 0x10020201, 0x332A0002, 0x01010000,
+       0x0B000404, 0x04030308, 0x00010100, 0x02020301,
+       0x01001000, 0x00000034, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x55AA55AA, 0x33CC33CC,
+       0x0FF00FF0, 0x0F0FF0F0, 0x00008E38, 0x00000001,
+       0x00000002, 0x00020001, 0x00020001, 0x02010201,
+       0x0000000F, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0xAAAAA593,
+       0xA5939999, 0x00000000, 0x00005555, 0x00003333,
+       0x0000CCCC, 0x00000000, 0x0003FFFF, 0x00003333,
+       0x0000CCCC, 0x00000000, 0x036DB6DB, 0x00249249,
+       0x05B6DB6D, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x036DB6DB, 0x00249249,
+       0x05B6DB6D, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x01000000, 0x00000100,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00010000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00010000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00080000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x01180400,
+       0x03020100, 0x00060504, 0x00010100, 0x00000008,
+       0x00080000, 0x00000001, 0x00000000, 0x0001AA00,
+       0x00000100, 0x00000000, 0x00010000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00020000, 0x00000100, 0x00010000, 0x0000000B,
+       0x0000001C, 0x00000100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x03010000, 0x01000100,
+       0x01020001, 0x00010300, 0x05000104, 0x01060001,
+       0x00010700, 0x00000000, 0x00000000, 0x00010000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000301, 0x00000000, 0x00000000, 0x01010000,
+       0x00000000, 0x00000200, 0x00000000, 0xB8000000,
+       0x010000FF, 0x0000FFE8, 0x00FFA801, 0xFFD80100,
+       0x00007F10, 0x00000000, 0x00000034, 0x0000003D,
+       0x00020079, 0x02000200, 0x02000204, 0x06000C06,
+       0x04040200, 0x04100804, 0x14090004, 0x1C081024,
+       0x0000120C, 0x00000015, 0x000000CF, 0x00000026,
+       0x0000017F, 0x00000130, 0x04000C2E, 0x00000404,
+       0x01080032, 0x01080032, 0x000F0032, 0x00000000,
+       0x00000000, 0x00000000, 0x00010300, 0x00010301,
+       0x03030000, 0x00000001, 0x00010303, 0x00030000,
+       0x0013000C, 0x0A060037, 0x03030526, 0x000C0032,
+       0x0017003D, 0x0025004B, 0x00010101, 0x0000000E,
+       0x00000019, 0x010000C8, 0x000F000F, 0x0007000C,
+       0x001A0100, 0x0015001A, 0x0100000B, 0x00C900C9,
+       0x005100A1, 0x29003329, 0x33290033, 0x0A070600,
+       0x0A07060D, 0x0D09070D, 0x000C000D, 0x00001000,
+       0x00000C00, 0x00001000, 0x00000C00, 0x02001000,
+       0x0002000E, 0x00160019, 0x1E1A00C8, 0x00100004,
+       0x361C0008, 0x00000000, 0x0000000C, 0x0006000C,
+       0x0300361C, 0x04001300, 0x000D0019, 0x0000361C,
+       0x20003300, 0x00000000, 0x02000000, 0x04040802,
+       0x00060404, 0x0003C34F, 0x05022001, 0x0203000A,
+       0x04040408, 0xC34F0604, 0x10010005, 0x040A0502,
+       0x0A080F11, 0x1C0A040A, 0x0022C34F, 0x0C0C1002,
+       0x00019E0A, 0x0000102C, 0x000002FE, 0x00001DEC,
+       0x0000185C, 0x0000F398, 0x04000400, 0x03030400,
+       0x002AF803, 0x00002AF8, 0x0000D6D7, 0x00000003,
+       0x0000006E, 0x00000016, 0x00004E20, 0x00004E20,
+       0x00030D40, 0x00000005, 0x000000C8, 0x00000027,
+       0x00027100, 0x00027100, 0x00186A00, 0x00000028,
+       0x00000640, 0x01000136, 0x00530040, 0x00010004,
+       0x00960040, 0x00010004, 0x04B00040, 0x00000318,
+       0x00280005, 0x05040404, 0x00070603, 0x06030503,
+       0x0503000D, 0x00640603, 0x06040608, 0x00040604,
+       0x00260015, 0x01050130, 0x01000100, 0x00020201,
+       0x04040000, 0x01010104, 0x03020302, 0x00000100,
+       0x02020101, 0x00000000, 0x09910260, 0x11911600,
+       0x19A21009, 0x19A10100, 0x19A10201, 0x19A10302,
+       0x19A10A03, 0x19A10B04, 0x19A10C05, 0x19A10E07,
+       0x19A10F08, 0x19A1110A, 0x19A1120B, 0x19A1130C,
+       0x19A1140D, 0x19A00C00, 0x199F0000, 0x199F0000,
+       0x199F0000, 0x199F0000, 0x01910300, 0x01A21009,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x001140BF, 0x01811009, 0x01850400, 0x01A10C05,
+       0x01850300, 0x01A10C11, 0x01850300, 0x001100BF,
+       0x01811009, 0x01850500, 0x019F0000, 0x019F0000,
+       0x01510001, 0x01D102A0, 0x01E21009, 0x00051900,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x01510001,
+       0x01D10290, 0x01E21009, 0x01510001, 0x01D10000,
+       0x01E21009, 0x00051800, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x0011008F, 0x00910000,
+       0x01811009, 0x01910040, 0x01A21009, 0x019F0000,
+       0x01911000, 0x01A21009, 0x01A10100, 0x01A10201,
+       0x01A10302, 0x01A10A03, 0x01A10B04, 0x01A10C05,
+       0x01A10E07, 0x01A10F08, 0x01A1110A, 0x01A1120B,
+       0x01A1130C, 0x01A1140D, 0x01A00C00, 0x01910800,
+       0x01A21009, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x0101017F, 0x00010101, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x01000000, 0x01000101,
+       0x00000000, 0x00000000, 0x00050000, 0x00070100,
+       0x000F0200, 0x00000000, 0x01A10100, 0x01A10201,
+       0x01A10302, 0x01A00B04, 0x00210D06, 0x01A1110A,
+       0x01A1140D, 0x00098000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
+       0x019F0000, 0x019F0000, 0x01A10100, 0x01A10201,
+       0x01A10302, 0x01A10A03, 0x01A10B04, 0x00210D06,
+       0x01A1110A, 0x00000000, 0x01A1140D, 0x00000000,
+       0x00000000, 0x00000000, 0x01A1120B, 0x000A0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x000A0000, 0x01061300,
+       0x00000000, 0x00000000, 0x00061180, 0x000612C0,
+       0x00000000, 0x00000000, 0x001F0000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x01811009, 0x0011EFAF,
+       0x01A1120B, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001100BF,
+       0x01A1120B, 0x080D0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x080C0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0200, 0x001F0200,
+       0x001F0200, 0x001F0200, 0x001F0200, 0x001F0200,
+       0x001F0200, 0x001F0200, 0x001F0200, 0x001F0200,
+       0x001F0200, 0x001F0200, 0x001100EF, 0x01A1120B,
+       0x001F0000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x01A1120B, 0x001F0000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x001100EF, 0x01A1120B,
+       0x001F0000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00211F14, 0x00212014,
+       0x00212116, 0x00212217, 0x001F0000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x001A85FF, 0x00051E00, 0x001F0000, 0x00000000,
+       0x00211F14, 0x00212015, 0x00212116, 0x00212217,
+       0x01A1120B, 0x001F0000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x0031FFBF, 0x01A11009,
+       0x01A10E07, 0x01A10F08, 0x003100BF, 0x01A11009,
+       0x00051800, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x0031FFBF, 0x01A11009,
+       0x01A10E07, 0x01A10F08, 0x003100BF, 0x01A11009,
+       0x00051800, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x08084340, 0x0011FFFF,
+       0x2011FFFB, 0x00012E00, 0x001100EF, 0x01A1120B,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x083E4340, 0x00212E00,
+       0x01A1120B, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x003F0000, 0x08201020,
+       0x28100020, 0x08083020, 0x08400020, 0x08402020,
+       0x08483020, 0x10083020, 0x20180020, 0x30480020,
+       0x78880020, 0x488010E0, 0x494B0000, 0x49089080,
+       0x49080000, 0x490011C0, 0x0A000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x08000020, 0x08000020, 0x08000020, 0x08000020,
+       0x001100FF, 0x01810302, 0x001100DF, 0x00010D06,
+       0x001100EF, 0x01A1120B, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x00010D06, 0x01810302, 0x0181160E, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
+       0x081A52FD, 0x001A12FF, 0x00051A00, 0x001A13FF,
+       0x00051B00, 0x001F13FF, 0x081A52FD, 0x001A12FF,
+       0x00051A00, 0x001A13FF, 0x00051B00, 0x001F13FF,
+       0x081A52FD, 0x001A12FF, 0x00051A00, 0x001A13FF,
+       0x00051B00, 0x001F13FF, 0x00032300, 0x00032400,
+       0x001F0000, 0x001F0000, 0x00800000, 0x0031FFBF,
+       0x01A11009, 0x01A10E07, 0x01A10F08, 0x003100BF,
+       0x01A11009, 0x00051800, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x00800000, 0x0031FFBF,
+       0x01A11009, 0x01A10E07, 0x01A10F08, 0x003100BF,
+       0x01A11009, 0x00051800, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
+       0x003F0000, 0x003F0000, 0x081100DF, 0x08010D06,
+       0x0011000F, 0x0181160E, 0x001100EF, 0x01A1120B,
+       0x001F0000, 0x001F0000, 0x001F0000, 0x009C0000,
+       0x08010D06, 0x0181160E, 0x01A1120B, 0x001F0000,
+       0x001F0000, 0x001F0000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x11910048,
+       0x09910060, 0x19A21009, 0x19A10100, 0x19A10201,
+       0x19A10302, 0x19A10A03, 0x19A10B04, 0x18051C00,
+       0x19A1110A, 0x19A1120B, 0x19A1130C, 0x19A1140D,
+       0x19A1160E, 0x181140BF, 0x19A11009, 0x19A10C05,
+       0x19A00C00, 0x19A10E07, 0x19A10F08, 0x19910280,
+       0x19A21009, 0x18051000, 0x18861101, 0x181F0000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18861100,
+       0x19A11009, 0x101B0001, 0x181B0100, 0x18000500,
+       0x181B0200, 0x00000000, 0x181B0600, 0x181B0C00,
+       0x181B0100, 0x181B0200, 0x181B0300, 0x181B0400,
+       0x181F0000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x18000000, 0x18000000, 0x18000000,
+       0x18000000, 0x004B1040, 0x001011C0, 0x00089080,
+       0x000811C0, 0x040811C0, 0x02000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x5F407FAA,
+       0x007B776F, 0x4AB555AA, 0xB5A9A956, 0x9F80BFAA,
+       0x00BBB7AF, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00002AF8, 0x0000D6D7, 0x0000006E,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x0000000E, 0x00000019, 0x000000C8,
+       0x00000001, 0x00000001, 0x00000003, 0x00000007,
+       0x00000007, 0x00000009, 0x00000001, 0x00000001,
+       0x00000003, 0x00000001, 0x00000001, 0x00000003,
+       0x0000006E, 0x000000C8, 0x00000640, 0x00000001,
+       0x00000001, 0x00000003, 0x00000002, 0x00000004,
+       0x0000001C, 0x00000007, 0x0000000B, 0x00000051,
+       0x0000000C, 0x00000015, 0x000000A1, 0x00000003,
+       0x00000000, 0x0000000C, 0x00000000, 0x00000000,
+       0x00000000, 0x0000000F, 0x0000000F, 0x0000000F,
+       0x00002AF9, 0x00002AF9, 0x00002AF9, 0x00000034,
+       0x0000001E, 0x0000003C, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x000000C0, 0x00000000, 0x00000000, 0x55550000,
+       0x00003C5A, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00D60000,
+       0x50005000, 0x803E0050, 0x00000200, 0x00000000,
+       0x00000000, 0x00007800, 0x00000000, 0x00000000,
+       0x00000000, 0x00C61110, 0x2C002834, 0x0C06002C,
+       0x00000200, 0x00000000, 0x00000000, 0x00007800,
+       0x00000000, 0x00000000, 0x00000000, 0x00C6BBB0,
+       0x2C002834, 0x0C06002C, 0x00000200, 0x00000000,
+       0x00000000, 0x00007800, 0x00000000, 0x00000000,
+       0x00000000, 0x00D60000, 0x50005000, 0x803E0050,
+       0x00000200, 0x00000000, 0x00000000, 0x00007800,
+       0x00000000, 0x00000000, 0x00000000, 0x00C61110,
+       0x2C002834, 0x082E002C, 0x00000200, 0x00000000,
+       0x00000000, 0x00007800, 0x00000000, 0x00000000,
+       0x00000000, 0x00C6BBB0, 0x2C002834, 0x082E002C,
+       0x00000200, 0x00000000, 0x00000000, 0x00007800,
+       0x00000000, 0x00000000, 0x00000000, 0x80808080,
+       0x800D8080, 0x80808080, 0x17808080, 0x80808025,
+       0x2221201F, 0x80808080, 0x80808080, 0x80808080,
+       0x80808080, 0x80808080, 0x80808080, 0x80808080,
+       0x80808080, 0x80808080, 0x80808080, 0x80808080,
+       0x80808080, 0x80808080, 0x80808080, 0x0A030201,
+       0x0E800C0B, 0x1211100F, 0x80161413, 0x08004C80,
+       0x8080801E, 0x80804E80, 0x80808080, 0x80808080,
+       0x80808080
+};
+
+struct dbsc5_table_patch {
+       const u32       reg;
+       const u32       val;
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_3200[] = {
+       { PHY_REGULATOR_EN_CNT, 0x10 },
+       { PHY_RX_CAL_ALL_DLY, 0x07 },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x08 },
+       { PHY_RDDATA_EN_OE_DLY, 0x0B },
+       { PHY_RPTR_UPDATE, 0x07 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x25 },
+       { PHY_RDLVL_MAX_EDGE, 0x012D },
+       { PHY_RDDATA_EN_DLY, 0x0B },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x04 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0x05 },
+       { PHY_GTLVL_LAT_ADJ_START, 0x03 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_3200[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_3200[] = {
+       { PI_TCKCKEL_F2, 0x03 },
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x57 },
+       { PI_TREF_F2, 0x613 },
+       { PI_TDFI_WRLVL_WW_F0, 0x2B },
+       { PI_TDFI_WRLVL_WW_F1, 0x2B },
+       { PI_TDFI_WRLVL_WW_F2, 0x2B },
+       { PI_RDLAT_ADJ_F2, 0x22 },
+       { PI_TDFI_CALVL_CAPTURE_F2, 0x1D },
+       { PI_TDFI_CALVL_CC_F2, 0x43 },
+       { PI_TVRCG_ENABLE_F2, 0x51 },
+       { PI_TVRCG_DISABLE_F2, 0x29 },
+       { PI_TXP_F2, 0x07 },
+       { PI_TMRWCKEL_F2, 0x0A },
+       { PI_TDFI_CALVL_STROBE_F2, 0x06 },
+       { PI_TFC_F2, 0x64 },
+       { PI_TCKEHDQS_F2, 0x12 },
+       { PI_TDFI_WDQLVL_RW_F2, 0x09 },
+       { PI_TDFI_WDQLVL_WR_F2, 0x10 },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x10 },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x1E },
+       { PI_TWTR_S_F2, 0x05 },
+       { PI_TWTR_L_F2, 0x05 },
+       { PI_TWTR_F2, 0x05 },
+       { PI_TWR_F2, 0x0E },
+       { PI_TDQSCK_MAX_F2, 0x01 },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x0C26 },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0x797C },
+       { PI_TXSNR_F2, 0x9B },
+       { PI_ZQRESET_F2, 0x0014 },
+       { PI_TCBTRTW_F2, 0x04 },
+       { PI_SEQ_WAIT_16_F2, 0x000064 },
+       { PI_SEQ_WAIT_17_F2, 0x000002 },
+       { PI_SEQ_WAIT_18_F2, 0x000007 },
+       { PI_SEQ_WAIT_19_F2, 0x000002 },
+       { PI_SEQ_WAIT_20_F2, 0x000002 },
+       { PI_SEQ_WAIT_21_F2, 0x000320 },
+       { PI_SEQ_WAIT_22_F2, 0x000002 },
+       { PI_SEQ_WAIT_23_F2, 0x00000E },
+       { PI_SEQ_WAIT_24_F2, 0x000029 },
+       { PI_SEQ_WAIT_25_F2, 0x000051 },
+       { PI_SEQ_WAIT_26_F2, 0x000003 },
+       { PI_SEQ_WAIT_30_F2, 0x00002B },
+       { PI_WRDCM_LVL_EN_F1, 0x00 },
+       { PI_WRDCM_LVL_EN_F2, 0x00 },
+       { PI_DRAMDCA_LVL_EN_F1, 0x00 },
+       { PI_DRAMDCA_LVL_EN_F2, 0x00 },
+       { PI_TINIT_F2, 0x013880 },
+       { PI_TINIT1_F2, 0x013880 },
+       { PI_TINIT3_F2, 0x0C3500 },
+       { PI_TINIT4_F2, 0x000014 },
+       { PI_TINIT5_F2, 0x000320 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_3733[] = {
+       { PHY_REGULATOR_EN_CNT, 0x13 },
+       { PHY_RX_CAL_ALL_DLY, 0x08 },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x0A },
+       { PHY_RDDATA_EN_OE_DLY, 0x0D },
+       { PHY_RPTR_UPDATE, 0x08 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x2A },
+       { PHY_RDLVL_MAX_EDGE, 0x0149 },
+       { PHY_RDDATA_EN_DLY, 0x0D },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x04 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0x9C },
+       { PHY_GTLVL_LAT_ADJ_START, 0x04 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_3733[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_3733[] = {
+       { PI_TCKCKEL_F2, 0x03 },
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x5B },
+       { PI_TREF_F2, 0x717 },
+       { PI_TDFI_WRLVL_WW_F0, 0x2C },
+       { PI_TDFI_WRLVL_WW_F1, 0x2C },
+       { PI_TDFI_WRLVL_WW_F2, 0x2C },
+       { PI_RDLAT_ADJ_F2, 0x24 },
+       { PI_TDFI_CALVL_CAPTURE_F2, 0x1F },
+       { PI_TDFI_CALVL_CC_F2, 0x45 },
+       { PI_TVRCG_ENABLE_F2, 0x5F },
+       { PI_TVRCG_DISABLE_F2, 0x30 },
+       { PI_TXP_F2, 0x07 },
+       { PI_TMRWCKEL_F2, 0x0A },
+       { PI_TDFI_CALVL_STROBE_F2, 0x06 },
+       { PI_TFC_F2, 0x75 },
+       { PI_TCKEHDQS_F2, 0x13 },
+       { PI_TDFI_WDQLVL_RW_F2, 0x09 },
+       { PI_TDFI_WDQLVL_WR_F2, 0x12 },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x10 },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x20 },
+       { PI_TWTR_S_F2, 0x06 },
+       { PI_TWTR_L_F2, 0x06 },
+       { PI_TWTR_F2, 0x06 },
+       { PI_TWR_F2, 0x10 },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x0E2E },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0x8DCC },
+       { PI_TXSNR_F2, 0xB5 },
+       { PI_ZQRESET_F2, 0x0018 },
+       { PI_TCBTRTW_F2, 0x05 },
+       { PI_SEQ_WAIT_16_F2, 0x000075 },
+       { PI_SEQ_WAIT_17_F2, 0x000002 },
+       { PI_SEQ_WAIT_18_F2, 0x000007 },
+       { PI_SEQ_WAIT_19_F2, 0x000002 },
+       { PI_SEQ_WAIT_20_F2, 0x000002 },
+       { PI_SEQ_WAIT_21_F2, 0x0003A6 },
+       { PI_SEQ_WAIT_22_F2, 0x000002 },
+       { PI_SEQ_WAIT_23_F2, 0x000011 },
+       { PI_SEQ_WAIT_24_F2, 0x000030 },
+       { PI_SEQ_WAIT_25_F2, 0x00005F },
+       { PI_SEQ_WAIT_26_F2, 0x000005 },
+       { PI_SEQ_WAIT_30_F2, 0x00002D },
+       { PI_TINIT_F2, 0x016C90 },
+       { PI_TINIT1_F2, 0x016C90 },
+       { PI_TINIT3_F2, 0x0E3D98 },
+       { PI_TINIT4_F2, 0x000018 },
+       { PI_TINIT5_F2, 0x0003A6 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_4266[] = {
+       { PHY_REGULATOR_EN_CNT, 0x16 },
+       { PHY_RX_CAL_ALL_DLY, 0x09 },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x0B },
+       { PHY_RDDATA_EN_OE_DLY, 0x0E },
+       { PHY_RPTR_UPDATE, 0x08 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x2E },
+       { PHY_RDLVL_MAX_EDGE, 0x0164 },
+       { PHY_RDDATA_EN_DLY, 0x0E },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x05 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0x30 },
+       { PHY_GTLVL_LAT_ADJ_START, 0x04 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_4266[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_4266[] = {
+       { PI_TCKCKEL_F2, 0x03 },
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x64 },
+       { PI_TREF_F2, 0x81C },
+       { PI_TDFI_WRLVL_WW_F0, 0x2D },
+       { PI_TDFI_WRLVL_WW_F1, 0x2D },
+       { PI_TDFI_WRLVL_WW_F2, 0x2D },
+       { PI_RDLAT_ADJ_F2, 0x2B },
+       { PI_TDFI_CALVL_CAPTURE_F2, 0x20 },
+       { PI_TDFI_CALVL_CC_F2, 0x46 },
+       { PI_TVRCG_ENABLE_F2, 0x6C },
+       { PI_TVRCG_DISABLE_F2, 0x37 },
+       { PI_TXP_F2, 0x07 },
+       { PI_TMRWCKEL_F2, 0x0A },
+       { PI_TFC_F2, 0x86 },
+       { PI_TCKEHDQS_F2, 0x14 },
+       { PI_TDFI_WDQLVL_RW_F2, 0x0B },
+       { PI_TDFI_WDQLVL_WR_F2, 0x13 },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x14 },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x27 },
+       { PI_TWTR_S_F2, 0x07 },
+       { PI_TWTR_L_F2, 0x07 },
+       { PI_TWTR_F2, 0x07 },
+       { PI_TWR_F2, 0x13 },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x1038 },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xA230 },
+       { PI_TXSNR_F2, 0xCF },
+       { PI_ZQRESET_F2, 0x001B },
+       { PI_TCBTRTW_F2, 0x06 },
+       { PI_SEQ_WAIT_16_F2, 0x000086 },
+       { PI_SEQ_WAIT_17_F2, 0x000002 },
+       { PI_SEQ_WAIT_18_F2, 0x000007 },
+       { PI_SEQ_WAIT_19_F2, 0x000002 },
+       { PI_SEQ_WAIT_20_F2, 0x000002 },
+       { PI_SEQ_WAIT_21_F2, 0x00042B },
+       { PI_SEQ_WAIT_22_F2, 0x000002 },
+       { PI_SEQ_WAIT_23_F2, 0x000013 },
+       { PI_SEQ_WAIT_24_F2, 0x000037 },
+       { PI_SEQ_WAIT_25_F2, 0x00006C },
+       { PI_SEQ_WAIT_26_F2, 0x000006 },
+       { PI_SEQ_WAIT_30_F2, 0x000032 },
+       { PI_TINIT_F2, 0x01A0AB },
+       { PI_TINIT1_F2, 0x01A0AB },
+       { PI_TINIT3_F2, 0x1046AB },
+       { PI_TINIT4_F2, 0x00001B },
+       { PI_TINIT5_F2, 0x00042B }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_4800[] = {
+       { PHY_REGULATOR_EN_CNT, 0x18 },
+       { PHY_RX_CAL_ALL_DLY, 0x0A },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x0D },
+       { PHY_RDDATA_EN_OE_DLY, 0x10 },
+       { PHY_RPTR_UPDATE, 0x08 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x31 },
+       { PHY_RDLVL_MAX_EDGE, 0x017F },
+       { PHY_RDDATA_EN_DLY, 0x10 },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x05 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0xC6 },
+       { PHY_GTLVL_LAT_ADJ_START, 0x05 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_4800[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_4800[] = {
+       { PI_TCKCKEL_F2, 0x03 },
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x68 },
+       { PI_RDLAT_ADJ_F2, 0x2D },
+       { PI_TREF_F2, 0x920 },
+       { PI_TDFI_WRLVL_WW_F0, 0x2E },
+       { PI_TDFI_WRLVL_WW_F1, 0x2E },
+       { PI_TDFI_WRLVL_WW_F2, 0x2E },
+       { PI_TDFI_CALVL_CAPTURE_F2, 0x21 },
+       { PI_TDFI_CALVL_CC_F2, 0x47 },
+       { PI_TVRCG_DISABLE_F2, 0x3D },
+       { PI_TVRCG_ENABLE_F2, 0x79 },
+       { PI_TXP_F2, 0x08 },
+       { PI_TMRWCKEL_F2, 0x0A },
+       { PI_TCKEHDQS_F2, 0x14 },
+       { PI_TFC_F2, 0x96 },
+       { PI_TDFI_WDQLVL_RW_F2, 0x0B },
+       { PI_TDFI_WDQLVL_WR_F2, 0x15 },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x18 },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x29 },
+       { PI_TWTR_S_F2, 0x08 },
+       { PI_TWR_F2, 0x15 },
+       { PI_TWTR_F2, 0x08 },
+       { PI_TWTR_L_F2, 0x08 },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x1240 },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xB680 },
+       { PI_TXSNR_F2, 0x0E9 },
+       { PI_ZQRESET_F2, 0x001E },
+       { PI_TCBTRTW_F2, 0x06 },
+       { PI_SEQ_WAIT_16_F2, 0x000096 },
+       { PI_SEQ_WAIT_17_F2, 0x000002 },
+       { PI_SEQ_WAIT_18_F2, 0x000008 },
+       { PI_SEQ_WAIT_19_F2, 0x000002 },
+       { PI_SEQ_WAIT_20_F2, 0x000002 },
+       { PI_SEQ_WAIT_21_F2, 0x0004B0 },
+       { PI_SEQ_WAIT_22_F2, 0x000002 },
+       { PI_SEQ_WAIT_23_F2, 0x000015 },
+       { PI_SEQ_WAIT_24_F2, 0x00003D },
+       { PI_SEQ_WAIT_25_F2, 0x000079 },
+       { PI_SEQ_WAIT_26_F2, 0x000008 },
+       { PI_SEQ_WAIT_30_F2, 0x000034 },
+       { PI_TINIT_F2, 0x01D4A9 },
+       { PI_TINIT1_F2, 0x01D4A9 },
+       { PI_TINIT3_F2, 0x124E91 },
+       { PI_TINIT4_F2, 0x00001E },
+       { PI_TINIT5_F2, 0x0004B0 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_5500[] = {
+       { PHY_REGULATOR_EN_CNT, 0x1C },
+       { PHY_RX_CAL_ALL_DLY, 0x0C },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x10 },
+       { PHY_RDDATA_EN_OE_DLY, 0x13 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x37 },
+       { PHY_RDLVL_MAX_EDGE, 0x01A3 },
+       { PHY_RDDATA_EN_DLY, 0x13 },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x06 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0x8F },
+       { PHY_GTLVL_LAT_ADJ_START, 0x06 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_5500[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_5500[] = {
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x71 },
+       { PI_RDLAT_ADJ_F2, 0x32 },
+       { PI_TREF_F2, 0xA79 },
+       { PI_TDFI_WRLVL_WW_F0, 0x30 },
+       { PI_TDFI_WRLVL_WW_F1, 0x30 },
+       { PI_TDFI_WRLVL_WW_F2, 0x30 },
+       { PI_TDFI_CALVL_CAPTURE_F2, 0x23 },
+       { PI_TDFI_CALVL_CC_F2, 0x49 },
+       { PI_TVRCG_DISABLE_F2, 0x46 },
+       { PI_TVRCG_ENABLE_F2, 0x8B },
+       { PI_TMRWCKEL_F2, 0x0B },
+       { PI_TCKEHDQS_F2, 0x15 },
+       { PI_TFC_F2, 0xAD },
+       { PI_TDFI_WDQLVL_RW_F2, 0x0C },
+       { PI_TDFI_WDQLVL_WR_F2, 0x17 },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x1C },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x2E },
+       { PI_TWTR_S_F2, 0x09 },
+       { PI_TWR_F2, 0x18 },
+       { PI_TWTR_F2, 0x09 },
+       { PI_TWTR_L_F2, 0x09 },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x14F2 },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xD174 },
+       { PI_TXSNR_F2, 0x10B },
+       { PI_ZQRESET_F2, 0x0023 },
+       { PI_TCBTRTW_F2, 0x07 },
+       { PI_SEQ_WAIT_16_F2, 0x0000AD },
+       { PI_SEQ_WAIT_21_F2, 0x000561 },
+       { PI_SEQ_WAIT_23_F2, 0x000019 },
+       { PI_SEQ_WAIT_24_F2, 0x000046 },
+       { PI_SEQ_WAIT_25_F2, 0x00008B },
+       { PI_SEQ_WAIT_26_F2, 0x00000A },
+       { PI_SEQ_WAIT_30_F2, 0x000038 },
+       { PI_TINIT_F2, 0x0219AF },
+       { PI_TINIT1_F2, 0x0219AF },
+       { PI_TINIT3_F2, 0x1500CF },
+       { PI_TINIT4_F2, 0x000023 },
+       { PI_TINIT5_F2, 0x000561 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_6000[] = {
+       { PHY_REGULATOR_EN_CNT, 0x1F },
+       { PHY_RDDATA_EN_TSEL_DLY, 0x12 },
+       { PHY_RDDATA_EN_OE_DLY, 0x15 },
+       { PHY_WRLVL_RESP_WAIT_CNT, 0x3A },
+       { PHY_RDLVL_MAX_EDGE, 0x01BD },
+       { PHY_RDDATA_EN_DLY, 0x15 },
+       { PHY_RDDQS_LATENCY_ADJUST, 0x07 },
+       { PHY_RDDQS_GATE_SLAVE_DELAY, 0x1B },
+       { PHY_GTLVL_LAT_ADJ_START, 0x06 },
+       { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_6000[] = {
+       { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
+       { PHY_ADR_CALVL_DLY_STEP, 0x02 }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_pi_6000[] = {
+       { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x75 },
+       { PI_RDLAT_ADJ_F2, 0x34 },
+       { PI_TREF_F2, 0xB6B },
+       { PI_TDFI_WRLVL_WW_F0, 0x31 },
+       { PI_TDFI_WRLVL_WW_F1, 0x31 },
+       { PI_TDFI_WRLVL_WW_F2, 0x31 },
+       { PI_TVRCG_DISABLE_F2, 0x4D },
+       { PI_TVRCG_ENABLE_F2, 0x98 },
+       { PI_TMRWCKEL_F2, 0x0C },
+       { PI_TFC_F2, 0xBC },
+       { PI_TDFI_WDQLVL_RW_F2, 0x0C },
+       { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x1C },
+       { PI_MBIST_RDLAT_ADJ_F2, 0x30 },
+       { PI_TWR_F2, 0x1A },
+       { PI_TDFI_CTRLUPD_MAX_F2, 0x16D6 },
+       { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xE45C },
+       { PI_TXSNR_F2, 0x123 },
+       { PI_ZQRESET_F2, 0x0026 },
+       { PI_SEQ_WAIT_16_F2, 0x0000BC },
+       { PI_SEQ_WAIT_21_F2, 0x0005DD },
+       { PI_SEQ_WAIT_23_F2, 0x00001B },
+       { PI_SEQ_WAIT_24_F2, 0x00004D },
+       { PI_SEQ_WAIT_25_F2, 0x000098 },
+       { PI_SEQ_WAIT_30_F2, 0x00003A },
+       { PI_TINIT_F2, 0x024A16 },
+       { PI_TINIT1_F2, 0x024A16 },
+       { PI_TINIT3_F2, 0x16E4D8 },
+       { PI_TINIT4_F2, 0x000026 },
+       { PI_TINIT5_F2, 0x0005DD }
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_mbpsdiv_640 = {
+       PHY_DATA_DC_CAL_CLK_SEL, 0x05
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_mbpsdiv_640 = {
+       PHY_CLK_DC_CAL_CLK_SEL, 0x04
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_640 = {
+       PHY_CAL_CLK_SELECT_0, 0x05
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_slice_mbpsdiv_572 = {
+       PHY_RX_PCLK_CLK_SEL, 0x3
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_572 = {
+       PHY_PAD_ACS_RX_PCLK_CLK_SEL, 0x03
+};
+
+static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_400[] = {
+       { PHY_PLL_CTRL, 0x1542 },
+       { PHY_PLL_CTRL_8X, 0x3342 }
+};
+
+/* Array of addresses for setting PI_DARRAY3_0 in each CS and frequency-set */
+static const u32 PI_DARRAY3_0_CSx_Fx[CS_CNT][3] = {
+       { PI_DARRAY3_0_CS0_F0, PI_DARRAY3_0_CS0_F1, PI_DARRAY3_0_CS0_F2 },
+       { PI_DARRAY3_0_CS1_F0, PI_DARRAY3_0_CS1_F1, PI_DARRAY3_0_CS1_F2 }
+};
+
+/* Array of addresses for setting PI_DARRAY3_1 in each CS and frequency-set */
+static const u32 PI_DARRAY3_1_CSx_Fx[CS_CNT][3] = {
+       { PI_DARRAY3_1_CS0_F0, PI_DARRAY3_1_CS0_F1, PI_DARRAY3_1_CS0_F2 },
+       { PI_DARRAY3_1_CS1_F0, PI_DARRAY3_1_CS1_F1, PI_DARRAY3_1_CS1_F2 }
+};
+
+/* DBSC registers */
+#define DBSC_DBSYSCONF0                        0x0
+#define DBSC_DBSYSCONF1                        0x0
+#define DBSC_DBSYSCONF1A               0x4
+#define DBSC_DBSYSCONF2                        0x4
+#define DBSC_DBPHYCONF0                        0x8
+#define DBSC_DBSYSCONF2A               0x8
+#define DBSC_DBMEMKIND                 0x20
+#define DBSC_DBMEMKINDA                        0x20
+#define DBSC_DBMEMCONF(ch, cs)         (0x30 + (0x2000 * ((ch) & 0x2)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
+#define DBSC_DBMEMCONFA(ch, cs)                (0x30 + (0x4000 * ((ch) & 0x2)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
+#define DBSC_DBSYSCNT0                 0x100
+#define DBSC_DBSYSCNT0A                        0x100
+#define DBSC_DBACEN                    0x200
+#define DBSC_DBRFEN                    0x204
+#define DBSC_DBCMD                     0x208
+#define DBSC_DBWAIT                    0x210
+#define DBSC_DBBL                      0x400
+#define DBSC_DBBLA                     0x400
+#define DBSC_DBRFCNF1                  0x414
+#define DBSC_DBRFCNF2                  0x418
+#define DBSC_DBCALCNF                  0x424
+#define DBSC_DBDBICNT                  0x518
+#define DBSC_DBDFIPMSTRCNF             0x520
+#define DBSC_DBDFICUPDCNF              0x540
+#define DBSC_DBBCAMDIS                 0x9FC
+#define DBSC_DBSCHRW1                  0x1024
+#define DBSC_DBSCHTR0                  0x1030
+#define DBSC_DBTR(x)                   (0x300 + (0x4 * (x)))
+#define DBSC_DBRNK(x)                  (0x430 + (0x4 * (x)))
+#define DBSC_DBDFISTAT(ch)             (0x600 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBDFICNT(ch)              (0x604 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDCNT2(ch)              (0x618 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDLK(ch)                        (0x620 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDRGA(ch)               (0x624 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDRGD(ch)               (0x628 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDRGM(ch)               (0x62C + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDSTAT0(ch)             (0x630 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDSTAT1(ch)             (0x634 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBSCHFCTST0               0x1040
+#define DBSC_DBSCHFCTST1               0x1044
+
+/* CPG PLL3 registers */
+#define CPG_CPGWPR                     0x0
+#define CPG_FRQCRD0                    0x80C
+#define CPG_PLLECR                     0x820
+#define CPG_PLL3CR0                    0x83C
+#define CPG_PLL3CR1                    0x8C0
+#define CPG_FSRCHKCLRR4                        0x590
+#define CPG_FSRCHKSETR4                        0x510
+#define CPG_FSRCHKRA4                  0x410
+#define CPG_SRCR4                      0x2C10
+#define CPG_SRSTCLR4                   0x2C90
+
+#define CPG_FRQCRD_KICK_BIT            BIT(31)
+#define CPG_PLL3CR0_KICK_BIT           BIT(31)
+#define CPG_PLLECR_PLL3ST_BIT          BIT(11)
+
+#define CLK_DIV(a, diva, b, divb)      (((a) * (divb)) / ((b) * (diva)))
+
+struct renesas_dbsc5_board_config {
+       /* Channels in use */
+       u8 bdcfg_phyvalid;
+       /* Read vref (SoC) training range */
+       u32 bdcfg_vref_r;
+       /* Write vref (MR14, MR15) training range */
+       u16 bdcfg_vref_w;
+       /* CA vref (MR12) training range */
+       u16 bdcfg_vref_ca;
+       /* RFM required check */
+       bool bdcfg_rfm_chk;
+
+       /* Board parameter about channels */
+       struct {
+               /*
+                * 0x00:  4Gb dual channel die /  2Gb single channel die
+                * 0x01:  6Gb dual channel die /  3Gb single channel die
+                * 0x02:  8Gb dual channel die /  4Gb single channel die
+                * 0x03: 12Gb dual channel die /  6Gb single channel die
+                * 0x04: 16Gb dual channel die /  8Gb single channel die
+                * 0x05: 24Gb dual channel die / 12Gb single channel die
+                * 0x06: 32Gb dual channel die / 16Gb single channel die
+                * 0x07: 24Gb single channel die
+                * 0x08: 32Gb single channel die
+                * 0xFF: NO_MEMORY
+                */
+               u8 bdcfg_ddr_density[CS_CNT];
+               /* SoC caX([6][5][4][3][2][1][0]) -> MEM caY: */
+               u32 bdcfg_ca_swap;
+               /* SoC dqsX([1][0]) -> MEM dqsY: */
+               u8 bdcfg_dqs_swap;
+               /* SoC dq([7][6][5][4][3][2][1][0]) -> MEM dqY/dm:  (8 means DM) */
+               u32 bdcfg_dq_swap[SLICE_CNT];
+               /* SoC dm -> MEM dqY/dm:  (8 means DM) */
+               u8 bdcfg_dm_swap[SLICE_CNT];
+               /* SoC ckeX([1][0]) -> MEM csY */
+               u8 bdcfg_cs_swap;
+       } ch[4];
+};
+
+struct renesas_dbsc5_dram_priv {
+       void __iomem    *regs;
+       void __iomem    *cpg_regs;
+
+       /* The board parameter structure of the board */
+       const struct renesas_dbsc5_board_config *dbsc5_board_config;
+
+       /* The board clock frequency */
+       u32             brd_clk;
+       u32             brd_clkdiv;
+       u32             brd_clkdiva;
+
+       /* The Mbps of Bus */
+       u32             bus_clk;
+       u32             bus_clkdiv;
+
+       /* The Mbps of DDR */
+       u32             ddr_mbps;
+       u32             ddr_mbpsdiv;
+
+       /* DDR memory multiplier setting value */
+       u32             ddr_mul;
+       u32             ddr_mul_nf;
+       u32             ddr_mul_low;
+       u32             ddr_mul_reg;
+
+       /* Value indicating the enabled channel */
+       u32             ddr_phyvalid;
+
+       /* The tccd value of DDR */
+       u32             ddr_tccd;
+
+       /* Memory capacity in each channel and each CS */
+       u8 ddr_density[DRAM_CH_CNT][CS_CNT];
+       /* Channels used for each memory rank */
+       u32             ch_have_this_cs[CS_CNT];
+       /* The maximum memory capacity */
+       u32             max_density;
+
+       /* Index of jedec spec1 setting table you use */
+       u32             js1_ind;
+       /* Array of jedec spec2 setting table */
+       u32             js2[JS2_CNT];
+       /* Read latency */
+       u32             RL;
+       /* Write latency */
+       u32             WL;
+
+       /* Array for DDR PI Slice settings */
+       u32             DDR_PI_REGSET[DDR_PI_REGSET_NUM_V4H];
+       /* Array for DDRPHY Slice settings */
+       u32             DDR_PHY_SLICE_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
+       /* Array for DDRPHY ADRRESS VALUE Slice settings */
+       u32             DDR_PHY_ADR_V_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
+       /* Array for DDRPHY ADRRESS CONTROL Slice settings */
+       u32             DDR_PHY_ADR_G_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
+};
+
+static const struct renesas_dbsc5_board_config renesas_v4h_dbsc5_board_config = {
+       /* RENESAS V4H White Hawk (64Gbit 1rank) */
+       .bdcfg_phyvalid = 0xF,
+       .bdcfg_vref_r   = 0x0,
+       .bdcfg_vref_w   = 0x0,
+       .bdcfg_vref_ca  = 0x0,
+       .bdcfg_rfm_chk  = true,
+       .ch = {
+               [0] = {
+                       .bdcfg_ddr_density =    { 0x06, 0xFF },
+                       .bdcfg_ca_swap =        0x04506132,
+                       .bdcfg_dqs_swap =       0x01,
+                       .bdcfg_dq_swap =        { 0x26147085, 0x12306845 },
+                       .bdcfg_dm_swap =        { 0x03, 0x07 },
+                       .bdcfg_cs_swap =        0x10
+               },
+               [1] = {
+                       .bdcfg_ddr_density =    { 0x06, 0xFF },
+                       .bdcfg_ca_swap =        0x02341065,
+                       .bdcfg_dqs_swap =       0x10,
+                       .bdcfg_dq_swap =        { 0x56782314, 0x71048365 },
+                       .bdcfg_dm_swap =        { 0x00, 0x02 },
+                       .bdcfg_cs_swap =        0x10
+               },
+               [2] = {
+                       .bdcfg_ddr_density =    { 0x06, 0xFF },
+                       .bdcfg_ca_swap =        0x02150643,
+                       .bdcfg_dqs_swap =       0x10,
+                       .bdcfg_dq_swap =        { 0x58264071, 0x41207536 },
+                       .bdcfg_dm_swap =        { 0x03, 0x08 },
+                       .bdcfg_cs_swap =        0x10
+               },
+               [3] = {
+                       .bdcfg_ddr_density =    { 0x06, 0xFF },
+                       .bdcfg_ca_swap =        0x01546230,
+                       .bdcfg_dqs_swap =       0x01,
+                       .bdcfg_dq_swap =        { 0x45761328, 0x62801745 },
+                       .bdcfg_dm_swap =        { 0x00, 0x03 },
+                       .bdcfg_cs_swap =        0x10
+               }
+       }
+};
+
+/**
+ * r_vch_nxt() - Macro for channel selection loop
+ *
+ * Return the ID of the channel to be used. Check for valid channels
+ * between the value of posn and the maximum number of CHs. If a valid
+ * channel is found, returns the value of that channel.
+ */
+static u32 r_vch_nxt(struct udevice *dev, u32 pos)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       int posn;
+
+       for (posn = pos; posn < DRAM_CH_CNT; posn++)
+               if (priv->ddr_phyvalid & BIT(posn))
+                       break;
+
+       return posn;
+}
+
+/* Select only valid channels in all channels from CH0. */
+#define r_foreach_vch(dev, ch)  \
+for ((ch) = r_vch_nxt((dev), 0); (ch) < DRAM_CH_CNT; (ch) = r_vch_nxt((dev), (ch) + 1))
+
+/* All channels are selected. */
+#define r_foreach_ech(ch) \
+for (ch = 0; ch < DRAM_CH_CNT; ch++)
+
+/**
+ * dbsc5_clk_cpg_write_32() - Write clock control register
+ *
+ * Write the complement value of setting value to the CPG_CPGWPR register
+ * for releaseing the protect. Write setting value to destination address.
+ */
+static void dbsc5_clk_cpg_write_32(struct udevice *dev, void __iomem *a, u32 v)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+
+       writel(~v, priv->cpg_regs + CPG_CPGWPR);
+       writel(v, a);
+}
+
+enum dbsc5_clk_pll3_mode {
+       PLL3_LOW_FREQUENCY_MODE = 0,
+       PLL3_HIGH_FREQUENCY_MODE,
+       PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER
+};
+
+/**
+ * dbsc5_clk_pll3_control() - Set PLL3
+ * @dev: DBSC5 device
+ * @mode: PLL3 frequency mode
+ *
+ * Determine the set value according to the frequency mode of the argument.
+ * Write the set value to CPG_FRQCRD0 register and CPG_FRQCRD0 one.
+ * Reflect settings
+ */
+static void dbsc5_clk_pll3_control(struct udevice *dev, u32 mode)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       u32 data_div, data_mul, data_nf, ssmode, val;
+       int ret;
+
+       /*
+        * PLL3VCO = EXTAL * priv->ddr_mul * 1/2
+        * clk_ctlr_sync = PLL3VCO * pll3_div
+        * priv->ddr_mul = (NI[7:0] + 1) * 2 + NF[24:0] / 2^24
+        */
+
+       switch (mode) {
+       case PLL3_LOW_FREQUENCY_MODE:
+               /* Low frequency mode (50MHz) */
+               data_mul = (priv->ddr_mul_low / 2) - 1; /* PLL3VCO = 1600MHz */
+               data_div = 0x9;                         /* div = 32 */
+               data_nf = 0x0;
+               ssmode = 0x0;
+               break;
+       case PLL3_HIGH_FREQUENCY_MODE:
+               /* High frequency mode */
+               data_mul = (priv->ddr_mul / 2) - 1;
+               data_div = 0x0;                         /* div = 2 */
+               data_nf = priv->ddr_mul_nf;
+               ssmode = 0x4;
+               break;
+       case PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER:
+               /* High frequency mode for loading to DDRPHY registers */
+               data_mul = (priv->ddr_mul_reg / 2) - 1;
+               data_div = 0x0;                         /* div = 2 */
+               data_nf = 0x0;
+               ssmode = 0x4;
+               break;
+       default:
+               printf("%s Mode %d not supported\n", __func__, mode);
+               hang();
+       }
+
+       data_mul = (data_mul << 20) | (ssmode << 16);
+       data_nf = data_nf << 21;
+
+       if (((readl(priv->cpg_regs + CPG_PLL3CR0) & 0x3FFFFF7F) != data_mul) ||
+           (readl(priv->cpg_regs + CPG_PLL3CR1) != data_nf)) {
+               /* PLL3CR0 multiplie set */
+               dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR0, data_mul);
+               /* PLL3CR1 multiplie set */
+               dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR1, data_nf);
+               dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR0,
+                                      readl(priv->cpg_regs + CPG_PLL3CR0) |
+                                      CPG_PLL3CR0_KICK_BIT);
+
+               ret = readl_poll_timeout(priv->cpg_regs + CPG_PLLECR, val,
+                                        (val & CPG_PLLECR_PLL3ST_BIT),
+                                        1000000);
+               if (ret < 0) {
+                       printf("%s CPG_PLLECR bit CPG_PLLECR_PLL3ST_BIT timeout\n", __func__);
+                       hang();
+               }
+       }
+
+       /* PLL3 DIV set(Target value) */
+       ret = readl_poll_timeout(priv->cpg_regs + CPG_FRQCRD0, val,
+                                ((val & CPG_FRQCRD_KICK_BIT) == 0),
+                                1000000);
+       if (ret < 0) {
+               printf("%s CPG_FRQCRD0 bit CPG_FRQCRD_KICK_BIT div set timeout\n", __func__);
+               hang();
+       }
+
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FRQCRD0,
+                              (readl(priv->cpg_regs + CPG_FRQCRD0) & 0xFFFFFFF0) |
+                              data_div);
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FRQCRD0,
+                              readl(priv->cpg_regs + CPG_FRQCRD0) |
+                              CPG_FRQCRD_KICK_BIT);
+       ret = readl_poll_timeout(priv->cpg_regs + CPG_FRQCRD0, val,
+                                ((val & CPG_FRQCRD_KICK_BIT) == 0),
+                                1000000);
+       if (ret < 0) {
+               printf("%s CPG_FRQCRD0 bit CPG_FRQCRD_KICK_BIT timeout\n", __func__);
+               hang();
+       }
+}
+
+/**
+ * dbsc5_clk_wait_freqchgreq() - Training handshake functions
+ *
+ * Check the value of the argument req_assert. If req_assert is 1, wait until
+ * FREQCHGREQ of all channels is 1 before time expires. If req_assert is 0,
+ * wait until FREQCHGREQ of all channels is 0 before time expires. Return the
+ * result of whether time has expired or not as a return value.
+ */
+static u32 dbsc5_clk_wait_freqchgreq(struct udevice *dev, u32 req_assert)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 count = 0xFFFFFF;
+       u32 ch, reg;
+
+       do {
+               reg = !!req_assert;
+               r_foreach_vch(dev, ch)
+                       reg &= readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch));
+               count = count - 1;
+       } while (((reg & 0x1) != !!req_assert) && (count != 0));
+
+       return count == 0x0;
+}
+
+/**
+ * dbsc5_clk_set_freqchgack() - Training handshake functions
+ * @dev: DBSC5 device
+ * @ack_assert: Select DBSC_DBPDCNT2 content
+ *
+ * Check the value of the argument ackassert. If the value of ackassert
+ * is greater than or equal to 0, write 0xCF01 to DBSC_DBPDCNT2.
+ * If the value of ackassert is 0, write 0x0 to DBSC_DBPDCNT2.
+ */
+static void dbsc5_clk_set_freqchgack(struct udevice *dev, u32 ack_assert)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       const u32 reg = ack_assert ? 0xcf01 : 0x0;
+       u32 ch;
+
+       r_foreach_vch(dev, ch)
+               writel(reg, regs_dbsc_d + DBSC_DBPDCNT2(ch));
+}
+
+/**
+ * dbsc5_clk_wait_dbpdstat1() - Wait for status register update
+ * @dev: DBSC5 device
+ * @status: Expected status
+ *
+ * Read value the DBSC_DBPDSTAT1(ch) register. Wait until the contents
+ * of the status register are the same as status.
+ */
+static void dbsc5_clk_wait_dbpdstat1(struct udevice *dev, u32 status)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 i, ch, reg;
+
+       for (i = 0; i < 2; i++) {
+               do {
+                       reg = status;
+                       r_foreach_vch(dev, ch)
+                               reg &= readl(regs_dbsc_d + DBSC_DBPDSTAT1(ch));
+               } while (reg != status);
+       }
+}
+
+/**
+ * dbsc5_clk_pll3_freq() - Set up the pll3 frequency
+ * @dev: DBSC5 device
+ *
+ * Wait for frequency change request. DBSC_DBPDSTAT0 value determines whether
+ * dbsc5_clk_pll3_control is called in low frequency mode or high frequency
+ * mode. Call dbsc5_clk_set_freqchgack(1) function. Check update completion until
+ * timeout. Call dbsc5_clk_set_freqchgack(0) function. If timed out, return with
+ * error log Wait for status register update.
+ */
+static int dbsc5_clk_pll3_freq(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 fsel, timeout;
+
+       dbsc5_clk_wait_freqchgreq(dev, 1);
+
+       fsel = (readl(regs_dbsc_d + DBSC_DBPDSTAT0(0)) & 0x300) >> 8;
+       dbsc5_clk_pll3_control(dev, fsel ? PLL3_HIGH_FREQUENCY_MODE :
+                                          PLL3_LOW_FREQUENCY_MODE);
+
+       dbsc5_clk_set_freqchgack(dev, 1);
+       timeout = dbsc5_clk_wait_freqchgreq(dev, 0);
+       dbsc5_clk_set_freqchgack(dev, 0);
+
+       if (timeout) {
+               printf("Time out\n");
+               return -ETIMEDOUT;
+       }
+
+       dbsc5_clk_wait_dbpdstat1(dev, 0x7);
+
+       return 0;
+}
+
+/**
+ * dbsc5_reg_write() - Write DBSC register
+ * @addr: Destination address
+ * @data: Setting value to be written
+ *
+ * Write 32bit value @data to register at @addr .
+ */
+static void dbsc5_reg_write(void __iomem *addr, u32 data)
+{
+       writel(data, addr);
+
+       if (((uintptr_t)addr & 0x000A0000) == 0x000A0000)
+               writel(data, addr + 0x4000);
+       else
+               writel(data, addr + 0x8000);
+}
+
+/**
+ * dbsc5_reg_write() - DRAM Command Write Access
+ * @dev: DBSC5 device
+ * @cmd DRAM command.
+ *
+ * First, execute the dummy read to DBSC_DBCMD.
+ * Confirm that no DBSC command operation is in progress 0.
+ * Write the contents of the command to be sent to DRAM.
+ */
+static void dbsc5_send_dbcmd2(struct udevice *dev, u32 cmd)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 val;
+       int ret;
+
+       /* dummy read */
+       readl(regs_dbsc_d + DBSC_DBCMD);
+
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT, val, ((val & BIT(0)) == 0), 1000000);
+       if (ret < 0) {
+               printf("%s DBWAIT bit 0 timeout\n", __func__);
+               hang();
+       }
+
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT + 0x4000, val, ((val & BIT(0)) == 0), 1000000);
+       if (ret < 0) {
+               printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__);
+               hang();
+       }
+
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBCMD, cmd);
+}
+
+/**
+ * dbsc5_reg_ddrphy_read() - Read setting from DDR PHY register
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @regadd: Destination address
+ *
+ * Write matching values to DBPDRGA register and read value out of DBSC_DBPDRGD.
+ * Wait until the write process completed in each step.
+ */
+static u32 dbsc5_reg_ddrphy_read(struct udevice *dev, u32 ch, u32 regadd)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 val;
+       int ret;
+
+       writel(regadd | BIT(14), regs_dbsc_d + DBSC_DBPDRGA(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15) | BIT(14))), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
+               hang();
+       }
+
+       val = readl(regs_dbsc_d + DBSC_DBPDRGA(ch));
+
+       writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
+               hang();
+       }
+
+       writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) again timeout\n", __func__);
+               hang();
+       }
+
+       return readl(regs_dbsc_d + DBSC_DBPDRGD(ch));
+}
+
+/**
+ * dbsc5_reg_ddrphy_write(dev, ) - Write setting to DDR PHY register
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @regadd: Destination address
+ * @regdata: Value to be written
+ *
+ * Write matching values to DBPDRGA, DBPDRGD, DBPDRGA, DBPDRGA registers.
+ * Wait until the write process completed in each step.
+ */
+static void dbsc5_reg_ddrphy_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 val;
+       int ret;
+
+       writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
+               hang();
+       }
+
+       writel(regdata, regs_dbsc_d + DBSC_DBPDRGD(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15))), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGD timeout\n", __func__);
+               hang();
+       }
+
+       writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
+               hang();
+       }
+
+       writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
+}
+
+/*
+ * dbsc5_reg_ddrphy_write_all() - Write setting from DDR PHY register for all channels
+ * @dev: DBSC5 device
+ * @regadd: Destination address
+ * @regdata: Value to be written
+ *
+ * Wrapper around dbsc5_reg_ddrphy_write() for all channels.
+ */
+static void dbsc5_reg_ddrphy_write_all(struct udevice *dev, u32 regadd, u32 regdata)
+{
+       u32 ch;
+
+       r_foreach_vch(dev, ch)
+               dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
+}
+
+/**
+ * dbsc5_reg_ddrphy_masked_write() - Write setting to DDR PHY register with mask
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @regadd: Destination address
+ * @regdata: Value to be written
+ * @msk: Register mask
+ *
+ * Wrapper around dbsc5_reg_ddrphy_write() with DBPDRGM set.
+ */
+static void dbsc5_reg_ddrphy_masked_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata, u32 msk)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 val;
+       int ret;
+
+       writel(msk, regs_dbsc_d + DBSC_DBPDRGM(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == msk), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGM timeout\n", __func__);
+               hang();
+       }
+
+       dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
+
+       writel(0, regs_dbsc_d + DBSC_DBPDRGM(ch));
+       ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == 0), 1000000);
+       if (ret < 0) {
+               printf("%s regs_dbsc_d + DBSC_DBPDRGM != 0 timeout\n", __func__);
+               hang();
+       }
+}
+
+/**
+ * dbsc5_ddr_setval_slice() - Write setting to DDR PHY hardware
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @slice: Target slice
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @val: Value to be written
+ *
+ * Calculate the bit field in which to write the setting value
+ * from encoded register and bitfield @regdef parameter. Call
+ * dbsc5_reg_ddrphy_masked_write() to write the value to hardware.
+ */
+static void dbsc5_ddr_setval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef, u32 val)
+{
+       const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
+       const u32 len = DDR_REGDEF_LEN(regdef);
+       const u32 lsb = DDR_REGDEF_LSB(regdef);
+       const u32 msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
+       const u32 dms = ~((!!(msk & BIT(24)) << 3) | (!!(msk & BIT(16)) << 2) |
+                         (!!(msk & BIT(8)) << 1) | !!(msk & BIT(0))) & 0xf;
+
+       dbsc5_reg_ddrphy_masked_write(dev, ch, adr, val << lsb, dms);
+}
+
+/*
+ * dbsc5_ddr_setval() - Write setting from DDR PHY hardware slice 0
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @val: Value to be written
+ *
+ * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
+ */
+static void dbsc5_ddr_setval(struct udevice *dev, u32 ch, u32 regdef, u32 val)
+{
+       dbsc5_ddr_setval_slice(dev, ch, 0, regdef, val);
+}
+
+/*
+ * dbsc5_ddr_setval_all_ch_slice() - Write setting from DDR PHY hardware for all channels and one slice
+ * @dev: DBSC5 device
+ * @slice: Target slice
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @val: Value to be written
+ *
+ * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
+ */
+static void dbsc5_ddr_setval_all_ch_slice(struct udevice *dev, u32 slice, u32 regdef, u32 val)
+{
+       u32 ch;
+
+       r_foreach_vch(dev, ch)
+               dbsc5_ddr_setval_slice(dev, ch, slice, regdef, val);
+}
+
+/*
+ * dbsc5_ddr_setval_all_ch() - Write setting from DDR PHY hardware for all channels and slice 0
+ * @dev: DBSC5 device
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @val: Value to be written
+ *
+ * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
+ */
+static void dbsc5_ddr_setval_all_ch(struct udevice *dev, u32 regdef, u32 val)
+{
+       dbsc5_ddr_setval_all_ch_slice(dev, 0, regdef, val);
+}
+
+/*
+ * dbsc5_ddr_setval_all_ch_all_slice() - Write setting from DDR PHY hardware for all channels and all slices
+ * @dev: DBSC5 device
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @val: Value to be written
+ *
+ * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
+ */
+static void dbsc5_ddr_setval_all_ch_all_slice(struct udevice *dev, u32 regdef, u32 val)
+{
+       u32 slice;
+
+       for (slice = 0; slice < SLICE_CNT; slice++)
+               dbsc5_ddr_setval_all_ch_slice(dev, slice, regdef, val);
+}
+
+/**
+ * dbsc5_ddr_getval_slice() - Read setting from DDR PHY/PI hardware
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @slice: Target slice
+ * @regdef: Encoded PHY/PI register and bitfield
+ *
+ * Calculate the address and the bit-field from "regdef" value.
+ * Call dbsc5_reg_ddrphy_read() to read value from the target address.
+ */
+static u32 dbsc5_ddr_getval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef)
+{
+       const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
+       const u32 len = DDR_REGDEF_LEN(regdef);
+       const u32 lsb = DDR_REGDEF_LSB(regdef);
+       const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
+
+       return (dbsc5_reg_ddrphy_read(dev, ch, adr) >> lsb) & msk;
+}
+
+/**
+ * dbsc5_ddr_getval() - Read setting from DDR PHY/PI hardware slice 0
+ * @dev: DBSC5 device
+ * @ch: Target channel
+ * @regdef: Encoded PHY/PI register and bitfield
+ *
+ * Wrapper around dbsc5_ddr_getval_slice() for slice 0.
+ */
+static u32 dbsc5_ddr_getval(struct udevice *dev, u32 ch, u32 regdef)
+{
+       return dbsc5_ddr_getval_slice(dev, ch, 0, regdef);
+}
+
+/**
+ * dbsc5_table_patch_set() - Modify DDR PHY/PI settings table
+ * @tbl: DDR PHY/PI setting table pointer
+ * @adrmsk_pi: Use wider address mask for PI register
+ * @patch: List of modifications to the settings table
+ * @patchlen: Length of the list of modifications to the settings table
+ *
+ * Calculate the target index of settings table, calculate the bit-field
+ * to write the setting value, and write the setting value to the target
+ * bit-field in the index.
+ */
+static void dbsc5_table_patch_set(u32 *tbl, const bool adrmsk_pi,
+                                 const struct dbsc5_table_patch *patch,
+                                 int patchlen)
+{
+       const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
+       u32 adr, len, lsb, msk;
+       int i;
+
+       for (i = 0; i < patchlen; i++) {
+               adr = DDR_REGDEF_ADR(patch[i].reg);
+               len = DDR_REGDEF_LEN(patch[i].reg);
+               lsb = DDR_REGDEF_LSB(patch[i].reg);
+               msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
+
+               tbl[adr & adrmsk] &= ~msk;
+               tbl[adr & adrmsk] |= (patch[i].val << lsb) & msk;
+       }
+}
+
+/**
+ * dbsc5_ddrtbl_getval() - Read setting from DDR PHY/PI settings table
+ * @tbl: DDR PHY/PI setting table pointer
+ * @regdef: Encoded PHY/PI register and bitfield
+ * @adrmsk_pi: Use wider address mask for PI register
+ *
+ * Calculate the target index of *tbl and the bit-field to read the
+ * setting value and read and return the setting value from the target
+ * bit-field in the index.
+ */
+static u32 dbsc5_ddrtbl_getval(const u32 *tbl, u32 regdef, bool adrmsk_pi)
+{
+       const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
+       const u32 adr = DDR_REGDEF_ADR(regdef);
+       const u32 len = DDR_REGDEF_LEN(regdef);
+       const u32 lsb = DDR_REGDEF_LSB(regdef);
+       const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
+
+       return (tbl[adr & adrmsk] >> lsb) & msk;
+}
+
+/**
+ * dbsc5_f_scale() - Calculate the best value for DBSC timing setting
+ * @priv: Driver private data
+ * @frac: Perform fractional rounding
+ * @ps Optimal setting value in pico second
+ * @cyc Optimal setting value in cycle count
+ *
+ * Convert the optimal value in pico second to in cycle count. Optionally, if @frac is true,
+ * perform fractional rounding. Compare the value of the result of the conversion with the
+ * value of the argument @cyc and return the larger value.
+ */
+static u32 dbsc5_f_scale(struct renesas_dbsc5_dram_priv *priv, const bool frac, u32 ps, u32 cyc)
+{
+       const u32 mul = frac ? 8 : 800000;
+       const u32 tmp = DIV_ROUND_UP(ps, 10UL) * priv->ddr_mbps;
+       const u32 f_scale_div = DIV_ROUND_UP(tmp, mul * priv->ddr_mbpsdiv);
+
+       return (f_scale_div > cyc) ? f_scale_div : cyc;
+}
+
+/**
+ * dbsc5_f_scale_js2() - Select optimal settings based on jedec_spec2
+ * @priv: Driver private data
+ *
+ * Calculate and assign each setting value of jedec_spec2 by "dbsc5_f_scale" function.
+ * Only the following array elements are calculated using different formulas from those
+ * described above -- JS2_tRRD/JS2_tFAW/JS2_tZQCALns/JS2_tRCpb/JS2_tRCab.
+ */
+static void dbsc5_f_scale_js2(struct renesas_dbsc5_dram_priv *priv)
+{
+       const int derate = 0;
+       int i;
+
+       for (i = 0; i < JS2_TBLCNT; i++) {
+               priv->js2[i] = dbsc5_f_scale(priv, false,
+                                            jedec_spec2[derate][i].ps,
+                                            jedec_spec2[derate][i].cyc);
+       }
+
+       priv->js2[JS2_tZQCALns] = dbsc5_f_scale(priv, false,
+                                               jedec_spec2[derate][JS2_tZQCALns].ps * 1000UL, 0);
+       priv->js2[JS2_tDQ72DQns] = dbsc5_f_scale(priv, false,
+                                                jedec_spec2[derate][JS2_tDQ72DQns].ps * 1000UL, 0);
+       priv->js2[JS2_tCAENTns] = dbsc5_f_scale(priv, false,
+                                               jedec_spec2[derate][JS2_tCAENTns].ps * 1000UL, 0);
+       priv->js2[JS2_tRCpb] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPpb];
+       priv->js2[JS2_tRCab] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPab];
+       priv->js2[JS2_tRFCab] = dbsc5_f_scale(priv, false,
+                                             jedec_spec2_tRFC_ab[priv->max_density] * 1000UL, 0);
+
+       priv->js2[JS2_tRBTP] = dbsc5_f_scale(priv, false, 7500, 2) - 2;
+       priv->js2[JS2_tXSR] = priv->js2[JS2_tRFCab] +
+                             dbsc5_f_scale(priv, false, 7500, 2);
+       priv->js2[JS2_tPDN] = dbsc5_f_scale(priv, false, 10000, 0) + 1;
+       priv->js2[JS2_tPDN_DSM] = dbsc5_f_scale(priv, true,
+                                               jedec_spec2[derate][JS2_tPDN_DSM].ps * 10UL, 0);
+       priv->js2[JS2_tXSR_DSM] = dbsc5_f_scale(priv, true,
+                                               jedec_spec2[derate][JS2_tXSR_DSM].ps * 10UL, 0);
+       priv->js2[JS2_tXDSM_XP] = dbsc5_f_scale(priv, true,
+                                               jedec_spec2[derate][JS2_tXDSM_XP].ps * 10UL, 0);
+       priv->js2[JS2_tWLWCKOFF] = dbsc5_f_scale(priv, false, 14000, 5);
+}
+
+/**
+ * dbsc5_ddrtbl_calc() - Calculate JS1/JS2
+ * @priv: Driver private data
+ *
+ * Determine jedec_spec1 configuration table based on priv->ddr_mbps
+ * and priv->ddr_mbpsdiv. Calculate the value of the jedec_spec2
+ * configuration table from priv->ddr_mbps and priv->ddr_mbpsdiv.
+ */
+static void dbsc5_ddrtbl_calc(struct renesas_dbsc5_dram_priv *priv)
+{
+       int i;
+
+       /* Search jedec_spec1 index */
+       for (i = JS1_USABLEC_SPEC_LO; i < JS1_FREQ_TBL_NUM - 1; i++)
+               if (js1[i].fx3 * 2 * priv->ddr_mbpsdiv >= priv->ddr_mbps * 3)
+                       break;
+
+       priv->js1_ind = max(i, JS1_USABLEC_SPEC_HI);
+
+       priv->RL = js1[priv->js1_ind].RLset1;
+       priv->WL = js1[priv->js1_ind].WLsetA;
+
+       /* Calculate jedec_spec2 */
+       dbsc5_f_scale_js2(priv);
+};
+
+/**
+ * dbsc5_ddrtbl_load() Load table data into DDR registers
+ * @dev: DBSC5 device
+ *
+ * Copy the base configuration table to a local array. Change PI register table
+ * settings to match priv->ddr_mbps and priv->ddr_mbpsdiv.
+ *
+ * If the set value vref_r is not 0, change the "Read Vref (SoC side) Training range"
+ * setting in the configuration table.
+ *
+ * If the set value vref_w is not 0, change the "Write Vref (MR14, MR15) Training range"
+ * setting in the configuration table.
+ *
+ * If the set value vref_ca is not 0, change the "CA Vref (MR12) Training range"
+ * setting in the configuration table.
+ *
+ * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 5120,
+ * change the contents of the PHY register setting table.
+ * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 4576,
+ * change the contents of the PHY register setting table.
+ *
+ * Reflect the contents of the configuration table in the register.
+ */
+static void dbsc5_ddrtbl_load(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbps = {
+               PHY_CAL_INTERVAL_COUNT_0, 10000 * priv->ddr_mbps / priv->ddr_mbpsdiv / 8 / 256,
+       };
+
+       const struct dbsc5_table_patch dbsc5_table_patch_pi_js[] = {
+               { PI_WRLAT_F2, priv->WL },
+               { PI_TWCKENL_WR_ADJ_F2, (js1[priv->js1_ind].WCKENLW * 4) + 4 },
+               { PI_TWCKENL_RD_ADJ_F2, (js1[priv->js1_ind].WCKENLR * 4) + 4 },
+               { PI_TWCKPRE_STATIC_F2, (js1[priv->js1_ind].WCKPRESTA * 4) },
+               { PI_TWCKPRE_TOGGLE_RD_F2, (js1[priv->js1_ind].WCKPRETGLR) * 4 },
+               { PI_CASLAT_F2, priv->RL },
+               { PI_TWCKENL_FS_ADJ_F2, (js1[priv->js1_ind].WCKENLF * 4) + 4 },
+               { PI_TRFC_F2, priv->js2[JS2_tRFCab] },
+               { PI_WRLVL_WCKOFF_F2, (priv->js2[JS2_tWLWCKOFF]) + 3 },
+               { PI_WRLAT_ADJ_F2, (priv->WL * 4) + 2 },
+               { PI_TCAENT_F2, priv->js2[JS2_tCAENTns] },
+               { PI_TVREF_LONG_F2, (priv->js2[JS2_tCAENTns]) + 1 },
+               { PI_TVREF_SHORT_F2, (priv->js2[JS2_tCAENTns]) + 1 },
+               { PI_TRCD_F2, priv->js2[JS2_tRCD] },
+               { PI_TRP_F2, priv->js2[JS2_tRPab] },
+               { PI_TRTP_F2, js1[priv->js1_ind].nRBTP },
+               { PI_TRAS_MIN_F2, priv->js2[JS2_tRAS] },
+               { PI_TMRD_F2, (priv->js2[JS2_tMRD]) + 1 },
+               { PI_TSR_F2, priv->js2[JS2_tSR] },
+               { PI_TZQCAL_F2, priv->js2[JS2_tZQCALns] },
+               { PI_TZQLAT_F2, priv->js2[JS2_tZQLAT] },
+               { PI_TDQ72DQ_F2, priv->js2[JS2_tDQ72DQns] },
+               { PI_MC_TRFC_F2, priv->js2[JS2_tRFCab] },
+       };
+
+       const u32 vref_r = priv->dbsc5_board_config->bdcfg_vref_r;
+       const struct dbsc5_table_patch dbsc5_table_patch_slice_vref_r[] = {
+               { PHY_VREF_INITIAL_START_POINT, vref_r & 0xFF },
+               { PHY_VREF_INITIAL_STOP_POINT, (vref_r & 0xFF00) >> 8 },
+               { PHY_VREF_INITIAL_STEPSIZE, (vref_r & 0xFF0000) >> 16 }
+       };
+
+       const u32 vref_w = priv->dbsc5_board_config->bdcfg_vref_w;
+       const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_w[] = {
+               { PI_WDQLVL_VREF_INITIAL_START_POINT_F0, vref_w & 0xff },
+               { PI_WDQLVL_VREF_INITIAL_START_POINT_F1, vref_w & 0xff },
+               { PI_WDQLVL_VREF_INITIAL_START_POINT_F2, vref_w & 0xff },
+               { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0, (vref_w & 0xff00) >> 8 },
+               { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1, (vref_w & 0xff00) >> 8 },
+               { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2, (vref_w & 0xff00) >> 8 }
+       };
+
+       const u32 vref_ca = priv->dbsc5_board_config->bdcfg_vref_ca;
+       const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_ca[] = {
+               { PI_CALVL_VREF_INITIAL_START_POINT_F0, vref_ca & 0xff },
+               { PI_CALVL_VREF_INITIAL_START_POINT_F1, vref_ca & 0xff },
+               { PI_CALVL_VREF_INITIAL_START_POINT_F2, vref_ca & 0xff },
+               { PI_CALVL_VREF_INITIAL_STOP_POINT_F0, (vref_ca & 0xff00) >> 8 },
+               { PI_CALVL_VREF_INITIAL_STOP_POINT_F1, (vref_ca & 0xff00) >> 8 },
+               { PI_CALVL_VREF_INITIAL_STOP_POINT_F2, (vref_ca & 0xff00) >> 8 }
+       };
+
+       int i, cs, slice;
+       u32 adr;
+
+       /* Prepare register tables */
+       memcpy(priv->DDR_PHY_SLICE_REGSET, DDR_PHY_SLICE_REGSET_V4H, sizeof(DDR_PHY_SLICE_REGSET_V4H));
+       memcpy(priv->DDR_PHY_ADR_V_REGSET, DDR_PHY_ADR_V_REGSET_V4H, sizeof(DDR_PHY_ADR_V_REGSET_V4H));
+       memcpy(priv->DDR_PHY_ADR_G_REGSET, DDR_PHY_ADR_G_REGSET_V4H, sizeof(DDR_PHY_ADR_G_REGSET_V4H));
+       memcpy(priv->DDR_PI_REGSET, DDR_PI_REGSET_V4H, sizeof(DDR_PI_REGSET_V4H));
+
+       /* Adjust PI parameters */
+       dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
+                             &dbsc5_table_patch_adr_g_mbps, 1);
+       dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                             dbsc5_table_patch_pi_js,
+                             ARRAY_SIZE(dbsc5_table_patch_pi_js));
+
+       if (priv->ddr_mbps < (3201 * priv->ddr_mbpsdiv)) {
+               /* 2751-3200 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_3200,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_3200));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_3200,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_3200));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_3200,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_3200));
+       } else if (priv->ddr_mbps < (3734 * priv->ddr_mbpsdiv)) {
+               /* 3201-3733 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_3733,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_3733));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_3733,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_3733));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_3733,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_3733));
+       } else if (priv->ddr_mbps < (4268 * priv->ddr_mbpsdiv)) {
+               /* 3734-4267 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_4266,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_4266));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_4266,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_4266));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_4266,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_4266));
+       } else if (priv->ddr_mbps < (4801 * priv->ddr_mbpsdiv)) {
+               /* 4269-4800 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_4800,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_4800));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_4800,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_4800));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_4800,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_4800));
+       } else if (priv->ddr_mbps < (5501 * priv->ddr_mbpsdiv)) {
+               /* 4801 - 5500 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_5500,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_5500));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_5500,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_5500));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_5500,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_5500));
+       } else if (priv->ddr_mbps < (6001 * priv->ddr_mbpsdiv)) {
+               /* 5501 - 6000 */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_6000,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_6000));
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     dbsc5_table_patch_adr_v_6000,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_v_6000));
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_6000,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_6000));
+       }
+
+       for (cs = 0; cs < CS_CNT; cs++) {
+               struct dbsc5_table_patch dbsc5_table_patch_pi_mr12[] = {
+                       { PI_DARRAY3_0_CSx_Fx[cs][2], js1[priv->js1_ind].MR1 },
+                       { PI_DARRAY3_1_CSx_Fx[cs][2], js1[priv->js1_ind].MR2 },
+               };
+
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_mr12,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_mr12));
+       }
+
+       /* Read Vref (SoC side) Training range */
+       if (priv->dbsc5_board_config->bdcfg_vref_r) {
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     dbsc5_table_patch_slice_vref_r,
+                                     ARRAY_SIZE(dbsc5_table_patch_slice_vref_r));
+       }
+
+       /* Write Vref (MR14, MR15) Training range */
+       if (priv->dbsc5_board_config->bdcfg_vref_w) {
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_vref_w,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_vref_w));
+       }
+
+       /* CA Vref (MR12) Training range */
+       if (priv->dbsc5_board_config->bdcfg_vref_ca) {
+               dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
+                                     dbsc5_table_patch_pi_vref_ca,
+                                     ARRAY_SIZE(dbsc5_table_patch_pi_vref_ca));
+       }
+
+       /* Low Freq setting */
+       if (priv->ddr_mbps < (8 * 640 * priv->ddr_mbpsdiv)) {
+               /* CAL_CLK(10-20MHz) */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     &dbsc5_table_patch_slice_mbpsdiv_640, 1);
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
+                                     &dbsc5_table_patch_adr_v_mbpsdiv_640, 1);
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
+                                     &dbsc5_table_patch_adr_g_mbpsdiv_640, 1);
+       }
+
+       if (priv->ddr_mbps < (8 * 572 * priv->ddr_mbpsdiv)) {
+               /* CAL_CLK(10-20MHz) */
+               dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
+                                     &dbsc5_table_patch_slice_mbpsdiv_572, 1);
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
+                                     &dbsc5_table_patch_adr_g_mbpsdiv_572, 1);
+       }
+
+       if (priv->ddr_mbps < (8 * 401 * priv->ddr_mbpsdiv)) {
+               dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
+                                     dbsc5_table_patch_adr_g_mbpsdiv_400,
+                                     ARRAY_SIZE(dbsc5_table_patch_adr_g_mbpsdiv_400));
+       }
+
+       /* SET DATA SLICE TABLE */
+       for (slice = 0; slice < SLICE_CNT; slice++) {
+               adr = DDR_PHY_SLICE_REGSET_OFS_V4H + (DDR_PHY_SLICE_REGSET_SIZE_V4H * slice);
+               for (i = 0; i < DDR_PHY_SLICE_REGSET_NUM_V4H; i++)
+                       dbsc5_reg_ddrphy_write_all(dev, adr + i, priv->DDR_PHY_SLICE_REGSET[i]);
+       }
+
+       /* SET ADR SLICE TABLE */
+       for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM_V4H; i++)
+               dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_V_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_V_REGSET[i]);
+
+       /* SET ADRCTRL SLICE TABLE */
+       for (i = 0; i < DDR_PHY_ADR_G_REGSET_NUM_V4H; i++)
+               dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_G_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_G_REGSET[i]);
+
+       /* SET PI REGISTERS */
+       for (i = 0; i < DDR_PI_REGSET_NUM_V4H; i++)
+               dbsc5_reg_ddrphy_write_all(dev, DDR_PI_REGSET_OFS_V4H + i, priv->DDR_PI_REGSET[i]);
+}
+
+/**
+ * dbsc5_ddr_config() - Configure DDR registers
+ * @dev: DBSC5 device
+ *
+ * Set up wiring for DQ and DM pins and VREF_DRIVING. Set the CA pin wiring
+ * and ADR_CALVL_SWIZZLE settings. Make wiring settings for the CS pin. When
+ * memory rank is 1, set RANK setting to 1 to disable CS training. Configure
+ * the DATA_BYTE_SWAP setting.
+ */
+static void dbsc5_ddr_config(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       u32 ca_swap, cs_swap, dqs_swap;
+       u32 ch, slice;
+
+       r_foreach_vch(dev, ch) {
+               /* Board settings (DQ, DM, VREF_DRIVING) */
+               dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
+               for (slice = 0; slice < SLICE_CNT; slice++) {
+                       dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE0,
+                                              priv->dbsc5_board_config->ch[ch].bdcfg_dq_swap[slice]);
+                       dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE1,
+                                              priv->dbsc5_board_config->ch[ch].bdcfg_dm_swap[slice]);
+                       dbsc5_ddr_setval_slice(dev, ch, slice, PHY_CALVL_VREF_DRIVING_SLICE,
+                                              !((dqs_swap >> (4 * slice)) & 1));
+               }
+               dbsc5_ddr_setval(dev, ch, PHY_DATA_BYTE_ORDER_SEL,
+                                priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap | 0x76543200);
+
+               /* Board settings (CA, ADDR_MUX) */
+               ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
+
+               /* ADDR_MUX */
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_0, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_1, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_2, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_3, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_4, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_5, ca_swap & 0xf);
+               ca_swap >>= 4;
+               dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_6, ca_swap & 0xf);
+               ca_swap >>= 4;
+
+               /* ADR_CALVL_SWIZZLE */
+               ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
+               dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_SWIZZLE0, ca_swap & 0x0fffffff);
+
+               /* Board settings (CS) */
+               /* CKE_MUX */
+               /* SoC CKE -> DRAM CS */
+               cs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_cs_swap;
+               dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_0, (cs_swap & 0xf) + 2);
+               dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_1, ((cs_swap >> 4) & 0xf) + 2);
+               dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT2_2, (cs_swap & 0xf) + 1);
+               dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT3_2, ((cs_swap >> 4) & 0xf) + 1);
+
+               /* Mask CS_MAP if RANK1 is not found */
+               if (!(priv->ch_have_this_cs[1] & BIT(ch))) {
+                       dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_RANK_CTRL, 0x0);
+                       for (slice = 0; slice < SLICE_CNT; slice++)
+                               dbsc5_ddr_setval_slice(dev, ch, slice, PHY_PER_CS_TRAINING_EN, 0x0);
+               }
+       }
+
+       r_foreach_vch(dev, ch) {
+               /* DATA_BYTE_SWAP */
+               dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
+
+               dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_EN, 0x1);
+               dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE0, dqs_swap & 0xf);
+               dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE1, (dqs_swap >> 4) & 0xf);
+
+               if (!(priv->ch_have_this_cs[1] & BIT(ch)))
+                       dbsc5_ddr_setval(dev, ch, PI_CS_MAP, 0x1);
+       }
+}
+
+/**
+ * dbsc5_dbsc_regset_pre() - Configure primary DDR registers
+ * @dev: DBSC5 device
+ *
+ * Set SDRAM type, Burst length, and PHY type. Frequency mode setting.
+ * Write SDRAM configuration contents to registers.
+ */
+static void dbsc5_dbsc_regset_pre(struct udevice *dev)
+{
+#define DBMEMCONF_REG(d3, row, bg, bank, col, dw)      \
+       (((d3) << 30) | ((row) << 24) | ((bg) << 20) | ((bank) << 16) | ((col) << 8) | (dw))
+#define DBMEMCONF_REGD(density)                   /* 16bit */  \
+       DBMEMCONF_REG(((density) % 2), ((((density) + 1) / 2) + (28 - 2 - 2 - 10 - 1)), 2, 2, 10, 1)
+
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 density;
+       u32 ch, cs;
+
+       /* Primary settings */
+       /* LPDDR5, BL=16, DFI interface */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBMEMKIND, 0xC);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBMEMKINDA, 0xC);
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBBL, 0x2);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBBLA, 0x2);
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBPHYCONF0, 0x1);
+
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF0, 0x1);
+
+       /* FREQRATIO=2 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF1, 0x20000);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF1A, 0x0);
+
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF2, 0x1);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF2A, 0x241);
+
+       r_foreach_ech(ch) {
+               for (cs = 0; cs < CS_CNT; cs++) {
+                       if (priv->ddr_density[ch][cs] == 0xFF) {
+                               writel(0x00, regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
+                               writel(0x00, regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
+                       } else {
+                               density = priv->ddr_density[ch][cs];
+                               writel(DBMEMCONF_REGD(density),
+                                      regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
+                               writel(DBMEMCONF_REGD(density),
+                                      regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
+                       }
+               }
+       }
+}
+
+/**
+ * dbsc5_dbsc_regset() - Set DBSC timing parameters
+ * @dev: DBSC5 device
+ *
+ * Set the timing registers of the DBSC.
+ * Configure Scheduler settings.
+ */
+static void dbsc5_dbsc_regset(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 tmp[4];
+
+       /* DBTR0.CL  : RL */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(0), priv->RL);
+
+       /* DBTR1.CWL : WL */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(1), priv->WL);
+
+       /* DBTR2.AL = 0 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(2), 0x0);
+
+       /* DBTR3.TRCD: tRCD */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(3), priv->js2[JS2_tRCD]);
+
+       /* DBTR4.TRPA,TRP: tRPab,tRPpb */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(4), (priv->js2[JS2_tRPab] << 16) |
+                                     priv->js2[JS2_tRPpb]);
+
+       /* DBTR5.TRC : tRCpb */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(5), priv->js2[JS2_tRCpb]);
+
+       /* DBTR6.TRAS : tRAS */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(6), priv->js2[JS2_tRAS]);
+
+       /* DBTR7.TRRD : tRRD */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(7), ((priv->js2[JS2_tRRD] - 1) << 16) |
+                                     (priv->js2[JS2_tRRD] - 1));
+
+       /* DBTR8.TFAW : tFAW */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(8), priv->js2[JS2_tFAW] - 1);
+
+       /* DBTR9.TRDPR: nRBTP */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(9), js1[priv->js1_ind].nRBTP);
+
+       /* DBTR10.TWR : nWR */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(10), js1[priv->js1_ind].nWR);
+
+       /*
+        * DBTR11.TRDWR : RL + BL/n_max + RU(tWCK2DQO(max)/tCK) +
+        * RD(tRPST/tCK) - ODTLon - RD(tODTon(min)/tCK) + 1 + feature
+        */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(11),
+                       priv->RL + 4 + priv->js2[JS2_tWCK2DQO_HF] -
+                       js1[priv->js1_ind].ODTLon - priv->js2[JS2_tODTon_min]);
+
+       /* DBTR12.TWRRD_S : WL + BL/2 + tWTR_S, TWRRD_L : WL + BL + tWTR_L */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(12),
+                       ((priv->WL + 2 + priv->js2[JS2_tWTR_S]) << 16) |
+                       (priv->WL + 4 + priv->js2[JS2_tWTR_L]));
+
+       /* DBTR13.TRFCAB : tRFCab */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(13), priv->js2[JS2_tRFCab]);
+
+       /* DBTR14.TCSCAL,TCKEHDLL,tCKEH : tCSCAL,tXP,tXP */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(14), (priv->js2[JS2_tCSCAL] << 24) |
+                                      (priv->js2[JS2_tXP] << 16) |
+                                      priv->js2[JS2_tXP]);
+
+       /* DBTR15.TESPD,TCKESR,TCKEL : tESPD = 2,tSR,tSR */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(15), (0x02 << 24) |
+                                      (priv->js2[JS2_tSR] << 16) |
+                                      priv->js2[JS2_tSR]);
+
+       /* DBTR16 */
+       /* wdql(tphy_wrlat + tphy_wrdata) */
+       tmp[0] = (priv->WL * 4) - 1 + 5;
+       /* dqenltcy(tphy_wrlat) */
+       tmp[1] = (priv->WL * 4) - 2 - 2 + 5;
+       /* dql(tphy_rdlat + trddata_en) RL * 4 + phy_rptr_update + phy_rddqs_latency_adjust + 39 */
+       tmp[2] = (priv->RL * 4) +
+                dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RPTR_UPDATE, false) +
+                dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDQS_LATENCY_ADJUST, false) +
+                39;
+       /* dqienltncy(trddata_en) RL * 4 - phy_rddata_en_dly_X + 4 * phy_wck_freq_ratio_X */
+       tmp[3] = (priv->RL * 4) + 4 -
+                dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDATA_EN_DLY, false);
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(16), (tmp[3] << 24) | (tmp[2] << 16) |
+                                      (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR17.TMODRD,TMOD: tMRR,tMRW */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(17), (priv->js2[JS2_tMRR] << 24) |
+                                      (priv->js2[JS2_tMRW] << 16));
+
+       /* DBTR18. RODTL, RODTA = 0 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(18), 0x0);
+
+       /* DBTR19. TZQCL, TZQCS = 0 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(19), 0x0);
+
+       /* DBTR20.TXSDLL, TXS : tXSR,tXSR */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(20), ((priv->js2[JS2_tXSR]) << 16) |
+                                      priv->js2[JS2_tXSR]);
+
+       /* DBTR21.TCCD */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(21), (priv->ddr_tccd << 16) |
+                                      (priv->ddr_tccd * 2));
+
+       /* DBTR22.TZQCAL,TZQLAT : tZQCAL,tZQLAT */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(22), (priv->js2[JS2_tZQCALns] << 16) | priv->js2[JS2_tZQLAT]);
+
+       /* DBTR23. RRSPC = 0 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(23), 0x0);
+
+       /* DBTR24 */
+       /* WRCSLAT(tphy_wrcslat) */
+       tmp[0] = (priv->WL * 4) - 2;
+       /* WRCSGAP(tphy_wrcsgap) */
+       tmp[1] = 0x0C;
+       /* RDCSLAT(tphy_rdcslat) */
+       tmp[2] = priv->RL * 4;
+       /* RDCSGAP(tphy_rdcsgap) */
+       tmp[3] = 0x0C;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(24), (tmp[3] << 24) | (tmp[2] << 16) |
+                                      (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR25. TWDQLVLDIS = 0 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(25), 0x0);
+
+       /* DBTR26. TWCK2DQOOSC,TDQSOSC : WCK2DQI interval timer run time, WCK2DQO interval timer run time */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(26), 0x0);
+
+       /* DBTR27.TPDN : tPDN */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(27), priv->js2[JS2_tPDN]);
+
+       /* DBTR28.txsrdsm : tXSR_DSM */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(28), priv->js2[JS2_tXSR_DSM]);
+
+       /* DBTR29.tdsmxp : tXDSM_XP */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(29), priv->js2[JS2_tXDSM_XP]);
+
+       /* DBTR30.TCMDPD : tCMDPD = 3 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(30), 0x3);
+
+       /* DBTR31.TWCK2DQOMAX,TWCK2DQIMAX : tWCK2DQI/O_HF/LF */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(31), (priv->js2[JS2_tWCK2DQO_HF] << 4) |
+                                      priv->js2[JS2_tWCK2DQI_HF]);
+
+       /* DBTR32 */
+       /* twckenr */
+       tmp[0] = (js1[priv->js1_ind].WCKENLR * 4) + 4 - 1;
+       /* twckenw  */
+       tmp[1] = (js1[priv->js1_ind].WCKENLW * 4) + 4 - 1;
+       /* twckenlf */
+       tmp[2] = (js1[priv->js1_ind].WCKENLF * 4) + 4;
+       /* twckpresta */
+       tmp[3] = js1[priv->js1_ind].WCKPRESTA * 4;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(32), (tmp[3] << 24) | (tmp[2] << 16) |
+                                      (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR33 */
+       /* TWCKTGL */
+       tmp[0] = 4;
+       /* TWCKDIS  (RL+ bl/n_max) * 4 + RU(tWCKPST/tWCK) : tWCKPST = 2.5(MR10[3:2]) */
+       tmp[1] = ((priv->RL + 4) * 4) + 3;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(33), (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR34 */
+       /* TWCKSUS = 4 */
+       tmp[0] = 4;
+       /* TWCKPST  RU(tWCKPST/tCK) : tWCKPST=2.5(MR10[3:2]) */
+       tmp[1] = 1;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(34), (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR35 */
+       /* TRD2WCKOFF RL + BL/n_max + RD(tWCKPST/tCK) + 1 */
+       tmp[0] = priv->RL + 4 + 0 + 1;
+       /* TWR2WCKOFF WL + BL/n_max + RD(tWCKPST/tCK) + 1 */
+       tmp[1] = priv->WL + 4 + 0 + 1;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(35), (tmp[1] << 16) | tmp[0]);
+
+       /* DBTR36 */
+       /* TWSSUSWRX : CAS(WCKSUS)WRX */
+       tmp[0] = 3;
+       /* TWSOFFWRX : CAS(WS_OFF)WRX */
+       tmp[1] = 3;
+       /* TWSFSWRX : CAS(WS_FS)WRX */
+       tmp[2] = 2;
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(36), (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
+
+       /* DBTR37 */
+       /* tOSCO */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(37), priv->js2[JS2_tOSCODQI]);
+
+       /* DBRNK2 */
+       /* RNKRR = 12 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(2), 0xCC);
+
+       /* DBRNK3 */
+       /* RNKRW = 6 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(3), 0x66);
+
+       /* DBRNK4 */
+       /* RNKWR = 6 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(4), 0x66);
+
+       /* DBRNK5 */
+       /* RNKWW = 14 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(5), 0xEE);
+
+       /* Timing registers for Scheduler */
+       /* SCFCTST0 */
+       /* SCPREACT */
+       tmp[0] = priv->js2[JS2_tRPpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       /* SCACTRDWR */
+       tmp[1] = (priv->WL + 2 + 1 + js1[priv->js1_ind].nWR + priv->js2[JS2_tRPpb]) *
+                priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       /* SCRDACRT */
+       tmp[2] = ((js1[priv->js1_ind].nRBTP + 2) + priv->js2[JS2_tRPpb]) *
+                priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       /* SCACTACT */
+       tmp[3] = priv->js2[JS2_tRCpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST0, (tmp[3] << 24) | (tmp[2] << 16) |
+                                         (tmp[1] << 8) | tmp[0]);
+
+       /* SCFCTST1 */
+       /* SCASYNCOFS */
+       tmp[0] = 12;
+       /* SCACTRDWR */
+       tmp[1] = priv->js2[JS2_tRCD] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       /* SCWRRD */
+       tmp[2] = (readl(regs_dbsc_d + DBSC_DBTR(12)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       /* SCRDWR */
+       tmp[3] = (readl(regs_dbsc_d + DBSC_DBTR(11)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST1, (tmp[3] << 24) | (tmp[2] << 16) |
+                                         (tmp[1] << 8) | tmp[0]);
+
+       /* DBSCHRW1 */
+       /* SCTRFCAB */
+       tmp[0] = (priv->js2[JS2_tRFCab] + priv->js2[JS2_tZQLAT]) *
+                priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv;
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHRW1, tmp[0]);
+
+       /* DBSCHTR0 */
+       /* SCDT0 */
+       tmp[0] = (4 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv) - 1;
+       /* SCDT1 */
+       tmp[1] = (8 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv) - 1;
+       /* SCDT2 */
+       tmp[2] = (12 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv) - 1;
+       /* SCDT3 */
+       tmp[3] = (16 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
+                priv->ddr_mbps / priv->bus_clkdiv) - 1;
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHTR0, (tmp[3] << 24) | (tmp[2] << 16) |
+                                      (tmp[1] << 8) | tmp[0]);
+
+       /* QOS and CAM */
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBBCAMDIS, 0x1);
+}
+
+/**
+ * dbsc5_dbsc_regset_post() - Set DBSC registers
+ * @dev: DBSC5 device
+ *
+ * If memory rank is 2, CS_TRAINING_EN is set to the other side.
+ * Configure DBI read/write settings. Execute DRAM refresh settings.
+ * Set WTmode of DFI PHY to OFF. Set up PHY Periodic Write DQ training.
+ * Set WTmode of DFI PHY to ON. Calibration settings for PHY PAD.
+ * Set SDRAM calibration. Make DFI Control Update Setting settings.
+ * In the case of WARM_BOOT, cancel the self-refresh setting.
+ * Enable SDRAM auto refresh. Set up PHY Periodic Write DQ training.
+ * Enable access to SDRAM.
+ */
+static void dbsc5_dbsc_regset_post(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       /* Average periodic refresh interval/Average Refresh Interval [ns] */
+       const u32 dbsc_refint = 1920;
+       /* 0: Average interval is REFINT, 1: Average interval is 1/2 REFINT */
+       const u32 dbsc_refints = 0;
+       /* Periodic-WriteDQ/ReadDQ Training Interval [us] */
+       const u32 periodic_training_interval = 20000;
+       u32 phymster_req_interval;
+       u32 ch, slice;
+       u32 clk_count;
+       u32 refcycle;
+       u32 ctrl_clk;
+       u32 reg;
+
+       if ((renesas_get_cpu_rev_integer() < 3) && priv->ch_have_this_cs[1]) {
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               dbsc5_ddr_setval_slice(dev, ch, slice,
+                                                      PHY_PER_CS_TRAINING_EN,
+                                                      0x0);
+                       }
+               }
+       }
+
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBDBICNT, 0x3);
+
+       /* set REFCYCLE */
+       refcycle = dbsc_refint * priv->ddr_mbps / 8000 / priv->ddr_mbpsdiv;
+       /* refpmax=8 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF1, (refcycle & 0xFFFF) | BIT(19));
+       /* refpmin=1 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF2, dbsc_refints | BIT(16));
+
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x0);
+
+       /* Periodic-WriteDQ Training setting */
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_VREF_EN, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_WDQLVL_ENABLE, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_PERIODIC, 0x1);
+
+       /* Periodic-ReadDQ Training setting */
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDLVL_DLY_STEP, 0x4);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_PERIODIC, 0x1);
+
+       /* DFI_PHYMSTR_ACK , WTmode = b'01 */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x11);
+
+       /* periodic SoC zqcal enable */
+       reg = dbsc5_ddrtbl_getval(priv->DDR_PHY_ADR_G_REGSET, PHY_CAL_MODE_0, false);
+       dbsc5_ddr_setval_all_ch(dev, PHY_CAL_MODE_0, reg | BIT(1));
+
+       /* Periodic dram zqcal enable */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBCALCNF, 0x1000010);
+
+       /* Periodic phy ctrl update enable */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFICUPDCNF, 0x504C0001);
+
+       /* Set Auto Refresh */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFEN, 0x1);
+
+       /* Periodic-WriteDQ/ReadDQ Training Interval setting */
+       phymster_req_interval = periodic_training_interval - 3000;
+       clk_count = 1024 - (dbsc5_ddrtbl_getval(priv->DDR_PI_REGSET, PI_LONG_COUNT_MASK, true) * 32);
+       ctrl_clk = priv->ddr_mbps / priv->ddr_mbpsdiv / 8;
+       reg = phymster_req_interval * ctrl_clk / clk_count;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_INTERVAL, reg);
+
+       /* DRAM access enable */
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBACEN, 0x1);
+}
+
+/**
+ * dbsc5_pi_training() - Training by PI
+ * @dev: DBSC5 device
+ *
+ * Enable WCK signal training and read gate training. Start PI training.
+ * After DFI initialization for all channels is once turned off, turned
+ * on all chennels of it. Power down the DRAM device once and then release
+ * the power down mode. Perform training in low frequency mode and training
+ * in high frequency mode. Wait for the DFI training completion status
+ * bit to stand until the time limit. Turn off DFI initialization for all
+ * channels. Turn off WTMODE of DFI PHY. Check if CA/CS Training has failed.
+ * Check if Wrlvl training is in error. If an error can be confirmed from
+ * the check result, the result is returned as a return value. Clear the
+ * status register for PI training.
+ */
+static u32 dbsc5_pi_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       const int retry_max = 0x10000;
+       u32 ca_training_ng = 0;
+       u32 wr_training_ng = 0;
+       u32 phytrainingok = 0;
+       u32 complete_ng = 0;
+       bool frqchg_req;
+       u32 ch, reg;
+       int retry;
+       int ret;
+
+       /* Init start */
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_9, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_10, 0x0);
+
+       /* PI_START */
+       dbsc5_ddr_setval_all_ch(dev, PI_START, 0x1);
+
+       r_foreach_vch(dev, ch)
+               writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
+
+       r_foreach_vch(dev, ch)
+               writel(0x21, regs_dbsc_d + DBSC_DBDFICNT(ch));
+
+       /* Dummy PDE */
+       dbsc5_send_dbcmd2(dev, 0x8840000);
+
+       /* PDX */
+       dbsc5_send_dbcmd2(dev, 0x8840001);
+
+       /* Wait init_complete */
+       for (retry = 0; retry < retry_max; retry++) {
+               frqchg_req = false;
+               for (ch = 0; ch < DRAM_CH_CNT; ch++) {
+                       if (!((~phytrainingok & priv->ddr_phyvalid) & BIT(ch)))
+                               continue;
+
+                       if (!(readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch)) & BIT(0)))
+                               continue;
+
+                       frqchg_req = true;
+                       break;
+               }
+
+               if (frqchg_req) {
+                       ret = dbsc5_clk_pll3_freq(dev);
+                       if (ret)
+                               break;
+               } else {
+                       r_foreach_vch(dev, ch) {
+                               if (readl(regs_dbsc_d + DBSC_DBDFISTAT(ch)) & BIT(0))
+                                       phytrainingok |= BIT(ch);
+                       }
+
+                       if (phytrainingok == priv->ddr_phyvalid)
+                               break;
+               }
+       }
+
+       /*
+        * dbdficnt0:
+        * dfi_dram_clk_disable=0
+        * dfi_frequency = 0
+        * freq_ratio = 10 (4:1)
+        * init_start =0
+        */
+       r_foreach_vch(dev, ch)
+               writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
+
+       /* DFI_PHYMSTR_ACK */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x1);
+
+       /* Error check */
+       r_foreach_vch(dev, ch) {
+               /* CA/CS Training Error Check */
+               /* PI_CALVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(4);
+               /* Error on decrement/increment pass */
+               reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS1) & (0x3 << 30);
+               /* Start outside of initial search range */
+               reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS2) & (0x3 << 24);
+               /* CSlvl error */
+               reg |= dbsc5_ddr_getval(dev, ch, PHY_CSLVL_OBS1) & (0xF << 28);
+               if (reg) {
+                       ca_training_ng |= BIT(ch);
+                       printf("%s pi_training_error:1\n", __func__);
+               }
+
+               /* Wrlvl Error Check */
+               /* PI_WRLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
+               if (reg) {
+                       wr_training_ng |= BIT(ch);
+                       printf("%s pi_training_error:2\n", __func__);
+               }
+       }
+
+       complete_ng = (wr_training_ng | ca_training_ng);
+       if (complete_ng)
+               return ~complete_ng;
+
+       /* PI_INT_ACK assert */
+       r_foreach_vch(dev, ch) {
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_write_leveling_adjust() - Write Leveling Cycle Adjust
+ * @dev: DBSC5 device
+ *
+ * Get delay value from the result write leveling of slice 0 and 1.
+ * Calculate latency of dfi_wrdata_en / dfi_wrdata / dfi_wrdata_mask
+ * signals based on delay values.
+ */
+static void dbsc5_write_leveling_adjust(struct udevice *dev)
+{
+       u32 result_hard0, result_hard1;
+       u32 avg, avg_frac, avg_cycle;
+       u32 ch;
+
+       r_foreach_vch(dev, ch) {
+               /* SLICE0 */
+               result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD0_DELAY_OBS);
+               result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD1_DELAY_OBS);
+
+               avg = result_hard0 + result_hard1;
+               if (result_hard0 > result_hard1)
+                       avg += 0x400;
+               avg /= 2;
+
+               avg_frac = avg & 0xFF;
+               avg_cycle = (avg >> 8) & 0x3;
+
+               if (avg_cycle == 0x3) {
+                       dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x1);
+                       dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, 0x0);
+               } else {
+                       dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x0);
+                       dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
+               }
+               dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
+
+               /* SLICE1 */
+               result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD0_DELAY_OBS);
+               result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD1_DELAY_OBS);
+
+               avg = result_hard0 + result_hard1;
+               if (result_hard0 >= result_hard1)
+                       avg += 0x400;
+               avg /= 2;
+               avg_frac = avg & 0xFF;
+               avg_cycle = (avg >> 8) & 0x3;
+
+               if (avg_cycle == 0x3) {
+                       dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x1);
+                       dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, 0x0);
+               } else {
+                       dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x0);
+                       dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
+               }
+               dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
+       }
+
+       dbsc5_ddr_setval_all_ch_all_slice(dev, SC_PHY_WCK_CALC, 0x1);
+}
+
+/**
+ * dbsc5_wl_gt_training() - Re-run Write Leveling & Read Gate Training
+ * @dev: DBSC5 device
+ *
+ * Set CA leveling OFF, read gate leveling ON, write gate leveling ON,
+ * PI dram wck training ON. Perform PI_DFS configuration. Start PI
+ * frequency training in manual mode. Perform training in high-frequency
+ * mode. Check for Write leveling Error and Gate leveling Error. If an
+ * error is identified, the resulting value is inverted and returned.
+ * Clear the PI status register.
+ */
+static u32 dbsc5_wl_gt_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const int retry_max = 0x10000;
+       u32 gt_training_ng = 0;
+       u32 wr_training_ng = 0;
+       u32 phytrainingok = 0;
+       u32 complete_ng = 0;
+       int retry, ret;
+       u32 ch, reg;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
+
+       dbsc5_ddr_setval_all_ch(dev, PI_DFS_ENTRY_SEQ_0, 0x181F0000);
+       dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_1, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
+
+       /* Freq Change High to High*/
+       ret = dbsc5_clk_pll3_freq(dev);
+       if (ret)
+               return ret;
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch)
+                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
+                               phytrainingok |= BIT(ch);
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+
+       /* Error Check */
+       r_foreach_vch(dev, ch) {
+               /* Wrlvl Error Check */
+               /* PI_WRLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
+               if (reg) {
+                       wr_training_ng |= BIT(ch);
+                       printf("%s wl_gt_training_error:1\n", __func__);
+               }
+
+               /* Gtlvl Error Check */
+               /* PI_RDLVL_GATE_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2);
+               /* SLICE0 delay setup error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
+               /* SLICE1 delay setup error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
+               if (reg) {
+                       gt_training_ng |= BIT(ch);
+                       printf("%s wl_gt_training_error:2\n", __func__);
+               }
+       }
+
+       complete_ng = (wr_training_ng | gt_training_ng);
+       if (complete_ng)
+               return ~complete_ng;
+
+       /* PI_INT_ACK assert */
+       r_foreach_vch(dev, ch) {
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_pi_int_ack_0_assert() - Training handshake functions
+ * @dev: DBSC5 device
+ * @bit: Status bit to poll
+ *
+ * Wait for the status bit specified in the argument to become 1 until the
+ * time limit. After checking status bits on all channels, clear the target
+ * status bits and returns the result of the check as the return value.
+ */
+static u32 dbsc5_pi_int_ack_0_assert(struct udevice *dev, u32 bit)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const int retry_max = 0x10000;
+       u32 ch, phytrainingok = 0;
+       int retry;
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch)
+                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(bit))
+                               phytrainingok |= BIT(ch);
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+
+       if (phytrainingok != priv->ddr_phyvalid)
+               return phytrainingok;
+
+       r_foreach_vch(dev, ch)
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, BIT(bit));
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_write_dca() - Write DCA Training
+ * @dev: DBSC5 device
+ *
+ * Get DCA Training CS0 Flip-0 training results for RANK0.
+ * Get DCA Training CS1 Flip-0 training results for RANK0.
+ * Calculate DRAMDCA settings from training results and write
+ * them to registers. Set DRAM DCA in MR30. Ensure that the
+ * training has been successfully completed. Clear CA status
+ * to 0.
+ */
+static void dbsc5_write_dca(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const int retry_max = 0x10000;
+       u32 phytrainingok = 0;
+       u32 ch, reg;
+       int retry;
+
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_CAL_START, 0x1);
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch) {
+                       reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_DATA_DC_CAL_START) |
+                             dbsc5_ddr_getval_slice(dev, ch, 1, PHY_DATA_DC_CAL_START);
+                       if (!reg)
+                               phytrainingok |= BIT(ch);
+               }
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+}
+
+/**
+ * dbsc5_dramdca_training() - DRAM DCA Training and Calculations
+ * @dev: DBSC5 device
+ *
+ * Get DCA Training CS0 Flip-0 training results for RANK0.
+ * Get DCA Training CS1 Flip-0 training results for RANK0.
+ * Calculate DRAMDCA settings from training results and write
+ * them to registers. Set DRAM DCA in MR30. Ensure that the
+ * training has been successfully completed. Clear CA status
+ * to 0.
+ */
+static u32 dbsc5_dramdca_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
+       const u32 mr30_conv[16] = {
+               0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1,
+               0x0, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
+       };
+       u32 dca_result_l_0[DRAM_CH_CNT][CS_CNT];
+       u32 dca_result_u_0[DRAM_CH_CNT][CS_CNT];
+       u32 dca_result_l_1[DRAM_CH_CNT][CS_CNT];
+       u32 dca_result_u_1[DRAM_CH_CNT][CS_CNT];
+       u32 ch, phytrainingok, reg;
+       u32 tempu, templ;
+
+       /* Run DRAM DCA Training for Flip-0 */
+       dbsc5_ddr_setval_all_ch(dev, PI_DCMLVL_CS_SW, rank);
+
+       /* DRAMDCA go */
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
+
+       /* PI_INT_ACK assert */
+       phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
+       if (phytrainingok != priv->ddr_phyvalid)
+               return phytrainingok;
+
+       /* Result for DRAMDCA flip-0 */
+       r_foreach_vch(dev, ch) {
+               reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
+               dca_result_u_0[ch][0] = mr30_conv[reg >> 4];
+               dca_result_l_0[ch][0] = mr30_conv[reg & 0xF];
+               if (!(rank & 0x2))
+                       continue;
+
+               reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
+               dca_result_u_0[ch][1] = mr30_conv[reg >> 4];
+               dca_result_l_0[ch][1] = mr30_conv[reg & 0xF];
+       }
+
+       /* Run DRAM DCA Training for Flip-1 */
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x1);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x0);
+
+       /* DRAMDCA go */
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
+
+       /* PI_INT_ACK assert */
+       phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
+       if (phytrainingok != priv->ddr_phyvalid)
+               return phytrainingok;
+
+       /* Result for DRAMDCA flip-1 */
+       r_foreach_vch(dev, ch) {
+               reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
+               dca_result_u_1[ch][0] = mr30_conv[reg >> 4];
+               dca_result_l_1[ch][0] = mr30_conv[reg & 0xF];
+               if (!(rank & 0x2))
+                       continue;
+
+               reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
+               dca_result_u_1[ch][1] = mr30_conv[reg >> 4];
+               dca_result_l_1[ch][1] = mr30_conv[reg & 0xF];
+       }
+
+       /* Calculate and set DRAMDCA value */
+       r_foreach_vch(dev, ch) {
+               /* CS0 */
+               tempu = (dca_result_u_0[ch][0] + dca_result_u_1[ch][0]) / 2;
+               templ = (dca_result_l_0[ch][0] + dca_result_l_1[ch][0]) / 2;
+               reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
+               dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS0_F2, reg);
+               if (!(rank & 0x2))
+                       continue;
+
+               /* CS1 */
+               tempu = (dca_result_u_0[ch][1] + dca_result_u_1[ch][1]) / 2;
+               templ = (dca_result_l_0[ch][1] + dca_result_l_1[ch][1]) / 2;
+               reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
+               dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS1_F2, reg);
+       }
+
+       /* Set DRAMDCA value in MR30 */
+       dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_0, 0x1A11E14);
+       dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_1, 0x1F0000);
+       dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, rank);
+       dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_START, 0x1);
+
+       /* PI_INT_ACK assert */
+       phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 19);
+       if (phytrainingok != priv->ddr_phyvalid)
+               return phytrainingok;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x2);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x1101FC);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x211A00);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x51500);
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_write_leveling() - Re-run Write Leveling
+ * @dev: DBSC5 device
+ *
+ * CALVL training is set to OFF, WRDCM training is set to OFF, and DRAMDCA
+ * training is set to OFF. Set the memory rank for the Write leveling target
+ * and start leveling. Wait until leveling is complete.
+ *
+ * Check for Write leveling errors. If an error is confirmed to have occurred,
+ * the result is returned as a return value. Clear the PI status bit.
+ */
+static u32 dbsc5_write_leveling(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
+       const int retry_max = 0x10000;
+       u32 wr_training_ng = 0;
+       u32 phytrainingok = 0;
+       u32 ch, reg;
+       int retry;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_CS_SW, rank);
+       dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_REQ, 0x1);
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch)
+                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(29))
+                               phytrainingok |= BIT(ch);
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+
+       /* Error check */
+       r_foreach_vch(dev, ch) {
+               /* Wrlvl Error Check */
+               /* PI_WRLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
+               /* SLICE0 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
+               /* SLICE1 wrlvl error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
+               if (reg) {
+                       wr_training_ng |= BIT(ch);
+                       printf("%s write_leveling_error:1\n", __func__);
+               }
+       }
+
+       if (wr_training_ng)
+               return ~wr_training_ng;
+
+       /* PI_INT_ACK assert */
+       r_foreach_vch(dev, ch) {
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_manual_write_dca() - Manual Write DCA Training
+ * @dev: DBSC5 device
+ *
+ * Write DCA training according to memory rank.
+ */
+static void dbsc5_manual_write_dca(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x2 : 0x1;
+       u32 slv_dly_center[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
+       u32 slv_dly_center_cyc;
+       u32 slv_dly_center_dly;
+       u32 slv_dly_min[DRAM_CH_CNT][SLICE_CNT];
+       u32 slv_dly_max[DRAM_CH_CNT][SLICE_CNT];
+       u32 slv_dly_min_tmp[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
+       u32 slv_dly_max_tmp[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
+       u32 phy_dcc_code_min[DRAM_CH_CNT][SLICE_CNT];
+       u32 phy_dcc_code_max[DRAM_CH_CNT][SLICE_CNT];
+       u32 phy_dcc_code_mid;
+       const int retry_max = 0x10000;
+       const u8 ratio_min_div = 0xA;
+       const u8 ratio_max_div = 0x2;
+       const u8 ratio_min = 0x6;
+       const u8 ratio_max = 0x3;
+       u32 ch, cs, slice, tmp;
+       u32 complete = 0;
+       int i, retry;
+
+       r_foreach_vch(dev, ch) {
+               for (slice = 0; slice < SLICE_CNT; slice++) {
+                       phy_dcc_code_min[ch][slice] = 0x7F;
+                       phy_dcc_code_max[ch][slice] = 0x0;
+               }
+       }
+
+       for (cs = 0; cs < rank; cs++) {
+               dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               slv_dly_center[ch][cs][slice] =
+                                       dbsc5_ddr_getval_slice(dev, ch, slice, PHY_CLK_WRDQS_SLAVE_DELAY);
+                               slv_dly_center_cyc = slv_dly_center[ch][cs][slice] & 0x180;
+                               slv_dly_center_dly = slv_dly_center[ch][cs][slice] & 0x7F;
+                               slv_dly_min_tmp[ch][cs][slice] =
+                                       slv_dly_center_cyc |
+                                       (slv_dly_center_dly * ratio_min / ratio_min_div);
+                               slv_dly_max_tmp[ch][cs][slice] = slv_dly_center_cyc;
+                               if ((slv_dly_center_dly * ratio_max) > (0x7F * ratio_max_div))
+                                       slv_dly_max_tmp[ch][cs][slice] |= 0x7F;
+                               else
+                                       slv_dly_max_tmp[ch][cs][slice] |= slv_dly_center_dly * ratio_max / ratio_max_div;
+                       }
+               }
+       }
+
+       r_foreach_vch(dev, ch) {
+               for (slice = 0; slice < SLICE_CNT; slice++) {
+                       if (rank == 0x2) {
+                               if (slv_dly_max_tmp[ch][0][slice] < slv_dly_max_tmp[ch][1][slice])
+                                       slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][1][slice];
+                               else
+                                       slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][0][slice];
+
+                               if (slv_dly_min_tmp[ch][0][slice] < slv_dly_min_tmp[ch][1][slice])
+                                       slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][0][slice];
+                               else
+                                       slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][1][slice];
+                       } else {
+                               slv_dly_max[ch][slice] = slv_dly_max_tmp[ch][0][slice];
+                               slv_dly_min[ch][slice] = slv_dly_min_tmp[ch][0][slice];
+                       }
+               }
+       }
+
+       for (i = 0; i <= 0x7F; i++) {
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               if (slv_dly_max[ch][slice] < (slv_dly_min[ch][slice] + i)) {
+                                       complete |= BIT(ch) << (8 * slice);
+                               } else {
+                                       /* CS0/1 same setting, Need masked write */
+                                       dbsc5_ddr_setval_slice(dev, ch, slice,
+                                                              PHY_CLK_WRDQS_SLAVE_DELAY,
+                                                              slv_dly_min[ch][slice] + i);
+                                       dbsc5_ddr_setval_slice(dev, ch, slice, SC_PHY_WCK_CALC, 0x1);
+                                       dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
+                               }
+                       }
+               }
+
+               if (complete == (priv->ddr_phyvalid | (priv->ddr_phyvalid << 8)))
+                       break;
+
+               /* Execute write dca */
+               r_foreach_vch(dev, ch)
+                       for (slice = 0; slice < SLICE_CNT; slice++)
+                               if (!(((complete >> (8 * slice)) >> ch) & 0x1))
+                                       dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DATA_DC_CAL_START, 0x1);
+
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               if (!(((complete >> (8 * slice)) >> ch) & 0x1)) {
+                                       for (retry = 0; retry < retry_max; retry++) {
+                                               tmp = dbsc5_ddr_getval_slice(dev, ch, slice,
+                                                                            PHY_DATA_DC_CAL_START);
+                                               if (!tmp)
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               if ((slv_dly_min[ch][slice] + i) > slv_dly_max[ch][slice])
+                                       continue;
+
+                               tmp = (dbsc5_ddr_getval_slice(dev, ch, slice, PHY_DATA_DC_DQS_CLK_ADJUST));
+                               if ((tmp >> 6) == 0x1)
+                                       tmp = 0x0;
+                               else if ((tmp >> 6) == 0x2)
+                                       tmp = 0x3F;
+
+                               if (tmp < phy_dcc_code_min[ch][slice])
+                                       phy_dcc_code_min[ch][slice] = tmp;
+
+                               if (phy_dcc_code_max[ch][slice] < tmp)
+                                       phy_dcc_code_max[ch][slice] = tmp;
+                       }
+               }
+       }
+
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
+       for (cs = 0; cs < rank; cs++) {
+               dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
+               r_foreach_vch(dev, ch) {
+                       for (slice = 0; slice < SLICE_CNT; slice++) {
+                               dbsc5_ddr_setval_slice(dev, ch, slice,
+                                                      PHY_CLK_WRDQS_SLAVE_DELAY,
+                                                      slv_dly_center[ch][cs][slice]);
+                               dbsc5_ddr_setval_slice(dev, ch, slice,
+                                                      SC_PHY_WCK_CALC, 0x1);
+                               dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
+                       }
+               }
+       }
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x1);
+
+       r_foreach_vch(dev, ch) {
+               for (slice = 0; slice < SLICE_CNT; slice++) {
+                       phy_dcc_code_mid = (phy_dcc_code_min[ch][slice] +
+                                           phy_dcc_code_max[ch][slice]) / 2;
+                       dbsc5_ddr_setval_slice(dev, ch, slice,
+                                              PHY_DATA_DC_DQS_CLK_ADJUST,
+                                              phy_dcc_code_mid);
+               }
+       }
+}
+
+/**
+ * dbsc5_read_gate_training() - Re-run read gate training by PI
+ * @dev: DBSC5 device
+ *
+ * Write leveling set to OFF, read gate leveling set to ON. Set memory rank
+ * for leveling target, turn on read gate leveling. Wait for leveling to be
+ * completed until the time limit. Check for errors during gate leveling.
+ *
+ * If an error is confirmed to have occurred, the result is returned as a
+ * return value. Clear the PI status register.
+ */
+static u32 dbsc5_read_gate_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
+       const int retry_max = 0x10000;
+       u32 gt_training_ng = 0;
+       u32 phytrainingok = 0;
+       u32 ch, reg;
+       int retry;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_REQ, 0x1);
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch)
+                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(24))
+                               phytrainingok |= BIT(ch);
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+
+       /* Error Check */
+       r_foreach_vch(dev, ch) {
+               /* Gtlvl Error Check */
+               /* PI_RDLVL_GATE_ERROR_BIT */
+               reg = (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2));
+               /* SLICE0 delay setup error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
+               /* SLICE1 delay setup error */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
+               if (reg) {
+                       gt_training_ng |= BIT(ch);
+                       printf("%s read_gate_training_error\n", __func__);
+               }
+       }
+
+       if (gt_training_ng)
+               return ~gt_training_ng;
+
+       /* PI_INT_ACK assert */
+       r_foreach_vch(dev, ch) {
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_read_vref_training() - Read Data Training with VREF Training
+ * @dev: DBSC5 device
+ *
+ * Set reading leveling to ON and Vref leveling of reading to OFF.
+ * Set Vref reading training to OFF. Get start value, end value and
+ * number of steps for Vref training. Determine the optimal VREFSEL
+ * value while increasing the Vref training setpoint by the starting
+ * value+step value.
+ */
+static u32 dbsc5_read_vref_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
+       u32 best_dvw_min_byte0, best_dvw_min_byte1;
+       u32 dvw_min_byte0_table[DRAM_CH_CNT][128];
+       u32 dvw_min_byte1_table[DRAM_CH_CNT][128];
+       u32 dvw_min_byte0[DRAM_CH_CNT] = { 0 };
+       u32 dvw_min_byte1[DRAM_CH_CNT] = { 0 };
+       u32 best_lower_vref, best_upper_vref;
+       u32 best_vref_byte0, best_vref_byte1;
+       u32 vref_start, vref_stop, vref_step;
+       u32 best_vref_byte0_index = 0;
+       u32 best_vref_byte1_index = 0;
+       const int retry_max = 0x10000;
+       u32 win_byte0, win_byte1;
+       u32 phytrainingok = 0;
+       u32 vref_stop_index;
+       u32 temple, tempte;
+       u32 best_thrshld;
+       u32 vref_outlier;
+       u32 outlier_cnt;
+       u32 curr_rank;
+       int i, retry;
+       u32 obs_sel;
+       u32 ch, reg;
+
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F0, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F1, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_VREF_TRAINING_CTRL, 0x0);
+
+       /* ch0 vref_point */
+       vref_start = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_START_POINT);
+       vref_stop = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STOP_POINT);
+       vref_step = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STEPSIZE);
+       vref_stop_index = (vref_stop - vref_start) / vref_step;
+
+       if (vref_stop_index > 0x80)
+               return 0;
+
+       for (i = 0; i <= vref_stop_index; i++) {
+               r_foreach_vch(dev, ch) {
+                       reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
+                       reg &= 0xF << 10;
+                       dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
+                                              reg | BIT(9) | (vref_start + (vref_step * i)));
+                       reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
+                       reg &= 0xF << 10;
+                       dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
+                                              reg | BIT(9) | (vref_start + (vref_step * i)));
+               }
+
+               for (curr_rank = 0; curr_rank < rank; curr_rank++) {
+                       /* All ch Read Training Start */
+                       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, BIT(curr_rank));
+                       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
+
+                       phytrainingok = 0;
+                       for (retry = 0; retry < retry_max; retry++) {
+                               r_foreach_vch(dev, ch)
+                                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(25))
+                                               phytrainingok |= BIT(ch);
+
+                               if (phytrainingok == priv->ddr_phyvalid)
+                                       break;
+                       }
+
+                       /* Read Training End */
+                       dbsc5_ddr_setval_all_ch(dev, PI_INT_ACK_0, BIT(25));
+
+                       r_foreach_vch(dev, ch) {
+                               /* minimum Data Valid Window for each VREF */
+                               dvw_min_byte0[ch] = 0xFFFFFFFF;
+                               dvw_min_byte1[ch] = 0xFFFFFFFF;
+                               for (obs_sel = 0x0; obs_sel < 0x19; obs_sel++) {
+                                       if (!((obs_sel < 0x11) || (obs_sel == 0x18)))
+                                               continue;
+
+                                       dbsc5_ddr_setval_slice(dev, ch, 0,
+                                                              PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
+                                                              obs_sel);
+                                       dbsc5_ddr_setval_slice(dev, ch, 1,
+                                                              PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
+                                                              obs_sel);
+
+                                       temple = dbsc5_ddr_getval_slice(dev, ch, 0,
+                                                                       PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
+                                       tempte = dbsc5_ddr_getval_slice(dev, ch, 0,
+                                                                       PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
+                                       if (tempte > temple)
+                                               win_byte0 = tempte - temple;
+                                       else
+                                               win_byte0 = 0;
+
+                                       temple = dbsc5_ddr_getval_slice(dev, ch, 1,
+                                                                       PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
+                                       tempte = dbsc5_ddr_getval_slice(dev, ch, 1,
+                                                                       PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
+                                       if (tempte > temple)
+                                               win_byte1 = tempte - temple;
+                                       else
+                                               win_byte1 = 0;
+
+                                       if (dvw_min_byte0[ch] > win_byte0)
+                                               dvw_min_byte0[ch] = win_byte0;
+
+                                       if (dvw_min_byte1[ch] > win_byte1)
+                                               dvw_min_byte1[ch] = win_byte1;
+                               }
+                       }
+               }
+
+               r_foreach_vch(dev, ch) {
+                       dvw_min_byte0_table[ch][i] = dvw_min_byte0[ch];
+                       dvw_min_byte1_table[ch][i] = dvw_min_byte1[ch];
+               }
+       }
+
+       r_foreach_vch(dev, ch) {
+               /* Search best VREF byte0 */
+               best_vref_byte0 = vref_start;
+               best_vref_byte0_index = 0;
+               best_dvw_min_byte0 = dvw_min_byte0_table[ch][0];
+
+               for (i = 0; i <= vref_stop_index; i++) {
+                       if (best_dvw_min_byte0 >= dvw_min_byte0_table[ch][i])
+                               continue;
+
+                       best_vref_byte0 = vref_start + (vref_step * i);
+                       best_vref_byte0_index = i;
+                       best_dvw_min_byte0 = dvw_min_byte0_table[ch][i];
+               }
+
+               /* Search best_lower VREF byte0 */
+               reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_DLY_STEP);
+               if (reg == 0)
+                       reg = 1;
+               best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_BEST_THRSHLD) * reg;
+
+               vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
+               best_lower_vref = best_vref_byte0;
+               outlier_cnt = vref_outlier;
+               for (i = best_vref_byte0_index; i >= 0; i--) {
+                       if (dvw_min_byte0_table[ch][i] <= 0)
+                               break;
+
+                       if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
+                               best_lower_vref = vref_start + (vref_step * i);
+                       } else {
+                               if (outlier_cnt > 0)
+                                       outlier_cnt--;
+                               else
+                                       break;
+                       }
+
+                       if (i == 0)
+                               break;
+               }
+
+               /* Search best_upper VREF byte0 */
+               vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
+               best_upper_vref = best_vref_byte0;
+               outlier_cnt = vref_outlier;
+               for (i = best_vref_byte0_index; i <= vref_stop_index; i++) {
+                       if (dvw_min_byte0_table[ch][i] <= 0)
+                               break;
+
+                       if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
+                               best_upper_vref = vref_start + (vref_step * i);
+                       } else {
+                               if (outlier_cnt > 0)
+                                       outlier_cnt--;
+                               else
+                                       break;
+                       }
+               }
+
+               /*  Calculate center of best vref range byte0 */
+               best_vref_byte0 = (best_lower_vref + best_upper_vref) / 2;
+
+               /* Search best VREF byte1 */
+               best_vref_byte1 = vref_start;
+               best_vref_byte1_index = 0;
+               best_dvw_min_byte1 = dvw_min_byte1_table[ch][0];
+               for (i = 0; i <= vref_stop_index; i++) {
+                       if (best_dvw_min_byte1 >= dvw_min_byte1_table[ch][i])
+                               continue;
+
+                       best_vref_byte1 = vref_start + (vref_step * i);
+                       best_vref_byte1_index = i;
+                       best_dvw_min_byte1 = dvw_min_byte1_table[ch][i];
+               }
+
+               /* Search best_lower VREF byte1 */
+               reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_DLY_STEP);
+               if (reg == 0)
+                       reg = 1;
+               best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_BEST_THRSHLD) * reg;
+
+               vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
+               best_lower_vref = best_vref_byte1;
+               outlier_cnt = vref_outlier;
+               for (i = best_vref_byte1_index; i >= 0; i--) {
+                       if (dvw_min_byte1_table[ch][i] <= 0)
+                               break;
+
+                       if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
+                               best_lower_vref = vref_start + (vref_step * i);
+                       } else {
+                               if (outlier_cnt > 0)
+                                       outlier_cnt--;
+                               else
+                                       break;
+                       }
+
+                       if (i == 0)
+                               break;
+               }
+
+               /* Search best_upper VREF byte1 */
+               vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
+               best_upper_vref = best_vref_byte1;
+               outlier_cnt = vref_outlier;
+               for (i = best_vref_byte1_index; i <= vref_stop_index; i++) {
+                       if (dvw_min_byte1_table[ch][i] <= 0)
+                               break;
+
+                       if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
+                               best_upper_vref = vref_start + (vref_step * i);
+                       } else {
+                               if (outlier_cnt > 0)
+                                       outlier_cnt--;
+                               else
+                                       break;
+                       }
+               }
+
+               /*  Calculate center of best vref range byte1 */
+               best_vref_byte1 = (best_lower_vref + best_upper_vref) / 2;
+
+               reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
+               reg &= 0xF << 10;
+               dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
+                                      reg | BIT(9) | best_vref_byte0);
+               reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
+               reg &= 0xF << 10;
+               dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
+                                      reg | BIT(9) | best_vref_byte1);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_read_write_training() - Read Data & RDDQ Training with best VREF & Write DQ VREF Training
+ * @dev: DBSC5 device
+ *
+ * Set read DQS/RDQS slave delay setting to 0. Write leveling set to OFF,
+ * read gate leveling set to OFF. Turn on read and write leveling. Start
+ * frequency training. Training in high-frequency mode. Wait until training
+ * is complete. Check for errors in write dq leveling and read leveling.
+
+ * If an error is confirmed to have occurred, return the inverted result
+ * value. Clear the PI status register.
+ */
+static u32 dbsc5_read_write_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const int retry_max = 0x10000;
+       u32 wdq_training_ng = 0;
+       u32 rd_training_ng = 0;
+       u32 phytrainingok = 0;
+       u32 complete_ng = 0;
+       int retry, ret;
+       u32 ch, reg;
+
+       /* RDDQ_SLAVE_DELAY Set 0x0050 -> 0x0000 */
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ0_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ1_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ2_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ3_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ4_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ5_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ6_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ7_SLAVE_DELAY, 0x0);
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDM_SLAVE_DELAY, 0x0);
+
+       dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
+       dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
+
+       dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
+
+       /* Freq Change High to High*/
+       ret = dbsc5_clk_pll3_freq(dev);
+       if (ret)
+               return ret;
+
+       for (retry = 0; retry < retry_max; retry++) {
+               r_foreach_vch(dev, ch)
+                       if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
+                               phytrainingok |= BIT(ch);
+
+               if (phytrainingok == priv->ddr_phyvalid)
+                       break;
+       }
+
+       /* Error Check */
+       r_foreach_vch(dev, ch) {
+               /* Rdlvl Error Check */
+               /* PI_RDLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
+               if (reg) {
+                       rd_training_ng |= BIT(ch);
+                       printf("%s read_write_training_error:1\n", __func__);
+               }
+
+               /* Wdqlvl Error Check */
+               /* PI_WDQLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(5);
+               /* SLICE0 wdqlvl_fail_dqZ */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
+               /* SLICE1 wdqlvl_fail_dqZ */
+               reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
+               if (reg) {
+                       wdq_training_ng |= BIT(ch);
+                       printf("%s read_write_training_error:2\n", __func__);
+               }
+       }
+
+       complete_ng = wdq_training_ng | rd_training_ng;
+       if (complete_ng)
+               return ~complete_ng;
+
+       /* PI_INT_ACK assert */
+       r_foreach_vch(dev, ch) {
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
+               dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
+       }
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_read_training() - Correct RDDQ Training result & Re-Run Read Data Training
+ * @dev: DBSC5 device
+ *
+ * Set the Read DQ correction value and its upper limit from the board
+ * settings. Check DDR memory ranks. Add the offset value to the current
+ * Read DQ value and write it to the register. Write the setting value
+ * to PI_RDLVL_TRAIN_SEQ_x. Start the Read training. PI_INT_ACK assert.
+ * Execute the Rdlvl Error Check. Confirm that training has been successfully
+ * completed. Return the result of the confirmation as the return value.
+ */
+static u32 dbsc5_read_training(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
+       const u32 rddq_delay_offset_ps = 0x19;
+       const u32 rddq_delay_max_ps = 0x67;
+       const u32 rddq_delay_addr[] = {
+               PHY_RDDQ0_SLAVE_DELAY, PHY_RDDQ1_SLAVE_DELAY, PHY_RDDQ2_SLAVE_DELAY,
+               PHY_RDDQ3_SLAVE_DELAY, PHY_RDDQ4_SLAVE_DELAY, PHY_RDDQ5_SLAVE_DELAY,
+               PHY_RDDQ6_SLAVE_DELAY, PHY_RDDQ7_SLAVE_DELAY, PHY_RDDM_SLAVE_DELAY
+       };
+       const u32 rddq_delay_offset = rddq_delay_offset_ps * priv->ddr_mbps * 256 /
+                                     (priv->ddr_mbpsdiv * 2 * 1000000);
+       const u32 rddq_delay_max = rddq_delay_max_ps * priv->ddr_mbps * 256 /
+                                  (priv->ddr_mbpsdiv * 2 * 1000000);
+       u32 rd_training_ng = 0;
+       u32 ch, reg, slice;
+       u32 phytrainingok;
+       int i;
+
+       r_foreach_vch(dev, ch) {
+               for (slice = 0; slice < SLICE_CNT; slice++) {
+                       for (i = 0; i < 9; i++) {
+                               reg = dbsc5_ddr_getval_slice(dev, ch, slice,
+                                                            rddq_delay_addr[i]) +
+                                                            rddq_delay_offset;
+                               if (reg > rddq_delay_max)
+                                       reg = rddq_delay_max;
+                               dbsc5_ddr_setval_slice(dev, ch, slice, rddq_delay_addr[i], reg);
+                       }
+               }
+       }
+
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_1, 0x89080);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_2, 0x811C0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_3, 0x40811C0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_4, 0x2000000);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_5, 0x0);
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
+
+       /* Read training go */
+       dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
+
+       /* PI_INT_ACK assert */
+       phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 25);
+       if (phytrainingok != priv->ddr_phyvalid)
+               return phytrainingok;
+
+       /* Error Check */
+       r_foreach_vch(dev, ch) {
+               /* Rdlvl Error Check */
+               /* PI_RDLVL_ERROR_BIT */
+               reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
+               if (reg) {
+                       rd_training_ng |= BIT(ch);
+                       printf("%s read_training_error\n", __func__);
+               }
+       }
+
+       if (rd_training_ng)
+               return ~rd_training_ng;
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_ddr_register_set() - DDR mode register setting
+ * @dev: DBSC5 device
+ *
+ * Set the mode register 28 of the SDRAM.
+ * ZQ Mode: Command-Based ZQ Calibration
+ * ZQ interval: Background Cal Interval < 64ms
+ */
+static void dbsc5_ddr_register_set(struct udevice *dev)
+{
+       dbsc5_send_dbcmd2(dev, 0xE841C24);
+}
+
+/**
+ * dbsc5_ddr_register_read() - DDR mode register read
+ * @dev: DBSC5 device
+ *
+ * Set the mode register 27 and 57 of the SDRAM.
+ */
+static void dbsc5_ddr_register_read(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+
+       if (!priv->dbsc5_board_config->bdcfg_rfm_chk)
+               return;
+
+       /* MR27 rank0 */
+       dbsc5_send_dbcmd2(dev, 0xF801B00);
+       /* MR57 rank0 */
+       dbsc5_send_dbcmd2(dev, 0xF803900);
+
+       if (!priv->ch_have_this_cs[1])
+               return;
+
+       /* MR27 rank1 */
+       dbsc5_send_dbcmd2(dev, 0xF811B00);
+       /* MR57 rank1 */
+       dbsc5_send_dbcmd2(dev, 0xF813900);
+}
+
+/**
+ * dbsc5_init_ddr() - Initialize DDR
+ * @dev: DBSC5 device
+ *
+ * Status monitor and perform reset and software reset for DDR.
+ * Disable DDRPHY software reset. Unprotect the DDRPHY register.
+ * Perform pre-setting of DBSC registers. Configure the ddrphy
+ * registers. Process ddr backup. Set DBSC registers.
+ *
+ * Initialize DFI and perform PI training. Setup DDR mode registers
+ * pre-traning. Adjust number of write leveling cycles. Perform PI
+ * training in manual mode. Perform DRAM DCA training. Perform write
+ * leveling. Execute phydca training. Execute read gate training.
+ *
+ * Perform Vref training on read gate. Read DQ Write DQ Execute.
+ * Frequency selection change (F1->F2). Disable the FREQ_SEL_MULTICAST &
+ * PER_CS_TRAINING_MULTICAST. Start setting DDR mode registers. Set DBSC
+ * registers after training is completed. Set write protection for PHY
+ * registers.
+ */
+static u32 dbsc5_init_ddr(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       u32 phytrainingok;
+       u32 ch, val;
+       int ret;
+
+       /* PLL3 initialization setting */
+       /* Reset Status Monitor clear */
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
+       /* Reset Status Monitor set */
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKSETR4, 0x600);
+       /* ddrphy soft reset assert */
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRCR4, readl(priv->cpg_regs + CPG_SRCR4) | 0x600);
+       /* Wait reset FB */
+       ret = readl_poll_timeout(priv->cpg_regs + CPG_FSRCHKRA4, val, ((val & 0x600) == 0), 1000000);
+       if (ret < 0) {
+               printf("%s CPG_FSRCHKRA4 Wait reset FB timeout\n", __func__);
+               hang();
+       }
+       /* Reset Status Monitor clear */
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
+
+       /* Initialize PLL3 setting */
+       dbsc5_clk_pll3_control(dev, PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER);
+
+       /* DDRPHY soft reset negate */
+       dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRSTCLR4, 0x600);
+       ret = readl_poll_timeout(priv->cpg_regs + CPG_SRCR4, val, ((val & 0x600) == 0), 1000000);
+       if (ret < 0) {
+               printf("%s CPG_SRCR4 DDRPHY soft reset negate timeout\n", __func__);
+               hang();
+       }
+
+       /* Unlock PHY */
+       /* Unlock DDRPHY register */
+       r_foreach_vch(dev, ch)
+               writel(0xA55A, regs_dbsc_d + DBSC_DBPDLK(ch));
+
+       /* DBSC register pre-setting */
+       dbsc5_dbsc_regset_pre(dev);
+
+       /* Load DDRPHY registers */
+       dbsc5_ddrtbl_calc(priv);
+       dbsc5_ddrtbl_load(dev);
+
+       /* Configure ddrphy registers */
+       dbsc5_ddr_config(dev);
+
+       /* DDR backupmode end */
+
+       /* DBSC register set */
+       dbsc5_dbsc_regset(dev);
+
+       /* Frequency selection change (F1->F2) */
+        dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_INDEX, 0x1);
+        dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_MULTICAST_EN, 0x0);
+
+       /* dfi_init_start (start ddrphy) & execute pi_training */
+       phytrainingok = dbsc5_pi_training(dev);
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:1\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Write leveling cycle adjust */
+       dbsc5_write_leveling_adjust(dev);
+
+       /* Execute write leveling & read gate training */
+       phytrainingok = dbsc5_wl_gt_training(dev);
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:2\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Execute write dca training */
+       dbsc5_write_dca(dev);
+
+       /* Execute dram dca training */
+       phytrainingok = dbsc5_dramdca_training(dev);
+
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:3\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Execute write leveling */
+       phytrainingok = dbsc5_write_leveling(dev);
+
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:4\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Execute manual write dca training */
+       dbsc5_manual_write_dca(dev);
+
+       /* Execute read gate training */
+       phytrainingok = dbsc5_read_gate_training(dev);
+
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:5\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Execute read vref training */
+       phytrainingok = dbsc5_read_vref_training(dev);
+
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:6\n", __func__);
+               return phytrainingok;
+       }
+
+       /* Execute read dq & write dq training with best vref */
+       phytrainingok = dbsc5_read_write_training(dev);
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:7\n", __func__);
+               return phytrainingok;
+       }
+
+       /* correct rddq training result & Execute read dq training */
+       phytrainingok = dbsc5_read_training(dev);
+
+       if (priv->ddr_phyvalid != phytrainingok) {
+               printf("%s init_ddr_error:8\n", __func__);
+               return phytrainingok;
+       }
+
+       /* PER_CS_TRAINING_MULTICAST SET (disable) */
+       dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
+
+       /* setup DDR mode registers */
+       /* MRS */
+       dbsc5_ddr_register_set(dev);
+
+       /* MRR */
+       dbsc5_ddr_register_read(dev);
+
+       /* training complete, setup DBSC */
+       dbsc5_dbsc_regset_post(dev);
+
+       /* Lock PHY */
+       /* Lock DDRPHY register */
+       r_foreach_vch(dev, ch)
+               writel(0x0, regs_dbsc_d + DBSC_DBPDLK(ch));
+
+       return phytrainingok;
+}
+
+/**
+ * dbsc5_get_board_data() - Obtain board specific DRAM configuration
+ *
+ * Return board specific DRAM configuration structure pointer.
+ */
+__weak const struct renesas_dbsc5_board_config *dbsc5_get_board_data(void)
+{
+       return &renesas_v4h_dbsc5_board_config;
+}
+
+/**
+ * renesas_dbsc5_dram_probe() - DDR Initialize entry
+ * @dev: DBSC5 device
+ *
+ * Remove write protection on DBSC register. Read DDR configuration
+ * information from driver data. Calculate board clock frequency and
+ * operating frequency from DDR configuration information. Call the
+ * main function of DDR initialization. Perform DBSC write protection
+ * after initialization is complete.
+ */
+static int renesas_dbsc5_dram_probe(struct udevice *dev)
+{
+#define RST_MODEMR0                    0x0
+#define RST_MODEMR1                    0x4
+       struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
+       ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
+       ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
+       void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
+       phys_addr_t rregs = ofnode_get_addr(rnode);
+       const u32 modemr0 = readl(rregs + RST_MODEMR0);
+       const u32 modemr1 = readl(rregs + RST_MODEMR1);
+       u32 breg, reg, md, sscg;
+       u32 ch, cs;
+
+       /* Get board data */
+       priv->dbsc5_board_config = dbsc5_get_board_data();
+       priv->ddr_phyvalid = (u32)(priv->dbsc5_board_config->bdcfg_phyvalid);
+       priv->max_density = 0;
+       priv->cpg_regs = (void __iomem *)ofnode_get_addr(cnode);
+
+       for (cs = 0; cs < CS_CNT; cs++)
+               priv->ch_have_this_cs[cs] = 0;
+
+       r_foreach_ech(ch)
+               for (cs = 0; cs < CS_CNT; cs++)
+                       priv->ddr_density[ch][cs] = 0xFF;
+
+       r_foreach_vch(dev, ch) {
+               for (cs = 0; cs < CS_CNT; cs++) {
+                       priv->ddr_density[ch][cs] = priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs];
+
+                       if (priv->ddr_density[ch][cs] == 0xFF)
+                               continue;
+
+                       if (priv->ddr_density[ch][cs] > priv->max_density)
+                               priv->max_density = priv->ddr_density[ch][cs];
+
+                       priv->ch_have_this_cs[cs] |= BIT(ch);
+               }
+       }
+
+       /* Decode board clock frequency from MD[14:13] pins */
+       priv->brd_clkdiv = 3;
+
+       breg = (modemr0 >> 13) & 0x3;
+       if (breg == 0) {
+               priv->brd_clk = 50;     /* 16.66 MHz */
+               priv->bus_clk = priv->brd_clk * 0x18;
+               priv->bus_clkdiv = priv->brd_clkdiv;
+       } else if (breg == 1) {
+               priv->brd_clk = 60;     /* 20 MHz */
+               priv->bus_clk = priv->brd_clk * 0x14;
+               priv->bus_clkdiv = priv->brd_clkdiv;
+       } else if (breg == 3) {
+               priv->brd_clk = 100;    /* 33.33 MHz */
+               priv->bus_clk = priv->brd_clk * 0x18;
+               priv->bus_clkdiv = priv->brd_clkdiv * 2;
+       } else {
+               printf("MD[14:13] setting 0x%x not supported!", breg);
+               hang();
+       }
+
+       priv->brd_clkdiva = !!(modemr0 & BIT(14));      /* MD14 */
+
+       /* Decode DDR operating frequency from MD[37:36,19,17] pins */
+       md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
+       sscg = (modemr1 >> 4) & 0x03;
+       if (sscg == 2) {
+               printf("MD[37:36] setting 0x%x not supported!", sscg);
+               hang();
+       }
+
+       if (md == 0) {
+               if (sscg == 0) {
+                       priv->ddr_mbps = 6400;
+                       priv->ddr_mbpsdiv = 1;
+               } else {
+                       priv->ddr_mbps = 19000;
+                       priv->ddr_mbpsdiv = 3;
+               }
+       } else if (md == 1) {
+               priv->ddr_mbps = 6000;
+               priv->ddr_mbpsdiv = 1;
+       } else if (md == 1) {
+               priv->ddr_mbps = 5500;
+               priv->ddr_mbpsdiv = 1;
+       } else if (md == 1) {
+               priv->ddr_mbps = 4800;
+               priv->ddr_mbpsdiv = 1;
+       }
+
+       priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
+                               priv->brd_clk, priv->brd_clkdiv * (priv->brd_clkdiva + 1));
+       priv->ddr_mul_low = CLK_DIV(6400, 2, priv->brd_clk,
+                                   priv->brd_clkdiv * (priv->brd_clkdiva + 1));
+
+       priv->ddr_mul_reg = priv->ddr_mul_low;
+       if (sscg != 0)
+               priv->ddr_mul_reg -= 2;
+
+       priv->ddr_mul_nf = ((8 * priv->ddr_mbps * priv->brd_clkdiv * (priv->brd_clkdiva + 1)) /
+                     (priv->ddr_mbpsdiv * priv->brd_clk * 2)) - (8 * (priv->ddr_mul / 2) * 2);
+
+       /* Adjust tccd */
+       priv->ddr_tccd = 2;
+
+       /* Initialize DDR */
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x1234);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x1234);
+
+       reg = dbsc5_init_ddr(dev);
+
+       dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x0);
+       dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x0);
+
+       return reg != priv->ddr_phyvalid;
+}
+
+/**
+ * renesas_dbsc5_dram_of_to_plat() - Convert OF data to plat data
+ * @dev: DBSC5 device
+ *
+ * Extract DBSC5 address from DT and store it in driver data.
+ */
+static int renesas_dbsc5_dram_of_to_plat(struct udevice *dev)
+{
+       struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+
+       priv->regs = dev_read_addr_ptr(dev);
+       if (!priv->regs)
+               return -EINVAL;
+
+       return 0;
+}
+
+/**
+ * renesas_dbsc5_dram_get_info() - Return RAM size
+ * @dev: DBSC5 device
+ * @info: Output RAM info
+ *
+ * Return size of the RAM managed by this RAM driver.
+ */
+static int renesas_dbsc5_dram_get_info(struct udevice *dev,
+                                      struct ram_info *info)
+{
+       info->base = 0x40000000;
+       info->size = 0;
+
+       return 0;
+}
+
+static const struct ram_ops renesas_dbsc5_dram_ops = {
+       .get_info = renesas_dbsc5_dram_get_info,
+};
+
+U_BOOT_DRIVER(renesas_dbsc5_dram) = {
+       .name           = "dbsc5_dram",
+       .id             = UCLASS_RAM,
+       .of_to_plat     = renesas_dbsc5_dram_of_to_plat,
+       .ops            = &renesas_dbsc5_dram_ops,
+       .probe          = renesas_dbsc5_dram_probe,
+       .priv_auto      = sizeof(struct renesas_dbsc5_dram_priv),
+};
diff --git a/drivers/ram/renesas/dbsc5/qos.c b/drivers/ram/renesas/dbsc5/qos.c
new file mode 100644 (file)
index 0000000..56a60b9
--- /dev/null
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <hang.h>
+#include <linux/sizes.h>
+#include <ram.h>
+#include "dbsc5.h"
+
+/* AXMM */
+#define AXMM_ADSPLCR0                          0x4008
+#define AXMM_ADSPLCR1                          0x400C
+#define AXMM_ADSPLCR2                          0x4010
+#define AXMM_ADSPLCR3                          0x4014
+#define AXMM_MMCR                              0x4300
+#define AXMM_TR0CR0                            0x51000
+#define AXMM_TR1CR0                            0x51004
+#define AXMM_TR2CR0                            0x51008
+#define AXMM_TR3CR                             0x5100C
+#define AXMM_TR3CR0                            0x5100C
+#define AXMM_TR0CR1                            0x51100
+#define AXMM_TR1CR1                            0x51104
+#define AXMM_TR2CR1                            0x51108
+#define AXMM_TR3CR1                            0x5110C
+#define AXMM_TR0CR2                            0x51200
+#define AXMM_TR1CR2                            0x51204
+#define AXMM_TR2CR2                            0x51208
+#define AXMM_TR3CR2                            0x5120C
+
+#define ACTEXT_RT0_R                           0xFFC50800
+#define ACTEXT_RT0_W                           0xFFC51800
+#define ACTEXT_IR0_R                           0xFF890800
+#define ACTEXT_IR0_W                           0xFF891800
+#define ACTEXT_IR1_R                           0xFF892800
+#define ACTEXT_IR1_W                           0xFF893800
+#define SI0_RW_MAX                             0xF1201110
+#define SI1_RW_MAX                             0xF1202110
+
+/* DBSC */
+#define DBSC_A_CH_OFFSET                       0x8000
+#define DBSC_D_CH_OFFSET                       0x4000
+
+#define DBSC_SYSCNT0                           0x0100
+#define DBSC_SYSCNT1                           0x0104
+#define DBSC_FCPRSCTRL                         0x0110
+#define DBSC_DBBUS0CNF2                                0x0808
+#define DBSC_DBCAM0CNF1                                0x0904
+#define DBSC_DBCAM0CNF2                                0x0908
+#define DBSC_DBCAM0CNF3                                0x090C
+#define DBSC_DBCAMDIS                          0x09FC
+#define DBSC_DBSCHCNT0                         0x1000
+#define DBSC_DBSCHSZ0                          0x1010
+#define DBSC_DBSCHRW0                          0x1020
+#define DBSC_SCFCTST2                          0x1048
+#define DBSC_DBSCHQOS_0_0                      0x1100
+#define DBSC_DBSCHQOS_0_1                      0x1104
+#define DBSC_DBSCHQOS_0_2                      0x1108
+#define DBSC_DBSCHQOS_0_3                      0x110C
+#define DBSC_DBSCHQOS_4_0                      0x1140
+#define DBSC_DBSCHQOS_4_1                      0x1144
+#define DBSC_DBSCHQOS_4_2                      0x1148
+#define DBSC_DBSCHQOS_4_3                      0x114C
+#define DBSC_DBSCHQOS_9_0                      0x1190
+#define DBSC_DBSCHQOS_9_1                      0x1194
+#define DBSC_DBSCHQOS_9_2                      0x1198
+#define DBSC_DBSCHQOS_9_3                      0x119C
+#define DBSC_DBSCHQOS_12_0                     0x11C0
+#define DBSC_DBSCHQOS_12_1                     0x11C4
+#define DBSC_DBSCHQOS_12_2                     0x11C8
+#define DBSC_DBSCHQOS_12_3                     0x11CC
+#define DBSC_DBSCHQOS_13_0                     0x11D0
+#define DBSC_DBSCHQOS_13_1                     0x11D4
+#define DBSC_DBSCHQOS_13_2                     0x11D8
+#define DBSC_DBSCHQOS_13_3                     0x11DC
+#define DBSC_DBSCHQOS_14_0                     0x11E0
+#define DBSC_DBSCHQOS_14_1                     0x11E4
+#define DBSC_DBSCHQOS_14_2                     0x11E8
+#define DBSC_DBSCHQOS_14_3                     0x11EC
+#define DBSC_DBSCHQOS_15_0                     0x11F0
+#define DBSC_DBSCHQOS_15_1                     0x11F4
+#define DBSC_DBSCHQOS_15_2                     0x11F8
+#define DBSC_DBSCHQOS_15_3                     0x11FC
+
+/* CCI */
+#define CCIQOS00                               0xC020
+#define CCIQOS01                               0xC024
+#define CCIQOS10                               0xD000
+#define CCIQOS11                               0xD004
+
+/* QOS */
+#define QOS_FIX_QOS_BANK0                      0x0
+#define QOS_FIX_QOS_BANK1                      0x1000
+#define QOS_BE_QOS_BANK0                       0x2000
+#define QOS_BE_QOS_BANK1                       0x3000
+#define QOS_SL_INIT                            0x8000
+#define QOS_REF_ARS                            0x8004
+#define QOS_STATQC                             0x8008
+#define QOS_REF_ENBL                           0x8044
+#define QOS_BWG                                        0x804C
+#define QOS_RAS                                        0x10000
+#define QOS_FSS                                        0x10048
+#define QOS_RAEN                               0x10018
+#define QOS_DANN_LOW                           0x10030
+#define QOS_DANN_HIGH                          0x10034
+#define QOS_DANT                               0x10038
+#define QOS_EMS_LOW                            0x10040
+#define QOS_EMS_HIGH                           0x10044
+#define QOS_INSFC                              0x10050
+#define QOS_EARLYR                             0x10060
+#define QOS_RACNT0                             0x10080
+#define QOS_STATGEN0                           0x10088
+
+#define QOSWT_FIX_QOS_BANK0                    0x800
+#define QOSWT_FIX_QOS_BANK1                    0x1800
+#define QOSWT_BE_QOS_BANK0                     0x2800
+#define QOSWT_BE_QOS_BANK1                     0x3800
+#define QOSWT_WTEN                             0x8030
+#define QOSWT_WTREF                            0x8034
+#define QOSWT_WTSET0                           0x8038
+#define QOSWT_WTSET1                           0x803C
+
+static const struct {
+       u64     fix;
+       u64     be;
+} g_qosbw_tbl[] = {
+       { 0x000C04010000FFFF, 0x00200030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00200030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00200030004FFC01 },
+       { 0x000C04010000FFFF, 0x0000000000000000 },
+       { 0x000C04080000FFFF, 0x00200030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00200030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x0000000000000000 },
+       { 0x000C08140000FFFF, 0x00100030004FFC01 },
+       { 0x000C08140000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFF0, 0x0000000000000000 },
+       { 0x000C04100000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x0000000000000000 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C08140000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x001404080000FFFF, 0x00100030004FFC01 },
+       { 0x001404080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x001000F0004FFC01 },
+       { 0x000C04010000FFFF, 0x001000F0004FFC01 },
+       { 0x000C04010000FFFF, 0x002000F0004FFC01 },
+       { 0x000C04010000FFFF, 0x002000F0004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C04200000FFFF, 0x00100030004FFC01 },
+       { 0x000C04100000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C144F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C0C4F0000FFFF, 0x00100030004FFC01 },
+       { 0x000C0C4F0000FFFF, 0x00100030004FFC01 },
+       { 0x001404080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x001424870000FFFF, 0x00100030004FFC01 },
+       { 0x001424870000FFFF, 0x00100030004FFC01 },
+       { 0x000C149E0000FFFF, 0x00100030004FFC01 },
+       { 0x000C149E0000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x00140C050000FFFF, 0x00100030004FFC01 },
+       { 0x0014450E0000FFFF, 0x00100030004FFC01 },
+       { 0x001424870000FFFF, 0x00100030004FFC01 },
+       { 0x0014289E0000FFFF, 0x00000000000FFC00 },
+       { 0x0014289E0000FFFF, 0x00000000000FFC00 },
+       { 0x0014149E0000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x001004080000FFFF, 0x0000000000000000 },
+       { 0x001004080000FFFF, 0x0000000000000000 },
+       { 0x001004080000FFFF, 0x0000000000000000 },
+       { 0x000C00000000FFFF, 0x001000F0004FFC01 },
+       { 0x000C00000000FFFF, 0x001000F0004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x001404080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000C04080000FFFF, 0x00100030004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04010000FFFF, 0x001001D0004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04010000FFFF, 0x001001D0004FFC01 },
+       { 0x000000000000FFFF, 0x0000000000000000 },
+       { 0x000C04010000FFFF, 0x001001D0004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x001001D0004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x000C04010000FFFF, 0x00100030004FFC01 },
+       { 0x001404010000FFFF, 0x00100030004FFC01 }
+};
+
+static const struct {
+       u64     fix;
+       u64     be;
+} g_qoswt_tbl[] = {
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x000C04050000FFFF, 0x0000000000000000 },
+       { 0x000C080C0000FFFF, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x000C04050000C001, 0x0000000000000000 },
+       { 0x000C080C0000C001, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x001424870000C001, 0x0000000000000000 },
+       { 0x001424870000C001, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x001424870000FFFF, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 },
+       { 0x0000000000000000, 0x0000000000000000 }
+};
+
+struct renesas_dbsc5_qos_priv {
+       void __iomem            *regs;
+};
+
+static int dbsc5_qos_dbsc_setting(struct udevice *dev)
+{
+       struct renesas_dbsc5_qos_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_dbsc_a, *regs_dbsc_d;
+       unsigned int ch, nch;
+
+       if (IS_ENABLED(CONFIG_R8A779G0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779G0)
+               nch = 2;
+       else if (IS_ENABLED(CONFIG_R8A779H0) &&
+                renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779H0)
+               nch = 1;
+       else
+               return -EINVAL;
+
+       for (ch = 0; ch < nch; ch++) {
+               regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET + ch * DBSC_A_CH_OFFSET;
+               regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET + ch * DBSC_D_CH_OFFSET;
+
+               /* DBSC CAM, Scheduling Setting */
+               writel(0x1234, regs_dbsc_d + DBSC_SYSCNT0);
+               writel(0x1234, regs_dbsc_a + DBSC_SYSCNT0);
+               writel(0x48218, regs_dbsc_a + DBSC_DBCAM0CNF1);
+               writel(0x1C4, regs_dbsc_a + DBSC_DBCAM0CNF2);
+               writel(0x3, regs_dbsc_a + DBSC_DBCAM0CNF3);
+
+               if (IS_ENABLED(CONFIG_R8A779G0) &&
+                   renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779G0 &&
+                   (renesas_get_cpu_rev_integer() < 2 ||
+                    (renesas_get_cpu_rev_integer() == 2 &&
+                     renesas_get_cpu_rev_fraction() <= 1))) {
+                       /* OTLINT-5579: V4H <= rev2.1 DBSC W/A-3 */
+                       writel(0x11, regs_dbsc_a + DBSC_DBCAMDIS);
+               } else {
+                       writel(0x10, regs_dbsc_a + DBSC_DBCAMDIS);
+               }
+
+               writel(0xF0037, regs_dbsc_a + DBSC_DBSCHCNT0);
+               writel(0x1, regs_dbsc_a + DBSC_DBSCHSZ0);
+               writel(0xF7311111, regs_dbsc_a + DBSC_DBSCHRW0);
+               writel(0x111F1FFF, regs_dbsc_a + DBSC_SCFCTST2);
+
+               /* OTLINT-5579: V4H DBSC WA3 */
+               writel(0x7, regs_dbsc_a + DBSC_DBBUS0CNF2);
+
+               /* DBSC QoS Setting */
+               writel(0xFFFF, regs_dbsc_a + DBSC_DBSCHQOS_0_0);
+               writel(0x480, regs_dbsc_a + DBSC_DBSCHQOS_0_1);
+               writel(0x300, regs_dbsc_a + DBSC_DBSCHQOS_0_2);
+               writel(0x180, regs_dbsc_a + DBSC_DBSCHQOS_0_3);
+               writel(0x400, regs_dbsc_a + DBSC_DBSCHQOS_4_0);
+               writel(0x300, regs_dbsc_a + DBSC_DBSCHQOS_4_1);
+               writel(0x200, regs_dbsc_a + DBSC_DBSCHQOS_4_2);
+               writel(0x100, regs_dbsc_a + DBSC_DBSCHQOS_4_3);
+               writel(0x300, regs_dbsc_a + DBSC_DBSCHQOS_9_0);
+               writel(0x240, regs_dbsc_a + DBSC_DBSCHQOS_9_1);
+               writel(0x180, regs_dbsc_a + DBSC_DBSCHQOS_9_2);
+               writel(0xC0, regs_dbsc_a + DBSC_DBSCHQOS_9_3);
+               writel(0x40, regs_dbsc_a + DBSC_DBSCHQOS_12_0);
+               writel(0x30, regs_dbsc_a + DBSC_DBSCHQOS_12_1);
+               writel(0x20, regs_dbsc_a + DBSC_DBSCHQOS_12_2);
+               writel(0x10, regs_dbsc_a + DBSC_DBSCHQOS_12_3);
+               writel(0x300, regs_dbsc_a + DBSC_DBSCHQOS_13_0);
+               writel(0x240, regs_dbsc_a + DBSC_DBSCHQOS_13_1);
+               writel(0x180, regs_dbsc_a + DBSC_DBSCHQOS_13_2);
+               writel(0xC0, regs_dbsc_a + DBSC_DBSCHQOS_13_3);
+               writel(0x200, regs_dbsc_a + DBSC_DBSCHQOS_14_0);
+               writel(0x180, regs_dbsc_a + DBSC_DBSCHQOS_14_1);
+               writel(0x100, regs_dbsc_a + DBSC_DBSCHQOS_14_2);
+               writel(0x80, regs_dbsc_a + DBSC_DBSCHQOS_14_3);
+               writel(0x100, regs_dbsc_a + DBSC_DBSCHQOS_15_0);
+               writel(0xC0, regs_dbsc_a + DBSC_DBSCHQOS_15_1);
+               writel(0x80, regs_dbsc_a + DBSC_DBSCHQOS_15_2);
+               writel(0x40, regs_dbsc_a + DBSC_DBSCHQOS_15_3);
+
+               /* Target register is only DBSC0 side. */
+               if (ch == 0)
+                       writel(0x1, regs_dbsc_a + DBSC_FCPRSCTRL);
+
+               writel(0x1, regs_dbsc_a + DBSC_SYSCNT1);
+               writel(0x0, regs_dbsc_d + DBSC_SYSCNT0);
+               writel(0x0, regs_dbsc_a + DBSC_SYSCNT0);
+       }
+
+       return 0;
+}
+
+static int dbsc5_qos_settings_init(struct udevice *dev)
+{
+       struct renesas_dbsc5_qos_priv *priv = dev_get_priv(dev);
+       void __iomem *regs_axmm = priv->regs + DBSC5_AXMM_OFFSET;
+       void __iomem *regs_cci = priv->regs + DBSC5_CCI_OFFSET;
+       void __iomem *regs_qos = priv->regs + DBSC5_QOS_OFFSET;
+       int i;
+
+       if (IS_ENABLED(CONFIG_R8A779G0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779G0) {
+               /* Address Split 2ch */
+               writel(0x0, regs_axmm + AXMM_ADSPLCR0);
+               writel(0xFF1B0C, regs_axmm + AXMM_ADSPLCR1);
+               writel(0x0, regs_axmm + AXMM_ADSPLCR2);
+               writel(0x0, regs_axmm + AXMM_ADSPLCR3);
+
+               writel(0x8000000, regs_cci + CCIQOS00);
+               writel(0x8000000, regs_cci + CCIQOS01);
+
+               if (renesas_get_cpu_rev_integer() >= 2) {
+                       writel(0x1, regs_cci + CCIQOS10);
+                       writel(0x1, regs_cci + CCIQOS11);
+               } else {
+                       writel(0x0, regs_cci + CCIQOS10);
+                       writel(0x0, regs_cci + CCIQOS11);
+               }
+
+               /* Resource Alloc setting */
+               writel(0x48, regs_qos + QOS_RAS);
+       } else if (IS_ENABLED(CONFIG_R8A779H0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779H0) {
+               /* Resource Alloc setting */
+               writel(0x30, regs_qos + QOS_RAS);
+       } else {
+               return -EINVAL;
+       }
+
+       writel(0x2020201, regs_qos + QOS_DANN_LOW);
+       writel(0x4040200, regs_qos + QOS_DANN_HIGH);
+       writel(0x181008, regs_qos + QOS_DANT);
+       writel(0x0, regs_qos + QOS_EMS_LOW);
+       writel(0x0, regs_qos + QOS_EMS_HIGH);
+       writel(0xA, regs_qos + QOS_FSS);
+       writel(0x30F0001, regs_qos + QOS_INSFC);
+       writel(0x0, regs_qos + QOS_EARLYR);
+       writel(0x50003, regs_qos + QOS_RACNT0);
+       writel(0x0, regs_qos + QOS_STATGEN0);
+
+       /* QoS MSTAT setting */
+       writel(0x70120, regs_qos + QOS_SL_INIT);
+       writel(0x11B0000, regs_qos + QOS_REF_ARS);
+       writel(0x12, regs_qos + QOS_REF_ENBL);
+       writel(0x4, regs_qos + QOS_BWG);
+
+       if (IS_ENABLED(CONFIG_R8A779G0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779G0 &&
+           (renesas_get_cpu_rev_integer() < 2 ||
+            (renesas_get_cpu_rev_integer() == 2 &&
+             renesas_get_cpu_rev_fraction() <= 1))) {
+               /* OTLINT-5579: V4H <= rev2.1 DBSC W/A-3 */
+               writel(0x0, regs_axmm + AXMM_MMCR);
+       } else {
+               writel(0x10000, regs_axmm + AXMM_MMCR);
+       }
+
+       writel(0x3, ACTEXT_RT0_R);
+       writel(0x3, ACTEXT_RT0_W);
+
+       /*
+        * This may be necessary, but this IP is powered off at this point:
+        * writel(0x3, ACTEXT_IR0_R);
+        * writel(0x3, ACTEXT_IR0_W);
+        * writel(0x3, ACTEXT_IR1_R);
+        * writel(0x3, ACTEXT_IR1_W);
+        */
+
+       if (IS_ENABLED(CONFIG_R8A779G0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779G0) {
+               writel(0x10000, regs_axmm + AXMM_TR3CR);
+
+               if (renesas_get_cpu_rev_integer() >= 2) {
+                       /* WA1 patch for IPL CA76 hang-up issue, REL_TRI_DN-7592 */
+                       writel(0x38, SI0_RW_MAX);
+                       writel(0x38, SI1_RW_MAX);
+               }
+       }
+
+       if (IS_ENABLED(CONFIG_R8A779H0) &&
+           renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779H0) {
+               writel(0x0, regs_axmm + AXMM_TR0CR0);
+               writel(0x0, regs_axmm + AXMM_TR1CR0);
+               writel(0x0, regs_axmm + AXMM_TR2CR0);
+               writel(0x0, regs_axmm + AXMM_TR3CR0);
+               writel(0x70707070, regs_axmm + AXMM_TR0CR1);
+               writel(0x70707070, regs_axmm + AXMM_TR1CR1);
+               writel(0x70707070, regs_axmm + AXMM_TR2CR1);
+               writel(0x70707070, regs_axmm + AXMM_TR3CR1);
+               writel(0x70707070, regs_axmm + AXMM_TR0CR2);
+               writel(0x70707070, regs_axmm + AXMM_TR1CR2);
+               writel(0x70707070, regs_axmm + AXMM_TR2CR2);
+               writel(0x70707070, regs_axmm + AXMM_TR3CR2);
+       }
+
+       for (i = 0U; i < ARRAY_SIZE(g_qosbw_tbl); i++) {
+               writeq(g_qosbw_tbl[i].fix, regs_qos + QOS_FIX_QOS_BANK0 + (i * 8));
+               writeq(g_qosbw_tbl[i].fix, regs_qos + QOS_FIX_QOS_BANK1 + (i * 8));
+               writeq(g_qosbw_tbl[i].be, regs_qos + QOS_BE_QOS_BANK0 + (i * 8));
+               writeq(g_qosbw_tbl[i].be, regs_qos + QOS_BE_QOS_BANK1 + (i * 8));
+       }
+
+       for (i = 0U; i < ARRAY_SIZE(g_qoswt_tbl); i++) {
+               writeq(g_qoswt_tbl[i].fix, regs_qos + QOSWT_FIX_QOS_BANK0 + (i * 8));
+               writeq(g_qoswt_tbl[i].fix, regs_qos + QOSWT_FIX_QOS_BANK1 + (i * 8));
+               writeq(g_qoswt_tbl[i].be, regs_qos + QOSWT_BE_QOS_BANK0 + (i * 8));
+               writeq(g_qoswt_tbl[i].be, regs_qos + QOSWT_BE_QOS_BANK1 + (i * 8));
+       }
+
+       /* QoS SRAM setting */
+       writel(0x1, regs_qos + QOS_RAEN);
+       writel(0x2080208, regs_qos + QOSWT_WTREF);
+       writel(0xD90050F, regs_qos + QOSWT_WTSET0);
+       writel(0xD90050F, regs_qos + QOSWT_WTSET1);
+       writel(0x1, regs_qos + QOSWT_WTEN);
+       writel(0x101, regs_qos + QOS_STATQC);
+
+       return 0;
+}
+
+static int renesas_dbsc5_qos_probe(struct udevice *dev)
+{
+       int ret;
+
+       /* Setting the register of DBSC4 for QoS initialize */
+       ret = dbsc5_qos_dbsc_setting(dev);
+       if (ret)
+               return ret;
+
+       return dbsc5_qos_settings_init(dev);
+}
+
+static int renesas_dbsc5_qos_of_to_plat(struct udevice *dev)
+{
+       struct renesas_dbsc5_qos_priv *priv = dev_get_priv(dev);
+
+       priv->regs = dev_read_addr_ptr(dev);
+       if (!priv->regs)
+               return -EINVAL;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(renesas_dbsc5_qos) = {
+       .name           = "dbsc5_qos",
+       .id             = UCLASS_NOP,
+       .of_to_plat     = renesas_dbsc5_qos_of_to_plat,
+       .probe          = renesas_dbsc5_qos_probe,
+       .priv_auto      = sizeof(struct renesas_dbsc5_qos_priv),
+};
diff --git a/drivers/ram/renesas/dbsc5/rtvram.c b/drivers/ram/renesas/dbsc5/rtvram.c
new file mode 100644 (file)
index 0000000..6c14928
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <ram.h>
+#include <linux/sizes.h>
+
+/* RT-VRAM register base address */
+#define RTVRAM_VBUF_CFG                        0x6504
+#define RTVRAM_VBUF_CFG_CACHE_MODE_8WAY        (1 << 8)
+#define RTVRAM_VBUF_CFG_VBUF_SIZE_28M  (6 << 0)
+#define RTVRAM_EXT_MODE                        0x8500
+#define RTVRAM_EXT_MODE_EXT            BIT(0)
+#define RTVRAM_VBUF_BADDR              0xC580
+
+#define RTVRAM_VBUF_NUM                        7
+
+#define SDRAM_40BIT_ADDR_TOP           0x0400000000ULL
+#define RTVRAM_VBUF_AREA_SIZE          SZ_4M
+
+struct renesas_dbsc5_rtvram_priv {
+       void __iomem            *regs;
+};
+
+static int renesas_dbsc5_rtvram_probe(struct udevice *dev)
+{
+       struct renesas_dbsc5_rtvram_priv *priv = dev_get_priv(dev);
+       u64 addr;
+       int i;
+
+       /* Set each 4MB from the top of SDRAM as the buffer area of RT-VRAM. */
+       for (i = 0; i < RTVRAM_VBUF_NUM; i++) {
+               addr = (SDRAM_40BIT_ADDR_TOP + (RTVRAM_VBUF_AREA_SIZE * i)) >> 16;
+               writel(lower_32_bits(addr), priv->regs + (RTVRAM_VBUF_BADDR + (4 * i)));
+       }
+
+       /* Cache Mode: 8-way, VBF size: 28M */
+       setbits_le32(priv->regs + RTVRAM_VBUF_CFG,
+                    RTVRAM_VBUF_CFG_CACHE_MODE_8WAY | RTVRAM_VBUF_CFG_VBUF_SIZE_28M);
+
+       /* Change from Compatible Mode to Extended Mode */
+       writel(RTVRAM_EXT_MODE_EXT, priv->regs + RTVRAM_EXT_MODE);
+
+       dsb();
+
+       return 0;
+}
+
+static int renesas_dbsc5_rtvram_of_to_plat(struct udevice *dev)
+{
+       struct renesas_dbsc5_rtvram_priv *priv = dev_get_priv(dev);
+
+       priv->regs = dev_read_addr_ptr(dev);
+       if (!priv->regs)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int renesas_dbsc5_rtvram_get_info(struct udevice *dev,
+                                        struct ram_info *info)
+{
+       struct renesas_dbsc5_rtvram_priv *priv = dev_get_priv(dev);
+
+       info->base = (phys_addr_t)priv->regs;
+       info->size = 28 * SZ_1M;
+
+       return 0;
+}
+
+static const struct ram_ops renesas_dbsc5_rtvram_ops = {
+       .get_info = renesas_dbsc5_rtvram_get_info,
+};
+
+static const struct udevice_id renesas_dbsc5_rtvram_ids[] = {
+       { .compatible = "renesas,r8a779g0-rtvram" },
+       { .compatible = "renesas,r8a779h0-rtvram" },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(renesas_dbsc5_rtvram) = {
+       .name           = "rtvram",
+       .id             = UCLASS_RAM,
+       .of_match       = renesas_dbsc5_rtvram_ids,
+       .of_to_plat     = renesas_dbsc5_rtvram_of_to_plat,
+       .ops            = &renesas_dbsc5_rtvram_ops,
+       .probe          = renesas_dbsc5_rtvram_probe,
+       .priv_auto      = sizeof(struct renesas_dbsc5_rtvram_priv),
+};