mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/7] VF610 OCOTP MAC address layout change
@ 2018-05-29  4:47 Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Everyone:

This patchset is as a result of dealing with VF610 U-Boot OCOTP/MAC
quirk.

	- Patch 1 and 2 are the actual patches dealing with U-Boot's
          idiosyncrasy (see individual commit messages for more
          details)

	- Patch 3 and 4 are trivial refactoring made possible with
          <linux/bitfield.h>

	- Patches 5, 6 and 7 are very much optional. IMHO,
          drivers/nvmem is a better place for OCOTP code, but if we
          want to keep the code as is, I am more than happy to drop
          these from the series.

Changes since [v1]:

	- Fixed a bug in MAC formatting spotted by Sascha.


[v1] http://lists.infradead.org/pipermail/barebox/2018-May/033094.html

Feedback is wellcome!

Thanks,
Andrey Smirnov

Andrey Smirnov (7):
  i.MX: ocotp: Unify code paths for reading MAC address
  i.MX: ocotp: Change MAC address layout for VFxxx
  i.MX: ocotp: Simplify OCOTP field packing/unpacking
  i.MX: ocotp: Simplify BF macro
  i.MX: ocotp: Move OCOTP driver to drivers/nvmem
  nvmem: Use name from struct nvmem_config for cdev
  nvmem: ocotp: Convert to NVMEM device

 arch/arm/mach-imx/Kconfig                    |  23 +--
 arch/arm/mach-imx/Makefile                   |   1 -
 arch/arm/mach-imx/include/mach/ocotp.h       |  31 ++-
 drivers/nvmem/Kconfig                        |  21 ++
 drivers/nvmem/Makefile                       |   3 +
 drivers/nvmem/core.c                         |  18 +-
 {arch/arm/mach-imx => drivers/nvmem}/ocotp.c | 201 ++++++++++++-------
 7 files changed, 183 insertions(+), 115 deletions(-)
 rename {arch/arm/mach-imx => drivers/nvmem}/ocotp.c (79%)

-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/7] i.MX: ocotp: Unify code paths for reading MAC address
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

There is no reason why code handling MAC-address properties of
"ocotp0" and code fetching this information to pass it along to
networking subsystem couldn't share majority of their code. Convert
the driver to do that.

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/ocotp.h |  15 +++-
 arch/arm/mach-imx/ocotp.c              | 112 +++++++++++--------------
 2 files changed, 65 insertions(+), 62 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/ocotp.h b/arch/arm/mach-imx/include/mach/ocotp.h
index 5474c27ed..b53000b16 100644
--- a/arch/arm/mach-imx/include/mach/ocotp.h
+++ b/arch/arm/mach-imx/include/mach/ocotp.h
@@ -1,9 +1,22 @@
 #ifndef __MACH_IMX_OCOTP_H
 #define __MACH_IMX_OCOTP_H
 
+#define OCOTP_SHADOW_OFFSET		0x400
+#define OCOTP_SHADOW_SPACING		0x10
+
+/*
+ * Trivial shadow register offset -> ocotp register index.
+ *
+ * NOTE: Doesn't handle special mapping quirks. See
+ * imx6q_addr_to_offset and vf610_addr_to_offset for more details. Use
+ * with care
+ */
+#define OCOTP_OFFSET_TO_INDEX(o)		\
+	(((o) - OCOTP_SHADOW_OFFSET) / OCOTP_SHADOW_SPACING)
+
 #define OCOTP_WORD_MASK_WIDTH	8
 #define OCOTP_WORD_MASK_SHIFT	0
-#define OCOTP_WORD(n)		((((n) - 0x400) >> 4) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1))
+#define OCOTP_WORD(n)		(OCOTP_OFFSET_TO_INDEX(n) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1))
 
 #define OCOTP_BIT_MASK_WIDTH	5
 #define OCOTP_BIT_MASK_SHIFT	(OCOTP_WORD_MASK_SHIFT + OCOTP_WORD_MASK_WIDTH)
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 99b365aad..d5e6b3d3e 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -66,6 +66,8 @@
 
 #define BF(value, field)		(((value) << field) & field##_MASK)
 
+#define OCOTP_OFFSET_TO_ADDR(o)		(OCOTP_OFFSET_TO_INDEX(o) * 4)
+
 /* Other definitions */
 #define IMX6_OTP_DATA_ERROR_VAL		0xBADABADA
 #define DEF_RELAX			20
