This adds a support for detecting AM62P SR1.0, SR1.1, SR1.2. On AM62P, silicon revision is discovered with GP_SW1 register instead of JTAGID register, so introduce GP_SW register range to determine SoC revision.
Signed-off-by: Judith Mendez <j...@ti.com> --- drivers/soc/soc_ti_k3.c | 66 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/drivers/soc/soc_ti_k3.c b/drivers/soc/soc_ti_k3.c index b34cbd08e07..d6097ee6d17 100644 --- a/drivers/soc/soc_ti_k3.c +++ b/drivers/soc/soc_ti_k3.c @@ -10,6 +10,8 @@ #include <asm/arch/hardware.h> #include <asm/io.h> +#define CTRLMMR_WKUP_GP_SW1_REG 4 + struct soc_ti_k3_plat { const char *family; const char *revision; @@ -76,12 +78,17 @@ static char *j721e_rev_string_map[] = { "1.0", "1.1", "2.0", }; +static char *am62p_gpsw_rev_string_map[] = { + "1.0", "1.1", "1.2", +}; + static char *typical_rev_string_map[] = { "1.0", "2.0", "3.0", }; -static const char *get_rev_string(u32 idreg) +static const char *get_rev_string(u32 idreg, u32 gpsw1) { + u32 gpsw_variant = gpsw1 % 16; u32 rev; u32 soc; @@ -93,7 +100,10 @@ static const char *get_rev_string(u32 idreg) if (rev >= ARRAY_SIZE(j721e_rev_string_map)) goto bail; return j721e_rev_string_map[rev]; - + case JTAG_ID_PARTNO_AM62PX: + if (gpsw_variant >= ARRAY_SIZE(am62p_gpsw_rev_string_map)) + goto bail; + return am62p_gpsw_rev_string_map[gpsw_variant]; default: if (rev >= ARRAY_SIZE(typical_rev_string_map)) goto bail; @@ -104,6 +114,48 @@ bail: return "Unknown Revision"; } +static int +soc_ti_k3_get_variant_alternate(struct udevice *dev, u32 idreg) +{ + void *gpsw_addr; + u32 jtag_dev_id; + void *offset; + u32 soc; + + jtag_dev_id = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID); + soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT; + + gpsw_addr = dev_read_addr_index_ptr(dev, 1); + if (!gpsw_addr) + return -EINVAL; + + switch (soc) { + case JTAG_ID_PARTNO_AM62PX: + offset = gpsw_addr + CTRLMMR_WKUP_GP_SW1_REG; + break; + default: + offset = gpsw_addr + CTRLMMR_WKUP_GP_SW1_REG; + } + + return (readl(offset)); +} + +static bool soc_ti_k3_variant_in_gp_sw(u32 idreg) +{ + u32 jtag_dev_id; + u32 soc; + + jtag_dev_id = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID); + soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT; + + switch (soc) { + case JTAG_ID_PARTNO_AM62PX: + return true; + default: + return false; + } +} + static int soc_ti_k3_get_family(struct udevice *dev, char *buf, int size) { struct soc_ti_k3_plat *plat = dev_get_plat(dev); @@ -130,17 +182,21 @@ static const struct soc_ops soc_ti_k3_ops = { int soc_ti_k3_probe(struct udevice *dev) { struct soc_ti_k3_plat *plat = dev_get_plat(dev); - u32 idreg; + u32 gp_sw1_val = 0; void *idreg_addr; + u32 idreg; - idreg_addr = dev_read_addr_ptr(dev); + idreg_addr = dev_read_addr_index_ptr(dev, 0); if (!idreg_addr) return -EINVAL; idreg = readl(idreg_addr); + if (soc_ti_k3_variant_in_gp_sw(idreg)) + gp_sw1_val = soc_ti_k3_get_variant_alternate(dev, idreg); + plat->family = get_family_string(idreg); - plat->revision = get_rev_string(idreg); + plat->revision = get_rev_string(idreg, gp_sw1_val); return 0; } -- 2.49.0