[PATCH v3 4/4] dm: soc: SoC identification driver for Renesas SoC's
Biju Das
biju.das.jz at bp.renesas.com
Thu Nov 12 20:07:20 CET 2020
Hi All,
I need to update copyright information for this patch. This work is derived from linux
and linux has extra copyright information. I have missed that.
Will send V4 for fixing it.
Regards,
Biju
> -----Original Message-----
> From: Biju Das <biju.das.jz at bp.renesas.com>
> Sent: 04 November 2020 10:56
> To: Simon Glass <sjg at chromium.org>; Marek Vasut
> <marek.vasut+renesas at gmail.com>
> Cc: Biju Das <biju.das.jz at bp.renesas.com>; Dave Gerlach <d-
> gerlach at ti.com>; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj at bp.renesas.com>; u-boot at lists.denx.de; Nobuhiro Iwamatsu
> <iwamatsu at nigauri.org>; Chris Paterson <Chris.Paterson2 at renesas.com>
> Subject: [PATCH v3 4/4] dm: soc: SoC identification driver for Renesas
> SoC's
>
> Add SoC identification driver for Renesas SoC's. This allows to identify
> the SoC type and revision based on Product Register.
>
> This can be checked where needed using soc_device_match().
>
> Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v2->v3: No Change.
> v2: New patch
> ---
> drivers/soc/Kconfig | 7 ++
> drivers/soc/Makefile | 1 +
> drivers/soc/soc_renesas.c | 239 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 247 insertions(+)
> create mode 100644 drivers/soc/soc_renesas.c
>
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index
> 864d00a885..475e94cd77 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -16,6 +16,13 @@ config SOC_DEVICE_TI_K3
> This allows Texas Instruments Keystone 3 SoCs to identify
> specifics about the SoC in use.
>
> +config SOC_DEVICE_RENESAS
> + depends on SOC_DEVICE
> + bool "Enable SoC driver for Renesas SoCs"
> + help
> + This allows Renesas 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
> 9ef20ca506..b143eac5fd 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -4,5 +4,6 @@
>
> obj-$(CONFIG_SOC_TI) += ti/
> obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
> +obj-$(CONFIG_$(SPL_)SOC_DEVICE_RENESAS) += soc_renesas.o
> obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
> obj-$(CONFIG_SANDBOX) += soc_sandbox.o
> diff --git a/drivers/soc/soc_renesas.c b/drivers/soc/soc_renesas.c new
> file mode 100644 index 0000000000..4543e0dbfd
> --- /dev/null
> +++ b/drivers/soc/soc_renesas.c
> @@ -0,0 +1,239 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Renesas Electronics Corp.
> + *
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <soc.h>
> +
> +#include <asm/io.h>
> +
> +struct soc_renesas_priv {
> + const char *family;
> + const char *soc_id;
> + char revision[6];
> +};
> +
> +struct renesas_family {
> + const char name[16];
> + u32 reg; /* CCCR or PRR, if not in DT */
> +};
> +
> +static const struct renesas_family fam_rcar_gen3 __maybe_unused = {
> + .name = "R-Car Gen3",
> + .reg = 0xfff00044, /* PRR (Product Register) */
> +};
> +
> +static const struct renesas_family fam_rzg2 __maybe_unused = {
> + .name = "RZ/G2",
> + .reg = 0xfff00044, /* PRR (Product Register) */
> +};
> +
> +struct renesas_soc {
> + const struct renesas_family *family;
> + u8 id;
> +};
> +
> +#ifdef CONFIG_R8A774A1
> +static const struct renesas_soc soc_rz_g2m = {
> + .family = &fam_rzg2,
> + .id = 0x52,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A774B1
> +static const struct renesas_soc soc_rz_g2n = {
> + .family = &fam_rzg2,
> + .id = 0x55,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A774C0
> +static const struct renesas_soc soc_rz_g2e = {
> + .family = &fam_rzg2,
> + .id = 0x57,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A774E1
> +static const struct renesas_soc soc_rz_g2h = {
> + .family = &fam_rzg2,
> + .id = 0x4f,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A7795
> +static const struct renesas_soc soc_rcar_h3 = {
> + .family = &fam_rcar_gen3,
> + .id = 0x4f,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A7796
> +static const struct renesas_soc soc_rcar_m3_w = {
> + .family = &fam_rcar_gen3,
> + .id = 0x52,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A77965
> +static const struct renesas_soc soc_rcar_m3_n = {
> + .family = &fam_rcar_gen3,
> + .id = 0x55,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A77970
> +static const struct renesas_soc soc_rcar_v3m = {
> + .family = &fam_rcar_gen3,
> + .id = 0x54,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A77980
> +static const struct renesas_soc soc_rcar_v3h = {
> + .family = &fam_rcar_gen3,
> + .id = 0x56,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A77990
> +static const struct renesas_soc soc_rcar_e3 = {
> + .family = &fam_rcar_gen3,
> + .id = 0x57,
> +};
> +#endif
> +
> +#ifdef CONFIG_R8A77995
> +static const struct renesas_soc soc_rcar_d3 = {
> + .family = &fam_rcar_gen3,
> + .id = 0x58,
> +};
> +#endif
> +
> +static int soc_renesas_get_family(struct udevice *dev, char *buf, int
> +size) {
> + struct soc_renesas_priv *priv = dev_get_priv(dev);
> +
> + snprintf(buf, size, "%s", priv->family);
> +
> + return 0;
> +}
> +
> +static int soc_renesas_get_revision(struct udevice *dev, char *buf, int
> +size) {
> + struct soc_renesas_priv *priv = dev_get_priv(dev);
> +
> + snprintf(buf, size, "%s", priv->revision);
> +
> + return 0;
> +}
> +
> +static int soc_renesas_get_soc_id(struct udevice *dev, char *buf, int
> +size) {
> + struct soc_renesas_priv *priv = dev_get_priv(dev);
> +
> + snprintf(buf, size, "%s", priv->soc_id);
> +
> + return 0;
> +}
> +
> +static const struct udevice_id renesas_socs[] = { #ifdef
> +CONFIG_R8A774A1
> + { .compatible = "renesas,r8a774a1", .data = (ulong)&soc_rz_g2m, },
> +#endif
> +#ifdef CONFIG_R8A774B1
> + { .compatible = "renesas,r8a774b1", .data = (ulong)&soc_rz_g2n, },
> +#endif
> +#ifdef CONFIG_R8A774C0
> + { .compatible = "renesas,r8a774c0", .data = (ulong)&soc_rz_g2e, },
> +#endif
> +#ifdef CONFIG_R8A774E1
> + { .compatible = "renesas,r8a774e1", .data = (ulong)&soc_rz_g2h, },
> +#endif
> +#ifdef CONFIG_R8A7795
> + { .compatible = "renesas,r8a7795", .data = (ulong)&soc_rcar_h3, },
> +#endif
> +#ifdef CONFIG_R8A7796
> + { .compatible = "renesas,r8a7796", .data = (ulong)&soc_rcar_m3_w,
> },
> +#endif
> +#ifdef CONFIG_R8A77965
> + { .compatible = "renesas,r8a77965", .data = (ulong)&soc_rcar_m3_n,
> },
> +#endif
> +#ifdef CONFIG_R8A77970
> + { .compatible = "renesas,r8a77970", .data = (ulong)&soc_rcar_v3m, },
> +#endif
> +#ifdef CONFIG_R8A77980
> + { .compatible = "renesas,r8a77980", .data = (ulong)&soc_rcar_v3h, },
> +#endif
> +#ifdef CONFIG_R8A77990
> + { .compatible = "renesas,r8a77990", .data = (ulong)&soc_rcar_e3, },
> +#endif
> +#ifdef CONFIG_R8A77995
> + { .compatible = "renesas,r8a77995", .data = (ulong)&soc_rcar_d3, },
> +#endif
> + { /* sentinel */ }
> +};
> +
> +static const struct udevice_id prr_ids[] = {
> + { .compatible = "renesas,prr" },
> + { /* sentinel */ }
> +};
> +
> +static const struct soc_ops soc_renesas_ops = {
> + .get_family = soc_renesas_get_family,
> + .get_revision = soc_renesas_get_revision,
> + .get_soc_id = soc_renesas_get_soc_id,
> +};
> +
> +int soc_renesas_probe(struct udevice *dev) {
> + struct soc_renesas_priv *priv = dev_get_priv(dev);
> + const struct renesas_family *family;
> + const struct udevice_id *match;
> + struct renesas_soc *soc;
> + unsigned int product, eshi = 0, eslo;
> + ofnode root_node;
> +
> + root_node = ofnode_path("/");
> + match = of_match_node(renesas_socs, root_node);
> + if (!match) {
> + printf("SoC entry is missing in DT\n");
> + return 0;
> + }
> +
> + soc = (struct renesas_soc *)match->data;
> + family = soc->family;
> +
> + product = readl(0xFFF00044);
> + /* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */
> + if ((product & 0x7fff) == 0x5210)
> + product ^= 0x11;
> + /* R-Car M3-W ES1.3 incorrectly identifies as ES2.1 */
> + if ((product & 0x7fff) == 0x5211)
> + product ^= 0x12;
> + if (soc->id && ((product >> 8) & 0xff) != soc->id) {
> + printf("SoC mismatch (product = 0x%x)\n", product);
> + return 0;
> + }
> + eshi = ((product >> 4) & 0x0f) + 1;
> + eslo = product & 0xf;
> +
> + priv->family = family->name;
> + priv->soc_id = strchr(match->compatible, ',') + 1;
> + snprintf(priv->revision, sizeof(priv->revision), "ES%u.%u", eshi,
> +eslo);
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(soc_renesas) = {
> + .name = "soc_renesas",
> + .id = UCLASS_SOC,
> + .ops = &soc_renesas_ops,
> + .of_match = prr_ids,
> + .probe = soc_renesas_probe,
> + .priv_auto_alloc_size = sizeof(struct soc_renesas_priv), };
> --
> 2.17.1
More information about the U-Boot
mailing list