tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8825 / 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/regs_global.h>
16 #include "efuse_drv.h"
17
18 #ifdef EFUSE_DEBUG
19 static inline void delay(unsigned long loops)
20 {
21         __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
22                           "bne 1b":"=r" (loops):"0"(loops));
23 }
24 #endif
25
26 //static void __iomem *ctl_efuse_base = 0;
27 void sci_efuse_poweron(void)
28 {
29         SCI_D(GR_GEN0) |= GEN0_EFUSE_EN;
30         SCI_D(REG_EFUSE_PGM_PARA) |= BIT_EFUSE_VDD_ON;
31         SCI_D(REG_EFUSE_PGM_PARA) |= BIT_CLK_EFS_EN;
32 }
33
34 void sci_efuse_poweroff(void)
35 {
36         SCI_D(REG_EFUSE_PGM_PARA) &= ~BIT_CLK_EFS_EN;
37         SCI_D(REG_EFUSE_PGM_PARA) &= ~BIT_EFUSE_VDD_ON;
38         SCI_D(GR_GEN0) &= ~GEN0_EFUSE_EN;
39 }
40
41 int sci_efuse_read(unsigned blk)
42 {
43         int busy = 0;
44
45         if (blk > (MASK_READ_INDEX >> SHIFT_READ_INDEX))
46         {
47                 return 0;
48         }
49
50         SCI_D(REG_EFUSE_BLOCK_INDEX) = BITS_READ_INDEX(blk);
51         SCI_D(REG_EFUSE_MODE_CTRL) |= BIT_RD_START;
52
53         do
54         {
55                 busy = SCI_D(REG_EFUSE_STATUS) & BIT_READ_BUSY;
56         } while (busy);
57
58         return SCI_D(REG_EFUSE_DATA_RD);
59 }
60
61 int sci_efuse_is_locked(unsigned blk)
62 {
63         return 0;
64 }
65
66 int sci_efuse_lock(unsigned blk)
67 {
68         return 0;
69 }
70
71 #ifdef EFUSE_DEBUG
72 int sci_efuse_program(unsigned blk, int data)
73 {
74         int busy = 0;
75
76         if (blk > (MASK_PGM_INDEX >> SHIFT_PGM_INDEX))
77         {
78                 return 0;
79         }
80
81         SCI_D(REG_EFUSE_BLOCK_INDEX) = BITS_PGM_INDEX(blk);
82         SCI_D(REG_EFUSE_DATA_WR) = data;
83         SCI_D(REG_EFUSE_MODE_CTRL) |= BIT_PG_START;
84
85         do
86         {
87                 busy = SCI_D(REG_EFUSE_STATUS) & BIT_PGM_BUSY;
88         } while(busy);
89
90         return 1;
91 }
92
93 /* low level */
94 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
95 {
96         int retVal;
97
98         SCI_D(REG_EFUSE_PGM_PARA) |= BIT_PGM_EN;
99         SCI_D(REG_EFUSE_MAGIC_NUMBER) = BITS_MAGIC_NUMBER(magic);
100         ADI_Analogdie_reg_write(0x420006D4, 0xC686);
101         ADI_Analogdie_reg_write(0x420006D8, 0x01);
102
103         delay(10000);
104
105         retVal = sci_efuse_program(blk, data);
106         SCI_D(REG_EFUSE_PGM_PARA) &= ~BIT_PGM_EN;
107
108         return retVal;
109 }
110 #else
111 int sci_efuse_program(unsigned blk, int data)
112 {
113         return 0;
114 }
115
116 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
117 {
118         return 0;
119 }
120 #endif
121
122 static int overclocking_flag = 0;
123 static int overclocking_data = 0;;
124
125 int sci_efuse_overclocking_get()
126 {
127         int data;
128
129         if (overclocking_flag == 0)
130         {
131                 sci_efuse_poweron();
132                 data = sci_efuse_read(1);
133                 sci_efuse_poweroff();
134
135                 if ((data & BIT_29) != 0) {
136                         overclocking_data = 1;
137                 }
138
139                 overclocking_flag = 1;
140         }
141
142         return overclocking_data;
143 }
144
145
146 #if 0
147 #define CAL_DATA_BLK    7
148 #define BASE_ADC_P0   785   //3.6V
149 #define BASE_ADC_P1   917   //4.2V
150 #define VOL_P0        3600
151 #define VOL_P1        4200
152 #define ADC_DATA_OFFSET 128
153 int sci_efuse_calibration_get(unsigned int * p_cal_data)
154 {
155         int data;
156     unsigned int cal_temp;
157     unsigned short adc_temp;
158
159         sci_efuse_poweron();
160         data = sci_efuse_read(CAL_DATA_BLK);
161         sci_efuse_poweroff();
162
163         data &= ~(1 << 31); 
164     
165 //    data = (173 |(171 << 8));
166     printf("sci_efuse_calibration data:%d\n",data);
167         if((!data)||(p_cal_data == NULL))
168         {
169                 return 0;
170         }
171     //adc 3.6V 
172     adc_temp = ((data>>8) & 0x00FF) + BASE_ADC_P0 - ADC_DATA_OFFSET;
173     p_cal_data[1] = (VOL_P0)|(adc_temp << 16);
174
175     //adc 4.2V
176         adc_temp = (data & 0x00FF) + BASE_ADC_P1 - ADC_DATA_OFFSET;
177     p_cal_data[0] = (VOL_P1)|(adc_temp << 16);
178
179         return 1;
180 }
181 #endif