summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/ocotp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/ocotp.c')
-rw-r--r--arch/arm/mach-imx/ocotp.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index e1d0c256a5..68ff0ce28b 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -67,7 +67,6 @@
#define BF(value, field) (((value) << field) & field##_MASK)
/* Other definitions */
-#define FUSE_REGS_COUNT (16 * 8)
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
#define DEF_RELAX 20
#define MAC_OFFSET (0x22 * 4)
@@ -75,6 +74,7 @@
struct imx_ocotp_data {
int num_regs;
+ u32 (*addr_to_offset)(u32 addr);
};
struct ocotp_priv {
@@ -86,6 +86,7 @@ struct ocotp_priv {
int sense_enable;
char ethaddr[6];
struct regmap_config map_config;
+ const struct imx_ocotp_data *data;
};
static struct ocotp_priv *imx_ocotp;
@@ -196,7 +197,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;
@@ -276,7 +278,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)
@@ -438,7 +441,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)
@@ -453,6 +456,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))
@@ -491,12 +495,48 @@ 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 u32 vf610_addr_to_offset(u32 addr)
+{
+ if (addr == 0x04)
+ return 0x450;
+ else
+ return imx6q_addr_to_offset(addr);
+}
+
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 struct imx_ocotp_data vf610_ocotp_data = {
+ .num_regs = 512,
+ .addr_to_offset = vf610_addr_to_offset,
};
static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
@@ -513,6 +553,9 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
.compatible = "fsl,imx6ul-ocotp",
.data = &imx6q_ocotp_data,
}, {
+ .compatible = "fsl,vf610-ocotp",
+ .data = &vf610_ocotp_data,
+ }, {
/* sentinel */
}
};