[PATCH v2 0/9] Introduce UCLASS_SOC

Hi,
This is v2 of the series to introduce UCLASS_SOC to be used for SOC identification and attribute matching based on SoC ID info. The first version of this series can be found at [1].
Biggest change is the addition of a patch to add documentation for the SOC ID framework as requested by several folks. Otherwise, several comments were addressed in the patch to introduce the UCLASS_SOC implementation:
* Renamed soc_device_attribute to soc_attr. * Added inline docs for same struct. * Moved ifdef for CONFIG_SOC_DEVICE to only include functions * Documented NULL return possiblity for soc_device_match.
And a change to SOC Revision macro naming in the soc_ti_k3 driver to use SR consistently instead of PG.
Regards, Dave
[1] https://lists.denx.de/pipermail/u-boot/2020-June/418109.html
Dave Gerlach (9): doc: Add new doc for soc ID driver model dm: soc: Introduce UCLASS_SOC for SOC ID and attribute matching test: Add tests for SOC uclass dm: soc: Introduce soc_ti_k3 driver for TI K3 SoCs arm: dts: k3-am65-wakeup: Introduce chipid node arm: dts: k3-j721e-mcu-wakeup: Introduce chipid node configs: am65x_evm: Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 configs: j721e_evm: Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 arm: mach-k3: Use SOC driver for device identification
arch/arm/dts/k3-am65-wakeup.dtsi | 5 + arch/arm/dts/k3-am654-base-board-u-boot.dtsi | 4 + .../k3-j721e-common-proc-board-u-boot.dtsi | 4 + arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 5 + arch/arm/mach-k3/common.c | 48 +++--- arch/arm/mach-k3/common.h | 6 - arch/arm/mach-k3/include/mach/hardware.h | 1 - arch/sandbox/dts/test.dts | 4 + configs/am65x_evm_a53_defconfig | 2 + configs/am65x_evm_r5_defconfig | 2 + configs/am65x_hs_evm_a53_defconfig | 2 + configs/am65x_hs_evm_r5_defconfig | 2 + configs/j721e_evm_a72_defconfig | 2 + configs/j721e_evm_r5_defconfig | 2 + configs/j721e_hs_evm_a72_defconfig | 2 + configs/j721e_hs_evm_r5_defconfig | 2 + configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + doc/driver-model/index.rst | 1 + doc/driver-model/soc-framework.rst | 68 ++++++++ drivers/soc/Kconfig | 16 ++ drivers/soc/Makefile | 3 + drivers/soc/soc-uclass.c | 102 ++++++++++++ drivers/soc/soc_sandbox.c | 56 +++++++ drivers/soc/soc_ti_k3.c | 124 +++++++++++++++ include/dm/uclass-id.h | 1 + include/soc.h | 145 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/soc.c | 120 +++++++++++++++ 31 files changed, 698 insertions(+), 36 deletions(-) create mode 100644 doc/driver-model/soc-framework.rst create mode 100644 drivers/soc/soc-uclass.c create mode 100644 drivers/soc/soc_sandbox.c create mode 100644 drivers/soc/soc_ti_k3.c create mode 100644 include/soc.h create mode 100644 test/dm/soc.c