@@ -366,55 +368,6 @@ bool imx_ocotp_sense_enable(bool enable)
 	return old_value;
 }
 
-static uint32_t inc_offset(uint32_t offset)
-{
-	if ((offset & 0x3) == 0x3)
-		return offset + 0xd;
-	else
-		return offset + 1;
-}
-
-static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
-{
-	char mac[6];
-	const __be32 *prop;
-	struct device_node *node = dev->device_node;
-	int len;
-
-	if (!node)
-		return;
-
-	prop = of_get_property(node, "barebox,provide-mac-address", &len);
-	if (!prop)
-		return;
-
-	while (len >= MAC_ADDRESS_PROPLEN) {
-		struct device_node *rnode;
-		uint32_t phandle, offset;
-
-		phandle = be32_to_cpup(prop++);
-
-		rnode = of_find_node_by_phandle(phandle);
-		offset = be32_to_cpup(prop++);
-
-		mac[5] = readb(base + offset);
-		offset = inc_offset(offset);
-		mac[4] = readb(base + offset);
-		offset = inc_offset(offset);
-		mac[3] = readb(base + offset);
-		offset = inc_offset(offset);
-		mac[2] = readb(base + offset);
-		offset = inc_offset(offset);
-		mac[1] = readb(base + offset);
-		offset = inc_offset(offset);
-		mac[0] = readb(base + offset);
-
-		of_eth_register_ethaddr(rnode, mac);
-
-		len -= MAC_ADDRESS_PROPLEN;
-	}
-}
-
 static void memreverse(void *dest, const void *src, size_t n)
 {
 	char *destp = dest;
@@ -424,21 +377,28 @@ static void memreverse(void *dest, const void *src, size_t n)
 		*destp++ = *srcp--;
 }
 
-static int imx_ocotp_get_mac(struct param_d *param, void *priv)
+static int imx_ocotp_read_mac(struct regmap *map, unsigned int offset,
+			      u8 mac[])
 {
-	char buf[MAC_BYTES];
+	u8 buf[MAC_BYTES];
 	int ret;
-	struct ocotp_priv_ethaddr *ethaddr = priv;
 
-	ret = regmap_bulk_read(ethaddr->map, ethaddr->offset,
-			       buf, MAC_BYTES);
+	ret = regmap_bulk_read(map, offset, buf, MAC_BYTES);
 	if (ret < 0)
 		return ret;
 
-	memreverse(ethaddr->value, buf, 6);
+	memreverse(mac, buf, 6);
 	return 0;
 }
 
+static int imx_ocotp_get_mac(struct param_d *param, void *priv)
+{
+	struct ocotp_priv_ethaddr *ethaddr = priv;
+
+	return imx_ocotp_read_mac(ethaddr->map, ethaddr->offset,
+				  ethaddr->value);
+}
+
 static int imx_ocotp_set_mac(struct param_d *param, void *priv)
 {
 	char buf[MAC_BYTES];
@@ -455,10 +415,41 @@ static struct regmap_bus imx_ocotp_regmap_bus = {
 	.reg_read = imx_ocotp_reg_read,
 };
 
+static void imx_ocotp_init_dt(struct ocotp_priv *priv)
+{
+	char mac[MAC_BYTES];
+	const __be32 *prop;
+	struct device_node *node = priv->dev.parent->device_node;
+	int len;
+
+	if (!node)
+		return;
+
+	prop = of_get_property(node, "barebox,provide-mac-address", &len);
+	if (!prop)
+		return;
+
+	for (; len >= MAC_ADDRESS_PROPLEN; len -= MAC_ADDRESS_PROPLEN) {
+		struct device_node *rnode;
+		uint32_t phandle, offset;
+
+		phandle = be32_to_cpup(prop++);
+
+		rnode = of_find_node_by_phandle(phandle);
+		offset = be32_to_cpup(prop++);
+
+		if (imx_ocotp_read_mac(priv->map,
+				       OCOTP_OFFSET_TO_ADDR(offset),
+				       mac))
+			continue;
+
+		of_eth_register_ethaddr(rnode, mac);
+	}
+}
+
 static int imx_ocotp_probe(struct device_d *dev)
 {
 	struct resource *iores;
-	void __iomem *base;
 	struct ocotp_priv *priv;
 	int ret = 0;
 	const struct imx_ocotp_data *data;
@@ -470,14 +461,11 @@ static int imx_ocotp_probe(struct device_d *dev)
 	iores = dev_request_mem_resource(dev, 0);
 	if (IS_ERR(iores))
 		return PTR_ERR(iores);
-	base = IOMEM(iores->start);
-
-	imx_ocotp_init_dt(dev, base);
 
 	priv = xzalloc(sizeof(*priv));
 
 	priv->data      = data;
-	priv->base	= base;
+	priv->base	= IOMEM(iores->start);
 	priv->clk	= clk_get(dev, NULL);
 	if (IS_ERR(priv->clk))
 		return PTR_ERR(priv->clk);
@@ -529,6 +517,8 @@ static int imx_ocotp_probe(struct device_d *dev)
 				  ethaddr->value, ethaddr);
 	}
 
