Add auto-detection and handling of Renesas R-Car V4H-3 and V4H-5
in addition to V4H-7 SoC variants based on OTP fuse programming.
The V4H-3 and V4H-5 variants have reduced DRAM frequency options.

Signed-off-by: Marek Vasut <[email protected]>
---
Cc: Nobuhiro Iwamatsu <[email protected]>
Cc: Tom Rini <[email protected]>
Cc: [email protected]
---
 drivers/ram/renesas/dbsc5/dbsc5.c |  3 +-
 drivers/ram/renesas/dbsc5/dbsc5.h |  1 +
 drivers/ram/renesas/dbsc5/dram.c  | 48 ++++++++++++++++++++-----------
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/ram/renesas/dbsc5/dbsc5.c 
b/drivers/ram/renesas/dbsc5/dbsc5.c
index d24b7c5c30a..4cbc6aeda43 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.c
+++ b/drivers/ram/renesas/dbsc5/dbsc5.c
@@ -59,7 +59,8 @@ int renesas_dbsc5_bind(struct udevice *dev)
 
 struct renesas_dbsc5_data r8a779g0_dbsc5_data = {
        .clock_node = "renesas,r8a779g0-cpg-mssr",
-       .reset_node = "renesas,r8a779g0-rst"
+       .reset_node = "renesas,r8a779g0-rst",
+       .otp_node = "renesas,r8a779g0-otp",
 };
 
 static const struct udevice_id renesas_dbsc5_ids[] = {
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.h 
b/drivers/ram/renesas/dbsc5/dbsc5.h
index c410eb0c5ed..bf22fcb8c11 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.h
+++ b/drivers/ram/renesas/dbsc5/dbsc5.h
@@ -23,6 +23,7 @@
 struct renesas_dbsc5_data {
        const char              *clock_node;
        const char              *reset_node;
+       const char              *otp_node;
 };
 
 #endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/dram.c
index 1b70faff7f7..c5c57858aac 100644
--- a/drivers/ram/renesas/dbsc5/dram.c
+++ b/drivers/ram/renesas/dbsc5/dram.c
@@ -4364,16 +4364,20 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
 {
 #define RST_MODEMR0                    0x0
 #define RST_MODEMR1                    0x4
+#define OTP_MONITOR17                  0x1144
        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);
+       ofnode onode = ofnode_by_compatible(ofnode_null(), data->otp_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;
+       phys_addr_t oregs = ofnode_get_addr(onode);
+       const u32 otpmon17 = readl(oregs + OTP_MONITOR17);
+       u32 breg, reg, md, sscg, product;
        u32 ch, cs;
 
        /* Get board data */
@@ -4428,29 +4432,41 @@ static int renesas_dbsc5_dram_probe(struct udevice *dev)
 
        /* Decode DDR operating frequency from MD[37:36,19,17] pins */
        md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
+       product = otpmon17 & 0xff;
        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 == 2) {
-               priv->ddr_mbps = 5500;
-               priv->ddr_mbpsdiv = 1;
-       } else if (md == 3) {
+       if (product == 0x2) {                   /* V4H-3 */
                priv->ddr_mbps = 4800;
                priv->ddr_mbpsdiv = 1;
+       } else if (product == 0x1) {            /* V4H-5 */
+               if (md == 3)
+                       priv->ddr_mbps = 4800;
+               else
+                       priv->ddr_mbps = 5000;
+               priv->ddr_mbpsdiv = 1;
+       } else {                                /* V4H-7 */
+               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 == 2) {
+                       priv->ddr_mbps = 5500;
+                       priv->ddr_mbpsdiv = 1;
+               } else if (md == 3) {
+                       priv->ddr_mbps = 4800;
+                       priv->ddr_mbpsdiv = 1;
+               }
        }
 
        priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
-- 
2.47.2

Reply via email to