diff options
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/Kconfig | 16 | ||||
-rw-r--r-- | drivers/soc/Makefile | 3 | ||||
-rw-r--r-- | drivers/soc/soc-uclass.c | 102 | ||||
-rw-r--r-- | drivers/soc/soc_sandbox.c | 56 | ||||
-rw-r--r-- | drivers/soc/soc_ti_k3.c | 124 |
5 files changed, 301 insertions, 0 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 7b4e4d6130..864d00a885 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,5 +1,21 @@ 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. + +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 ce253b7aa8..9ef20ca506 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -3,3 +3,6 @@ # Makefile for the U-Boot SOC specific device drivers. 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-uclass.c b/drivers/soc/soc-uclass.c new file mode 100644 index 0000000000..c32d647864 --- /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/drivers/soc/soc_sandbox.c b/drivers/soc/soc_sandbox.c new file mode 100644 index 0000000000..5c82ad84fc --- /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/drivers/soc/soc_ti_k3.c b/drivers/soc/soc_ti_k3.c new file mode 100644 index 0000000000..ae23ef7475 --- /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), +}; |