Merge remote-tracking branch 'origin/develop-3.10' into develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / 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/spinlock.h>
11 #include <linux/rockchip/iomap.h>
12 #include <linux/kobject.h>
13 #include "efuse.h"
14
15 #define efuse_readl(offset) readl_relaxed(RK_EFUSE_VIRT + offset)
16 #define efuse_writel(val, offset) writel_relaxed(val, RK_EFUSE_VIRT + offset)
17
18 static u8 efuse_buf[32 + 1] = {0, 0};
19
20 static int efuse_readregs(u32 addr, u32 length, u8 *buf)
21 {
22 #ifndef efuse_readl
23         return 0;
24 #else
25         unsigned long flags;
26         static DEFINE_SPINLOCK(efuse_lock);
27         int ret = length;
28
29         if (!length)
30                 return 0;
31
32         spin_lock_irqsave(&efuse_lock, flags);
33
34         efuse_writel(EFUSE_CSB, REG_EFUSE_CTRL);
35         efuse_writel(EFUSE_LOAD | EFUSE_PGENB, REG_EFUSE_CTRL);
36         udelay(2);
37         do {
38                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
39                         (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), REG_EFUSE_CTRL);
40                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
41                         ((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT),
42                         REG_EFUSE_CTRL);
43                 udelay(2);
44                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
45                                 EFUSE_STROBE, REG_EFUSE_CTRL);
46                 udelay(2);
47                 *buf = efuse_readl(REG_EFUSE_DOUT);
48                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
49                                 (~EFUSE_STROBE), REG_EFUSE_CTRL);
50                 udelay(2);
51                 buf++;
52                 addr++;
53         } while (--length);
54         udelay(2);
55         efuse_writel(efuse_readl(REG_EFUSE_CTRL) | EFUSE_CSB, REG_EFUSE_CTRL);
56         udelay(1);
57
58         spin_unlock_irqrestore(&efuse_lock, flags);
59         return ret;
60 #endif
61 }
62
63 /*
64 static int efuse_writeregs(u32 addr, u32 length, u8 *buf)
65 {
66         u32 j=0;
67         unsigned long flags;
68         static DEFINE_SPINLOCK(efuse_lock);
69         spin_lock_irqsave(&efuse_lock, flags);
70
71         efuse_writel(EFUSE_CSB|EFUSE_LOAD|EFUSE_PGENB,REG_EFUSE_CTRL);
72         udelay(10);
73         efuse_writel((~EFUSE_PGENB)&(efuse_readl(REG_EFUSE_CTRL)),
74                 REG_EFUSE_CTRL);
75         udelay(10);
76         efuse_writel((~(EFUSE_LOAD | EFUSE_CSB))&(efuse_readl(REG_EFUSE_CTRL)),
77                 REG_EFUSE_CTRL);
78         udelay(1);
79
80         do {
81                 for(j=0; j<8; j++){
82                         if(*buf & (1<<j)){
83                                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
84                                         (~(EFUSE_A_MASK << EFUSE_A_SHIFT)),
85                                         REG_EFUSE_CTRL);
86                                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
87                                         (((addr + (j<<5))&EFUSE_A_MASK) << EFUSE_A_SHIFT),
88                                         REG_EFUSE_CTRL);
89                                 udelay(1);
90                                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
91                                 EFUSE_STROBE, REG_EFUSE_CTRL);
92                                 udelay(10);
93                                 efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
94                                 (~EFUSE_STROBE), REG_EFUSE_CTRL);
95                                 udelay(1);
96                         }
97                 }
98                 buf++;
99                 addr++;
100         } while (--length);
101
102         udelay(1);
103         efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
104                 EFUSE_CSB | EFUSE_LOAD, REG_EFUSE_CTRL);
105         udelay(1);
106         efuse_writel(efuse_readl(REG_EFUSE_CTRL)|EFUSE_PGENB, REG_EFUSE_CTRL);
107         udelay(1);
108
109         spin_unlock_irqrestore(&efuse_lock, flags);
110         return 0;
111 }
112 */
113
114 int rockchip_efuse_version(void)
115 {
116         int ret = efuse_buf[4] & (~(0x1 << 3));
117         return ret;
118 }
119
120 int rockchip_get_leakage(int ch)
121 {
122         if ((ch < 0) || (ch > 2))
123                 return 0;
124
125         return efuse_buf[23+ch];
126 }
127
128 static int efuse_init(void)
129 {
130         efuse_readregs(0, 32, efuse_buf);
131
132         return 0;
133 }
134
135 core_initcall(efuse_init);