From mboxrd@z Thu Jan 1 00:00:00 1970 From: Siarhei Siamashka Date: Sat, 24 Dec 2016 01:55:54 +0200 Subject: [U-Boot] [linux-sunxi] [PATCH] sunxi: fix SID read on H3 In-Reply-To: <20161219180336.5817-1-icenowy@aosc.xyz> References: <20161219180336.5817-1-icenowy@aosc.xyz> Message-ID: <20161224015554.3d04f79f@i7> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Tue, 20 Dec 2016 02:03:36 +0800 Icenowy Zheng 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 > --- > 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