memory: brcmstb: dpfe: use byte 3 of registers MR4-MR8
authorMarkus Mayer <mmayer@broadcom.com>
Tue, 12 Feb 2019 01:24:43 +0000 (17:24 -0800)
committerFlorian Fainelli <f.fainelli@gmail.com>
Mon, 20 May 2019 16:32:35 +0000 (09:32 -0700)
For dual-rank LPDDR4, result data for any command is placed in byte 0
and byte 3 of the corresponding MR register by the firmware.
Single-rank RAM was supposed to work the same way. However, due to a
firmware bug, result values are only placed in byte 3 of the
corresponding MR register.

Since byte 3 works for single-rank and dual-rank setups, we change the
Linux driver to always use byte 3, thus returning the correct value in
either case.

Signed-off-by: Markus Mayer <mmayer@broadcom.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
drivers/memory/brcmstb_dpfe.c

index 1095c1d95df485ffc77433c2c64e17305ce8c71b..fae3ac3d65c6f6938489f50821b08f0e9dd5d03b 100644 (file)
@@ -61,6 +61,7 @@
 #define DRAM_INFO_MR4          0x4
 #define DRAM_INFO_ERROR                0x8
 #define DRAM_INFO_MR4_MASK     0xff
+#define DRAM_INFO_MR4_SHIFT    24      /* We need to look at byte 3 */
 
 /* DRAM MR4 Offsets & Masks */
 #define DRAM_MR4_REFRESH       0x0     /* Refresh rate */
@@ -82,6 +83,7 @@
 #define DRAM_VENDOR_MR8                0xc
 #define DRAM_VENDOR_ERROR      0x10
 #define DRAM_VENDOR_MASK       0xff
+#define DRAM_VENDOR_SHIFT      24      /* We need to look at byte 3 */
 
 /* Reset register bits & masks */
 #define DCPU_RESET_SHIFT       0x0
@@ -582,7 +584,8 @@ static ssize_t show_refresh(struct device *dev,
        if (!info)
                return ret;
 
-       mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK;
+       mr4 = (readl_relaxed(info + DRAM_INFO_MR4) >> DRAM_INFO_MR4_SHIFT) &
+             DRAM_INFO_MR4_MASK;
 
        refresh = (mr4 >> DRAM_MR4_REFRESH) & DRAM_MR4_REFRESH_MASK;
        sr_abort = (mr4 >> DRAM_MR4_SR_ABORT) & DRAM_MR4_SR_ABORT_MASK;
@@ -630,6 +633,7 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
        struct private_data *priv;
        void __iomem *info;
        ssize_t ret;
+       u32 mr5, mr6, mr7, mr8, err;
 
        priv = dev_get_drvdata(dev);
        ret = generic_show(DPFE_CMD_GET_VENDOR, response, priv, buf);
@@ -640,13 +644,17 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
        if (!info)
                return ret;
 
-       return sprintf(buf, "%#x %#x %#x %#x %#x\n",
-                      readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK,
-                      readl_relaxed(info + DRAM_VENDOR_MR6) & DRAM_VENDOR_MASK,
-                      readl_relaxed(info + DRAM_VENDOR_MR7) & DRAM_VENDOR_MASK,
-                      readl_relaxed(info + DRAM_VENDOR_MR8) & DRAM_VENDOR_MASK,
-                      readl_relaxed(info + DRAM_VENDOR_ERROR) &
-                                    DRAM_VENDOR_MASK);
+       mr5 = (readl_relaxed(info + DRAM_VENDOR_MR5) >> DRAM_VENDOR_SHIFT) &
+               DRAM_VENDOR_MASK;
+       mr6 = (readl_relaxed(info + DRAM_VENDOR_MR6) >> DRAM_VENDOR_SHIFT) &
+               DRAM_VENDOR_MASK;
+       mr7 = (readl_relaxed(info + DRAM_VENDOR_MR7) >> DRAM_VENDOR_SHIFT) &
+               DRAM_VENDOR_MASK;
+       mr8 = (readl_relaxed(info + DRAM_VENDOR_MR8) >> DRAM_VENDOR_SHIFT) &
+               DRAM_VENDOR_MASK;
+       err = readl_relaxed(info + DRAM_VENDOR_ERROR) & DRAM_VENDOR_MASK;
+
+       return sprintf(buf, "%#x %#x %#x %#x %#x\n", mr5, mr6, mr7, mr8, err);
 }
 
 static int brcmstb_dpfe_resume(struct platform_device *pdev)