Add a new documentation file for UCLASS_SOC and its usage to describe the SoC Device ID framework that allows SoC identification and device data matching.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- doc/driver-model/index.rst | 1 + doc/driver-model/soc-framework.rst | 68 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 doc/driver-model/soc-framework.rst
diff --git a/doc/driver-model/index.rst b/doc/driver-model/index.rst index b9df221627e2..f17c72ce69d8 100644 --- a/doc/driver-model/index.rst +++ b/doc/driver-model/index.rst @@ -19,5 +19,6 @@ Driver Model pmic-framework remoteproc-framework serial-howto + soc-framework spi-howto usb-info diff --git a/doc/driver-model/soc-framework.rst b/doc/driver-model/soc-framework.rst new file mode 100644 index 000000000000..2609fda64421 --- /dev/null +++ b/doc/driver-model/soc-framework.rst @@ -0,0 +1,68 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. (C) Copyright 2020 +.. Texas Instruments Incorporated - http://www.ti.com/ + +SOC ID Framework +================ + +Introduction +------------ + +The driver-model SOC ID framework is able to provide identification +information about a specific SoC in use at runtime, and also provide matching +from a set of identification information from an array. This can be useful for +enabling small quirks in drivers that exist between SoC variants that are +impractical to implement using device tree flags. It is based on UCLASS_SOC. + +UCLASS_SOC: + - drivers/soc/soc-uclass.c + - include/soc.h + +Configuration: + - CONFIG_SOC_DEVICE is selected by drivers as needed. + +Implementing a UCLASS_SOC provider +---------------------------------- + +The purpose of this framework is to allow UCLASS_SOC provider drivers to supply +identification information about the SoC in use at runtime. The framework +allows drivers to define soc_ops that return identification strings. All +soc_ops need not be defined and can be left as NULL, in which case the +framework will return -ENOSYS and not consider the value when doing an +soc_device_match. + +It is left to the driver implementor to decide how the information returned is +determined, but in general the same SOC should always return the same set of +identifying information. Information returned must be in the form of a NULL +terminated string. + +See include/soc.h for documentation of the available soc_ops and the intended +meaning of the values that can be returned. See drivers/soc/soc_sandbox.c for +an example UCLASS_SOC provider driver. + +Using a UCLASS_SOC driver +------------------------- + +The framework provides the ability to retrieve and use the identification +strings directly. It also has the ability to return a match from a list of +different sets of SoC data using soc_device_match. + +An array of 'struct soc_attr' can be defined, each containing ID information +for a specific SoC, and when passed to soc_device_match, the identifier values +for each entry in the list will be compared against the values provided by the +UCLASS_SOC driver that is in use. The first entry in the list that matches all +non-null values will be returned by soc_device_match. + +An example of various uses of the framework can be found at test/dm/soc.c. + +Describing the device using device tree +--------------------------------------- + +.. code-block:: none + + chipid: chipid { + compatible = "sandbox,soc"; + }; + +All that is required in a DT node is a compatible for a corresponding +UCLASS_SOC driver.

On Wed, 15 Jul 2020 at 22:40, Dave Gerlach d-gerlach@ti.com wrote:
Add a new documentation file for UCLASS_SOC and its usage to describe the SoC Device ID framework that allows SoC identification and device data matching.
Signed-off-by: Dave Gerlach d-gerlach@ti.com
doc/driver-model/index.rst | 1 + doc/driver-model/soc-framework.rst | 68 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 doc/driver-model/soc-framework.rst
Reviewed-by: Simon Glass sjg@chromium.org

