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.
17 * The electrical fuse is a type of non-volatile memory fabricated
18 * in standard CMOS logic process. This electrical fuse macro is widely
19 * used in chip ID, memory redundancy, security code, configuration setting,
20 * and feature selection, etc.
22 * This efuse controller is designed for 32*32 bits electrical fuses,
23 * support TSMC HPM 28nm product of "TEF28HPM32X32HD18_PHRM".
25 * and we default use double-bit, 512bits efuse are visiable for software.
27 * efuse driver ONLY support module ip version since from r3p0
28 * which had integrated into scx30g and scx35l etc.
31 * 1. do something when block had been locked with bit31 if need
32 * 1. check and clear blk prog/err flag if need
33 * 1. wait *300ms* for read/prog ready time-out
34 * 1. only mutexlock and hwspinlock for efuse access sync with cp
35 * 1. be care not do use efuse API in interrupt function
36 * 1. no need soft reset after efuse read/prog and power on/off
37 * 1. efuse block width should less than 8bits
38 * 1. efuse block count should not bigger than 32! or not should expland the cached otp arrary
39 * 1. support efuse DT info (version, blocks, ...) later
40 * 1. there is no handle for efuse module removed
44 #include <linux/types.h>
45 #include <linux/err.h>
47 //#include <asm/arch/hardware.h>
48 #include <asm/arch/sprd_reg.h>
49 #include <asm/arch/sci.h>
50 #include <asm/arch/__regs_efuse.h>
51 #define EFUSE_MAGIC 0x8810
53 #define pr_debug(args...) printf(args)
54 #define pr_info() printf
57 u32 SCI_GetTickCount(void);
58 #define jiffies (SCI_GetTickCount()) /* return msec count */
59 #define msecs_to_jiffies(a) (a)
60 #define time_after(a,b) ((int)(b) - (int)(a) < 0)
63 static void msleep(u32 ms)
65 u32 timeout = jiffies + ms;
66 while(!time_after(jiffies, timeout)) {
71 #define REGS_EFUSE_BASE SPRD_UIDEFUSE_PHYS
73 #define EFUSE_BLOCK_MAX ( 16 )
74 #define EFUSE_BLOCK_WIDTH ( 32 ) /* bit counts */
76 void efuse_lookat(void)
78 volatile u32 *reg = (volatile u32 *)REGS_EFUSE_BASE;
81 printf("[%p] = %08x\n", reg, *reg);
87 static void efuse_lock(void)
91 static void efuse_unlock(void)
95 static void efuse_reset(void)
97 /* should enable module before soft reset efuse */
98 WARN_ON(!sci_glb_read(REG_AON_APB_APB_EB0, BIT_EFUSE_EB));
99 sci_glb_set(REG_AON_APB_APB_RST0, BIT_EFUSE_SOFT_RST);
101 sci_glb_clr(REG_AON_APB_APB_RST0, BIT_EFUSE_SOFT_RST);
104 /* FIXME: Set EFS_VDD_ON will open 0.9v static power supply for efuse memory,
105 * before any operation towards to efuse memory this bit have to set to 1.
106 * Once this bit is cleared, the efuse will go to power down mode.
108 * each time when EFS_VDD_ON changes, software should wait at least 1ms to let
111 * For VDDQ(1.8v) power, to prevent the overshot of VDDQ, a extra power switch
112 * connected to ground are controlled by "EFS_VDDQ_K2_ON"
114 void __efuse_power_on(void)
117 sci_glb_set(REG_AON_APB_APB_EB0, BIT_EFUSE_EB);
119 cfg0 = __raw_readl((void *)REG_EFUSE_CFG0);
120 cfg0 &= ~BIT_EFS_VDDQ_K1_ON;
121 cfg0 |= BIT_EFS_VDD_ON | BIT_EFS_VDDQ_K2_ON;
122 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
126 void __efuse_power_off(void)
128 u32 cfg0 = __raw_readl((void *)REG_EFUSE_CFG0);
129 if (cfg0 & BIT_EFS_VDDQ_K1_ON) {
130 cfg0 &= ~BIT_EFS_VDDQ_K1_ON;
131 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
135 cfg0 |= BIT_EFS_VDDQ_K2_ON;
136 cfg0 &= ~BIT_EFS_VDD_ON;
137 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
140 sci_glb_clr(REG_AON_APB_APB_EB0, BIT_EFUSE_EB);
143 static __inline int __efuse_wait_clear(u32 bits)
146 unsigned long timeout;
148 pr_debug("wait %x\n", __raw_readl((void *)REG_EFUSE_STATUS));
150 /* wait for maximum of 300 msec */
151 timeout = jiffies + msecs_to_jiffies(300);
152 while (__raw_readl((void *)REG_EFUSE_STATUS) & bits) {
153 if (time_after(jiffies, timeout)) {
163 static u32 __efuse_read(int blk)
167 /* enable efuse module clk and power before */
169 __raw_writel(BITS_READ_WRITE_INDEX(blk),
170 (void *)REG_EFUSE_READ_WRITE_INDEX);
171 __raw_writel(BIT_RD_START, (void *)REG_EFUSE_MODE_CTRL);
173 if (IS_ERR_VALUE(__efuse_wait_clear(BIT_READ_BUSY)))
176 val = __raw_readl((void *)REG_EFUSE_DATA_RD);
182 static u32 efuse_read(int blk_index)
185 pr_debug("efuse read %d\n", blk_index);
189 val = __efuse_read(blk_index);
196 u32 __ddie_efuse_read(int blk_index)
198 return efuse_read(blk_index);
200 //EXPORT_SYMBOL_GPL(__ddie_efuse_read);
203 void __efuse_prog_power_on(void)
206 sci_glb_set(REG_AON_APB_APB_EB0, BIT_EFUSE_EB);
207 cfg0 = __raw_readl((void *)REG_EFUSE_CFG0);
208 cfg0 &= ~(BIT_EFS_VDDQ_K2_ON | BIT_EFS_VDDQ_K1_ON);
209 cfg0 |= BIT_EFS_VDD_ON;
210 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
213 cfg0 |= BIT_EFS_VDDQ_K1_ON;
214 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
219 static int __efuse_prog(int blk, u32 val)
221 u32 cfg0 = __raw_readl((void *)REG_EFUSE_CFG0);
224 if (blk < 0 || blk >= EFUSE_BLOCK_MAX) /* debug purpose */
227 /* enable pgm mode and setup magic number before programming */
229 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
230 __raw_writel(BITS_MAGIC_NUMBER(EFUSE_MAGIC),
231 (void *)REG_EFUSE_MAGIC_NUMBER);
233 __raw_writel(val, (void *)REG_EFUSE_DATA_WR);
234 __raw_writel(BITS_READ_WRITE_INDEX(blk),
235 (void *)REG_EFUSE_READ_WRITE_INDEX);
236 pr_debug("cfg0 %x\n", __raw_readl((void *)REG_EFUSE_CFG0));
237 __raw_writel(BIT_PG_START, (void *)REG_EFUSE_MODE_CTRL);
238 if (IS_ERR_VALUE(__efuse_wait_clear(BIT_PGM_BUSY)))
242 __raw_writel(0, (void *)REG_EFUSE_MAGIC_NUMBER);
244 __raw_writel(cfg0, (void *)REG_EFUSE_CFG0);
249 static int efuse_prog(int blk_index, u32 val)
252 pr_debug("efuse prog %d %08x\n", blk_index, val);
256 /* enable vddon && vddq */
257 __efuse_prog_power_on();
258 ret = __efuse_prog(blk_index, val);
266 int __ddie_efuse_prog(int blk_index, u32 val)
268 return efuse_prog(blk_index, val);
271 void __ddie_efuse_block_dump(void)
274 printf("ddie efuse base %08x\n", REGS_EFUSE_BASE);
275 printf("ddie efuse blocks dump:\n");
276 for (idx = 0; idx < EFUSE_BLOCK_MAX; idx++) {
277 printf("[%02d] %08x\n", idx, __ddie_efuse_read(idx));