2 * Copyright (C) 2013 ROCKCHIP, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/delay.h>
10 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <plat/efuse.h>
15 #if defined(CONFIG_ARCH_RK3188) || defined(CONFIG_SOC_RK3028) || defined(CONFIG_ARCH_RK3066B)
16 #define efuse_readl(offset) readl_relaxed(RK30_EFUSE_BASE + offset)
17 #define efuse_writel(val, offset) writel_relaxed(val, RK30_EFUSE_BASE + offset)
20 #if defined(CONFIG_ARCH_RK3026)
21 #define efuse_readl(offset) readl_relaxed(RK2928_EFUSE_BASE + offset)
22 #define efuse_writel(val, offset) writel_relaxed(val, RK2928_EFUSE_BASE + offset)
25 u8 efuse_buf[32 + 1] = {0, 0};
27 static int efuse_readregs(u32 addr, u32 length, u8 *buf)
33 static DEFINE_SPINLOCK(efuse_lock);
39 spin_lock_irqsave(&efuse_lock, flags);
41 efuse_writel(EFUSE_CSB, REG_EFUSE_CTRL);
42 efuse_writel(EFUSE_LOAD | EFUSE_PGENB, REG_EFUSE_CTRL);
45 efuse_writel(efuse_readl(REG_EFUSE_CTRL) & (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), REG_EFUSE_CTRL);
46 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT), REG_EFUSE_CTRL);
48 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_STROBE, REG_EFUSE_CTRL);
50 *buf = efuse_readl(REG_EFUSE_DOUT);
51 efuse_writel(efuse_readl(REG_EFUSE_CTRL) & (~EFUSE_STROBE), REG_EFUSE_CTRL);
57 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_CSB, REG_EFUSE_CTRL);
60 spin_unlock_irqrestore(&efuse_lock, flags);
65 void rk_efuse_init(void)
67 #if defined(CONFIG_ARCH_RK3026)
71 efuse_readregs(0x0, 32, efuse_buf);
74 * i = 10, need time = 2,860,875 ns
75 * i = 100, need time = 27,327,000 ns
77 for (i = 0; i < 10; i++){
78 efuse_readregs(0x0, 32, tmp_buf);
79 for (j = 0; j < 32; j++){
80 if (efuse_buf[j] != tmp_buf[j]){
81 printk(KERN_WARNING ":%s:rk3026 efuse bit err\n", __func__);
82 efuse_readregs(0x0, 32, efuse_buf);
90 printk(KERN_ERR "%s:rk3026 get efuse err\n", __func__);
91 efuse_buf[5] = 0x00; /* set default SOC version */
92 efuse_buf[22] = 0x00; /* clean msg about leakage */
97 efuse_readregs(0x0, 32, efuse_buf);
101 int rk_pll_flag(void)
103 return efuse_buf[22] & 0x3;
107 return efuse_buf[22] & (0x1 << 3);
110 int rk_leakage_val(void)
115 * 0:enable leakage level auto voltage scale
116 * 1:disalbe leakage level avs
118 if ((efuse_buf[22] >> 2) & 0x1)
121 return (efuse_buf[22] >> 4) & 0x0f;
124 int rk3028_version_val(void)
129 int rk3026_version_val(void)