aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIcenowy Zheng2016-12-20 02:03:36 +0800
committerJagan Teki2016-12-20 16:08:50 +0100
commit65d2d4f239b3f0dfb195b8ccb9e076d6eeeebd37 (patch)
tree5509f90ba199daa8980829e232979b7b089515a9
parent4cf5c5f1e60e6541630ae829b5fa2db704c268f0 (diff)
sunxi: fix SID read on H3
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 <icenowy@aosc.xyz> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Jagan Teki <jagan@openedev.com>
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun4i.h1
-rw-r--r--arch/arm/mach-sunxi/cpu_info.c44
2 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 7232f6d9277..3c852224e6a 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 76b6719d99e..f1f6fd5ba43 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);
+
+ 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);
+
+ 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;