ARM: rockchip: rk3228: add efuse support
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / efuse.c
index 4c83082376b3f9faff12ae4600520a2c4ac63871..77afe8a4bcb56a026edeae31b8a0935d607c99d4 100644 (file)
@@ -49,7 +49,9 @@ static struct rockchip_efuse efuse;
 #define SEC_REG_WR_32 (SEC_REG_WR | SEC_REG_32)
 #define SEC_REG_WR_64 (SEC_REG_WR | SEC_REG_64)
 
-#define PSCI_OS_ACCESS_REG             (0xa600ffb0)
+#define PSCI_SIP_ACCESS_REG            (0x82000002)
+#define PSCI_SIP_RKTF_VER              (0x82000001)
+
 static phys_addr_t efuse_phys;
 
 /*
@@ -96,7 +98,7 @@ static u32 secure_regs_rd_32(u64 addr_phy)
 {
        u64 val = 0;
 
-       reg_rd_fn(PSCI_OS_ACCESS_REG, 0, addr_phy, SEC_REG_RD_32, &val);
+       reg_rd_fn(PSCI_SIP_ACCESS_REG, 0, addr_phy, SEC_REG_RD_32, &val);
        return val;
 }
 
@@ -104,7 +106,7 @@ static u32 secure_regs_wr_32(u64 addr_phy, u32 val)
 {
        u64 val_64 = val;
 
-       return reg_wr_fn(PSCI_OS_ACCESS_REG, val_64, addr_phy, SEC_REG_WR_32);
+       return reg_wr_fn(PSCI_SIP_ACCESS_REG, val_64, addr_phy, SEC_REG_WR_32);
 }
 
 static u32 efuse_readl(u32 offset)
@@ -116,6 +118,40 @@ static void efuse_writel(u32 val, u32 offset)
 {
        secure_regs_wr_32(efuse_phys + offset, val);
 }
+
+#define RKTF_VER_MAJOR(ver) (((ver) >> 16) & 0xffff)
+#define RKTF_VER_MINOR(ver) ((ver) & 0xffff)
+/* valid ver */
+#define RKTF_VLDVER_MAJOR (1)
+#define RKTF_VLDVER_MINOR (3)
+
+
+static int __init rockchip_tf_ver_check(void)
+{
+       u64 val;
+       u32 ver_val;
+
+       ver_val = reg_rd_fn(PSCI_SIP_RKTF_VER, 0, 0, 0, &val);
+       if (ver_val == 0xffffffff)
+               goto ver_error;
+
+       if ((RKTF_VER_MAJOR(ver_val) >= RKTF_VLDVER_MAJOR) &&
+               (RKTF_VER_MINOR(ver_val) >= RKTF_VLDVER_MINOR))
+               return 0;
+
+ver_error:
+
+       pr_err("read tf version 0x%x!\n", ver_val);
+
+       do {
+               mdelay(1000);
+               pr_err("trusted firmware need to update to(%d.%d) or is invaild!\n",
+                       RKTF_VLDVER_MAJOR, RKTF_VLDVER_MINOR);
+       } while(1);
+
+       return 0;
+}
+device_initcall_sync(rockchip_tf_ver_check);
 #endif
 
 static int rk3288_efuse_readregs(u32 addr, u32 length, u8 *buf)
@@ -175,7 +211,6 @@ static int rk3288_get_leakage(int ch)
        return efuse_buf[23+ch];
 }
 
-#ifdef CONFIG_ARM
 static void __init rk3288_set_system_serial(void)
 {
        int i;
@@ -189,9 +224,6 @@ static void __init rk3288_set_system_serial(void)
        system_serial_low = crc32(0, buf, 8);
        system_serial_high = crc32(system_serial_low, buf + 8, 8);
 }
-#else
-static inline void __init rk3288_set_system_serial(void) {}
-#endif
 
 int rk312x_efuse_readregs(u32 addr, u32 length, u8 *buf)
 {
@@ -284,7 +316,7 @@ void __init rockchip_efuse_init(void)
 {
        int ret;
 
-       if (cpu_is_rk3288()) {
+       if (cpu_is_rk3288() || cpu_is_rk3228()) {
                rk3288_efuse_init();
        } else if (cpu_is_rk312x()) {
                ret = rk312x_efuse_readregs(0, 32, efuse_buf);
@@ -308,7 +340,6 @@ static int __init rockchip_efuse_probe(struct platform_device *pdev)
        efuse_phys = regs->start;
 
        rk3288_efuse_init();
-
        return 0;
 }