Introduce UCLASS_SOC to be used for SOC identification and attribute matching based on the SoC ID info. This allows drivers to be provided for SoCs to retrieve SoC identifying information and also for matching device attributes for selecting SoC specific data.
This is useful for other device drivers that may need different parameters or quirks enabled depending on the specific device variant in use.
Reviewed-by: Simon Glass sjg@chromium.org Signed-off-by: Dave Gerlach d-gerlach@ti.com --- drivers/soc/Kconfig | 9 +++ drivers/soc/Makefile | 1 + drivers/soc/soc-uclass.c | 102 +++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/soc.h | 145 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 258 insertions(+) create mode 100644 drivers/soc/soc-uclass.c create mode 100644 include/soc.h
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 7b4e4d613088..e715dfd01712 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,5 +1,14 @@ menu "SOC (System On Chip) specific Drivers"
+config SOC_DEVICE + bool "Enable SoC Device ID drivers using Driver Model" + help + This allows drivers to be provided for SoCs to help in identifying + the SoC in use and matching SoC attributes for selecting SoC + specific data. This is useful for other device drivers that may + need different parameters or quirks enabled depending on the + specific device variant in use. + source "drivers/soc/ti/Kconfig"
endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index ce253b7aa886..1c09a8465670 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -3,3 +3,4 @@ # Makefile for the U-Boot SOC specific device drivers.
obj-$(CONFIG_SOC_TI) += ti/ +obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o diff --git a/drivers/soc/soc-uclass.c b/drivers/soc/soc-uclass.c new file mode 100644 index 000000000000..c32d647864f2 --- /dev/null +++ b/drivers/soc/soc-uclass.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 - Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach d-gerlach@ti.com + */ + +#include <common.h> +#include <soc.h> +#include <dm.h> +#include <errno.h> +#include <dm/lists.h> +#include <dm/root.h> + +int soc_get(struct udevice **devp) +{ + return uclass_first_device_err(UCLASS_SOC, devp); +} + +int soc_get_machine(struct udevice *dev, char *buf, int size) +{ + struct soc_ops *ops = soc_get_ops(dev); + + if (!ops->get_machine) + return -ENOSYS; + + return ops->get_machine(dev, buf, size); +} + +int soc_get_family(struct udevice *dev, char *buf, int size) +{ + struct soc_ops *ops = soc_get_ops(dev); + + if (!ops->get_family) + return -ENOSYS; + + return ops->get_family(dev, buf, size); +} + +int soc_get_revision(struct udevice *dev, char *buf, int size) +{ + struct soc_ops *ops = soc_get_ops(dev); + + if (!ops->get_revision) + return -ENOSYS; + + return ops->get_revision(dev, buf, size); +} + +const struct soc_attr * +soc_device_match(const struct soc_attr *matches) +{ + bool match; + struct udevice *soc; + char str[SOC_MAX_STR_SIZE]; + + if (!matches) + return NULL; + + if (soc_get(&soc)) + return NULL; + + while (1) { + if (!(matches->machine || matches->family || + matches->revision)) + break; + + match = true; + + if (matches->machine) { + if (!soc_get_machine(soc, str, SOC_MAX_STR_SIZE)) { + if (strcmp(matches->machine, str)) + match = false; + } + } + + if (matches->family) { + if (!soc_get_family(soc, str, SOC_MAX_STR_SIZE)) { + if (strcmp(matches->family, str)) + match = false; + } + } + + if (matches->revision) { + if (!soc_get_revision(soc, str, SOC_MAX_STR_SIZE)) { + if (strcmp(matches->revision, str)) + match = false; + } + } + + if (match) + return matches; + + matches++; + } + + return NULL; +} + +UCLASS_DRIVER(soc) = { + .id = UCLASS_SOC, + .name = "soc", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 7837d459f18c..690a8ed4df49 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -97,6 +97,7 @@ enum uclass_id { UCLASS_SERIAL, /* Serial UART */ UCLASS_SIMPLE_BUS, /* Bus with child devices */ UCLASS_SMEM, /* Shared memory interface */ + UCLASS_SOC, /* SOC Device */ UCLASS_SOUND, /* Playing simple sounds */ UCLASS_SPI, /* SPI bus */ UCLASS_SPI_FLASH, /* SPI flash */ diff --git a/include/soc.h b/include/soc.h new file mode 100644 index 000000000000..a55eb1b5724e --- /dev/null +++ b/include/soc.h @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2020 - Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach d-gerlach@ti.com + */ + +#ifndef __SOC_H +#define __SOC_H + +#define SOC_MAX_STR_SIZE 128 + +/** + * struct soc_attr - Contains SoC identify information to be used in + * SoC matching. An array of these structs + * representing different SoCs can be passed to + * soc_device_match and the struct matching the SoC + * in use will be returned. + * + * @family - Name of SoC family that can include multiple related SoC + * variants. Example: am33 + * @machine - Name of a specific SoC. Example: am3352 + * @revision - Name of a specific SoC revision. Example: SR1.1 + * @data - A pointer to user data for the SoC variant + */ +struct soc_attr { + const char *family; + const char *machine; + const char *revision; + const void *data; +}; + +struct soc_ops { + /** + * get_machine() - Get machine name of an SOC + * + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ + int (*get_machine)(struct udevice *dev, char *buf, int size); + + /** + * get_revision() - Get revision name of a SOC + * + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ + int (*get_revision)(struct udevice *dev, char *buf, int size); + + /** + * get_family() - Get family name of an SOC + * + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ + int (*get_family)(struct udevice *dev, char *buf, int size); +}; + +#define soc_get_ops(dev) ((struct soc_ops *)(dev)->driver->ops) + +#ifdef CONFIG_SOC_DEVICE +/** + * soc_get() - Return the soc device for the soc in use. + * @devp: Pointer to structure to receive the soc device. + * + * Since there can only be at most one SOC instance, the API can supply a + * function that returns the unique device. + * + * Return: 0 if OK, -ve on error. + */ +int soc_get(struct udevice **devp); + +/** + * soc_get_machine() - Get machine name of an SOC + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * + * Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int soc_get_machine(struct udevice *dev, char *buf, int size); + +/** + * soc_get_revision() - Get revision name of an SOC + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * + * Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int soc_get_revision(struct udevice *dev, char *buf, int size); + +/** + * soc_get_family() - Get family name of an SOC + * @dev: Device to check (UCLASS_SOC) + * @buf: Buffer to place string + * @size: Size of string space + * + * Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error + */ +int soc_get_family(struct udevice *dev, char *buf, int size); + +/** + * soc_device_match() - Return match from an array of soc_attr + * @matches: Array with any combination of family, revision or machine set + * + * Return: Pointer to struct from matches array with set attributes matching + * those provided by the soc device, or NULL if no match found. + */ +const struct soc_attr * +soc_device_match(const struct soc_attr *matches); + +#else +static inline int soc_get(struct udevice **devp) +{ + return -ENOSYS; +} + +static inline int soc_get_machine(struct udevice *dev, char *buf, int size) +{ + return -ENOSYS; +} + +static inline int soc_get_revision(struct udevice *dev, char *buf, int size) +{ + return -ENOSYS; +} + +static inline int soc_get_family(struct udevice *dev, char *buf, int size) +{ + return -ENOSYS; +} + +static inline const struct soc_attr * +soc_device_match(const struct soc_attr *matches) +{ + return NULL; +} +#endif +#endif /* _SOC_H */

