diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 7232f6d9277508003703c3923c70f96380cbc438..3c852224e6a44a8885734ff03b4d1a972126cea2 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 76b6719d99ee36b154b90f7a140e51e3a522227a..f1f6fd5ba430ec9926ca742ac9a4ea100f298f42 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;