[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