androidComputer: changed for display
[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) || 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)
18 #endif
19
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)
23 #endif
24
25 u8 efuse_buf[32 + 1] = {0, 0};
26
27 static int efuse_readregs(u32 addr, u32 length, u8 *buf)
28 {
29 #ifndef efuse_readl
30         return 0;
31 #else
32         unsigned long flags;
33         static DEFINE_SPINLOCK(efuse_lock);
34         int ret = length;
35
36         if (!length)
37                 return 0;
38
39         spin_lock_irqsave(&efuse_lock, flags);
40
41         efuse_writel(EFUSE_CSB, REG_EFUSE_CTRL);
42         efuse_writel(EFUSE_LOAD | EFUSE_PGENB, REG_EFUSE_CTRL);
43         udelay(2);
44         do {
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);
47                 udelay(2);
48                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_STROBE, REG_EFUSE_CTRL);
49                 udelay(2);
50                 *buf = efuse_readl(REG_EFUSE_DOUT);
51                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) & (~EFUSE_STROBE), REG_EFUSE_CTRL);
52                 udelay(2);
53                 buf++;
54                 addr++;
55         } while(--length);
56         udelay(2);
57         efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_CSB, REG_EFUSE_CTRL);
58         udelay(1);
59
60         spin_unlock_irqrestore(&efuse_lock, flags);
61         return ret;
62 #endif
63 }
64
65 void rk_efuse_init(void)
66 {
67 #if defined(CONFIG_ARCH_RK3026)
68         u8 tmp_buf[32];
69         int i, j, err = 0;
70
71         efuse_readregs(0x0, 32, efuse_buf);
72
73         /*
74          * i = 10,      need time = 2,860,875   ns
75          * i = 100,     need time = 27,327,000  ns
76          */
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);
83                                 i = 0;
84                                 err++;
85                                 break;
86                         }
87                 }
88
89                 if (err >= 500) {
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 */
93                         break;
94                 }
95         }
96 #else
97         efuse_readregs(0x0, 32, efuse_buf);
98 #endif
99 }
100
101 int rk_pll_flag(void)
102 {
103         return efuse_buf[22] & 0x3;
104 }
105 int rk_tflag(void)
106 {
107         return efuse_buf[22] & (0x1 << 3);
108 }
109
110 int rk_leakage_val(void)
111 {
112         /*
113          * efuse_buf[22]
114          * bit[2]:
115          *      0:enable leakage level auto voltage scale
116          *      1:disalbe leakage level avs
117          */
118         if ((efuse_buf[22] >> 2) & 0x1)
119                 return 0;
120         else
121                 return  (efuse_buf[22] >> 4) & 0x0f;
122 }
123
124 int rk3028_version_val(void)
125 {
126         return efuse_buf[5];
127 }
128
129 int rk3026_version_val(void)
130 {
131         return efuse_buf[5];
132 }