summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-04 19:47:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-04 19:47:11 -0700
commit694b5a5d313f3997764b67d52bab66ec7e59e714 (patch)
tree9805ee9750144aa7dec19492ee5af6f3cc5362fe /drivers/soc
parent587f17018a2c6c414e41a312b002faaef60cf423 (diff)
parentd2353bad2c1eef7a1228645fbb21e7887c633d12 (diff)
Merge tag 'arm-soc-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM SoC updates from Arnd Bergmann: "One new platform gets added, the Realtek RTD1195, which is an older Cortex-a7 based relative of the RTD12xx chips that are already supported in arch/arm64. The platform may also be extended to support running 32-bit kernels on those 64-bit chips for memory-constrained machines. In the Renesas shmobile platform, we gain support for "RZ/G1H" or R8A7742, an eight-core chip based on Cortex-A15 and Cortex-A7 cores, originally released in 2016 as one of the last high-end 32-bit designs. There is ongoing cleanup for the integrator, tegra, imx, and omap2 platforms, with integrator getting very close to the goal of having zero code in arch/arm/, and omap2 moving more of the chip specifics from old board code into device tree files. The Versatile Express platform is made more modular, with built-in drivers now becoming loadable modules. This is part of a greater effort for the Android OS to have a common kernel binary for all platforms and any platform specific code in loadable modules. The PXA platform drops support for Compulab's pxa2xx boards that had rather unusual flash and PCI drivers but no known users remaining. All device drivers specific to those boards can now get removed as well. Across platforms, there is ongoing cleanup, with Geert and Rob revisiting some a lot of Kconfig options" * tag 'arm-soc-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (94 commits) ARM: omap2: fix omap5_realtime_timer_init definition ARM: zynq: Don't select CONFIG_ICST ARM: OMAP2+: Fix regression for using local timer on non-SMP SoCs clk: versatile: Fix kconfig dependency on COMMON_CLK_VERSATILE ARM: davinci: fix build failure without I2C power: reset: vexpress: fix build issue power: vexpress: cleanup: use builtin_platform_driver power: vexpress: add suppress_bind_attrs to true Revert "ARM: vexpress: Don't select VEXPRESS_CONFIG" MAINTAINERS: pxa: remove Compulab arm/pxa support ARM: pxa: remove Compulab pxa2xx boards bus: arm-integrator-lm: Fix return value check in integrator_ap_lm_probe() soc: imx: move cpu code to drivers/soc/imx ARM: imx: move cpu definitions into a header ARM: imx: use device_initcall for imx_soc_device_init ARM: imx: pcm037: make pcm970_sja1000_platform_data static bus: ti-sysc: Timers no longer need legacy quirk handling ARM: OMAP2+: Drop old timer code for dmtimer and 32k counter ARM: dts: Configure system timers for omap2 ARM: dts: Configure system timers for ti81xx ...
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/imx/Makefile3
-rw-r--r--drivers/soc/imx/soc-imx.c192
2 files changed, 195 insertions, 0 deletions
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 103e2c93c342..446143241fe7 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -1,4 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
+ifeq ($(CONFIG_ARM),y)
+obj-$(CONFIG_ARCH_MXC) += soc-imx.o
+endif
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
diff --git a/drivers/soc/imx/soc-imx.c b/drivers/soc/imx/soc-imx.c
new file mode 100644
index 000000000000..fec3d672b606
--- /dev/null
+++ b/drivers/soc/imx/soc-imx.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 NXP
+ */
+
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#include <soc/imx/cpu.h>
+#include <soc/imx/revision.h>
+
+#define OCOTP_UID_H 0x420
+#define OCOTP_UID_L 0x410
+
+#define OCOTP_ULP_UID_1 0x4b0
+#define OCOTP_ULP_UID_2 0x4c0
+#define OCOTP_ULP_UID_3 0x4d0
+#define OCOTP_ULP_UID_4 0x4e0
+
+static int __init imx_soc_device_init(void)
+{
+ struct soc_device_attribute *soc_dev_attr;
+ const char *ocotp_compat = NULL;
+ struct soc_device *soc_dev;
+ struct device_node *root;
+ struct regmap *ocotp = NULL;
+ const char *soc_id;
+ u64 soc_uid = 0;
+ u32 val;
+ int ret;
+
+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ if (!soc_dev_attr)
+ return -ENOMEM;
+
+ soc_dev_attr->family = "Freescale i.MX";
+
+ root = of_find_node_by_path("/");
+ ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+ of_node_put(root);
+ if (ret)
+ goto free_soc;
+
+ switch (__mxc_cpu_type) {
+ case MXC_CPU_MX1:
+ soc_id = "i.MX1";
+ break;
+ case MXC_CPU_MX21:
+ soc_id = "i.MX21";
+ break;
+ case MXC_CPU_MX25:
+ soc_id = "i.MX25";
+ break;
+ case MXC_CPU_MX27:
+ soc_id = "i.MX27";
+ break;
+ case MXC_CPU_MX31:
+ soc_id = "i.MX31";
+ break;
+ case MXC_CPU_MX35:
+ soc_id = "i.MX35";
+ break;
+ case MXC_CPU_MX51:
+ soc_id = "i.MX51";
+ break;
+ case MXC_CPU_MX53:
+ soc_id = "i.MX53";
+ break;
+ case MXC_CPU_IMX6SL:
+ ocotp_compat = "fsl,imx6sl-ocotp";
+ soc_id = "i.MX6SL";
+ break;
+ case MXC_CPU_IMX6DL:
+ ocotp_compat = "fsl,imx6q-ocotp";
+ soc_id = "i.MX6DL";
+ break;
+ case MXC_CPU_IMX6SX:
+ ocotp_compat = "fsl,imx6sx-ocotp";
+ soc_id = "i.MX6SX";
+ break;
+ case MXC_CPU_IMX6Q:
+ ocotp_compat = "fsl,imx6q-ocotp";
+ soc_id = "i.MX6Q";
+ break;
+ case MXC_CPU_IMX6UL:
+ ocotp_compat = "fsl,imx6ul-ocotp";
+ soc_id = "i.MX6UL";
+ break;
+ case MXC_CPU_IMX6ULL:
+ ocotp_compat = "fsl,imx6ull-ocotp";
+ soc_id = "i.MX6ULL";
+ break;
+ case MXC_CPU_IMX6ULZ:
+ ocotp_compat = "fsl,imx6ull-ocotp";
+ soc_id = "i.MX6ULZ";
+ break;
+ case MXC_CPU_IMX6SLL:
+ ocotp_compat = "fsl,imx6sll-ocotp";
+ soc_id = "i.MX6SLL";
+ break;
+ case MXC_CPU_IMX7D:
+ ocotp_compat = "fsl,imx7d-ocotp";
+ soc_id = "i.MX7D";
+ break;
+ case MXC_CPU_IMX7ULP:
+ ocotp_compat = "fsl,imx7ulp-ocotp";
+ soc_id = "i.MX7ULP";
+ break;
+ case MXC_CPU_VF500:
+ ocotp_compat = "fsl,vf610-ocotp";
+ soc_id = "VF500";
+ break;
+ case MXC_CPU_VF510:
+ ocotp_compat = "fsl,vf610-ocotp";
+ soc_id = "VF510";
+ break;
+ case MXC_CPU_VF600:
+ ocotp_compat = "fsl,vf610-ocotp";
+ soc_id = "VF600";
+ break;
+ case MXC_CPU_VF610:
+ ocotp_compat = "fsl,vf610-ocotp";
+ soc_id = "VF610";
+ break;
+ default:
+ soc_id = "Unknown";
+ }
+ soc_dev_attr->soc_id = soc_id;
+
+ if (ocotp_compat) {
+ ocotp = syscon_regmap_lookup_by_compatible(ocotp_compat);
+ if (IS_ERR(ocotp))
+ pr_err("%s: failed to find %s regmap!\n", __func__, ocotp_compat);
+ }
+
+ if (!IS_ERR_OR_NULL(ocotp)) {
+ if (__mxc_cpu_type == MXC_CPU_IMX7ULP) {
+ regmap_read(ocotp, OCOTP_ULP_UID_4, &val);
+ soc_uid = val & 0xffff;
+ regmap_read(ocotp, OCOTP_ULP_UID_3, &val);
+ soc_uid <<= 16;
+ soc_uid |= val & 0xffff;
+ regmap_read(ocotp, OCOTP_ULP_UID_2, &val);
+ soc_uid <<= 16;
+ soc_uid |= val & 0xffff;
+ regmap_read(ocotp, OCOTP_ULP_UID_1, &val);
+ soc_uid <<= 16;
+ soc_uid |= val & 0xffff;
+ } else {
+ regmap_read(ocotp, OCOTP_UID_H, &val);
+ soc_uid = val;
+ regmap_read(ocotp, OCOTP_UID_L, &val);
+ soc_uid <<= 32;
+ soc_uid |= val;
+ }
+ }
+
+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
+ (imx_get_soc_revision() >> 4) & 0xf,
+ imx_get_soc_revision() & 0xf);
+ if (!soc_dev_attr->revision) {
+ ret = -ENOMEM;
+ goto free_soc;
+ }
+
+ soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid);
+ if (!soc_dev_attr->serial_number) {
+ ret = -ENOMEM;
+ goto free_rev;
+ }
+
+ 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_rev:
+ kfree(soc_dev_attr->revision);
+free_soc:
+ kfree(soc_dev_attr);
+ return ret;
+}
+device_initcall(imx_soc_device_init);