+	imx_ocotp_init_dt(priv);
+
 	dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv);
 
 	return 0;
@@ -536,7 +526,7 @@ static int imx_ocotp_probe(struct device_d *dev)
 
 static u32 imx6sl_addr_to_offset(u32 addr)
 {
-	return 0x400 + addr * 0x10;
+	return OCOTP_SHADOW_OFFSET + addr * OCOTP_SHADOW_SPACING;
 }
 
 static u32 imx6q_addr_to_offset(u32 addr)
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/7] i.MX: ocotp: Change MAC address layout for VFxxx
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking Andrey Smirnov
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

For reasons unclear VFxxx port of U-Boot chose to store MAC address in
OCOTP using a layout that is incompatible with rest of i.MX
world (both in U-Boot and Barebox). Unfortunately for us, that means
that there are a number of boards out there that have had their MAC
addresses programmed using U-Boot and in order to properly support
those boards we need to change VFxxx port of Barebox to be compatible.

Since the number of Barebox users on VFxx is in single digits, just
chage the layout to that of U-Boot without trying to make this a
configurable option.

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 64 +++++++++++++++++++++++++++++++++------
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index d5e6b3d3e..151c10cc3 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -76,9 +76,16 @@
 #define MAX_MAC_OFFSETS			2
 #define MAC_BYTES			8
 
+enum imx_ocotp_format_mac_direction {
+	OCOTP_HW_TO_MAC,
+	OCOTP_MAC_TO_HW,
+};
+
 struct imx_ocotp_data {
 	int num_regs;
 	u32 (*addr_to_offset)(u32 addr);
+	void (*format_mac)(u8 *dst, const u8 *src,
+			   enum imx_ocotp_format_mac_direction dir);
 	u8  mac_offsets[MAX_MAC_OFFSETS];
 	u8  mac_offsets_num;
 };
@@ -87,6 +94,7 @@ struct ocotp_priv_ethaddr {
 	char value[MAC_BYTES];
 	struct regmap *map;
 	u8 offset;
+	const struct imx_ocotp_data *data;
 };
 
 struct ocotp_priv {
@@ -368,16 +376,46 @@ bool imx_ocotp_sense_enable(bool enable)
 	return old_value;
 }
 
-static void memreverse(void *dest, const void *src, size_t n)
+static void imx_ocotp_format_mac(u8 *dst, const u8 *src,
+				 enum imx_ocotp_format_mac_direction dir)
 {
-	char *destp = dest;
-	const char *srcp = src + n - 1;
+	/*
+	 * This transformation is symmetic, so we don't care about the
+	 * value of 'dir'.
+	 */
+	dst[5] = src[0];
+	dst[4] = src[1];
+	dst[3] = src[2];
+	dst[2] = src[3];
+	dst[1] = src[4];
+	dst[0] = src[5];
+}
 
-	while(n--)
-		*destp++ = *srcp--;
+static void vf610_ocotp_format_mac(u8 *dst, const u8 *src,
+				   enum imx_ocotp_format_mac_direction dir)
+{
+	switch (dir) {
+	case OCOTP_HW_TO_MAC:
+		dst[1] = src[0];
+		dst[0] = src[1];
+		dst[5] = src[4];
+		dst[4] = src[5];
+		dst[3] = src[6];
+		dst[2] = src[7];
+		break;
+	case OCOTP_MAC_TO_HW:
+		dst[0] = src[1];
+		dst[1] = src[0];
+		dst[4] = src[5];
+		dst[5] = src[4];
+		dst[6] = src[3];
+		dst[7] = src[2];
+		break;
+	}
 }
 
