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
9 ******************************************************************************
\r
11 ** ------------------------------------------------------------------------- *
\r
12 ** DATE NAME DESCRIPTION *
\r
13 ** 25/06/2010 jiayong.yang Create *
\r
14 ******************************************************************************/
\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
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
30 #define SPRD_SDIO_CLK (16000000)
\r
32 #define SDIO_PRINTF(x) printf x
\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
44 typedef enum RW_CASE_SDIO_TAG{
\r
49 extern void Dcache_CleanRegion(unsigned int addr, unsigned int length);
\r
50 /**---------------------------------------------------------------------------*
\r
52 **---------------------------------------------------------------------------*/
\r
54 static int __sdio_write(CARD_SDIO_HANDLE cardHandle,
\r
55 unsigned int block_len,
\r
57 unsigned int start_addr,
\r
61 unsigned int inc_flag = 1; // addr increase
\r
67 if(FALSE == SDIO_WriteBytes(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){
\r
68 SDIO_PRINTF((" writebytes failed!!"));
\r
75 if(FALSE == SDIO_WriteBlocks(cardHandle,SDIO_SLAVE_FUNC_1,start_addr,inc_flag,count,buf)){
\r
76 SDIO_PRINTF(("writeblocks failed!!"));
\r
82 SDIO_PRINTF(("mode-type out of range"));
\r
90 static int __sdio_read(CARD_SDIO_HANDLE cardHandle,
\r
91 unsigned int block_len,
\r
93 unsigned int start_addr,
\r
97 unsigned int inc_flag = 1; // addr increase
\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
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
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
120 SDIO_PRINTF(("test readblocks done!!"));
\r
123 SDIO_PRINTF(("mode-type out of range"));
\r
131 static CARD_SDIO_HANDLE __init_slot(int slotNo)
\r
133 CARD_SDIO_HANDLE cardHandle;
\r
134 int block_size = MAX_BLOCK_SIZE;
\r
137 cardHandle = SPRD_SDSlave_Open(slotNo);
\r
139 if(NULL == cardHandle){
\r
140 SDIO_PRINTF(("slot%d Open Failed!!\r\n", slotNo));
\r
144 // Step2: select slot, this step must be after card open
\r
145 CARD_SDIO_SlotSelect(slotNo);
\r
148 SPRD_SDSlave_PwrCtl(cardHandle,TRUE);
\r
150 //SDHOST_SetClkDiv(slotNo,2);
\r
153 if(FALSE == SPRD_SDSlave_InitCard(cardHandle)){
\r
154 SDIO_PRINTF(("slot%d Init Failed!!\r\n", slotNo));
\r
157 if(FALSE == SDIO_SetBusClock(cardHandle,SPRD_SDIO_CLK)){
\r
158 SDIO_PRINTF(("Set bus clock Failed!!\r\n"));
\r
161 if(FALSE == SDIO_SetBusWidth(cardHandle,SDIO_CARD_PAL_4_BIT)){
\r
162 SDIO_PRINTF(("Set bus width Failed!!\r\n"));
\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
171 if(FALSE == SDIO_SetBlockLength(cardHandle,SDIO_SLAVE_FUNC_1,block_size )){
\r
172 SDIO_PRINTF(("Set func1 blk-len Failed!!\r\n"));
\r
177 __FuncEnable(cardHandle);
\r
181 int sdio_write(SDIO_HANDLE handle,unsigned char *buffer,int size)
\r
183 int block_count = 0;
\r
184 int byte_count = 0;
\r
188 block_count = size/MAX_BLOCK_SIZE;
\r
189 byte_count = size%MAX_BLOCK_SIZE;
\r
191 if(block_count >= MAX_BLOCK_COUNT){
\r
192 SDIO_PRINTF(("too many block!!!\r\n"));
\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
202 SDIO_PRINTF(("write block failed!!\r\n"));
\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
209 write_len += byte_count;
\r
211 SDIO_PRINTF(("write byte failed!!\r\n"));
\r
217 int sdio_read(SDIO_HANDLE handle,unsigned char *buffer,int size)
\r
219 int block_count = 0;
\r
220 int byte_count = 0;
\r
224 block_count = size/MAX_BLOCK_SIZE;
\r
225 byte_count = size%MAX_BLOCK_SIZE;
\r
227 if(block_count >= MAX_BLOCK_COUNT){
\r
228 SDIO_PRINTF(("too many block!!!\r\n"));
\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
238 SDIO_PRINTF(("read block failed!!\r\n"));
\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
245 read_len += byte_count;
\r
247 SDIO_PRINTF(("read byte failed!!\r\n"));
\r
254 SDIO_HANDLE sdio_open(void)
\r
256 CARD_SDIO_HANDLE sio_handle;
\r
260 SDIO_PRINTF(("init slot0 ...\r\n"));
\r
261 slot_num = SDIO_APCP_HOST_SLOT_NUM;
\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
267 return (SDIO_HANDLE)sio_handle;
\r
270 void sdio_close(SDIO_HANDLE handle)
\r
272 SPRD_SDSlave_Close((CARD_SDIO_HANDLE)handle);
\r