Message ID | 1553273350-28852-1-git-send-email-abel.vesa@nxp.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Commit | a7e26f356ca12906a164d83c9e9f8527ee7da022 |
Headers | show |
Series | [RESEND,v2] soc: imx: Add generic i.MX8 SoC driver | expand |
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
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 <leonard.crestez@nxp.com> It might still be nice to find a way to identify imx8mq B0.
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 <abel.vesa@nxp.com> Applied, thanks.
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);
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 <abel.vesa@nxp.com> --- 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