dcb829515d5ef6fa0346c5c97b62a33854521e51
[firefly-linux-kernel-4.4.55.git] / arch / arm / plat-rk / efuse.c
1 /*
2  * Copyright (C) 2013 ROCKCHIP, Inc.
3  *
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.
7  */
8
9 #include <linux/delay.h>
10 #include <linux/kernel.h>
11 #include <linux/io.h>
12 #include <linux/spinlock.h>
13 #include <plat/efuse.h>
14
15 #if defined(CONFIG_ARCH_RK3188)
16 #define efuse_readl(offset)             readl_relaxed(RK30_EFUSE_BASE + offset)
17 #define efuse_writel(val, offset)       writel_relaxed(val, RK30_EFUSE_BASE + offset)
18 #endif
19
20 u8 efuse_buf[32 + 1] = {0, 0};
21
22 static int efuse_readregs(u32 addr, u32 length, u8 *buf)
23 {
24 #ifndef efuse_readl
25         return 0;
26 #else
27         unsigned long flags;
28         static DEFINE_SPINLOCK(efuse_lock);
29         int ret = length;
30
31         if (!length)
32                 return 0;
33
34         spin_lock_irqsave(&efuse_lock, flags);
35
36         efuse_writel(EFUSE_CSB, REG_EFUSE_CTRL);
37         efuse_writel(EFUSE_LOAD | EFUSE_PGENB, REG_EFUSE_CTRL);
38         udelay(2);
39         do {
40                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) & (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), REG_EFUSE_CTRL);
41                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT), REG_EFUSE_CTRL);
42                 udelay(2);
43                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_STROBE, REG_EFUSE_CTRL);
44                 udelay(2);
45                 *buf = efuse_readl(REG_EFUSE_DOUT);
46                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) & (~EFUSE_STROBE), REG_EFUSE_CTRL);
47                 udelay(2);
48                 buf++;
49                 addr++;
50         } while(--length);
51         udelay(2);
52         efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_CSB, REG_EFUSE_CTRL);
53         udelay(1);
54
55         spin_unlock_irqrestore(&efuse_lock, flags);
56         return ret;
57 #endif
58 }
59
60 void rk_efuse_init(void)
61 {
62         efuse_readregs(0x0, 32, efuse_buf);
63 }
64
65 int rk_pll_flag(void)
66 {
67         return efuse_buf[22] & 0x3;
68 }
69
70 int rk_leakage_val(void)
71 {
72         return (efuse_buf[22] >> 4) & 0x0f;
73 }