Add a sandbox SOC driver, and some tests for the SOC uclass.
Reviewed-by: Simon Glass sjg@chromium.org Signed-off-by: Dave Gerlach d-gerlach@ti.com --- arch/sandbox/dts/test.dts | 4 + configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/soc_sandbox.c | 56 ++++++++++++++ test/dm/Makefile | 1 + test/dm/soc.c | 120 +++++++++++++++++++++++++++++ 9 files changed, 186 insertions(+) create mode 100644 drivers/soc/soc_sandbox.c create mode 100644 test/dm/soc.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 5ce5e2847642..20404c4a0ce9 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -492,6 +492,10 @@ }; };
+ chipid: chipid { + compatible = "sandbox,soc"; + }; + i2s: i2s { compatible = "sandbox,i2s"; #sound-dai-cells = <1>; diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index a3f049e124e1..3ded31f4a9a7 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -114,6 +114,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SOC_DEVICE=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5b7569319b73..b19f337f3f0c 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -133,6 +133,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SOC_DEVICE=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 21f9047046a3..b889ecb058c8 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -99,6 +99,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SOC_DEVICE=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index fc8b26e88cfe..45cb9e78d769 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -118,6 +118,7 @@ CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y CONFIG_MISC=y +CONFIG_SOC_DEVICE=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 1c09a8465670..649e92b3906d 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -4,3 +4,4 @@
obj-$(CONFIG_SOC_TI) += ti/ obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o +obj-$(CONFIG_SANDBOX) += soc_sandbox.o diff --git a/drivers/soc/soc_sandbox.c b/drivers/soc/soc_sandbox.c new file mode 100644 index 000000000000..5c82ad84fc21 --- /dev/null +++ b/drivers/soc/soc_sandbox.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Sandbox driver for the SOC uclass + * + * (C) Copyright 2020 - Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach d-gerlach@ti.com + */ + +#include <common.h> +#include <dm.h> +#include <soc.h> + +int soc_sandbox_get_family(struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "SANDBOX1xx"); + + return 0; +} + +int soc_sandbox_get_machine(struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "SANDBOX123"); + + return 0; +} + +int soc_sandbox_get_revision(struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "1.0"); + + return 0; +} + +static const struct soc_ops soc_sandbox_ops = { + .get_family = soc_sandbox_get_family, + .get_revision = soc_sandbox_get_revision, + .get_machine = soc_sandbox_get_machine, +}; + +int soc_sandbox_probe(struct udevice *dev) +{ + return 0; +} + +static const struct udevice_id soc_sandbox_ids[] = { + { .compatible = "sandbox,soc" }, + { } +}; + +U_BOOT_DRIVER(soc_sandbox) = { + .name = "soc_sandbox", + .id = UCLASS_SOC, + .ops = &soc_sandbox_ops, + .of_match = soc_sandbox_ids, + .probe = soc_sandbox_probe, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 6c18fd04ce1c..9d570d3f5b89 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_AXI) += axi.o obj-$(CONFIG_MISC) += misc.o obj-$(CONFIG_DM_SERIAL) += serial.o obj-$(CONFIG_CPU) += cpu.o +obj-$(CONFIG_SOC_DEVICE) += soc.o obj-$(CONFIG_SOUND) += sound.o obj-$(CONFIG_TEE) += tee.o obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o diff --git a/test/dm/soc.c b/test/dm/soc.c new file mode 100644 index 000000000000..3ad0f561f27b --- /dev/null +++ b/test/dm/soc.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for the SOC uclass + * + * (C) Copyright 2020 - Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach d-gerlach@ti.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <dm/uclass-internal.h> +#include <soc.h> +#include <test/ut.h> + +struct sb_soc_data { + unsigned long param; +}; + +static int dm_test_soc(struct unit_test_state *uts) +{ + struct udevice *dev; + char text[128]; + const struct soc_attr *soc_data; + const struct sb_soc_data *match_data; + + static const struct sb_soc_data soc_sandbox1_sr10_data = { 0x91919191 }; + static const struct sb_soc_data soc_sandbox123_data = { 0x84848484 }; + + static const struct soc_attr sb_soc_devices_full[] = { + { + .family = "SANDBOX0xx", + .machine = "SANDBOX012", + .revision = "1.0", + .data = NULL, + }, + { + .family = "SANDBOX1xx", + .machine = "SANDBOX107", + .revision = "1.0", + .data = NULL, + }, + { + .family = "SANDBOX1xx", + .machine = "SANDBOX123", + .revision = "1.0", + .data = &soc_sandbox123_data, + }, + { + .family = "SANDBOX1xx", + .machine = "SANDBOX131", + .revision = "2.0", + .data = NULL, + }, + { /* sentinel */ } + }; + + static const struct soc_attr sb_soc_devices_partial[] = { + { + .family = "SANDBOX0xx", + .revision = "1.0", + .data = NULL, + }, + { + .family = "SANDBOX1xx", + .revision = "1.0", + .data = &soc_sandbox1_sr10_data, + }, + { + .family = "SANDBOX1xx", + .revision = "2.0", + .data = NULL, + }, + { /* sentinel */ } + }; + + static const struct soc_attr sb_soc_devices_nomatch[] = { + { + .family = "SANDBOX0xx", + .revision = "1.0", + .data = NULL, + }, + { + .family = "SANDBOX1xx", + .revision = "2.0", + .data = NULL, + }, + { /* sentinel */ } + }; + + ut_assertok(soc_get(&dev)); + + ut_assertok(soc_get_machine(dev, text, sizeof(text))); + ut_assertok(strcmp(text, "SANDBOX123")); + + ut_assertok(soc_get_family(dev, text, sizeof(text))); + ut_assertok(strcmp(text, "SANDBOX1xx")); + + ut_assertok(soc_get_revision(dev, text, sizeof(text))); + ut_asserteq_str(text, "1.0"); + + soc_data = soc_device_match(sb_soc_devices_full); + ut_assert(soc_data); + + match_data = soc_data->data; + ut_asserteq(match_data->param, 0x84848484); + + soc_data = soc_device_match(sb_soc_devices_partial); + ut_assert(soc_data); + + match_data = soc_data->data; + ut_asserteq(match_data->param, 0x91919191); + + soc_data = soc_device_match(sb_soc_devices_nomatch); + ut_asserteq_ptr(soc_data, NULL); + + return 0; +} + +DM_TEST(dm_test_soc, DM_TESTF_SCAN_FDT);

Introduce an soc_ti_k3_driver that allows identification and selection of SoC specific data based on the JTAG ID register for device identification, as described for AM65x[0] and J721E[1] devices.
[0] http://www.ti.com/lit/ug/spruid7e/spruid7e.pdf [1] http://www.ti.com/lit/ug/spruil1a/spruil1a.pdf
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- drivers/soc/Kconfig | 7 +++ drivers/soc/Makefile | 1 + drivers/soc/soc_ti_k3.c | 124 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/soc/soc_ti_k3.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index e715dfd01712..864d00a88538 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -9,6 +9,13 @@ config SOC_DEVICE need different parameters or quirks enabled depending on the specific device variant in use.
+config SOC_DEVICE_TI_K3 + depends on SOC_DEVICE + bool "Enable SoC Device ID driver for TI K3 SoCs" + help + This allows Texas Instruments Keystone 3 SoCs to identify + specifics about the SoC in use. + source "drivers/soc/ti/Kconfig"
endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 649e92b3906d..9ef20ca5066f 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -4,4 +4,5 @@
obj-$(CONFIG_SOC_TI) += ti/ obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o +obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o obj-$(CONFIG_SANDBOX) += soc_sandbox.o diff --git a/drivers/soc/soc_ti_k3.c b/drivers/soc/soc_ti_k3.c new file mode 100644 index 000000000000..ae23ef747520 --- /dev/null +++ b/drivers/soc/soc_ti_k3.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach d-gerlach@ti.com + */ + +#include <common.h> +#include <dm.h> +#include <soc.h> + +#include <asm/io.h> + +#define AM65X 0xbb5a +#define J721E 0xbb64 + +#define REV_SR1_0 0 +#define REV_SR2_0 1 + +#define JTAG_ID_VARIANT_SHIFT 28 +#define JTAG_ID_VARIANT_MASK (0xf << 28) +#define JTAG_ID_PARTNO_SHIFT 12 +#define JTAG_ID_PARTNO_MASK (0xffff << 12) + +struct soc_ti_k3_platdata { + const char *family; + const char *revision; +}; + +static const char *get_family_string(u32 idreg) +{ + const char *family; + u32 soc; + + soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT; + + switch (soc) { + case AM65X: + family = "AM65X"; + break; + case J721E: + family = "J721E"; + break; + default: + family = "Unknown Silicon"; + }; + + return family; +} + +static const char *get_rev_string(u32 idreg) +{ + const char *revision; + u32 rev; + + rev = (idreg & JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT; + + switch (rev) { + case REV_SR1_0: + revision = "1.0"; + break; + case REV_SR2_0: + revision = "2.0"; + break; + default: + revision = "Unknown Revision"; + }; + + return revision; +} + +static int soc_ti_k3_get_family(struct udevice *dev, char *buf, int size) +{ + struct soc_ti_k3_platdata *plat = dev_get_platdata(dev); + + snprintf(buf, size, "%s", plat->family); + + return 0; +} + +static int soc_ti_k3_get_revision(struct udevice *dev, char *buf, int size) +{ + struct soc_ti_k3_platdata *plat = dev_get_platdata(dev); + + snprintf(buf, size, "SR%s", plat->revision); + + return 0; +} + +static const struct soc_ops soc_ti_k3_ops = { + .get_family = soc_ti_k3_get_family, + .get_revision = soc_ti_k3_get_revision, +}; + +int soc_ti_k3_probe(struct udevice *dev) +{ + struct soc_ti_k3_platdata *plat = dev_get_platdata(dev); + u32 idreg; + void *idreg_addr; + + idreg_addr = dev_read_addr_ptr(dev); + if (!idreg_addr) + return -EINVAL; + + idreg = readl(idreg_addr); + + plat->family = get_family_string(idreg); + plat->revision = get_rev_string(idreg); + + return 0; +} + +static const struct udevice_id soc_ti_k3_ids[] = { + { .compatible = "ti,am654-chipid" }, + { } +}; + +U_BOOT_DRIVER(soc_ti_k3) = { + .name = "soc_ti_k3", + .id = UCLASS_SOC, + .ops = &soc_ti_k3_ops, + .of_match = soc_ti_k3_ids, + .probe = soc_ti_k3_probe, + .platdata_auto_alloc_size = sizeof(struct soc_ti_k3_platdata), +};

Introduce a chipid node to provide a UCLASS_SOC driver to identify TI K3 SoCs.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- arch/arm/dts/k3-am65-wakeup.dtsi | 5 +++++ arch/arm/dts/k3-am654-base-board-u-boot.dtsi | 4 ++++ 2 files changed, 9 insertions(+)
diff --git a/arch/arm/dts/k3-am65-wakeup.dtsi b/arch/arm/dts/k3-am65-wakeup.dtsi index 2676d6035b21..666c30d01919 100644 --- a/arch/arm/dts/k3-am65-wakeup.dtsi +++ b/arch/arm/dts/k3-am65-wakeup.dtsi @@ -62,4 +62,9 @@ clocks = <&k3_clks 115 1>; power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>; }; + + chipid: chipid@43000014 { + compatible = "ti,am654-chipid"; + reg = <0x43000014 0x4>; + }; }; diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi index a7e5eb055313..ef75a68fd511 100644 --- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi +++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi @@ -393,3 +393,7 @@ u-boot,dm-spl; }; }; + +&chipid { + u-boot,dm-spl; +};

