tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / sdio / sdio_api.c
1 /******************************************************************************\r
2  ** File Name:      sdio.c                                                    *\r
3  ** Author:         jiayong.yang                                              *\r
4  ** DATE:           25/06/2012                                                *\r
5  ** Copyright:      2012 Spreatrum, Incoporated. All Rights Reserved.         *\r
6  ** Description:    add sdio API for modem boot in u-boot in SDIO mode        *\r
7  ******************************************************************************\r
8 \r
9  ******************************************************************************\r
10  **                        Edit History                                       *\r
11  ** ------------------------------------------------------------------------- *\r
12  ** DATE           NAME             DESCRIPTION                               *\r
13  ** 25/06/2010     jiayong.yang       Create                                  *\r
14  ******************************************************************************/\r
15 #include <common.h>\r
16 #include <asm/arch/bits.h>\r
17 #include "asm/arch/sci_types.h"\r
18 #include "sdio_card_pal.h"\r
19 #include "sdio_master_pal.h"\r
20 \r
21 /**---------------------------------------------------------------------------*\r
22  **                         Macro Definition                                  *\r
23  **---------------------------------------------------------------------------*/\r
24 #define MAX_BLOCK_COUNT     511   \r
25 #define MAX_BLOCK_SIZE      512\r
26 #define MAX_BUF_SIZE        (MAX_BLOCK_COUNT*MAX_BLOCK_SIZE)\r
27 #if defined(CONFIG_SC7710G2)\r
28         #define SPRD_SDIO_CLK       (48000000)\r
29 #else\r
30         #define SPRD_SDIO_CLK       (16000000)\r
31 #endif\r
32 #define SDIO_PRINTF(x) printf x\r
33 \r
34 #define mdelay(x)       udelay(1000*x)\r
35 typedef void* SDIO_HANDLE;\r
36 /*----------------------------------------------------------------------------*\r
37 **                             Data Structures                                *\r
38 **----------------------------------------------------------------------------*/\r
39 typedef enum CARD_SLOT_NAME_TAG{\r
40         CARD_SLOT_0,\r
41         TEST_MAX_SLOT_NO\r
42 }CARD_SLOT_NAME_E;\r
43 \r
44 typedef enum RW_CASE_SDIO_TAG{\r
45     RW_BYTE_MODE,\r
46     RW_BLOCK_MODE,\r
47     RW_MAX_MODE\r
48 }RW_MODE_E;\r
49 extern void Dcache_CleanRegion(unsigned int addr, unsigned int length);\r
50 /**---------------------------------------------------------------------------*\r
51  **                          Variables                                        *\r
52  **---------------------------------------------------------------------------*/\r
53 \r
54 static int __sdio_write(CARD_SDIO_HANDLE cardHandle,\r
55         unsigned int block_len,\r
56         unsigned int count,\r
57         unsigned int start_addr,\r
58         unsigned char* buf,\r
59         RW_MODE_E mode)\r
60 {\r
61     unsigned int inc_flag = 1; // addr increase\r
62     int ret = TRUE;\r
63 \r
64     switch(mode)\r
65     {\r
66         case RW_BYTE_MODE:\r
67             if(FALSE == SDIO_WriteBytes(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){\r
68                 SDIO_PRINTF((" writebytes failed!!"));\r
69                 ret = FALSE;\r
70                 break;\r
71             }\r
72         break;\r
73     \r
74         case RW_BLOCK_MODE:\r
75             if(FALSE == SDIO_WriteBlocks(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){\r
76                 SDIO_PRINTF(("writeblocks failed!!"));\r
77                 ret = FALSE;\r
78                 break;\r
79             }              \r
80         break;\r
81         default:\r
82             SDIO_PRINTF(("mode-type out of range"));\r
83             return FALSE;\r
84         break;\r
85     }\r
86 \r
87     return ret;\r
88 }\r
89 \r
90 static int __sdio_read(CARD_SDIO_HANDLE cardHandle,\r
91         unsigned int block_len,\r
92         unsigned int count,\r
93         unsigned int start_addr,\r
94         unsigned char* buf,\r
95         RW_MODE_E mode)\r
96 {\r
97     unsigned int inc_flag = 1; // addr increase\r
98     int ret = TRUE;\r
99 \r
100     // delay \r
101        \r
102     switch(mode)\r
103     {\r
104         case RW_BYTE_MODE:\r
105             if(FALSE == SDIO_ReadBytes(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){\r
106                 SDIO_PRINTF(("test readbytes failed!!"));\r
107                 ret = FALSE;\r
108                 break;\r
109             } \r
110             //MMU_InvalideDCACHEALL((unsigned int)buf,(unsigned int)count);       \r
111             //SDIO_PRINTF(("ACK(0x%08x):0x%08x 0x%08x\n",(unsigned int)buf,*(int *)buf,*(int *)(buf+4)));\r
112         break;\r
113     \r
114         case RW_BLOCK_MODE:\r
115             if(FALSE == SDIO_ReadBlocks(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){\r
116                 SDIO_PRINTF(("test readblocks failed!!"));\r
117                 ret = FALSE;\r
118                 break;\r
119             }    \r
120             SDIO_PRINTF(("test readblocks done!!"));\r
121         break;\r
122         default:\r
123             SDIO_PRINTF(("mode-type out of range"));\r
124             return FALSE;\r
125         break;\r
126     }\r
127 \r
128     return ret;\r
129 }\r
130 \r
131 static CARD_SDIO_HANDLE __init_slot(int slotNo)\r
132 {\r
133         CARD_SDIO_HANDLE cardHandle;\r
134         int block_size = MAX_BLOCK_SIZE;\r
135     \r
136         // Step1: Open\r
137         cardHandle = SPRD_SDSlave_Open(slotNo);\r
138 \r
139         if(NULL == cardHandle){\r
140                 SDIO_PRINTF(("slot%d Open Failed!!\r\n", slotNo));\r
141                 return NULL;\r
142         }\r
143 \r
144         // Step2: select slot, this step must be after card open\r
145         CARD_SDIO_SlotSelect(slotNo);\r
146     \r
147         // Step3: Power on\r
148         SPRD_SDSlave_PwrCtl(cardHandle,TRUE);\r
149 \r
150         //SDHOST_SetClkDiv(slotNo,2);\r
151  \r
152         // Step4: Init\r
153         if(FALSE == SPRD_SDSlave_InitCard(cardHandle)){\r
154                 SDIO_PRINTF(("slot%d Init Failed!!\r\n", slotNo));\r
155                 return NULL;\r
156         }\r
157         if(FALSE == SDIO_SetBusClock(cardHandle,SPRD_SDIO_CLK)){\r
158                 SDIO_PRINTF(("Set bus clock  Failed!!\r\n"));\r
159                 return NULL;\r
160         }\r
161         if(FALSE == SDIO_SetBusWidth(cardHandle,SDIO_CARD_PAL_4_BIT)){\r
162                 SDIO_PRINTF(("Set bus width Failed!!\r\n"));\r
163                 return NULL;\r
164         }\r
165         \r
166         \r
167         if(FALSE == SDIO_SetBlockLength(cardHandle,SDIO_SLAVE_FUNC_0,block_size )){\r
168                 SDIO_PRINTF(("Set func0 blk-len Failed!!\r\n"));\r
169                 return NULL;\r
170         }\r
171         if(FALSE == SDIO_SetBlockLength(cardHandle,SDIO_SLAVE_FUNC_1,block_size )){\r
172                 SDIO_PRINTF(("Set func1 blk-len Failed!!\r\n"));\r
173                 return NULL;\r
174         }\r
175         \r
176 \r
177         __FuncEnable(cardHandle);\r
178         \r
179         return cardHandle;\r
180 }\r
181 int sdio_write(SDIO_HANDLE handle,unsigned char *buffer,int size)\r
182 {\r
183         int block_count = 0;\r
184         int byte_count = 0;\r
185         int write_len = 0;\r
186         int result;\r
187         \r
188         block_count = size/MAX_BLOCK_SIZE;\r
189         byte_count = size%MAX_BLOCK_SIZE;\r
190 \r
191         if(block_count >= MAX_BLOCK_COUNT){\r
192                 SDIO_PRINTF(("too many block!!!\r\n"));\r
193                 return 0;\r
194         }\r
195         Dcache_CleanRegion((unsigned int)buffer,(unsigned int)size);\r
196         if(block_count != 0){\r
197                 result = __sdio_write((CARD_SDIO_HANDLE)handle,MAX_BLOCK_SIZE,block_count,0,buffer,RW_BLOCK_MODE);\r
198                 if(result == TRUE){\r
199                         write_len = block_count * MAX_BLOCK_SIZE;\r
200                         buffer += write_len;\r
201                 } else  {\r
202                         SDIO_PRINTF(("write block failed!!\r\n"));      \r
203                         return 0;\r
204                 }\r
205         }\r
206         if(byte_count != 0){\r
207                 result = __sdio_write((CARD_SDIO_HANDLE)handle,MAX_BLOCK_SIZE,byte_count,0,buffer,RW_BYTE_MODE);\r
208                 if(result == TRUE)\r
209                         write_len += byte_count;\r
210                 else {\r
211                         SDIO_PRINTF(("write byte failed!!\r\n"));                       \r
212                 }\r
213         }\r
214         return write_len;\r
215          \r
216 }\r
217 int sdio_read(SDIO_HANDLE handle,unsigned char *buffer,int size)\r
218 {\r
219         int block_count = 0;\r
220         int byte_count = 0;\r
221         int read_len = 0;\r
222         int result;\r
223         \r
224         block_count = size/MAX_BLOCK_SIZE;\r
225         byte_count = size%MAX_BLOCK_SIZE;\r
226 \r
227         if(block_count >= MAX_BLOCK_COUNT){\r
228                 SDIO_PRINTF(("too many block!!!\r\n"));\r
229                 return 0;\r
230         }\r
231         //MMU_InvalideDCACHEALL((unsigned int)buffer,(unsigned int)size);\r
232         if(block_count != 0){\r
233                 result = __sdio_read((CARD_SDIO_HANDLE)handle,MAX_BLOCK_SIZE,block_count,0,buffer,RW_BLOCK_MODE);\r
234                 if(result == TRUE){\r
235                         read_len = block_count * MAX_BLOCK_SIZE;\r
236                         buffer += read_len;\r
237                 } else  {\r
238                         SDIO_PRINTF(("read block failed!!\r\n"));                       \r
239                         return 0;\r
240                 }\r
241         }\r
242         if(byte_count != 0){\r
243                 result = __sdio_read((CARD_SDIO_HANDLE)handle,MAX_BLOCK_SIZE,byte_count,0,buffer,RW_BYTE_MODE);\r
244                 if(result == TRUE)\r
245                         read_len += byte_count;\r
246                 else {\r
247                         SDIO_PRINTF(("read byte failed!!\r\n"));                        \r
248                 }\r
249         }\r
250         return read_len;\r
251 }\r
252 \r
253 // public function\r
254 SDIO_HANDLE sdio_open(void)\r
255\r
256     CARD_SDIO_HANDLE sio_handle;\r
257         int slot_num;\r
258         \r
259     MMU_DisableIDCM();\r
260     SDIO_PRINTF(("init slot0 ...\r\n"));\r
261         slot_num = SDIO_APCP_HOST_SLOT_NUM;\r
262        \r
263     sio_handle = __init_slot(slot_num);\r
264     if(NULL == sio_handle){\r
265             SDIO_PRINTF(("slot0 handle is NULL!!\r\n"));\r
266     }\r
267     return (SDIO_HANDLE)sio_handle;\r
268 }\r
269 \r
270 void sdio_close(SDIO_HANDLE handle)\r
271 {\r
272         SPRD_SDSlave_Close((CARD_SDIO_HANDLE)handle);\r
273         return;\r
274 }\r