ram: renesas: dbsc5: Add V4H-3/V4H-5/V4H-7 OTP based detection
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 16 Mar 2025 13:51:43 +0000 (14:51 +0100)
committerMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 16 Mar 2025 13:56:16 +0000 (14:56 +0100)
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 <marek.vasut+renesas@mailbox.org>
drivers/ram/renesas/dbsc5/dbsc5.c
drivers/ram/renesas/dbsc5/dbsc5.h
drivers/ram/renesas/dbsc5/dram.c

index d24b7c5..4cbc6ae 100644 (file)
@@ -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[] = {
index c410eb0..bf22fcb 100644 (file)
@@ -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__ */
index 1b70faf..c5c5785 100644 (file)
@@ -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,