Introduce a chipid node to provide a UCLASS_SOC driver to identify TI K3 SoCs.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi | 4 ++++ arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 5 +++++ 2 files changed, 9 insertions(+)
diff --git a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi index 7b01e4204f73..bea77cb1f74c 100644 --- a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi +++ b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi @@ -377,3 +377,7 @@ &mcu_fss0_ospi1_pins_default { u-boot,dm-spl; }; + +&chipid { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi index 2eed50aa5a4c..7a815620a507 100644 --- a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi @@ -199,4 +199,9 @@ clocks = <&k3_clks 195 0>; power-domains = <&k3_pds 195 TI_SCI_PD_EXCLUSIVE>; }; + + chipid: chipid@43000014 { + compatible = "ti,am654-chipid"; + reg = <0x0 0x43000014 0x0 0x4>; + }; };

Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 so the TI K3 SoC driver can be used for SoC detection.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- configs/am65x_evm_a53_defconfig | 2 ++ configs/am65x_evm_r5_defconfig | 2 ++ configs/am65x_hs_evm_a53_defconfig | 2 ++ configs/am65x_hs_evm_r5_defconfig | 2 ++ 4 files changed, 8 insertions(+)
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index d74a2d09309b..32817321e762 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -144,3 +144,5 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x6162 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_FAT_WRITE=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig index 4fc199e80911..f6b1d71d9d83 100644 --- a/configs/am65x_evm_r5_defconfig +++ b/configs/am65x_evm_r5_defconfig @@ -118,3 +118,5 @@ CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig index 117953817d82..58f47bd511f3 100644 --- a/configs/am65x_hs_evm_a53_defconfig +++ b/configs/am65x_hs_evm_a53_defconfig @@ -146,3 +146,5 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x6162 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_FAT_WRITE=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/am65x_hs_evm_r5_defconfig b/configs/am65x_hs_evm_r5_defconfig index b2d638672e33..13be670a3647 100644 --- a/configs/am65x_hs_evm_r5_defconfig +++ b/configs/am65x_hs_evm_r5_defconfig @@ -119,3 +119,5 @@ CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y

Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 so the TI K3 SoC driver can be used for SoC detection.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- configs/j721e_evm_a72_defconfig | 2 ++ configs/j721e_evm_r5_defconfig | 2 ++ configs/j721e_hs_evm_a72_defconfig | 2 ++ configs/j721e_hs_evm_r5_defconfig | 2 ++ 4 files changed, 8 insertions(+)
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index 4deb4e219fe7..1bc0ef4ed8a0 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -168,3 +168,5 @@ CONFIG_CADENCE_UFS=y CONFIG_TI_J721E_UFS=y CONFIG_FAT_WRITE=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index ee9217aee238..eec5a3c0d11c 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -133,3 +133,5 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x6163 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_FS_EXT4=y CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/j721e_hs_evm_a72_defconfig b/configs/j721e_hs_evm_a72_defconfig index ae540a26a401..c6755e41cc6b 100644 --- a/configs/j721e_hs_evm_a72_defconfig +++ b/configs/j721e_hs_evm_a72_defconfig @@ -156,3 +156,5 @@ CONFIG_CADENCE_UFS=y CONFIG_TI_J721E_UFS=y CONFIG_FAT_WRITE=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y diff --git a/configs/j721e_hs_evm_r5_defconfig b/configs/j721e_hs_evm_r5_defconfig index 51d5a3bb98fa..f8893ed58622 100644 --- a/configs/j721e_hs_evm_r5_defconfig +++ b/configs/j721e_hs_evm_r5_defconfig @@ -114,3 +114,5 @@ CONFIG_SPL_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_FS_EXT4=y CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y

