2 * Copyright (C) 2012 Spreadtrum Communications Inc.
3 * Copyright (C) 2012 steve zhan
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
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.
16 *For arm read ,delay about 1us when clk_adi runs at 76.8M
17 *The interface timing is compatible with spi timing
22 #include <asm/errno.h>
23 #include <asm/arch/ldo.h>
24 #include <ubi_uboot.h>
25 #include <asm/sizes.h>
26 #include <asm/arch/sprd_reg.h>
28 #include <asm/arch/chip_drv_common_io.h>
33 #define SPRD_MISC_BASE SPRD_MISC_PHYS
35 /* registers definitions for controller CTL_ADI */
36 #define REG_ADI_CTRL0 (SPRD_MISC_BASE + 0x04)
37 #define REG_ADI_CHNL_PRI (SPRD_MISC_PHYS + 0x08)
38 #define REG_ADI_INT_RAW (SPRD_MISC_PHYS + 0x10)
39 #define REG_ADI_RD_CMD (SPRD_MISC_PHYS + 0x24)
40 #define REG_ADI_RD_DATA (SPRD_MISC_PHYS + 0x28)
41 #define REG_ADI_FIFO_STS (SPRD_MISC_PHYS + 0x2c)
43 /* bits definitions for register REG_ADI_CTRL0 */
44 #define BIT_ARM_SCLK_EN ( BIT_1 )
45 #define BITS_CMMB_WR_PRI ( (1) << 4 & (BIT_4|BIT_5) )
47 /* bits definitions for register REG_ADI_CHNL_PRI */
48 #define BITS_PD_WR_PRI ( (1) << 14 & (BIT_14|BIT_15) )
49 #define BITS_RFT_WR_PRI ( (1) << 12 & (BIT_12|BIT_13) )
50 #define BITS_DSP_RD_PRI ( (2) << 10 & (BIT_10|BIT_11) )
51 #define BITS_DSP_WR_PRI ( (2) << 8 & (BIT_8|BIT_9) )
52 #define BITS_ARM_RD_PRI ( (3) << 6 & (BIT_6|BIT_7) )
53 #define BITS_ARM_WR_PRI ( (3) << 4 & (BIT_4|BIT_5) )
54 #define BITS_STC_WR_PRI ( (1) << 2 & (BIT_2|BIT_3) )
55 #define BITS_INT_STEAL_PRI ( (3) << 0 & (BIT_0|BIT_1) )
57 /* bits definitions for register REG_ADI_RD_DATA */
58 #define BIT_RD_CMD_BUSY ( BIT_31 )
59 #define SHIFT_RD_ADDR ( 16 )
61 #define SHIFT_RD_VALU ( 0 )
62 #define MASK_RD_VALU ( 0xFFFF )
64 /* bits definitions for register REG_ADI_FIFO_STS */
65 #define BIT_FIFO_FULL ( BIT_11 )
66 #define FIFO_IS_FULL() (__raw_readl(REG_ADI_FIFO_STS) & BIT_FIFO_FULL)
68 #define BIT_FIFO_EMPTY ( BIT_10 )
70 /* special V1 (sc8830 soc) defined */
71 /* bits definitions for register REG_ADI_CTRL0 */
72 #define BIT_ADI_WR(_X_) ( (_X_) << 2 )
73 #define BITS_ADDR_BYTE_SEL(_X_) ( (_X_) << 0 & (BIT_0|BIT_1) )
75 /* bits definitions for register REG_ADI_CHNL_PRI */
76 #define VALUE_CH_PRI (0x0)
78 #define REG_ADI_GSSI_CFG0 (SPRD_MISC_PHYS + 0x1C)
79 #define REG_ADI_GSSI_CFG1 (SPRD_MISC_PHYS + 0x20)
83 static u32 readback_addr_mak = 0;
84 static u8 is_ana_init = 0;
86 #if defined(CONFIG_NAND_SPL) || defined(CONFIG_FDL1)
87 #define panic(x...) do{}while(0)
88 #define printf(x...) do{}while(0)
93 for (i=0; i<cnt; i++);\
97 /*FIXME: Now define adi IP version, sc8825 is zero, sc8830 is one,
98 * Adi need init early that than read soc id, now using this ARCH dependency.
100 static inline int __adi_ver(void)
109 #define TO_ADDR(_x_) ( ((_x_) >> SHIFT_RD_ADDR) & readback_addr_mak )
111 /*FIXME:If we have not hwspinlock , we need use spinlock to do it*/
112 static inline void __adi_lock(unsigned long *flags, unsigned long *hw_flags)
117 static inline void __adi_unlock(unsigned long *flags, unsigned long *hw_flags)
122 static inline int __adi_fifo_drain(void)
125 while (!(__raw_readl(REG_ADI_FIFO_STS) & BIT_FIFO_EMPTY) && cnt--) {
130 printf("[0x%s]: ADI READ timeout!!! \n", __func__);
137 #define ANA_VIRT_BASE ( SPRD_MISC_BASE )
138 #define ANA_PHYS_BASE ( SPRD_MISC_PHYS )
139 #define ANA_ADDR_SIZE ( SZ_32K + SZ_4K )
140 #define ADDR_VERIFY(_X_) do { \
141 BUG_ON((_X_) < ANA_VIRT_BASE || (_X_) > (ANA_VIRT_BASE + ANA_ADDR_SIZE));} while (0)
143 static inline u32 __adi_translate_addr(u32 regvddr)
145 regvddr = regvddr - ANA_VIRT_BASE + ANA_PHYS_BASE;
149 static inline int __adi_read(u32 regPddr)
155 * We don't wait write fifo empty in here,
156 * Because if normal write is SYNC, that will
157 * wait fifo empty at the end of the write.
159 __raw_writel(regPddr, REG_ADI_RD_CMD);
162 * wait read operation complete, RD_data[31]
163 * is set simulaneously when writing read command.
164 * RD_data[31] will be cleared after the read operation complete,
167 val = __raw_readl(REG_ADI_RD_DATA);
168 } while ((val & BIT_RD_CMD_BUSY) && cnt--);
172 printf("[0x%s]: ADI READ timeout!!! reg = 0x%x, value = 0x%x\n", __func__, regPddr, val);
176 /* val high part should be the address of the last read operation */
177 BUG_ON(TO_ADDR(val) != (regPddr & readback_addr_mak));
179 return (val & MASK_RD_VALU);
182 int sci_adi_read(u32 reg)
187 reg = __adi_translate_addr(reg);
188 __adi_lock(&flags, NULL);
189 val = __adi_read(reg);
190 __adi_unlock(&flags, NULL);
194 /*This value have a bit of depending on real hardware fifo size*/
195 #define CACHE_SIZE (16)
196 static struct __data {
199 } __data_array[CACHE_SIZE];
200 struct __data *head_p = &__data_array[0];
201 struct __data *tail_p = &__data_array[0];
202 static u32 data_in_cache = 0;
205 static inline void __p_add(struct __data **p, u32 isHead)
207 if (++(*p) > &__data_array[CACHE_SIZE - 1])
208 (*p) = &__data_array[0];
209 if (head_p == tail_p) {
210 if (isHead == HEAD_ADD) {
213 data_in_cache = CACHE_SIZE;
220 static inline int __adi_write(u32 reg, u16 val, u32 sync)
224 __p_add(&tail_p, TAIL_ADD);
225 while (!FIFO_IS_FULL() && (data_in_cache != 0)) {
226 __raw_writel(head_p->val, head_p->reg);
227 __p_add(&head_p, HEAD_ADD);
230 if (sync || data_in_cache == CACHE_SIZE) {
232 while (data_in_cache != 0) {
233 while (FIFO_IS_FULL()) {
236 __raw_writel(head_p->val, head_p->reg);
237 __p_add(&head_p, HEAD_ADD);
245 int sci_adi_write_fast(u32 reg, u16 val, u32 sync)
249 __adi_lock(&flags, NULL);
250 __adi_write(reg, val, sync);
251 __adi_unlock(&flags, NULL);
255 int sci_adi_write(u32 reg, u16 or_val, u16 clear_msk)
260 __adi_lock(&flags, NULL);
262 (__adi_read(__adi_translate_addr(reg)) &
263 ~clear_msk) | or_val, 1);
264 __adi_unlock(&flags, NULL);
268 static void __adi_init(void)
271 value = __raw_readl(REG_ADI_CTRL0);
273 if (__adi_ver() == 0) {
274 value &= ~BIT_ARM_SCLK_EN;
275 value |= BITS_CMMB_WR_PRI;
276 __raw_writel(value, REG_ADI_CTRL0);
278 value = __raw_readl(REG_ADI_CHNL_PRI);
279 value |= BITS_PD_WR_PRI | BITS_RFT_WR_PRI |
280 BITS_DSP_RD_PRI | BITS_DSP_WR_PRI |
281 BITS_ARM_RD_PRI | BITS_ARM_WR_PRI |
282 BITS_STC_WR_PRI | BITS_INT_STEAL_PRI;
283 __raw_writel(value, REG_ADI_CHNL_PRI);
285 readback_addr_mak = 0x7ff;
286 } else if (__adi_ver() == 1) {
290 value = VALUE_CH_PRI;
291 __raw_writel(value, REG_ADI_CHNL_PRI);
293 value = __raw_readl(REG_ADI_GSSI_CFG0);
294 readback_addr_mak = (value & 0x3f) - ((value >> 11) & 0x1f) - 1;
298 void sci_adi_init(void)
301 /* enable adi in global regs */
302 CHIP_REG_OR(REG_AON_APB_APB_EB0, BIT_ADI_EB);
304 CHIP_REG_OR(REG_AON_APB_APB_RST0, BIT_ADI_SOFT_RST);
306 CHIP_REG_AND(REG_AON_APB_APB_RST0, (~BIT_ADI_SOFT_RST));
314 * sci_get_adie_chip_id - read a-die chip id
317 * the a-die chip id, example: 0x2711A000
319 u32 sci_get_adie_chip_id(void)
327 chip_id = (sci_adi_read(ANA_REG_GLB_CHIP_ID_HIGH) & 0xffff) << 16;
328 chip_id |= sci_adi_read(ANA_REG_GLB_CHIP_ID_LOW) & 0xffff;