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-sc8825/ldo.h>
24 #include <asm/arch/sc8810_reg_global.h>
25 #include <asm/arch/regs_adi.h>
26 #include <asm/arch/regs_global.h>
27 #include <asm/arch/regs_cpc.h>
28 #include <asm/arch/analog_reg_v3.h>
29 #include <ubi_uboot.h>
30 #include <asm/sizes.h>
33 /* soc defined begin*/
34 #define CTL_ADI_BASE (SPRD_ADI_BASE)
35 #define SPRD_MISC_BASE (SPRD_ADI_BASE)
36 #define SPRD_MISC_PHYS (SPRD_ADI_BASE)
38 /* registers definitions for controller CTL_ADI */
39 #define REG_ADI_CTRL0 (CTL_ADI_BASE + 0x04)
40 #define REG_ADI_CHNL_PRI (CTL_ADI_BASE + 0x08)
41 #define REG_ADI_INT_RAW (CTL_ADI_BASE + 0x10)
42 #define REG_ADI_RD_CMD (CTL_ADI_BASE + 0x24)
43 #define REG_ADI_RD_DATA (CTL_ADI_BASE + 0x28)
44 #define REG_ADI_FIFO_STS (CTL_ADI_BASE + 0x2c)
46 /* bits definitions for register REG_ADI_CTRL0 */
47 #define BIT_ARM_SCLK_EN ( BIT_1 )
48 #define BITS_CMMB_WR_PRI ( (1) << 4 & (BIT_4|BIT_5) )
50 /* bits definitions for register REG_ADI_CHNL_PRI */
51 #define BITS_PD_WR_PRI ( (1) << 14 & (BIT_14|BIT_15) )
52 #define BITS_RFT_WR_PRI ( (1) << 12 & (BIT_12|BIT_13) )
53 #define BITS_DSP_RD_PRI ( (2) << 10 & (BIT_10|BIT_11) )
54 #define BITS_DSP_WR_PRI ( (2) << 8 & (BIT_8|BIT_9) )
55 #define BITS_ARM_RD_PRI ( (3) << 6 & (BIT_6|BIT_7) )
56 #define BITS_ARM_WR_PRI ( (3) << 4 & (BIT_4|BIT_5) )
57 #define BITS_STC_WR_PRI ( (1) << 2 & (BIT_2|BIT_3) )
58 #define BITS_INT_STEAL_PRI ( (3) << 0 & (BIT_0|BIT_1) )
60 /* bits definitions for register REG_ADI_RD_DATA */
61 #define BIT_RD_CMD_BUSY ( BIT_31 )
62 #define SHIFT_RD_ADDR ( 16 )
64 #define SHIFT_RD_VALU ( 0 )
65 #define MASK_RD_VALU ( 0xFFFF )
67 /* bits definitions for register REG_ADI_FIFO_STS */
68 #define BIT_FIFO_FULL ( BIT_11 )
69 #define FIFO_IS_FULL() (__raw_readl(REG_ADI_FIFO_STS) & BIT_FIFO_FULL)
71 #define BIT_FIFO_EMPTY ( BIT_10 )
73 /* special V1 (sc8830 soc) defined */
74 /* bits definitions for register REG_ADI_CTRL0 */
75 #define BIT_ADI_WR(_X_) ( (_X_) << 2 )
76 #define BITS_ADDR_BYTE_SEL(_X_) ( (_X_) << 0 & (BIT_0|BIT_1) )
78 /* bits definitions for register REG_ADI_CHNL_PRI */
79 #define VALUE_CH_PRI (0x0)
81 #define REG_ADI_GSSI_CFG0 (CTL_ADI_BASE + 0x1C)
82 #define REG_ADI_GSSI_CFG1 (CTL_ADI_BASE + 0x20)
86 static u32 readback_addr_mak = 0;
88 /*FIXME: Now define adi IP version, sc8825 is zero, sc8830 is one,
89 * Adi need init early that than read soc id, now using this ARCH dependency.
91 static inline int __adi_ver(void)
100 #define TO_ADDR(_x_) ( ((_x_) >> SHIFT_RD_ADDR) & readback_addr_mak )
102 /*FIXME:If we have not hwspinlock , we need use spinlock to do it*/
103 static inline void __adi_lock(unsigned long *flags, unsigned long *hw_flags)
108 static inline void __adi_unlock(unsigned long *flags, unsigned long *hw_flags)
113 static inline int __adi_fifo_drain(void)
116 while (!(__raw_readl(REG_ADI_FIFO_STS) & BIT_FIFO_EMPTY) && cnt--) {
119 WARN(cnt == 0, "ADI WAIT timeout!!!");
123 #define ANA_VIRT_BASE ( SPRD_MISC_BASE )
124 #define ANA_PHYS_BASE ( SPRD_MISC_PHYS )
125 #define ANA_ADDR_SIZE (SZ_4K)
126 #define ADDR_VERIFY(_X_) do { \
127 BUG_ON((_X_) < ANA_VIRT_BASE || (_X_) > (ANA_VIRT_BASE + ANA_ADDR_SIZE));} while (0)
129 static inline u32 __adi_translate_addr(u32 regvddr)
131 regvddr = regvddr - ANA_VIRT_BASE + ANA_PHYS_BASE;
135 static inline int __adi_read(u32 regPddr)
141 * We don't wait write fifo empty in here,
142 * Because if normal write is SYNC, that will
143 * wait fifo empty at the end of the write.
145 __raw_writel(regPddr, REG_ADI_RD_CMD);
148 * wait read operation complete, RD_data[31]
149 * is set simulaneously when writing read command.
150 * RD_data[31] will be cleared after the read operation complete,
153 val = __raw_readl(REG_ADI_RD_DATA);
154 } while ((val & BIT_RD_CMD_BUSY) && cnt--);
156 WARN(cnt == 0, "ADI READ timeout!!!");
157 /* val high part should be the address of the last read operation */
158 BUG_ON(TO_ADDR(val) != (regPddr & readback_addr_mak));
160 return (val & MASK_RD_VALU);
163 int sci_adi_read(u32 reg)
168 reg = __adi_translate_addr(reg);
169 __adi_lock(&flags, NULL);
170 val = __adi_read(reg);
171 __adi_unlock(&flags, NULL);
175 EXPORT_SYMBOL(sci_adi_read);
177 /*This value have a bit of depending on real hardware fifo size*/
178 #define CACHE_SIZE (16)
179 static struct __data {
182 } __data_array[CACHE_SIZE];
183 struct __data *head_p = &__data_array[0];
184 struct __data *tail_p = &__data_array[0];
185 static u32 data_in_cache = 0;
188 static inline void __p_add(struct __data **p, u32 isHead)
190 if (++(*p) > &__data_array[CACHE_SIZE - 1])
191 (*p) = &__data_array[0];
192 if (head_p == tail_p) {
193 if (isHead == HEAD_ADD) {
196 data_in_cache = CACHE_SIZE;
203 static inline int __adi_write(u32 reg, u16 val, u32 sync)
207 __p_add(&tail_p, TAIL_ADD);
208 while (!FIFO_IS_FULL() && (data_in_cache != 0)) {
209 __raw_writel(head_p->val, head_p->reg);
210 __p_add(&head_p, HEAD_ADD);
213 if (sync || data_in_cache == CACHE_SIZE) {
215 while (data_in_cache != 0) {
216 while (FIFO_IS_FULL()) {
219 __raw_writel(head_p->val, head_p->reg);
220 __p_add(&head_p, HEAD_ADD);
228 int sci_adi_write_fast(u32 reg, u16 val, u32 sync)
232 __adi_lock(&flags, NULL);
233 __adi_write(reg, val, sync);
234 __adi_unlock(&flags, NULL);
238 EXPORT_SYMBOL(sci_adi_write_fast);
240 int sci_adi_write(u32 reg, u16 or_val, u16 clear_msk)
245 __adi_lock(&flags, NULL);
247 (__adi_read(__adi_translate_addr(reg)) &
248 ~clear_msk) | or_val, 1);
249 __adi_unlock(&flags, NULL);
253 EXPORT_SYMBOL(sci_adi_write);
255 inline int sci_adi_raw_write(u32 reg, u16 val)
257 return sci_adi_write_fast(reg, val, 1);
260 inline int sci_adi_set(u32 reg, u16 bits)
262 return sci_adi_write(reg, bits, 0);
265 inline int sci_adi_clr(u32 reg, u16 bits)
267 return sci_adi_write(reg, 0, bits);
270 static void __adi_init(void)
273 value = __raw_readl(REG_ADI_CTRL0);
275 if (__adi_ver() == 0) {
276 value &= ~BIT_ARM_SCLK_EN;
277 value |= BITS_CMMB_WR_PRI;
278 __raw_writel(value, REG_ADI_CTRL0);
280 value = __raw_readl(REG_ADI_CHNL_PRI);
281 value |= BITS_PD_WR_PRI | BITS_RFT_WR_PRI |
282 BITS_DSP_RD_PRI | BITS_DSP_WR_PRI |
283 BITS_ARM_RD_PRI | BITS_ARM_WR_PRI |
284 BITS_STC_WR_PRI | BITS_INT_STEAL_PRI;
285 __raw_writel(value, REG_ADI_CHNL_PRI);
287 readback_addr_mak = 0x7ff;
288 } else if (__adi_ver() == 1) {
292 value = VALUE_CH_PRI;
293 __raw_writel(value, REG_ADI_CHNL_PRI);
295 value = __raw_readl(REG_ADI_GSSI_CFG0);
296 readback_addr_mak = (value & 0x3f) - ((value >> 11) & 0x1f) - 1;
300 int sci_adi_init(void)
302 /* enable adi in global regs */
303 sci_glb_set(GR_GEN0, GEN0_ADI_EN);
306 sci_glb_set(GR_SOFT_RST, ADI_SOFT_RST);
308 sci_glb_clr(GR_SOFT_RST, ADI_SOFT_RST);