2 * Copyright (C) 2012 Spreadtrum Communications Inc.
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.
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.
15 #include <asm/arch/sprd_reg.h>
16 #include <asm/arch/adi.h>
17 #include "asm/arch/efuse_drv.h"
20 #define REG32(x) (*((volatile uint32 *)(x)))
23 #if defined(CONFIG_SPX15)
25 #define EFUSE_CONTROLLER_NUM 2
27 #undef SPRD_UIDEFUSE_PHYS
28 #define SPRD_UIDEFUSE_PHYS (0x40240000 + idx * 0x100)
32 #define EFUSE_REGISTER_DUMP
33 static void efuse_dump(void)
35 #if defined(EFUSE_REGISTER_DUMP)
36 printf("----------------- efuse dump start --------------------------------\n");
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));
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));
52 printf("----------------- efuse dump end --------------------------------\n");
56 static inline void efuse_udelay(unsigned long usec)
59 for (i = 0; i < (usec << 1); i++);
62 //static void __iomem *ctl_efuse_base = 0;
63 void sci_efuse_poweron(void)
66 /* enable efuse clock */
67 REG32(REG_AON_APB_APB_EB0) |= BIT_EFUSE_EB;
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;
75 REG32(EFUSE_PGM_PARA) |= BIT_EFS_VDD_ON;
76 REG32(EFUSE_PGM_PARA) |= BIT_CLK_EFS_EN;
79 void sci_efuse_poweroff(void)
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;
86 int sci_efuse_read(unsigned blk)
91 #if defined(CONFIG_SPX15)
95 if(idx >= EFUSE_CONTROLLER_NUM) {
96 printf("%s()->Line:%d; efuse idx: %d exceed maximum!\n", __func__, __LINE__, idx);
103 if (blk > (MASK_READ_INDEX >> SHIFT_READ_INDEX))
108 REG32(EFUSE_BLOCK_INDEX) = BITS_READ_INDEX(blk);
109 REG32(EFUSE_MODE_CTRL) |= BIT_RD_START;
115 busy = REG32(EFUSE_STATUS) & BIT_READ_BUSY;
118 reg_val = REG32(EFUSE_DATA_RD);
120 sci_efuse_poweroff();
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);
125 printf("%s()->Line:%d; efuse blk=%d; data=0x%08x;\n", __func__, __LINE__, blk, reg_val);
132 #define EFUSE_MAGIC_VAL 0x8810
133 int sci_efuse_program(unsigned blk, int data)
137 #if defined(CONFIG_SPX15)
141 if(idx >= EFUSE_CONTROLLER_NUM) {
142 printf("%s()->Line:%d; efuse idx: %d exceed maximum!\n", __func__, __LINE__, idx);
147 if (blk > (MASK_PGM_INDEX >> SHIFT_PGM_INDEX))
152 REG32(EFUSE_BLOCK_INDEX) = BITS_PGM_INDEX(blk);
153 REG32(EFUSE_DATA_WR) = data;
154 REG32(EFUSE_MODE_CTRL) |= BIT_PG_START;
158 busy = REG32(EFUSE_STATUS) & BIT_PGM_BUSY;
165 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
169 REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE0_PWR_ON;
170 REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE1_PWR_ON;
172 REG32(EFUSE_PGM_PARA) |= BIT_PGM_EN;
173 REG32(EFUSE_MAGIC_NUMBER) = BITS_MAGIC_NUMBER(magic);
177 retVal = sci_efuse_program(blk, data);
178 REG32(EFUSE_PGM_PARA) &= ~BIT_PGM_EN;
183 int sci_efuse_program(unsigned blk, int data)
188 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
194 #define CAL_DATA_BLK 7
195 #define BASE_ADC_P0 711 /* 3.6V */
196 #define BASE_ADC_P1 830 /* 4.2V */
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)
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);
213 while(BIT_AFUSE_READ_REQ & sci_adi_read(ANA_REG_GLB_AFUSE_CTRL)) {
226 data = sci_adi_read(ANA_REG_GLB_AFUSE_OUT0);
227 data |= (sci_adi_read(ANA_REG_GLB_AFUSE_OUT1)) << 16;
235 printf("afuse: data = 0x%x\n\r",data);
237 adc_temp = ((data & 0xFF00) >> 8) + BASE_ADC_P0 - ADC_DATA_OFFSET;
238 p_cal_data[1] = (VOL_P0) | ((adc_temp << 2) << 16);
241 adc_temp = (data & 0xFF) + BASE_ADC_P1 - ADC_DATA_OFFSET;
242 p_cal_data[0] = (VOL_P1)|((adc_temp << 2) << 16);