2019-03-22 16:50:32

by Abel Vesa

[permalink] [raw]
Subject: [RESEND v2] soc: imx: Add generic i.MX8 SoC driver

Add generic i.MX8 SoC driver along with the i.MX8MQ SoC specific code.
For now, only i.MX8MQ revision B1 is supported. For any other, i.MX8MQ
revision it will print 'unknown'.

Signed-off-by: Abel Vesa <[email protected]>
---
drivers/soc/imx/Makefile | 1 +
drivers/soc/imx/soc-imx8.c | 115 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 drivers/soc/imx/soc-imx8.c

diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 506a6f3..d6b529e0 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
+obj-$(CONFIG_ARCH_MXC) += soc-imx8.o
diff --git a/drivers/soc/imx/soc-imx8.c b/drivers/soc/imx/soc-imx8.c
new file mode 100644
index 0000000..fc6429f
--- /dev/null
+++ b/drivers/soc/imx/soc-imx8.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#define REV_B1 0x21
+
+#define IMX8MQ_SW_INFO_B1 0x40
+#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
+
+struct imx8_soc_data {
+ char *name;
+ u32 (*soc_revision)(void);
+};
+
+static u32 __init imx8mq_soc_revision(void)
+{
+ struct device_node *np;
+ void __iomem *ocotp_base;
+ u32 magic;
+ u32 rev = 0;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ if (!np)
+ goto out;
+
+ ocotp_base = of_iomap(np, 0);
+ WARN_ON(!ocotp_base);
+
+ magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
+ if (magic == IMX8MQ_SW_MAGIC_B1)
+ rev = REV_B1;
+
+ iounmap(ocotp_base);
+
+out:
+ of_node_put(np);
+ return rev;
+}
+
+static const struct imx8_soc_data imx8mq_soc_data = {
+ .name = "i.MX8MQ",
+ .soc_revision = imx8mq_soc_revision,
+};
+
+static const struct of_device_id imx8_soc_match[] = {
+ { .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, },
+ { }
+};
+
+#define imx8_revision(soc_rev) \
+ soc_rev ? \
+ kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \
+ "unknown"
+
+static int __init imx8_soc_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct device_node *root;
+ const struct of_device_id *id;
+ u32 soc_rev = 0;
+ const struct imx8_soc_data *data;
+ int ret;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENODEV;
+
+ soc_dev_attr->family = "Freescale i.MX";
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+ if (ret)
+ goto free_soc;
+
+ id = of_match_node(imx8_soc_match, root);
+ if (!id)
+ goto free_soc;
+
+ of_node_put(root);
+
+ data = id->data;
+ if (data) {
+ soc_dev_attr->soc_id = data->name;
+ if (data->soc_revision)
+ soc_rev = data->soc_revision();
+ }
+
+ soc_dev_attr->revision = imx8_revision(soc_rev);
+ if (!soc_dev_attr->revision)
+ goto free_soc;
+
+ soc_dev = soc_device_register(soc_dev_attr);
+ if (IS_ERR(soc_dev))
+ goto free_rev;
+
+ return 0;
+
+free_rev:
+ kfree(soc_dev_attr->revision);
+free_soc:
+ kfree(soc_dev_attr);
+ of_node_put(root);
+ return -ENODEV;
+}
+device_initcall(imx8_soc_init);
--
2.7.4



2019-03-28 16:45:08

by Leonard Crestez

[permalink] [raw]
Subject: Re: [RESEND v2] soc: imx: Add generic i.MX8 SoC driver

On Fri, 2019-03-22 at 16:49 +0000, Abel Vesa wrote:
> Add generic i.MX8 SoC driver along with the i.MX8MQ SoC specific code.
> For now, only i.MX8MQ revision B1 is supported. For any other, i.MX8MQ
> revision it will print 'unknown'.

> +#define REV_B1 0x21
> +
> +#define IMX8MQ_SW_INFO_B1 0x40
> +#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
> +
> + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");+
> + ocotp_base = of_iomap(np, 0);
> +
> + magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
> + if (magic == IMX8MQ_SW_MAGIC_B1)
> + rev = REV_B1;

This is based on ATF code in vendor tree, but shouldn't we have some
sort of explanation for this "magic"?

Looking at the OCOTP driver reg 0x40 is IMX_OCOTP_ADDR_DATA2 and it's
used as part of fuse writes. According to the driver code 8mq is
compatible with 7d and this write path is enabled for imx8mq-ocotp.

Looking at the OCOTP manual reg 0x40 is OCOTP_HW_OCOTP_READ_FUSE_DATA
and it's meant to be used together with IMX_OCOTP_ADDR_CTRL to read
info. Maybe my manual (rev0 2018-01) is incorrect?

Looking at the manual this will return the value of the fuse last
requested via IMX_OCOTP_ADDR_CTRL but no such request is made in this
driver. So reading from OCOTP 0x40 might return an unrelated value?!

The manual does document that fuse 0x440[3:0] is a "silicon revision
number"; maybe we should read that?

--
Regards,
Leonard

2019-04-18 22:03:26

by Leonard Crestez

[permalink] [raw]
Subject: Re: [RESEND v2] soc: imx: Add generic i.MX8 SoC driver

On 3/28/2019 6:43 PM, Leonard Crestez wrote:
> On Fri, 2019-03-22 at 16:49 +0000, Abel Vesa wrote:
>> Add generic i.MX8 SoC driver along with the i.MX8MQ SoC specific code.
>> For now, only i.MX8MQ revision B1 is supported. For any other, i.MX8MQ
>> revision it will print 'unknown'.
>
>> +#define REV_B1 0x21
>> +
>> +#define IMX8MQ_SW_INFO_B1 0x40
>> +#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
>> +
>> + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");+
>> + ocotp_base = of_iomap(np, 0);
>> +
>> + magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
>> + if (magic == IMX8MQ_SW_MAGIC_B1)
>> + rev = REV_B1;
>
> This is based on ATF code in vendor tree, but shouldn't we have some
> sort of explanation for this "magic"?
>
> Looking at the OCOTP driver reg 0x40 is IMX_OCOTP_ADDR_DATA2 and it's
> used as part of fuse writes. According to the driver code 8mq is
> compatible with 7d and this write path is enabled for imx8mq-ocotp.

After further digging in NXP manuals and uboot sources it seems that
imx8mq ocotp is like imx6 rather than imx7. Posted fix for nvmem driver:

https://patchwork.kernel.org/patch/10908081/

Reviewed-by: Leonard Crestez <[email protected]>

It might still be nice to find a way to identify imx8mq B0.

2019-04-20 13:30:46

by Shawn Guo

[permalink] [raw]
Subject: Re: [RESEND v2] soc: imx: Add generic i.MX8 SoC driver

On Fri, Mar 22, 2019 at 04:49:20PM +0000, Abel Vesa wrote:
> Add generic i.MX8 SoC driver along with the i.MX8MQ SoC specific code.
> For now, only i.MX8MQ revision B1 is supported. For any other, i.MX8MQ
> revision it will print 'unknown'.
>
> Signed-off-by: Abel Vesa <[email protected]>

Applied, thanks.