tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8830 / efuse_drv.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <common.h>
14 #include <asm/io.h>
15 #include <asm/arch/sprd_reg.h>
16 #include <asm/arch/adi.h>
17 #include "asm/arch/efuse_drv.h"
18
19 #ifndef REG32
20 #define REG32(x)                                                        (*((volatile uint32 *)(x)))
21 #endif
22
23 #if defined(CONFIG_SPX15)
24 static int idx = 0;
25 #define EFUSE_CONTROLLER_NUM    2
26
27 #undef SPRD_UIDEFUSE_PHYS
28 #define SPRD_UIDEFUSE_PHYS              (0x40240000 + idx * 0x100)
29 #endif
30
31
32 #define EFUSE_REGISTER_DUMP
33 static void efuse_dump(void)
34 {
35 #if defined(EFUSE_REGISTER_DUMP)
36         printf("----------------- efuse dump start --------------------------------\n");
37
38         printf("Efuse base addr = 0x%08x\n", SPRD_UIDEFUSE_PHYS);
39         printf("REG_EFUSE_DATA_RD = 0x%08x\n", REG32(EFUSE_DATA_RD));
40         printf("REG_EFUSE_DATA_WR = 0x%08x\n", REG32(EFUSE_DATA_WR));
41         printf("REG_EFUSE_BLOCK_INDEX = 0x%08x\n", REG32(EFUSE_BLOCK_INDEX));
42         printf("REG_EFUSE_MODE_CTRL = 0x%08x\n", REG32(EFUSE_MODE_CTRL));
43         printf("REG_EFUSE_PGM_PARA = 0x%08x\n", REG32(EFUSE_PGM_PARA));
44         printf("REG_EFUSE_STATUS = 0x%08x\n", REG32(EFUSE_STATUS));
45         printf("REG_EFUSE_BLK_FLAGS = 0x%08x\n", REG32(EUSE_MEM_BLOCK_FLAGS));
46         printf("REG_EFUSE_BLK_CLR = 0x%08x\n", REG32(EUSE_MEM_BLOCK_FLAGS_CLR));
47         printf("REG_EFUSE_MAGIC_NUMBER = 0x%08x\n", REG32(EFUSE_MAGIC_NUMBER));
48
49         printf("REG_AON_APB_APB_EB0 = 0x%08x\n", REG32(REG_AON_APB_APB_EB0));
50         printf("REG_AON_APB_PWR_CTRL = 0x%08x\n", REG32(REG_AON_APB_PWR_CTRL));
51
52         printf("----------------- efuse dump end --------------------------------\n");
53 #endif
54 }
55
56 static inline void efuse_udelay(unsigned long usec)
57 {
58         unsigned long i;
59         for (i = 0; i < (usec << 1); i++);
60 }
61
62 //static void __iomem *ctl_efuse_base = 0;
63 void sci_efuse_poweron(void)
64 {
65         uint32 i = 0;
66         /* enable efuse clock */
67         REG32(REG_AON_APB_APB_EB0)  |= BIT_EFUSE_EB;
68
69         // efuse reset
70         REG32(REG_AON_APB_APB_RST0) |=  BIT_EFUSE_SOFT_RST;
71         for(i = 0; i < 100; i++);
72         REG32(REG_AON_APB_APB_RST0) &= ~BIT_EFUSE_SOFT_RST;
73
74         /* power on effuse */
75         REG32(EFUSE_PGM_PARA) |= BIT_EFS_VDD_ON;
76         REG32(EFUSE_PGM_PARA) |= BIT_CLK_EFS_EN;
77 }
78
79 void sci_efuse_poweroff(void)
80 {
81         REG32(EFUSE_PGM_PARA) &= ~BIT_CLK_EFS_EN;
82         REG32(EFUSE_PGM_PARA) &= ~BIT_EFS_VDD_ON;
83         REG32(REG_AON_APB_APB_EB0)  &= ~BIT_EFUSE_EB;
84 }
85
86 int sci_efuse_read(unsigned blk)
87 {
88         int busy = 0;
89         uint32 reg_val = 0;
90
91 #if defined(CONFIG_SPX15)
92         idx = blk / 8;
93         blk %= 8;
94
95         if(idx >= EFUSE_CONTROLLER_NUM) {
96                 printf("%s()->Line:%d; efuse idx: %d exceed maximum!\n", __func__, __LINE__, idx);
97                 return 0;
98         }
99 #endif
100
101         sci_efuse_poweron();
102
103         if (blk > (MASK_READ_INDEX >> SHIFT_READ_INDEX))
104         {
105                 return 0;
106         }
107
108         REG32(EFUSE_BLOCK_INDEX) = BITS_READ_INDEX(blk);
109         REG32(EFUSE_MODE_CTRL) |= BIT_RD_START;
110
111         efuse_dump();
112
113         do
114         {
115                 busy = REG32(EFUSE_STATUS) & BIT_READ_BUSY;
116         } while (busy);
117
118         reg_val = REG32(EFUSE_DATA_RD);
119
120         sci_efuse_poweroff();
121
122 #if defined(CONFIG_SPX15)
123         printf("%s()->Line:%d; efuse idx=%d; blk=%d; data=0x%08x;\n", __func__, __LINE__, idx, blk, reg_val);
124 #else
125         printf("%s()->Line:%d; efuse blk=%d; data=0x%08x;\n", __func__, __LINE__, blk, reg_val);
126 #endif
127
128         return reg_val;
129 }
130
131 #ifdef EFUSE_DEBUG
132 #define EFUSE_MAGIC_VAL                         0x8810
133 int sci_efuse_program(unsigned blk, int data)
134 {
135         int busy = 0;
136
137 #if defined(CONFIG_SPX15)
138         idx = blk / 8;
139         blk %= 8;
140
141         if(idx >= EFUSE_CONTROLLER_NUM) {
142                 printf("%s()->Line:%d; efuse idx: %d exceed maximum!\n", __func__, __LINE__, idx);
143                 return 0;
144         }
145 #endif
146
147         if (blk > (MASK_PGM_INDEX >> SHIFT_PGM_INDEX))
148         {
149                 return 0;
150         }
151
152         REG32(EFUSE_BLOCK_INDEX) = BITS_PGM_INDEX(blk);
153         REG32(EFUSE_DATA_WR) = data;
154         REG32(EFUSE_MODE_CTRL) |= BIT_PG_START;
155
156         do
157         {
158                 busy = REG32(EFUSE_STATUS) & BIT_PGM_BUSY;
159         } while(busy);
160
161         return 1;
162 }
163
164 /* low level */
165 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
166 {
167         int retVal;
168
169         REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE0_PWR_ON;
170         REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE1_PWR_ON;
171
172         REG32(EFUSE_PGM_PARA) |= BIT_PGM_EN;
173         REG32(EFUSE_MAGIC_NUMBER) = BITS_MAGIC_NUMBER(magic);
174
175         delay(10000);
176
177         retVal = sci_efuse_program(blk, data);
178         REG32(EFUSE_PGM_PARA) &= ~BIT_PGM_EN;
179
180         return retVal;
181 }
182 #else
183 int sci_efuse_program(unsigned blk, int data)
184 {
185         return 0;
186 }
187
188 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
189 {
190         return 0;
191 }
192 #endif
193
194 #define CAL_DATA_BLK                                    7
195 #define BASE_ADC_P0                                             711                     /* 3.6V */
196 #define BASE_ADC_P1                                             830                     /* 4.2V */
197 #define VOL_P0                                                  3600
198 #define VOL_P1                                                  4200
199 #define ADC_DATA_OFFSET                                 128
200 /* they were stored in afuse of shark*/
201 int sci_efuse_calibration_get(unsigned int * p_cal_data)
202 {
203         int timeout;
204         unsigned int data;
205         unsigned short adc_temp;
206 #if defined(CONFIG_SPX15)
207         data = sci_efuse_read(CAL_DATA_BLK);
208 #elif !(defined(CONFIG_ADIE_SC2723) || defined(CONFIG_ADIE_SC2723S))
209         /* wait for maximum of 100 msec */
210         sci_adi_raw_write(ANA_REG_GLB_AFUSE_CTRL, BIT_AFUSE_READ_REQ);
211         efuse_udelay(1);
212         timeout = 1000;
213         while(BIT_AFUSE_READ_REQ & sci_adi_read(ANA_REG_GLB_AFUSE_CTRL)) {
214                 if(timeout <= 0){
215                         break;
216                 }
217                 efuse_udelay(500);
218                 timeout--;
219         }
220
221         if (timeout <= 0)
222         {
223                 return 0;
224         }
225
226         data = sci_adi_read(ANA_REG_GLB_AFUSE_OUT0);
227         data |= (sci_adi_read(ANA_REG_GLB_AFUSE_OUT1)) << 16;
228 #endif
229
230         if (data == 0)
231         {
232                 return 0;
233         }
234
235         printf("afuse: data = 0x%x\n\r",data);
236         /* adc 3.6V  */
237         adc_temp = ((data & 0xFF00) >> 8) + BASE_ADC_P0 - ADC_DATA_OFFSET;
238         p_cal_data[1] = (VOL_P0) | ((adc_temp << 2) << 16);
239
240         /* adc 4.2V */
241         adc_temp = (data & 0xFF) + BASE_ADC_P1 - ADC_DATA_OFFSET;
242         p_cal_data[0] = (VOL_P1)|((adc_temp << 2) << 16);
243         return 1;
244 }
245