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

Reply via email to