[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