On Tue, 20 Dec 2016 02:03:36 +0800 Icenowy Zheng <icen...@aosc.xyz> wrote:
> H3 SID controller has some bug, which makes the initial SID value at > SUNXI_SID_BASE wrong when boot. > > Change the SID retrieve code to call the SID Controller directly on H3, > which can get the correct value, and also fix the SID value at > SUNXI_SID_BASE, so that it can be used by further operations. > > Signed-off-by: Icenowy Zheng <icen...@aosc.xyz> > --- > arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 1 + > arch/arm/mach-sunxi/cpu_info.c | 44 > +++++++++++++++++++++++++++++ > 2 files changed, 45 insertions(+) > > diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > index 7232f6d927..3c852224e6 100644 > --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h > @@ -97,6 +97,7 @@ > #if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \ > defined(CONFIG_MACH_SUN50I) > /* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */ > +#define SUNXI_SIDC_BASE 0x01c14000 > #define SUNXI_SID_BASE 0x01c14200 > #else > #define SUNXI_SID_BASE 0x01c23800 > diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c > index 76b6719d99..f1f6fd5ba4 100644 > --- a/arch/arm/mach-sunxi/cpu_info.c > +++ b/arch/arm/mach-sunxi/cpu_info.c > @@ -99,10 +99,54 @@ int print_cpuinfo(void) > } > #endif > > +#ifdef CONFIG_MACH_SUN8I_H3 > + > +#define SIDC_PRCTL 0x40 > +#define SIDC_RDKEY 0x60 > + > +#define SIDC_OP_LOCK 0xAC > + > +uint32_t sun8i_efuse_read(uint32_t offset) > +{ > + uint32_t reg_val; > + > + reg_val = readl(SUNXI_SIDC_BASE + SIDC_PRCTL); > + reg_val &= ~(((0x1ff) << 16) | 0x3); > + reg_val |= (offset << 16); > + writel(reg_val, SUNXI_SIDC_BASE + SIDC_PRCTL); Normally clrsetbits_le32() is used for this kind of code in U-Boot. > + > + reg_val &= ~(((0xff) << 8) | 0x3); > + reg_val |= (SIDC_OP_LOCK << 8) | 0x2; > + writel(reg_val, SUNXI_SIDC_BASE + SIDC_PRCTL); > + > + while (readl(SUNXI_SIDC_BASE + SIDC_PRCTL) & 0x2); > + > + reg_val &= ~(((0x1ff) << 16) | ((0xff) << 8) | 0x3); > + writel(reg_val, SUNXI_SIDC_BASE + SIDC_PRCTL); Same here. > + > + reg_val = readl(SUNXI_SIDC_BASE + SIDC_RDKEY); > + return reg_val; > +} > +#endif > + > int sunxi_get_sid(unsigned int *sid) > { > #ifdef CONFIG_AXP221_POWER > return axp_get_sid(sid); > +#elif defined CONFIG_MACH_SUN8I_H3 > + /* > + * H3 SID controller has a bug, which makes the initial value of > + * SUNXI_SID_BASE at boot wrong. > + * Read the value directly from SID controller, in order to get > + * the correct value, and also refresh the wrong value at > + * SUNXI_SID_BASE. > + */ > + int i; > + > + for (i = 0; i< 4; i++) > + sid[i] = sun8i_efuse_read(i * 4); > + > + return 0; > #elif defined SUNXI_SID_BASE > int i; > Thanks for this workaround. This problem has buggered some people since a while ago. It's good that you took time to investigate and fix it. -- Best regards, Siarhei Siamashka _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot