arm: sc8830: remove build warnings
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8830 / ana_efuse.c
1 /*
2  * Copyright (C) 2014 Spreadtrum Communications Inc.
3  *
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.
8  *
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.
13  *
14  */
15
16 /* IMPORTANT:
17  *
18  * TODO:
19  */
20 #include <common.h>
21 #include <linux/types.h>
22 #include <linux/err.h>
23 #include <asm/io.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>
30
31 #define pr_debug(args...)  printf(args)
32
33 #define WARN_ON(a)
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)
38 #define cpu_relax()
39
40 #define SPRD_ADISLAVE_BASE (SPRD_ADI_PHYS + 0x8000)
41
42 #define ANA_REGS_EFUSE_BASE             ( SPRD_ADISLAVE_BASE + 0x200 )
43
44 #define EFUSE_BLOCK_MAX                 ( 32 )
45 #define EFUSE_BLOCK_WIDTH               ( 8 )   /* bit counts */
46
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,
52 };
53
54 void adie_efuse_workaround(void)
55 {
56 #define REG_ADI_GSSI_CFG0                                       (SPRD_ADI_PHYS + 0x1C)
57 /** BIT_RF_GSSI_SCK_ALL_IN
58    * 0: sclk auto gate
59    * 1: sclk always on
60 */
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);
64 }
65
66 void adie_efuse_lookat(void)
67 {
68         volatile u32 *reg = (volatile u32 *)ANA_REGS_EFUSE_BASE;
69         int cnt = 16;
70         while (cnt--) {
71                 printf("[%p] = %08x\n", reg, sci_adi_read((u32) reg));
72                 reg++;
73         }
74         printf("\n");
75 }
76
77 static void adie_efuse_lock(void)
78 {
79 }
80
81 static void adie_efuse_unlock(void)
82 {
83 }
84
85 static void __adie_efuse_power_on(void)
86 {
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);
90          */
91
92         /* FIXME: sclk always on or not ? */
93         /* adie_efuse_workaround(); */
94 }
95
96 static void __adie_efuse_power_off(void)
97 {
98         /* FIXME: rtc_efs only for prog
99            sci_adi_clr(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_EFS_EN);
100          */
101         sci_adi_clr(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_EFS_EN);
102 }
103
104 static __inline int __adie_efuse_wait_clear(u32 bits)
105 {
106         int ret = 0;
107         unsigned long timeout;
108
109         pr_debug("wait %x\n", sci_adi_read(ANA_REG_EFUSE_STATUS));
110
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)) {
115                         WARN_ON(1);
116                         ret = -ETIMEDOUT;
117                         break;
118                 }
119                 cpu_relax();
120         }
121         return ret;
122 }
123
124 static u32 adie_efuse_read(int blk_index)
125 {
126         u32 val = 0;
127
128         pr_debug("adie efuse read %d\n", blk_index);
129         adie_efuse_lock();
130         __adie_efuse_power_on();
131         /* enable adie_efuse module clk and power before */
132
133         /* adie_efuse_lookat(); */
134
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));
138          */
139
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);
143
144         if (IS_ERR_VALUE(__adie_efuse_wait_clear(BIT_READ_BUSY)))
145                 goto out;
146
147         val = sci_adi_read(ANA_REG_EFUSE_DATA_RD);
148
149         /* FIXME: reverse the otp value */
150         val = BITS_EFUSE_DATA_RD(~val);
151
152 out:
153         __adie_efuse_power_off();
154         adie_efuse_unlock();
155         return val;
156 }
157
158 u32 __adie_efuse_read(int blk_index)
159 {
160         return adie_efuse_read(blk_index);
161 }
162
163 //EXPORT_SYMBOL_GPL(__adie_efuse_read);
164
165 u32 __adie_efuse_read_bits(int bit_index, int length)
166 {
167         int i, blk_index = (int)bit_index / EFUSE_BLOCK_WIDTH;
168         int blk_max = DIV_ROUND_UP(bit_index + length, EFUSE_BLOCK_WIDTH);
169         u32 val = 0;
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);
175         }
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);
180         return val;
181 }
182
183 void __adie_efuse_block_dump(void)
184 {
185         int i, idx;
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++) {
189                 u32 val = 0;
190                 printf("\n");
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");
196                 printf("\n");
197         }
198         printf("\n");
199 }