diff options
Diffstat (limited to 'drivers/soc/imx')
-rw-r--r-- | drivers/soc/imx/Kconfig | 10 | ||||
-rw-r--r-- | drivers/soc/imx/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/imx/soc-imx-scu.c | 187 | ||||
-rw-r--r-- | drivers/soc/imx/soc-imx.c | 3 | ||||
-rw-r--r-- | drivers/soc/imx/soc-imx8m.c | 10 |
5 files changed, 11 insertions, 200 deletions
diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index d515d2cc20ed..a9370f4aacca 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -8,20 +8,12 @@ config IMX_GPCV2_PM_DOMAINS select PM_GENERIC_DOMAINS default y if SOC_IMX7D -config IMX_SCU_SOC - bool "i.MX System Controller Unit SoC info support" - depends on IMX_SCU - select SOC_BUS - help - If you say yes here you get support for the NXP i.MX System - Controller Unit SoC info module, it will provide the SoC info - like SoC family, ID and revision etc. - config SOC_IMX8M bool "i.MX8M SoC family support" depends on ARCH_MXC || COMPILE_TEST default ARCH_MXC && ARM64 select SOC_BUS + select ARM_GIC_V3 if ARCH_MXC help If you say yes here you get support for the NXP i.MX8M family support, it will provide the SoC info like SoC family, diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index 446143241fe7..078dc918f4f3 100644 --- a/drivers/soc/imx/Makefile +++ b/drivers/soc/imx/Makefile @@ -5,4 +5,3 @@ endif obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o -obj-$(CONFIG_IMX_SCU_SOC) += soc-imx-scu.o diff --git a/drivers/soc/imx/soc-imx-scu.c b/drivers/soc/imx/soc-imx-scu.c deleted file mode 100644 index 20d37eaeb5f2..000000000000 --- a/drivers/soc/imx/soc-imx-scu.c +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright 2019 NXP. - */ - -#include <dt-bindings/firmware/imx/rsrc.h> -#include <linux/firmware/imx/sci.h> -#include <linux/slab.h> -#include <linux/sys_soc.h> -#include <linux/platform_device.h> -#include <linux/of.h> - -#define IMX_SCU_SOC_DRIVER_NAME "imx-scu-soc" - -static struct imx_sc_ipc *soc_ipc_handle; - -struct imx_sc_msg_misc_get_soc_id { - struct imx_sc_rpc_msg hdr; - union { - struct { - u32 control; - u16 resource; - } __packed req; - struct { - u32 id; - } resp; - } data; -} __packed __aligned(4); - -struct imx_sc_msg_misc_get_soc_uid { - struct imx_sc_rpc_msg hdr; - u32 uid_low; - u32 uid_high; -} __packed; - -static int imx_scu_soc_uid(u64 *soc_uid) -{ - struct imx_sc_msg_misc_get_soc_uid msg; - struct imx_sc_rpc_msg *hdr = &msg.hdr; - int ret; - - hdr->ver = IMX_SC_RPC_VERSION; - hdr->svc = IMX_SC_RPC_SVC_MISC; - hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID; - hdr->size = 1; - - ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true); - if (ret) { - pr_err("%s: get soc uid failed, ret %d\n", __func__, ret); - return ret; - } - - *soc_uid = msg.uid_high; - *soc_uid <<= 32; - *soc_uid |= msg.uid_low; - - return 0; -} - -static int imx_scu_soc_id(void) -{ - struct imx_sc_msg_misc_get_soc_id msg; - struct imx_sc_rpc_msg *hdr = &msg.hdr; - int ret; - - hdr->ver = IMX_SC_RPC_VERSION; - hdr->svc = IMX_SC_RPC_SVC_MISC; - hdr->func = IMX_SC_MISC_FUNC_GET_CONTROL; - hdr->size = 3; - - msg.data.req.control = IMX_SC_C_ID; - msg.data.req.resource = IMX_SC_R_SYSTEM; - - ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true); - if (ret) { - pr_err("%s: get soc info failed, ret %d\n", __func__, ret); - return ret; - } - - return msg.data.resp.id; -} - -static int imx_scu_soc_probe(struct platform_device *pdev) -{ - struct soc_device_attribute *soc_dev_attr; - struct soc_device *soc_dev; - int id, ret; - u64 uid = 0; - u32 val; - - ret = imx_scu_get_handle(&soc_ipc_handle); - if (ret) - return ret; - - soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), - GFP_KERNEL); - if (!soc_dev_attr) - return -ENOMEM; - - soc_dev_attr->family = "Freescale i.MX"; - - ret = of_property_read_string(of_root, - "model", - &soc_dev_attr->machine); - if (ret) - return ret; - - id = imx_scu_soc_id(); - if (id < 0) - return -EINVAL; - - ret = imx_scu_soc_uid(&uid); - if (ret < 0) - return -EINVAL; - - /* format soc_id value passed from SCU firmware */ - val = id & 0x1f; - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x", val); - if (!soc_dev_attr->soc_id) - return -ENOMEM; - - /* format revision value passed from SCU firmware */ - val = (id >> 5) & 0xf; - val = (((val >> 2) + 1) << 4) | (val & 0x3); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, - "%d.%d", - (val >> 4) & 0xf, - val & 0xf); - if (!soc_dev_attr->revision) { - ret = -ENOMEM; - goto free_soc_id; - } - - soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", uid); - if (!soc_dev_attr->serial_number) { - ret = -ENOMEM; - goto free_revision; - } - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - ret = PTR_ERR(soc_dev); - goto free_serial_number; - } - - return 0; - -free_serial_number: - kfree(soc_dev_attr->serial_number); -free_revision: - kfree(soc_dev_attr->revision); -free_soc_id: - kfree(soc_dev_attr->soc_id); - return ret; -} - -static struct platform_driver imx_scu_soc_driver = { - .driver = { - .name = IMX_SCU_SOC_DRIVER_NAME, - }, - .probe = imx_scu_soc_probe, -}; - -static int __init imx_scu_soc_init(void) -{ - struct platform_device *pdev; - struct device_node *np; - int ret; - - np = of_find_compatible_node(NULL, NULL, "fsl,imx-scu"); - if (!np) - return -ENODEV; - - of_node_put(np); - - ret = platform_driver_register(&imx_scu_soc_driver); - if (ret) - return ret; - - pdev = platform_device_register_simple(IMX_SCU_SOC_DRIVER_NAME, - -1, NULL, 0); - if (IS_ERR(pdev)) - platform_driver_unregister(&imx_scu_soc_driver); - - return PTR_ERR_OR_ZERO(pdev); -} -device_initcall(imx_scu_soc_init); diff --git a/drivers/soc/imx/soc-imx.c b/drivers/soc/imx/soc-imx.c index fec3d672b606..01bfea1cb64a 100644 --- a/drivers/soc/imx/soc-imx.c +++ b/drivers/soc/imx/soc-imx.c @@ -33,6 +33,9 @@ static int __init imx_soc_device_init(void) u32 val; int ret; + if (of_machine_is_compatible("fsl,ls1021a")) + return 0; + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c index 7b0759adb47d..cc57a384d74d 100644 --- a/drivers/soc/imx/soc-imx8m.c +++ b/drivers/soc/imx/soc-imx8m.c @@ -22,6 +22,8 @@ #define OCOTP_UID_LOW 0x410 #define OCOTP_UID_HIGH 0x420 +#define IMX8MP_OCOTP_UID_OFFSET 0x10 + /* Same as ANADIG_DIGPROG_IMX7D */ #define ANADIG_DIGPROG_IMX8MM 0x800 @@ -87,6 +89,8 @@ static void __init imx8mm_soc_uid(void) { void __iomem *ocotp_base; struct device_node *np; + u32 offset = of_machine_is_compatible("fsl,imx8mp") ? + IMX8MP_OCOTP_UID_OFFSET : 0; np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-ocotp"); if (!np) @@ -95,9 +99,9 @@ static void __init imx8mm_soc_uid(void) ocotp_base = of_iomap(np, 0); WARN_ON(!ocotp_base); - soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH); + soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); soc_uid <<= 32; - soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW); + soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); iounmap(ocotp_base); of_node_put(np); @@ -146,7 +150,7 @@ static const struct imx8_soc_data imx8mp_soc_data = { .soc_revision = imx8mm_soc_revision, }; -static const struct of_device_id imx8_soc_match[] = { +static __maybe_unused const struct of_device_id imx8_soc_match[] = { { .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, }, { .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, }, { .compatible = "fsl,imx8mn", .data = &imx8mn_soc_data, }, |