On Sat, 18 Jul 2020 at 08:45, Rayagonda Kokatanur <rayagonda.kokata...@broadcom.com> wrote: > > Use device tree and UCLASS_SYSCON driver to get > Generic Interrupt Controller (GIC) lpi address and > maximum GIC redistributors count. > > Also update Kconfig to select REGMAP and SYSCON when > GIC_V3_ITS is enabled. > > Signed-off-by: Rayagonda Kokatanur <rayagonda.kokata...@broadcom.com> > --- > arch/arm/Kconfig | 2 ++ > arch/arm/include/asm/gic-v3.h | 4 +-- > arch/arm/lib/gic-v3-its.c | 63 +++++++++++++++++++++++++++++++---- > 3 files changed, 60 insertions(+), 9 deletions(-)
Reviewed-by: Simon Glass <s...@chromium.org> > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index f115fcdcc4..2fd20fc648 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -64,6 +64,8 @@ endif > > config GIC_V3_ITS > bool "ARM GICV3 ITS" > + select REGMAP > + select SYSCON > help > ARM GICV3 Interrupt translation service (ITS). > Basic support for programming locality specific peripheral > diff --git a/arch/arm/include/asm/gic-v3.h b/arch/arm/include/asm/gic-v3.h > index 5131fabec4..35efec78c3 100644 > --- a/arch/arm/include/asm/gic-v3.h > +++ b/arch/arm/include/asm/gic-v3.h > @@ -127,9 +127,9 @@ > #define GIC_REDISTRIBUTOR_OFFSET 0x20000 > > #ifdef CONFIG_GIC_V3_ITS > -int gic_lpi_tables_init(u64 base, u32 max_redist); > +int gic_lpi_tables_init(void); > #else > -int gic_lpi_tables_init(u64 base, u32 max_redist) > +int gic_lpi_tables_init(void) > { > return 0; > } > diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c > index 5057cc5421..5e82bdf568 100644 > --- a/arch/arm/lib/gic-v3-its.c > +++ b/arch/arm/lib/gic-v3-its.c > @@ -4,6 +4,8 @@ > */ > #include <common.h> > #include <dm.h> > +#include <regmap.h> > +#include <syscon.h> > #include <asm/gic.h> > #include <asm/gic-v3.h> > #include <asm/io.h> > @@ -16,15 +18,22 @@ static u32 lpi_id_bits; > #define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K) > #define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) > > +/* Number of GIC re-distributors */ > +#define MAX_GIC_REDISTRIBUTORS 8 > + > /* > * gic_v3_its_priv - gic details > * > * @gicd_base: gicd base address > * @gicr_base: gicr base address > + * @lpi_base: gic lpi base address > + * @num_redist: number of gic re-distributors > */ > struct gic_v3_its_priv { > u32 gicd_base; > u32 gicr_base; > + u32 lpi_base; > + u32 num_redist; If these are addresses I think they should be ulong > }; > > static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv) > @@ -58,13 +67,39 @@ static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv > *priv) > return 0; > } > > +static int gic_v3_its_get_gic_lpi_addr(struct gic_v3_its_priv *priv) > +{ > + struct regmap *regmap; > + struct udevice *dev; > + int ret; > + > + ret = uclass_get_device_by_driver(UCLASS_SYSCON, > + DM_GET_DRIVER(gic_lpi_syscon), > &dev); > + if (ret) { > + pr_err("%s: failed to get %s syscon device\n", __func__, > + DM_GET_DRIVER(gic_lpi_syscon)->name); > + return ret; > + } > + > + regmap = syscon_get_regmap(dev); > + if (!regmap) { > + pr_err("%s: failed to regmap for %s syscon device\n", > __func__, > + DM_GET_DRIVER(gic_lpi_syscon)->name); > + return -ENODEV; > + } > + priv->lpi_base = regmap->ranges[0].start; > + > + priv->num_redist = dev_read_u32_default(dev, "max-gic-redistributors", > + MAX_GIC_REDISTRIBUTORS); > + > + return 0; > +} > + > /* > * Program the GIC LPI configuration tables for all > * the re-distributors and enable the LPI table > - * base: Configuration table address > - * num_redist: number of redistributors > */ > -int gic_lpi_tables_init(u64 base, u32 num_redist) > +int gic_lpi_tables_init(void) > { > struct gic_v3_its_priv priv; > u32 gicd_typer; > @@ -77,6 +112,9 @@ int gic_lpi_tables_init(u64 base, u32 num_redist) > if (gic_v3_its_get_gic_addr(&priv)) > return -EINVAL; > > + if (gic_v3_its_get_gic_lpi_addr(&priv)) > + return -EINVAL; > + > gicd_typer = readl((uintptr_t)(priv.gicd_base + GICD_TYPER)); > /* GIC support for Locality specific peripheral interrupts (LPI's) */ > if (!(gicd_typer & GICD_TYPER_LPIS)) { > @@ -89,7 +127,7 @@ int gic_lpi_tables_init(u64 base, u32 num_redist) > * Once the LPI table is enabled, can not program the > * LPI configuration tables again, unless the GIC is reset. > */ > - for (i = 0; i < num_redist; i++) { > + for (i = 0; i < priv.num_redist; i++) { > u32 offset = i * GIC_REDISTRIBUTOR_OFFSET; > > if ((readl((uintptr_t)(priv.gicr_base + offset))) & > @@ -105,7 +143,7 @@ int gic_lpi_tables_init(u64 base, u32 num_redist) > ITS_MAX_LPI_NRBITS); > > /* Set PropBase */ > - val = (base | > + val = (priv.lpi_base | > GICR_PROPBASER_INNERSHAREABLE | > GICR_PROPBASER_RAWAWB | > ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); > @@ -122,10 +160,10 @@ int gic_lpi_tables_init(u64 base, u32 num_redist) > } > } > > - redist_lpi_base = base + LPI_PROPBASE_SZ; > + redist_lpi_base = priv.lpi_base + LPI_PROPBASE_SZ; > > pend_base = priv.gicr_base + GICR_PENDBASER; > - for (i = 0; i < num_redist; i++) { > + for (i = 0; i < priv.num_redist; i++) { > u32 offset = i * GIC_REDISTRIBUTOR_OFFSET; > > val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) | > @@ -159,3 +197,14 @@ U_BOOT_DRIVER(arm_gic_v3_its) = { > .id = UCLASS_IRQ, > .of_match = gic_v3_its_ids, > }; > + > +static const struct udevice_id gic_lpi_syscon_ids[] = { > + { .compatible = "gic-lpi-base" }, > + {} > +}; > + > +U_BOOT_DRIVER(gic_lpi_syscon) = { > + .name = "gic-lpi-base", > + .id = UCLASS_SYSCON, > + .of_match = gic_lpi_syscon_ids, > +}; > -- > 2.17.1 >