[PATCH 1/3] arm: imx6: ocotp: Added support for the i.MX6UL
Daniel Schultz
d.schultz at phytec.de
Wed Nov 30 03:10:43 PST 2016
This patch adds support for the i.MX6UL SoC.
Also, the driver was extended to handle two MAC addresses.
Signed-off-by: Daniel Schultz <d.schultz at phytec.de>
---
arch/arm/mach-imx/ocotp.c | 82 +++++++++++++++++++++++++++++++++-------
dts/Bindings/nvmem/imx-ocotp.txt | 7 ++--
2 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index e1d0c25..9efa46a 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -70,11 +70,13 @@
#define FUSE_REGS_COUNT (16 * 8)
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
#define DEF_RELAX 20
-#define MAC_OFFSET (0x22 * 4)
+#define MAC0_OFFSET (0x22 * 4)
+#define MAC1_OFFSET (0x23 * 4)
#define MAC_BYTES 8
struct imx_ocotp_data {
int num_regs;
+ bool scnd_mac_addr;
};
struct ocotp_priv {
@@ -84,7 +86,7 @@ struct ocotp_priv {
struct device_d dev;
int permanent_write_enable;
int sense_enable;
- char ethaddr[6];
+ char ethaddr[2][6];
struct regmap_config map_config;
};
@@ -394,38 +396,79 @@ static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
}
}
-static int imx_ocotp_get_mac(struct param_d *param, void *priv)
+static int imx_ocotp_get_mac(unsigned int mac_no, struct param_d *param,
+ void *priv)
{
struct ocotp_priv *ocotp_priv = priv;
char buf[8];
int i, ret;
+ int offset;
- ret = regmap_bulk_read(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
+ if (mac_no > 1)
+ return -EINVAL;
+
+ ret = regmap_bulk_read(ocotp_priv->map,
+ (mac_no == 0) ? MAC0_OFFSET : MAC1_OFFSET, buf,
+ MAC_BYTES);
if (ret < 0)
return ret;
+ offset = mac_no << 1;
for (i = 0; i < 6; i++)
- ocotp_priv->ethaddr[i] = buf[5 - i];
+ ocotp_priv->ethaddr[mac_no][i] = buf[5 - i + offset];
return 0;
}
-static int imx_ocotp_set_mac(struct param_d *param, void *priv)
+static inline int imx_ocotp_get_mac0(struct param_d *param, void *priv)
+{
+ return imx_ocotp_get_mac(0, param, priv);
+}
+static inline int imx_ocotp_get_mac1(struct param_d *param, void *priv)
+{
+ return imx_ocotp_get_mac(1, param, priv);
+}
+
+static int imx_ocotp_set_mac(unsigned int mac_no, struct param_d *param,
+ void *priv)
{
struct ocotp_priv *ocotp_priv = priv;
char buf[8];
int i, ret;
+ int offset;
+
+ if (mac_no > 1)
+ return -EINVAL;
+
+ offset = mac_no << 1;
+ if (mac_no == 0) {
+ buf[6] = ocotp_priv->ethaddr[1][5];
+ buf[7] = ocotp_priv->ethaddr[1][4];
+ } else {
+ buf[0] = ocotp_priv->ethaddr[0][1];
+ buf[1] = ocotp_priv->ethaddr[0][0];
+ }
for (i = 0; i < 6; i++)
- buf[5 - i] = ocotp_priv->ethaddr[i];
- buf[6] = 0; buf[7] = 0;
+ buf[5 - i + offset] = ocotp_priv->ethaddr[mac_no][i];
- ret = regmap_bulk_write(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
+ ret = regmap_bulk_write(ocotp_priv->map,
+ (mac_no == 0) ? MAC0_OFFSET : MAC1_OFFSET, buf,
+ MAC_BYTES);
if (ret < 0)
return ret;
return 0;
}
+static inline int imx_ocotp_set_mac0(struct param_d *param, void *priv)
+{
+ return imx_ocotp_set_mac(0, param, priv);
+}
+
+static inline int imx_ocotp_set_mac1(struct param_d *param, void *priv)
+{
+ return imx_ocotp_set_mac(1, param, priv);
+}
static struct regmap_bus imx_ocotp_regmap_bus = {
.reg_write = imx_ocotp_reg_write,
@@ -482,9 +525,15 @@ static int imx_ocotp_probe(struct device_d *dev)
NULL, NULL, &priv->permanent_write_enable, NULL);
}
- if (IS_ENABLED(CONFIG_NET))
- dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac,
- imx_ocotp_get_mac, priv->ethaddr, priv);
+ if (IS_ENABLED(CONFIG_NET)) {
+ dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac0,
+ imx_ocotp_get_mac0, priv->ethaddr[0], priv);
+
+ if (data->scnd_mac_addr)
+ dev_add_param_mac(&(priv->dev), "mac_addr1",
+ imx_ocotp_set_mac1, imx_ocotp_get_mac1,
+ priv->ethaddr[1], priv);
+ }
dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv);
@@ -493,10 +542,17 @@ static int imx_ocotp_probe(struct device_d *dev)
static struct imx_ocotp_data imx6q_ocotp_data = {
.num_regs = 512,
+ .scnd_mac_addr = false,
+};
+
+static struct imx_ocotp_data imx6ul_ocotp_data = {
+ .num_regs = 512,
+ .scnd_mac_addr = true,
};
static struct imx_ocotp_data imx6sl_ocotp_data = {
.num_regs = 256,
+ .scnd_mac_addr = false,
};
static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
@@ -511,7 +567,7 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
.data = &imx6sl_ocotp_data,
}, {
.compatible = "fsl,imx6ul-ocotp",
- .data = &imx6q_ocotp_data,
+ .data = &imx6ul_ocotp_data,
}, {
/* sentinel */
}
diff --git a/dts/Bindings/nvmem/imx-ocotp.txt b/dts/Bindings/nvmem/imx-ocotp.txt
index 383d588..5314b88 100644
--- a/dts/Bindings/nvmem/imx-ocotp.txt
+++ b/dts/Bindings/nvmem/imx-ocotp.txt
@@ -1,13 +1,14 @@
Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
This binding represents the on-chip eFuse OTP controller found on
-i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
+i.MX6Q/D, i.MX6DL/S, i.MX6SL, i.MX6SX and i.MX6UL SoCs.
Required properties:
- compatible: should be one of
"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
- "fsl,imx6sl-ocotp" (i.MX6SL), or
- "fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
+ "fsl,imx6sl-ocotp" (i.MX6SL),
+ "fls,imx6ul-ocotp" (i.MX6UL) or
+ "fls,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
- reg: Should contain the register base and length.
- clocks: Should contain a phandle pointing to the gated peripheral clock.
--
1.9.1
More information about the barebox
mailing list