Make use of UCLASS_SOC to find device family and revision for print_cpuinfo.
Signed-off-by: Dave Gerlach d-gerlach@ti.com --- arch/arm/mach-k3/common.c | 48 ++++++++++-------------- arch/arm/mach-k3/common.h | 6 --- arch/arm/mach-k3/include/mach/hardware.h | 1 - 3 files changed, 19 insertions(+), 36 deletions(-)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 9695b2236ecd..b88516b8c02b 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -25,6 +25,7 @@ #include <fs.h> #include <env.h> #include <elf.h> +#include <soc.h>
struct ti_sci_handle *get_ti_sci_handle(void) { @@ -308,38 +309,27 @@ void reset_cpu(ulong ignored) #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { - u32 soc, rev; - char *name; - - soc = (readl(CTRLMMR_WKUP_JTAG_ID) & - JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT; - rev = (readl(CTRLMMR_WKUP_JTAG_ID) & - JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT; + struct udevice *soc; + char name[64]; + int ret;
printf("SoC: "); - switch (soc) { - case AM65X: - name = "AM65x"; - break; - case J721E: - name = "J721E"; - break; - default: - name = "Unknown Silicon"; - };
- printf("%s SR ", name); - switch (rev) { - case REV_PG1_0: - name = "1.0"; - break; - case REV_PG2_0: - name = "2.0"; - break; - default: - name = "Unknown Revision"; - }; - printf("%s\n", name); + ret = soc_get(&soc); + if (ret) { + printf("UNKNOWN\n"); + return 0; + } + + ret = soc_get_family(soc, name, 64); + if (!ret) { + printf("%s ", name); + } + + ret = soc_get_revision(soc, name, 64); + if (!ret) { + printf("%s\n", name); + }
return 0; } diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 94cdcb56aded..ba344c5bc9dd 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -8,12 +8,6 @@
#include <asm/armv7_mpu.h>
-#define AM65X 0xbb5a -#define J721E 0xbb64 - -#define REV_PG1_0 0 -#define REV_PG2_0 1 - struct fwl_data { const char *name; u16 fwl_id; diff --git a/arch/arm/mach-k3/include/mach/hardware.h b/arch/arm/mach-k3/include/mach/hardware.h index 0ad761418bb7..f2ca80af1a9b 100644 --- a/arch/arm/mach-k3/include/mach/hardware.h +++ b/arch/arm/mach-k3/include/mach/hardware.h @@ -15,7 +15,6 @@ #endif
/* Assuming these addresses and definitions stay common across K3 devices */ -#define CTRLMMR_WKUP_JTAG_ID 0x43000014 #define JTAG_ID_VARIANT_SHIFT 28 #define JTAG_ID_VARIANT_MASK (0xf << 28) #define JTAG_ID_PARTNO_SHIFT 12

