Shadow memory does not have a true 1:1 mapping to fuse address
space. All i.MX6 devices, with exception of i.MX6SL have a 0x100 byte
gap between banks 5 and 6 (or addresses 0x2f and 0x30), so we need to
account for that when reading data from shadow memory.

Signed-off-by: Andrey Smirnov <[email protected]>
---
 arch/arm/mach-imx/ocotp.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 44ee0b7..b978508 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -73,6 +73,7 @@
 
 struct imx_ocotp_data {
        int num_regs;
+       u32 (*addr_to_offset)(u32 addr);
 };
 
 struct ocotp_priv {
@@ -84,6 +85,7 @@ struct ocotp_priv {
        int sense_enable;
        char ethaddr[6];
        struct regmap_config map_config;
+       const struct imx_ocotp_data *data;
 };
 
 static int imx6_ocotp_set_timing(struct ocotp_priv *priv)
@@ -192,7 +194,8 @@ static int imx_ocotp_reg_read(void *ctx, unsigned int reg, 
unsigned int *val)
                if (ret)
                        return ret;
        } else {
-               *(u32 *)val = readl(priv->base + 0x400 + index * 0x10);
+               *(u32 *)val = readl(priv->base +
+                                   priv->data->addr_to_offset(index));
        }
 
        return 0;
@@ -272,7 +275,8 @@ static int imx_ocotp_reg_write(void *ctx, unsigned int reg, 
unsigned int val)
                if (ret < 0)
                        return ret;
        } else {
-               writel(val, priv->base + 0x400 + index * 0x10);
+               writel(val, priv->base +
+                      priv->data->addr_to_offset(index));
        }
 
        if (priv->permanent_write_enable)
@@ -374,7 +378,7 @@ static int imx_ocotp_probe(struct device_d *dev)
        void __iomem *base;
        struct ocotp_priv *priv;
        int ret = 0;
-       struct imx_ocotp_data *data;
+       const struct imx_ocotp_data *data;
 
        ret = dev_get_drvdata(dev, (const void **)&data);
        if (ret)
@@ -389,6 +393,7 @@ static int imx_ocotp_probe(struct device_d *dev)
 
        priv = xzalloc(sizeof(*priv));
 
+       priv->data      = data;
        priv->base      = base;
        priv->clk       = clk_get(dev, NULL);
        if (IS_ERR(priv->clk))
@@ -425,12 +430,35 @@ static int imx_ocotp_probe(struct device_d *dev)
        return 0;
 }
 
+static u32 imx6sl_addr_to_offset(u32 addr)
+{
+       return 0x400 + addr * 0x10;
+}
+
+static u32 imx6q_addr_to_offset(u32 addr)
+{
+       u32 addendum = 0;
+
+       if (addr > 0x2F) {
+               /*
+                * If we are reading past Bank 5, take into account a
+                * 0x100 bytes wide gap between Bank 5 and Bank 6
+                */
+               addendum += 0x100;
+       }
+
+
+       return imx6sl_addr_to_offset(addr) + addendum;
+}
+
 static struct imx_ocotp_data imx6q_ocotp_data = {
        .num_regs = 512,
+       .addr_to_offset = imx6q_addr_to_offset,
 };
 
 static struct imx_ocotp_data imx6sl_ocotp_data = {
        .num_regs = 256,
+       .addr_to_offset = imx6sl_addr_to_offset,
 };
 
 static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
-- 
2.5.5


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to