-static int imx_ocotp_read_mac(struct regmap *map, unsigned int offset,
+static int imx_ocotp_read_mac(const struct imx_ocotp_data *data,
+			      struct regmap *map, unsigned int offset,
 			      u8 mac[])
 {
 	u8 buf[MAC_BYTES];
@@ -387,7 +425,8 @@ static int imx_ocotp_read_mac(struct regmap *map, unsigned int offset,
 	if (ret < 0)
 		return ret;
 
-	memreverse(mac, buf, 6);
+	data->format_mac(mac, buf, OCOTP_HW_TO_MAC);
+
 	return 0;
 }
 
@@ -395,7 +434,7 @@ static int imx_ocotp_get_mac(struct param_d *param, void *priv)
 {
 	struct ocotp_priv_ethaddr *ethaddr = priv;
 
-	return imx_ocotp_read_mac(ethaddr->map, ethaddr->offset,
+	return imx_ocotp_read_mac(ethaddr->data, ethaddr->map, ethaddr->offset,
 				  ethaddr->value);
 }
 
@@ -404,7 +443,8 @@ static int imx_ocotp_set_mac(struct param_d *param, void *priv)
 	char buf[MAC_BYTES];
 	struct ocotp_priv_ethaddr *ethaddr = priv;
 
-	memreverse(buf, ethaddr->value, 6);
+	ethaddr->data->format_mac(buf, ethaddr->value,
+				  OCOTP_MAC_TO_HW);
 
 	return regmap_bulk_write(ethaddr->map, ethaddr->offset,
 				 buf, MAC_BYTES);
@@ -438,7 +478,7 @@ static void imx_ocotp_init_dt(struct ocotp_priv *priv)
 		rnode = of_find_node_by_phandle(phandle);
 		offset = be32_to_cpup(prop++);
 
-		if (imx_ocotp_read_mac(priv->map,
+		if (imx_ocotp_read_mac(priv->data, priv->map,
 				       OCOTP_OFFSET_TO_ADDR(offset),
 				       mac))
 			continue;
@@ -502,6 +542,7 @@ static int imx_ocotp_probe(struct device_d *dev)
 			ethaddr = &priv->ethaddr[i];
 			ethaddr->map = priv->map;
 			ethaddr->offset = priv->data->mac_offsets[i];
+			ethaddr->data = data;
 
 			dev_add_param_mac(&priv->dev, xasprintf("mac_addr%d", i),
 					  imx_ocotp_set_mac, imx_ocotp_get_mac,
@@ -558,6 +599,7 @@ static struct imx_ocotp_data imx6q_ocotp_data = {
 	.addr_to_offset = imx6q_addr_to_offset,
 	.mac_offsets_num = 1,
 	.mac_offsets = { MAC_OFFSET_0 },
+	.format_mac = imx_ocotp_format_mac,
 };
 
 static struct imx_ocotp_data imx6sl_ocotp_data = {
@@ -565,6 +607,7 @@ static struct imx_ocotp_data imx6sl_ocotp_data = {
 	.addr_to_offset = imx6sl_addr_to_offset,
 	.mac_offsets_num = 1,
 	.mac_offsets = { MAC_OFFSET_0 },
+	.format_mac = imx_ocotp_format_mac,
 };
 
 static struct imx_ocotp_data vf610_ocotp_data = {
@@ -572,6 +615,7 @@ static struct imx_ocotp_data vf610_ocotp_data = {
 	.addr_to_offset = vf610_addr_to_offset,
 	.mac_offsets_num = 2,
 	.mac_offsets = { MAC_OFFSET_0, MAC_OFFSET_1 },
+	.format_mac = vf610_ocotp_format_mac,
 };
 
 static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 4/7] i.MX: ocotp: Simplify BF macro Andrey Smirnov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Simplify OCOTP field packing/unpacking with macros from
<linux/bitfield.h>.

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/include/mach/ocotp.h | 18 +++++++++---------
 arch/arm/mach-imx/ocotp.c              |  8 ++++----
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/ocotp.h b/arch/arm/mach-imx/include/mach/ocotp.h
index b53000b16..76a6da53d 100644
--- a/arch/arm/mach-imx/include/mach/ocotp.h
+++ b/arch/arm/mach-imx/include/mach/ocotp.h
@@ -1,6 +1,8 @@
 #ifndef __MACH_IMX_OCOTP_H
 #define __MACH_IMX_OCOTP_H
 
+#include <linux/bitfield.h>
+
 #define OCOTP_SHADOW_OFFSET		0x400
 #define OCOTP_SHADOW_SPACING		0x10
 
@@ -14,17 +16,15 @@
 #define OCOTP_OFFSET_TO_INDEX(o)		\
 	(((o) - OCOTP_SHADOW_OFFSET) / OCOTP_SHADOW_SPACING)
 
-#define OCOTP_WORD_MASK_WIDTH	8
-#define OCOTP_WORD_MASK_SHIFT	0
-#define OCOTP_WORD(n)		(OCOTP_OFFSET_TO_INDEX(n) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1))
+#define OCOTP_WORD_MASK		GENMASK( 7,  0)
+#define OCOTP_BIT_MASK		GENMASK(12,  8)
+#define OCOTP_WIDTH_MASK 	GENMASK(17, 13)
 
-#define OCOTP_BIT_MASK_WIDTH	5
-#define OCOTP_BIT_MASK_SHIFT	(OCOTP_WORD_MASK_SHIFT + OCOTP_WORD_MASK_WIDTH)
-#define OCOTP_BIT(n)		(((n) & ((1 << OCOTP_BIT_MASK_WIDTH) - 1)) << OCOTP_BIT_MASK_SHIFT)
+#define OCOTP_WORD(n)		FIELD_PREP(OCOTP_WORD_MASK, \
+					   OCOTP_OFFSET_TO_INDEX(n))
+#define OCOTP_BIT(n)		FIELD_PREP(OCOTP_BIT_MASK, n)
+#define OCOTP_WIDTH(n)		FIELD_PREP(OCOTP_WIDTH_MASK, (n) - 1)
 
-#define OCOTP_WIDTH_MASK_WIDTH	5
-#define OCOTP_WIDTH_MASK_SHIFT	(OCOTP_BIT_MASK_SHIFT + OCOTP_BIT_MASK_WIDTH)
-#define OCOTP_WIDTH(n)		((((n) - 1) & ((1 << OCOTP_WIDTH_MASK_WIDTH) - 1)) << OCOTP_WIDTH_MASK_SHIFT)
 
 int imx_ocotp_read_field(uint32_t field, unsigned *value);
 int imx_ocotp_write_field(uint32_t field, unsigned value);
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 151c10cc3..5b21479eb 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -314,10 +314,10 @@ static void imx_ocotp_field_decode(uint32_t field, unsigned *word,
 {
 	unsigned width;
 
-	*word = ((field >> OCOTP_WORD_MASK_SHIFT) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1)) * 4;
-	*bit = (field >> OCOTP_BIT_MASK_SHIFT) & ((1 << OCOTP_BIT_MASK_WIDTH) - 1);
-	width = ((field >> OCOTP_WIDTH_MASK_SHIFT) & ((1 << OCOTP_WIDTH_MASK_WIDTH) - 1)) + 1;
-	*mask = (1 << width) - 1;
+	*word = FIELD_GET(OCOTP_WORD_MASK, field) * 4;
+	*bit = FIELD_GET(OCOTP_BIT_MASK, field);
+	width = FIELD_GET(OCOTP_WIDTH_MASK, field);
+	*mask = GENMASK(width, 0);
 }
 
 int imx_ocotp_read_field(uint32_t field, unsigned *value)
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 4/7] i.MX: ocotp: Simplify BF macro
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
                   ` (2 preceding siblings ...)
  2018-05-29  4:47 ` [PATCH v2 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem Andrey Smirnov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 5b21479eb..8c44bbb16 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -55,16 +55,13 @@
 #define OCOTP_CTRL_ERROR		(1 << 9)
 #define OCOTP_CTRL_RELOAD_SHADOWS	(1 << 10)
 
-#define OCOTP_TIMING_STROBE_READ	16
 #define OCOTP_TIMING_STROBE_READ_MASK	0x003F0000
-#define OCOTP_TIMING_RELAX		12
 #define OCOTP_TIMING_RELAX_MASK		0x0000F000
-#define OCOTP_TIMING_STROBE_PROG	0
 #define OCOTP_TIMING_STROBE_PROG_MASK	0x00000FFF
 
 #define OCOTP_READ_CTRL_READ_FUSE	0x00000001
 
-#define BF(value, field)		(((value) << field) & field##_MASK)
+#define BF(value, field)		FIELD_PREP(field##_MASK, value)
 
 #define OCOTP_OFFSET_TO_ADDR(o)		(OCOTP_OFFSET_TO_INDEX(o) * 4)
 
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
                   ` (3 preceding siblings ...)
  2018-05-29  4:47 ` [PATCH v2 4/7] i.MX: ocotp: Simplify BF macro Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 6/7] nvmem: Use name from struct nvmem_config for cdev Andrey Smirnov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Move OCOTP driver to drivers/nvmem to be consistent with Linux
kerenel.

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/mach-imx/Kconfig                    | 23 ++------------------
 arch/arm/mach-imx/Makefile                   |  1 -
 drivers/nvmem/Kconfig                        | 21 ++++++++++++++++++
 drivers/nvmem/Makefile                       |  3 +++
 {arch/arm/mach-imx => drivers/nvmem}/ocotp.c |  0
 5 files changed, 26 insertions(+), 22 deletions(-)
 rename {arch/arm/mach-imx => drivers/nvmem}/ocotp.c (100%)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 2b5f825b0..721b0d2e3 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -180,6 +180,7 @@ config ARCH_VF610
 	select OFTREE
 	select COMMON_CLK
 	select COMMON_CLK_OF_PROVIDER
+	select NVMEM
 	select IMX_OCOTP	# Needed for clock adjustement
 
 config IMX_MULTI_BOARDS
@@ -734,33 +735,13 @@ config IMX_IIM_FUSE_BLOW
 	  enable it:
 	    imx_iim0.permanent_write_enable=1
 
-config IMX_OCOTP
-	tristate "i.MX6 On Chip OTP controller"
-	depends on ARCH_IMX6 || ARCH_VF610
-	depends on OFDEVICE
-	help
-	  This adds support for the i.MX6 On-Chip OTP controller. Currently the
-	  only supported functionality is reading the MAC address and assigning
-	  it to an ethernet device.
-
-config IMX_OCOTP_WRITE
-	bool
-	prompt "Enable write support of i.MX6 CPUs OTP fuses"
-	depends on IMX_OCOTP
-	help
-	  This adds write support to IMX6 On-Chip OTP registers. Example of set
-	  MAC to 12:34:56:78:9A:BC (2 words with address 0x22 (OCOTP_MAC0) and
-	  address 0x23 (OCOTP_MAC1)). To calculate the file offset multiply
-	  the value of the address by 4.
-	    mw -l -d /dev/imx-ocotp 0x8C 0x00001234
-	    mw -l -d /dev/imx-ocotp 0x88 0x56789ABC
-
 config HAB
 	bool
 
 config HABV4
 	tristate "HABv4 support"
 	select HAB
+	select NVMEM
 	select IMX_OCOTP
 	depends on ARCH_IMX6
 	depends on OFDEVICE
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 160ed4b08..969f5347b 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_ARCH_IMX7) += imx7.o
 obj-$(CONFIG_ARCH_VF610) += vf610.o
 obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
-obj-$(CONFIG_IMX_OCOTP)	+= ocotp.o
 obj-$(CONFIG_NAND_IMX) += nand.o
 lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o
 obj-y += devices.o imx.o
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index d801cc25a..53086d1aa 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -15,4 +15,25 @@ config NVMEM_SNVS_LPGPR
 	help
 	  If you say yes here you get NVMEM support for the Freescale SNVS
 	  Low Power Generic Purpose Register (LPGPR).
+
+config IMX_OCOTP
+	tristate "i.MX6 On Chip OTP controller"
+	depends on ARCH_IMX6 || ARCH_VF610
+	depends on OFDEVICE
+	help
+	  This adds support for the i.MX6 On-Chip OTP controller. Currently the
+	  only supported functionality is reading the MAC address and assigning
+	  it to an ethernet device.
+
+config IMX_OCOTP_WRITE
+	bool
+	prompt "Enable write support of i.MX6 CPUs OTP fuses"
+	depends on IMX_OCOTP
+	help
+	  This adds write support to IMX6 On-Chip OTP registers. Example of set
+	  MAC to 12:34:56:78:9A:BC (2 words with address 0x22 (OCOTP_MAC0) and
+	  address 0x23 (OCOTP_MAC1)). To calculate the file offset multiply
+	  the value of the address by 4.
+	    mw -l -d /dev/imx-ocotp 0x8C 0x00001234
+	    mw -l -d /dev/imx-ocotp 0x88 0x56789ABC
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 32522e9fb..998a9c4b9 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -8,3 +8,6 @@ nvmem_core-y			:= core.o
 # Devices
 obj-$(CONFIG_NVMEM_SNVS_LPGPR)	+= nvmem_snvs_lpgpr.o
 nvmem_snvs_lpgpr-y		:= snvs_lpgpr.o
+
+obj-$(CONFIG_IMX_OCOTP)		+= nvmem_ocotp.o
+nvmem_ocotp-y			:= ocotp.o
\ No newline at end of file
diff --git a/arch/arm/mach-imx/ocotp.c b/drivers/nvmem/ocotp.c
similarity index 100%
rename from arch/arm/mach-imx/ocotp.c
rename to drivers/nvmem/ocotp.c
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 6/7] nvmem: Use name from struct nvmem_config for cdev
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
                   ` (4 preceding siblings ...)
  2018-05-29  4:47 ` [PATCH v2 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-29  4:47 ` [PATCH v2 7/7] nvmem: ocotp: Convert to NVMEM device Andrey Smirnov
  2018-05-31 15:27 ` [PATCH v2 0/7] VF610 OCOTP MAC address layout change Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Original name, 'nvmemN', doesn't really give any hint about which
physical HW it may represent, so change the code to either pick up an
DT alias or use the name passed via 'struct nvmem_config'.

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/nvmem/core.c | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 172fa8b72..53b934bb3 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -88,26 +88,14 @@ static struct cdev_operations nvmem_chrdev_ops = {
 	.lseek = dev_lseek_default,
 };
 
-static int nvmem_register_cdev(struct nvmem_device *nvmem)
+static int nvmem_register_cdev(struct nvmem_device *nvmem, const char *name)
 {
 	struct device_d *dev = &nvmem->dev;
 	const char *alias;
-	char *devname;
-	int err;
 
 	alias = of_alias_get(dev->device_node);
-	if (alias) {
-		devname = xstrdup(alias);
-	} else {
-		err = cdev_find_free_index("nvmem");
-		if (err < 0) {
-			dev_err(dev, "no index found to name device\n");
-			return err;
-		}
-		devname = xasprintf("nvmem%d", err);
-	}
 
-	nvmem->cdev.name = devname;
+	nvmem->cdev.name = xstrdup(alias ?: name);
 	nvmem->cdev.flags = DEVFS_IS_CHARACTER_DEV;
 	nvmem->cdev.ops = &nvmem_chrdev_ops;
 	nvmem->cdev.dev = &nvmem->dev;
@@ -222,7 +210,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		return ERR_PTR(rval);
 	}
 
-	rval = nvmem_register_cdev(nvmem);
+	rval = nvmem_register_cdev(nvmem, config->name);
 	if (rval) {
 		kfree(nvmem);
 		return ERR_PTR(rval);
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 7/7] nvmem: ocotp: Convert to NVMEM device
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
                   ` (5 preceding siblings ...)
  2018-05-29  4:47 ` [PATCH v2 6/7] nvmem: Use name from struct nvmem_config for cdev Andrey Smirnov
@ 2018-05-29  4:47 ` Andrey Smirnov
  2018-05-31 15:27 ` [PATCH v2 0/7] VF610 OCOTP MAC address layout change Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Andrey Smirnov @ 2018-05-29  4:47 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov, Vivien Didelot

Not that barebox has a proper NVMEM subsystem, convert OCOTP driver to
use that to both make things more consistent with Linux and also allow
accessing OCOTP fields without the need for
imx_ocotp_read_field()/imx_ocotp_write_field().

Cc: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 drivers/nvmem/ocotp.c | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/ocotp.c b/drivers/nvmem/ocotp.c
index 8c44bbb16..86d0b9cd0 100644
--- a/drivers/nvmem/ocotp.c
+++ b/drivers/nvmem/ocotp.c
@@ -29,6 +29,7 @@
 #include <regmap.h>
 #include <linux/clk.h>
 #include <mach/ocotp.h>
+#include <linux/nvmem-provider.h>
 
 /*
  * a single MAC address reference has the form
@@ -105,6 +106,7 @@ struct ocotp_priv {
 	struct regmap_config map_config;
 	const struct imx_ocotp_data *data;
 	int  mac_offset_idx;
+	struct nvmem_config config;
 };
 
 static struct ocotp_priv *imx_ocotp;
@@ -484,12 +486,34 @@ static void imx_ocotp_init_dt(struct ocotp_priv *priv)
 	}
 }
 
+static int imx_ocotp_write(struct device_d *dev, const int offset,
+			    const void *val, int bytes)
+{
+	struct ocotp_priv *priv = dev->parent->priv;
+
+	return regmap_bulk_write(priv->map, offset, val, bytes);
+}
+
+static int imx_ocotp_read(struct device_d *dev, const int offset, void *val,
+			   int bytes)
+{
+	struct ocotp_priv *priv = dev->parent->priv;
+
+	return regmap_bulk_read(priv->map, offset, val, bytes);
+}
+
+static const struct nvmem_bus imx_ocotp_nvmem_bus = {
+	.write = imx_ocotp_write,
+	.read  = imx_ocotp_read,
+};
+
 static int imx_ocotp_probe(struct device_d *dev)
 {
 	struct resource *iores;
 	struct ocotp_priv *priv;
 	int ret = 0;
 	const struct imx_ocotp_data *data;
+	struct nvmem_device *nvmem;
 
 	ret = dev_get_drvdata(dev, (const void **)&data);
 	if (ret)
@@ -520,9 +544,17 @@ static int imx_ocotp_probe(struct device_d *dev)
 	if (IS_ERR(priv->map))
 		return PTR_ERR(priv->map);
 
-	ret = regmap_register_cdev(priv->map, "imx-ocotp");
-	if (ret)
-		return ret;
+	priv->config.name = "imx-ocotp";
+	priv->config.dev = dev;
+	priv->config.stride = 4;
+	priv->config.word_size = 4;
+	priv->config.size = data->num_regs;
+	priv->config.bus = &imx_ocotp_nvmem_bus;
+	dev->priv = priv;
+
+	nvmem = nvmem_register(&priv->config);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
 
 	imx_ocotp = priv;
 
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/7] VF610 OCOTP MAC address layout change
  2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
                   ` (6 preceding siblings ...)
  2018-05-29  4:47 ` [PATCH v2 7/7] nvmem: ocotp: Convert to NVMEM device Andrey Smirnov
@ 2018-05-31 15:27 ` Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-05-31 15:27 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox, Vivien Didelot

On Mon, May 28, 2018 at 09:47:24PM -0700, Andrey Smirnov wrote:
> Everyone:
> 
> This patchset is as a result of dealing with VF610 U-Boot OCOTP/MAC
> quirk.
> 
> 	- Patch 1 and 2 are the actual patches dealing with U-Boot's
>           idiosyncrasy (see individual commit messages for more
>           details)
> 
> 	- Patch 3 and 4 are trivial refactoring made possible with
>           <linux/bitfield.h>
> 
> 	- Patches 5, 6 and 7 are very much optional. IMHO,
>           drivers/nvmem is a better place for OCOTP code, but if we
>           want to keep the code as is, I am more than happy to drop
>           these from the series.
> 
> Changes since [v1]:
> 
> 	- Fixed a bug in MAC formatting spotted by Sascha.
> 
> 
> [v1] http://lists.infradead.org/pipermail/barebox/2018-May/033094.html
> 
> Feedback is wellcome!

Applied, thanks

Sascha

> 
> Thanks,
> Andrey Smirnov
> 
> Andrey Smirnov (7):
>   i.MX: ocotp: Unify code paths for reading MAC address
>   i.MX: ocotp: Change MAC address layout for VFxxx
>   i.MX: ocotp: Simplify OCOTP field packing/unpacking
>   i.MX: ocotp: Simplify BF macro
>   i.MX: ocotp: Move OCOTP driver to drivers/nvmem
>   nvmem: Use name from struct nvmem_config for cdev
>   nvmem: ocotp: Convert to NVMEM device
> 
>  arch/arm/mach-imx/Kconfig                    |  23 +--
>  arch/arm/mach-imx/Makefile                   |   1 -
>  arch/arm/mach-imx/include/mach/ocotp.h       |  31 ++-
>  drivers/nvmem/Kconfig                        |  21 ++
>  drivers/nvmem/Makefile                       |   3 +
>  drivers/nvmem/core.c                         |  18 +-
>  {arch/arm/mach-imx => drivers/nvmem}/ocotp.c | 201 ++++++++++++-------
>  7 files changed, 183 insertions(+), 115 deletions(-)
>  rename {arch/arm/mach-imx => drivers/nvmem}/ocotp.c (79%)
> 
> -- 
> 2.17.0
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-05-31 15:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-29  4:47 [PATCH v2 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 4/7] i.MX: ocotp: Simplify BF macro Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 6/7] nvmem: Use name from struct nvmem_config for cdev Andrey Smirnov
2018-05-29  4:47 ` [PATCH v2 7/7] nvmem: ocotp: Convert to NVMEM device Andrey Smirnov
2018-05-31 15:27 ` [PATCH v2 0/7] VF610 OCOTP MAC address layout change Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox