2 * Copyright (C) 2014 Spreadtrum Communications Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
21 #include <linux/types.h>
22 #include <linux/err.h>
24 //#include <asm/arch/hardware.h>
25 #include <asm/arch/sprd_reg.h>
26 #include <asm/arch/sci.h>
27 #include <asm/arch/adi.h>
28 #include <asm/arch/__regs_efuse.h>
29 #include <asm/arch/__regs_ana_efuse.h>
31 #define pr_debug(args...) printf(args)
34 u32 SCI_GetTickCount(void);
35 #define jiffies (SCI_GetTickCount()) /* return msec count */
36 #define msecs_to_jiffies(a) (a)
37 #define time_after(a,b) ((int)(b) - (int)(a) < 0)
40 #define SPRD_ADISLAVE_BASE (SPRD_ADI_PHYS + 0x8000)
42 #define ANA_REGS_EFUSE_BASE ( SPRD_ADISLAVE_BASE + 0x200 )
44 #define EFUSE_BLOCK_MAX ( 32 )
45 #define EFUSE_BLOCK_WIDTH ( 8 ) /* bit counts */
47 static u8 dummy_cached_otp[EFUSE_BLOCK_MAX] = {
48 0x9f, 0xdf, 0xef, 0x37, 0x91, 0x27, 0xfc, 0xfd,
49 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xfe, 0x7d, 0xbf,
50 0x7f, 0xff, 0x6c, 0x00, 0xe7, 0x71, 0x5f, 0xb7,
51 0x81, 0x5b, 0xe7, 0x3c, 0xa1, 0x27, 0x8a, 0xa1,
54 void adie_efuse_workaround(void)
56 #define REG_ADI_GSSI_CFG0 (SPRD_ADI_PHYS + 0x1C)
57 /** BIT_RF_GSSI_SCK_ALL_IN
61 #define BIT_RF_GSSI_SCK_ALL_IN BIT(30)
62 sci_glb_write(REG_ADI_GSSI_CFG0,
63 BIT_RF_GSSI_SCK_ALL_IN, BIT_RF_GSSI_SCK_ALL_IN);
66 void adie_efuse_lookat(void)
68 volatile u32 *reg = (volatile u32 *)ANA_REGS_EFUSE_BASE;
71 printf("[%p] = %08x\n", reg, sci_adi_read((u32) reg));
77 static void adie_efuse_lock(void)
81 static void adie_efuse_unlock(void)
85 static void __adie_efuse_power_on(void)
87 sci_adi_set(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_EFS_EN);
88 /* FIXME: rtc_efs only for prog
89 sci_adi_set(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_EFS_EN);
92 /* FIXME: sclk always on or not ? */
93 /* adie_efuse_workaround(); */
96 static void __adie_efuse_power_off(void)
98 /* FIXME: rtc_efs only for prog
99 sci_adi_clr(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_EFS_EN);
101 sci_adi_clr(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_EFS_EN);
104 static __inline int __adie_efuse_wait_clear(u32 bits)
107 unsigned long timeout;
109 pr_debug("wait %x\n", sci_adi_read(ANA_REG_EFUSE_STATUS));
111 /* wait for maximum of 3000 msec */
112 timeout = jiffies + msecs_to_jiffies(3000);
113 while (sci_adi_read(ANA_REG_EFUSE_STATUS) & bits) {
114 if (time_after(jiffies, timeout)) {
124 static u32 adie_efuse_read(int blk_index)
128 pr_debug("adie efuse read %d\n", blk_index);
130 __adie_efuse_power_on();
131 /* enable adie_efuse module clk and power before */
133 /* adie_efuse_lookat(); */
135 /* FIXME: set read timing, why 0x20 (default value)
136 sci_adi_raw_write(ANA_REG_EFUSE_RD_TIMING_CTRL,
137 BITS_EFUSE_RD_TIMING(0x20));
140 sci_adi_raw_write(ANA_REG_EFUSE_BLOCK_INDEX,
141 BITS_READ_WRITE_INDEX(blk_index));
142 sci_adi_raw_write(ANA_REG_EFUSE_MODE_CTRL, BIT_RD_START);
144 if (IS_ERR_VALUE(__adie_efuse_wait_clear(BIT_READ_BUSY)))
147 val = sci_adi_read(ANA_REG_EFUSE_DATA_RD);
149 /* FIXME: reverse the otp value */
150 val = BITS_EFUSE_DATA_RD(~val);
153 __adie_efuse_power_off();
158 u32 __adie_efuse_read(int blk_index)
160 return adie_efuse_read(blk_index);
163 //EXPORT_SYMBOL_GPL(__adie_efuse_read);
165 u32 __adie_efuse_read_bits(int bit_index, int length)
167 int i, blk_index = (int)bit_index / EFUSE_BLOCK_WIDTH;
168 int blk_max = DIV_ROUND_UP(bit_index + length, EFUSE_BLOCK_WIDTH);
170 pr_debug("otp read blk %d - %d\n", blk_index, blk_max);
171 /* FIXME: length should not bigger than 8 */
172 for (i = blk_index; i < blk_max; i++) {
173 val |= __adie_efuse_read(i)
174 << ((i - blk_index) * EFUSE_BLOCK_WIDTH);
176 //pr_debug("val=%08x\n", val);
177 val >>= (bit_index & (EFUSE_BLOCK_WIDTH - 1));
178 val &= BIT(length) - 1;
179 pr_debug("otp read bits %d ++ %d 0x%08x\n\n", bit_index, length, val);
183 void __adie_efuse_block_dump(void)
186 printf("adie efuse blocks dump:\n");
187 printf("-- 7 6 5 4 3 2 1 0");
188 for (idx = 0; idx < EFUSE_BLOCK_MAX; idx++) {
191 val = __adie_efuse_read(idx);
192 dummy_cached_otp[idx] = (u8) val;
193 printf("%02d ", idx);
194 for (i = EFUSE_BLOCK_WIDTH - 1; i >= 0; --i)
195 printf("%s ", (val & BIT(i)) ? "1" : "0");