On 16/07/2020 07:39, Dave Gerlach wrote:
Hi,
This is v2 of the series to introduce UCLASS_SOC to be used for SOC identification and attribute matching based on SoC ID info. The first version of this series can be found at [1].
Biggest change is the addition of a patch to add documentation for the SOC ID framework as requested by several folks. Otherwise, several comments were addressed in the patch to introduce the UCLASS_SOC implementation:
- Renamed soc_device_attribute to soc_attr.
- Added inline docs for same struct.
- Moved ifdef for CONFIG_SOC_DEVICE to only include functions
- Documented NULL return possiblity for soc_device_match.
And a change to SOC Revision macro naming in the soc_ti_k3 driver to use SR consistently instead of PG.
Regards, Dave
[1] https://lists.denx.de/pipermail/u-boot/2020-June/418109.html
Dave Gerlach (9): doc: Add new doc for soc ID driver model dm: soc: Introduce UCLASS_SOC for SOC ID and attribute matching test: Add tests for SOC uclass dm: soc: Introduce soc_ti_k3 driver for TI K3 SoCs arm: dts: k3-am65-wakeup: Introduce chipid node arm: dts: k3-j721e-mcu-wakeup: Introduce chipid node configs: am65x_evm: Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 configs: j721e_evm: Enable CONFIG_SOC_DEVICE and CONFIG_SOC_DEVICE_TI_K3 arm: mach-k3: Use SOC driver for device identification
arch/arm/dts/k3-am65-wakeup.dtsi | 5 + arch/arm/dts/k3-am654-base-board-u-boot.dtsi | 4 + .../k3-j721e-common-proc-board-u-boot.dtsi | 4 + arch/arm/dts/k3-j721e-mcu-wakeup.dtsi | 5 + arch/arm/mach-k3/common.c | 48 +++--- arch/arm/mach-k3/common.h | 6 - arch/arm/mach-k3/include/mach/hardware.h | 1 - arch/sandbox/dts/test.dts | 4 + configs/am65x_evm_a53_defconfig | 2 + configs/am65x_evm_r5_defconfig | 2 + configs/am65x_hs_evm_a53_defconfig | 2 + configs/am65x_hs_evm_r5_defconfig | 2 + configs/j721e_evm_a72_defconfig | 2 + configs/j721e_evm_r5_defconfig | 2 + configs/j721e_hs_evm_a72_defconfig | 2 + configs/j721e_hs_evm_r5_defconfig | 2 + configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + doc/driver-model/index.rst | 1 + doc/driver-model/soc-framework.rst | 68 ++++++++ drivers/soc/Kconfig | 16 ++ drivers/soc/Makefile | 3 + drivers/soc/soc-uclass.c | 102 ++++++++++++ drivers/soc/soc_sandbox.c | 56 +++++++ drivers/soc/soc_ti_k3.c | 124 +++++++++++++++ include/dm/uclass-id.h | 1 + include/soc.h | 145 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/soc.c | 120 +++++++++++++++ 31 files changed, 698 insertions(+), 36 deletions(-) create mode 100644 doc/driver-model/soc-framework.rst create mode 100644 drivers/soc/soc-uclass.c create mode 100644 drivers/soc/soc_sandbox.c create mode 100644 drivers/soc/soc_ti_k3.c create mode 100644 include/soc.h create mode 100644 test/dm/soc.c
Thank you. Reviewed-by: Grygorii Strashko grygorii.strashko@ti.com
participants (3)
-
Dave Gerlach
-
Grygorii Strashko
-
Simon Glass