diff options
author | Markus Mayer <mmayer@broadcom.com> | 2019-02-12 04:24:43 +0300 |
---|---|---|
committer | Florian Fainelli <f.fainelli@gmail.com> | 2019-05-20 19:32:35 +0300 |
commit | 78a6f5bef9b8132e34f58f60c190da83b46cefef (patch) | |
tree | b38fed3fe4077ff97aceb40e07cc8066288fedfe /drivers/memory | |
parent | 900c8f578be2032e46dd936684838aa59cd5a477 (diff) | |
download | linux-78a6f5bef9b8132e34f58f60c190da83b46cefef.tar.xz |
memory: brcmstb: dpfe: use byte 3 of registers MR4-MR8
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>
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/brcmstb_dpfe.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 1095c1d95df4..fae3ac3d65c6 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c @@ -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) |