* [PATCH 1/7] i.MX: ocotp: Unify code paths for reading MAC address
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-22 23:05 ` [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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] 10+ messages in thread
* [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
2018-05-22 23:05 ` [PATCH 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-23 8:21 ` Sascha Hauer
2018-05-22 23:05 ` [PATCH 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking Andrey Smirnov
` (4 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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..a70adee37 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] = dst[0];
+ dst[4] = dst[5];
+ dst[5] = dst[4];
+ dst[6] = dst[3];
+ dst[7] = dst[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] 10+ messages in thread
* Re: [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx
2018-05-22 23:05 ` [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
@ 2018-05-23 8:21 ` Sascha Hauer
2018-05-25 3:06 ` Andrey Smirnov
0 siblings, 1 reply; 10+ messages in thread
From: Sascha Hauer @ 2018-05-23 8:21 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox, Vivien Didelot
On Tue, May 22, 2018 at 04:05:13PM -0700, Andrey Smirnov wrote:
> 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..a70adee37 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] = dst[0];
> + dst[4] = dst[5];
> + dst[5] = dst[4];
> + dst[6] = dst[3];
> + dst[7] = dst[2];
> + break;
only src[1] used? This looks wrong.
Sascha
--
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] 10+ messages in thread
* Re: [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx
2018-05-23 8:21 ` Sascha Hauer
@ 2018-05-25 3:06 ` Andrey Smirnov
0 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-25 3:06 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List, Vivien Didelot
On Wed, May 23, 2018 at 1:21 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Tue, May 22, 2018 at 04:05:13PM -0700, Andrey Smirnov wrote:
>> 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..a70adee37 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] = dst[0];
>> + dst[4] = dst[5];
>> + dst[5] = dst[4];
>> + dst[6] = dst[3];
>> + dst[7] = dst[2];
>> + break;
>
> only src[1] used? This looks wrong.
Yeah, that's wrong for sure. Will fix in v2.
Thanks,
Andrey Smrinov
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
2018-05-22 23:05 ` [PATCH 1/7] i.MX: ocotp: Unify code paths for reading MAC address Andrey Smirnov
2018-05-22 23:05 ` [PATCH 2/7] i.MX: ocotp: Change MAC address layout for VFxxx Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-22 23:05 ` [PATCH 4/7] i.MX: ocotp: Simplify BF macro Andrey Smirnov
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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 a70adee37..026d23cad 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] 10+ messages in thread
* [PATCH 4/7] i.MX: ocotp: Simplify BF macro
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
` (2 preceding siblings ...)
2018-05-22 23:05 ` [PATCH 3/7] i.MX: ocotp: Simplify OCOTP field packing/unpacking Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-22 23:05 ` [PATCH 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem Andrey Smirnov
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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 026d23cad..4c9927b37 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] 10+ messages in thread
* [PATCH 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
` (3 preceding siblings ...)
2018-05-22 23:05 ` [PATCH 4/7] i.MX: ocotp: Simplify BF macro Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-22 23:05 ` [PATCH 6/7] nvmem: Use name from struct nvmem_config for cdev Andrey Smirnov
2018-05-22 23:05 ` [PATCH 7/7] nvmem: ocotp: Convert to NVMEM device Andrey Smirnov
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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] 10+ messages in thread
* [PATCH 6/7] nvmem: Use name from struct nvmem_config for cdev
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
` (4 preceding siblings ...)
2018-05-22 23:05 ` [PATCH 5/7] i.MX: ocotp: Move OCOTP driver to drivers/nvmem Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
2018-05-22 23:05 ` [PATCH 7/7] nvmem: ocotp: Convert to NVMEM device Andrey Smirnov
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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] 10+ messages in thread
* [PATCH 7/7] nvmem: ocotp: Convert to NVMEM device
2018-05-22 23:05 [PATCH 0/7] VF610 OCOTP MAC address layout change Andrey Smirnov
` (5 preceding siblings ...)
2018-05-22 23:05 ` [PATCH 6/7] nvmem: Use name from struct nvmem_config for cdev Andrey Smirnov
@ 2018-05-22 23:05 ` Andrey Smirnov
6 siblings, 0 replies; 10+ messages in thread
From: Andrey Smirnov @ 2018-05-22 23:05 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 4c9927b37..1a3a30b49 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] 10+ messages in thread