tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / yp_mmc / sdio_core.c
1 /*********************************************************************\r
2  ** File Name:          sdio_pal.c\r
3  ** Author:                     yanping.xie\r
4  ** DATE:                       09/05/2013\r
5  ** Copyright:                  2004 Spreadtrum, Incoporated. All Rights Reserved.\r
6  ** Description:                This file describe operation of sdio host.\r
7  *********************************************************************\r
8
9  *********************************************************************\r
10  **                               Edit History                                                                                   **\r
11  ** ------------------------------------------------------------------------- **\r
12  ** DATE                                NAME                            DESCRIPTION\r
13  ** 09/05/2013          ypxie                           Create.\r
14  ********************************************************************/\r
15 #include "sdio_reg.h"\r
16 #include "sdio_phy.h"\r
17 #include "sdio_core.h"\r
18 \r
19 #ifdef SDIO_DEBUG\r
20 #define sdio_printf(x)                  printf(x)\r
21 #endif\r
22 \r
23 typedef struct\r
24 {\r
25         sdio_cmd_e                                              cmd;\r
26         uint32                                                  cmd_index;\r
27         uint32                                                  int_filter;\r
28         uint32                                                  response;\r
29         uint32                                                  err_filter;\r
30         uint32                                                  transmode;\r
31 } cmd_ctl_flg_t;\r
32 \r
33 // response Name                                                cmd int filter                          , rsp                           , cmd error filter\r
34 #define CARD_SDIO_NO_RSP                        NULL    | INT_CMD_CMPLT , SDIO_NO_RSP   , NULL\r
35 #define CARD_SDIO_R1                                    NULL    | INT_CMD_CMPLT , SDIO_R1               , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
36 #define CARD_SDIO_R2                                    NULL    | INT_CMD_CMPLT , SDIO_R2               , INT_TRGT_RESP                                 | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
37 #define CARD_SDIO_R3                                    NULL    | INT_CMD_CMPLT , SDIO_R3               , INT_TRGT_RESP                                 | INT_CMD_END_BIT                                       | INT_CMD_TIMEOUT\r
38 #define CARD_SDIO_R4                                    NULL    | INT_CMD_CMPLT , SDIO_R4               , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
39 #define CARD_SDIO_R5                                    NULL    | INT_CMD_CMPLT , SDIO_R5               , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
40 #define CARD_SDIO_R6                                    NULL    | INT_CMD_CMPLT , SDIO_R6               , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
41 #define CARD_SDIO_R7                                    NULL    | INT_CMD_CMPLT , SDIO_R7               , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
42 #define CARD_SDIO_R1B                           NULL    | INT_CMD_CMPLT , SDIO_R1B              , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
43 //#define CARD_SDIO_R5B                         NULL    | INT_CMD_CMPLT , SDIO_R5B              , INT_TRGT_RESP | INT_CMD_IND   | INT_CMD_END_BIT       | INT_CMD_CRC   | INT_CMD_TIMEOUT\r
44 \r
45 const cmd_ctl_flg_t sdio_cmd_detail[]=\r
46 {\r
47         // cmdindex,rsp,transmode\r
48         //#define CMDname                                               cmdindex        ,data int filter        +       (cmd int filter+)rsp(+cmd error filter) +       ,data error filter                                                                                      , transmode\r
49         { CMD0_GO_IDLE_STATE                                    , 0     , NULL                  | CARD_SDIO_NO_RSP      | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
50         { CMD1_SEND_OP_COND                                     , 1     , NULL                  | CARD_SDIO_R3          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
51         { CMD2_ALL_SEND_CID                                             , 2     , NULL                  | CARD_SDIO_R2          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
52         { CMD3_SET_RELATIVE_ADDR_SD                     , 3     , NULL                  | CARD_SDIO_R6          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
53         { CMD3_SET_RELATIVE_ADDR                                , 3     , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
54         { CMD4_SET_DSR                                                  , 4     , NULL                  | CARD_SDIO_NO_RSP      | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
55 //      { CMD5_SLEEP_AWAKE                                              , 5     , NULL                  | CARD_SDIO_R4                                                                                          , NULL                                                          , CMD_TYPE_NORMAL                                                                                                                               },\r
56         { CMD6_SWITCH                                                   , 6     , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_DIR_READ   | SDIO_TRANS_DMA_EN                     | SDIO_DATA_PRE                 },\r
57         { CMD7_SELECT_CARD_SD                                   , 7     , NULL                  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
58         { CMD7_SELECT_CARD                                              , 7     , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
59         { CMD8_SEND_IF_COND_SD                                  , 8     , NULL                  | CARD_SDIO_R7          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
60         { CMD8_SEND_IF_COND                                             , 8     , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_DIR_READ   | SDIO_TRANS_DMA_EN                     | SDIO_DATA_PRE                 },\r
61         { CMD9_SEND_CSD                                         , 9     , NULL                  | CARD_SDIO_R2          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
62         { CMD10_SEND_CID                                                , 10    , NULL                  | CARD_SDIO_R2          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
63         { CMD11_READ_DAT_UNTIL_STOP                     , 11    , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_DIR_READ                   | SDIO_TRANS_BLK_CNT_EN         | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE                                                 },\r
64         { CMD11_READ_DAT_UNTIL_STOP_AUT12               , 11    , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT      | INT_AUTO_CMD12        , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_DIR_READ                   | SDIO_TRANS_AUTO_CMD12_EN| SDIO_TRANS_BLK_CNT_EN       | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE },\r
65         { CMD12_STOP_TRANSMISSION                               , 12    , INT_TR_CMPLT  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
66         { CMD13_SEND_STATUS                                     , 13    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
67         { CMD15_GO_INACTIVE_STATE                               , 15    , NULL                  | CARD_SDIO_NO_RSP      | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
68         { CMD16_SET_BLOCKLEN                                    , 16    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
69         { CMD17_READ_SINGLE_BLOCK                               , 17    , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_DIR_READ   | SDIO_TRANS_DMA_EN                     | SDIO_DATA_PRE                 },\r
70         { CMD18_READ_MULTIPLE_BLOCK                             , 18    , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_DIR_READ                   | SDIO_TRANS_BLK_CNT_EN         | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE                                                 },\r
71         { CMD18_READ_MULTIPLE_BLOCK_AUT12               , 18    , INT_TR_CMPLT  | CARD_SDIO_R1          | INT_DATA_END_BIT      | INT_DATA_CRC  | INT_DATA_TIMEOUT      | INT_AUTO_CMD12        , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_DIR_READ                   | SDIO_TRANS_AUTO_CMD12_EN| SDIO_TRANS_BLK_CNT_EN       | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE },\r
72         { CMD20_WRITE_DAT_UNTIL_STOP                    , 20    , INT_TR_CMPLT  | CARD_SDIO_R1                                                  | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_BLK_CNT_EN                 | SDIO_TRANS_DMA_EN             | SDIO_DATA_PRE                                                                                                 },\r
73         { CMD20_WRITE_DAT_UNTIL_STOP_AUT12      , 20    , INT_TR_CMPLT  | CARD_SDIO_R1                                                  | INT_DATA_CRC  | INT_DATA_TIMEOUT      | INT_AUTO_CMD12        , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_AUTO_CMD12_EN      | SDIO_TRANS_BLK_CNT_EN         | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE                                                 },\r
74         { CMD23_SET_BLOCK_COUNT                         , 23    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
75         { CMD24_WRITE_BLOCK                                     , 24    , INT_TR_CMPLT  | CARD_SDIO_R1                                                  | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_DMA_EN             | SDIO_DATA_PRE                                                                                 },\r
76         { CMD25_WRITE_MULTIPLE_BLOCK                    , 25    , INT_TR_CMPLT  | CARD_SDIO_R1                                                  | INT_DATA_CRC  | INT_DATA_TIMEOUT                                              , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_BLK_CNT_EN                 | SDIO_TRANS_DMA_EN             | SDIO_DATA_PRE                                                                                                 },\r
77         { CMD25_WRITE_MULTIPLE_BLOCK_AUT12              , 25    , INT_TR_CMPLT  | CARD_SDIO_R1                                                  | INT_DATA_CRC  | INT_DATA_TIMEOUT      | INT_AUTO_CMD12        , SDIO_TRANS_MULTIBLK   | SDIO_TRANS_AUTO_CMD12_EN      | SDIO_TRANS_BLK_CNT_EN         | SDIO_TRANS_DMA_EN     | SDIO_DATA_PRE                                                 },\r
78         { CMD26_PROGRAM_CID                                     , 26    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
79         { CMD27_PROGRAM_CSD                                     , 27    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
80         { CMD28_SET_WRITE_PROT                                  , 28    , INT_TR_CMPLT  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
81         { CMD29_CLR_WRITE_PROT                                  , 29    , INT_TR_CMPLT  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
82         { CMD30_SEND_WRITE_PROT                         , 30    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
83         { CMD32_ERASE_WR_BLK_START                      , 32    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
84         { CMD33_ERASE_WR_BLK_END                                , 33    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
85         { CMD35_ERASE_GROUP_START                               , 35    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
86         { CMD36_ERASE_GROUP_END                         , 36    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
87         { CMD38_ERASE                                                   , 38    , INT_CMD_CMPLT         | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
88         { CMD39_FAST_IO                                                 , 39    , NULL                  | CARD_SDIO_R4          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
89         { CMD40_GO_IRQ_STATE                                    , 40    , NULL                  | CARD_SDIO_R5          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
90         { CMD42_LOCK_UNLOCK_SD                                  , 42    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
91         { CMD42_LOCK_UNLOCK_MMC                         , 42    , NULL                  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
92         { CMD55_APP_CMD                                         , 55    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
93         { CMD56_GEN_CMD_SD                                      , 56    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
94         { CMD56_GEN_CMD_MMC                                     , 56    , NULL                  | CARD_SDIO_R1B         | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
95         { ACMD6_SET_BUS_WIDTH                                   , 6     , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
96         { ACMD13_SD_STATUS                                              , 13    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
97         { ACMD22_SEND_NUM_WR_BLCOKS                     , 22    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
98         { ACMD23_SET_WR_BLK_ERASE_COUNT         , 23    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
99         { ACMD41_SD_SEND_OP_COND                                , 41    , NULL                  | CARD_SDIO_R3          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
100         { ACMD42_SET_CLR_CARD_DETECT                    , 42    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
101         { ACMD51_SEND_SCR                                               , 51    , NULL                  | CARD_SDIO_R1          | NULL                                                                                                                                          , NULL                                                                                                                                                  },\r
102 \r
103         { CMD_MAX                                                               , 0     , NULL                  | CARD_SDIO_NO_RSP      | NULL                                                                                                                                          , NULL                                                                                                                                                  }\r
104 };\r
105 \r
106 /* every sdio controller have one s_sdio_pal_hd table */\r
107 /* slot0,1,2 is sdio0; slot3,4,5 is sdio1; slot6,7,8 is sdio2; slot9,10,11 is sdio3; */\r
108 sdio_pal_t pal_hd[SLOT_MAX_NUM] = {0,0,0, 0,0,0, 0,0,0, 0,0,0};\r
109 \r
110 /*********************************************************************
111 **      Description :
112 **              This function used to init card event.\r
113 **      Param :
114 **              p_hd                    : sdio pal handle.\r
115 **      Return :\r
116 **              none
117 **      Date                                    Author                          Operation
118 **      2013/09/12                      ypxie                           create\r
119 *********************************************************************/\r
120 void init_card_event (sdio_pal_ptr p_hd)\r
121 {\r
122         p_hd->card_event = 0;\r
123 } /* end of card_event_init */\r
124 \r
125 uint32 wait_card_event (sdio_pal_ptr p_hd, uint32 event_id)\r
126 {\r
127         if (event_id == (p_hd->card_event & event_id)) {\r
128                 return 0;\r
129         }\r
130         else {\r
131                 return 1;\r
132         }\r
133 }\r
134 \r
135 void set_card_event (sdio_pal_ptr p_hd, uint32 event_id)\r
136 {\r
137         p_hd->card_event |= event_id;\r
138 }\r
139 \r
140 /*********************************************************************
141 **      Description :
142 **              This function used to controller irq process function.\r
143 **      Param :
144 **              msg                             : int status information.\r
145 **              slot_no                 : slot no.\r
146 **      Return :\r
147 **              none
148 **      Date                                    Author                          Operation
149 **      2013/09/12                      ypxie                           create\r
150 *********************************************************************/\r
151 void  irq_handle (uint32 isr_num)\r
152 {\r
153         uint32 msg;\r
154         sdio_pal_ptr p_hd;\r
155 \r
156         if(isr_num == SLOT_MAX_NUM){\r
157                 return ISR_DONE;\r
158         }\r
159         p_hd = &pal_hd[(isr_num/3)];\r
160 \r
161         msg = sdhost_get_int_st(p_hd->host_cfg);\r
162 \r
163         sdhost_int_st_sig_dis(p_hd->host_cfg, msg);\r
164         sdhost_int_st_clr(p_hd->host_cfg, msg);\r
165 \r
166         if (0 != (msg & INT_TR_CMPLT)) {\r
167                 msg &= ~INT_DATA_TIMEOUT;\r
168                 set_card_event(p_hd, msg);\r
169         }\r
170         else if (0 != (msg & INT_DMA_INT)) {\r
171                 volatile uint32 next_addr;\r
172 \r
173                 next_addr = sdhost_get_dma_addr(p_hd->host_cfg);\r
174                 sdhost_set_dma_addr(p_hd->host_cfg, next_addr);\r
175 \r
176                 sdhost_int_st_sig_en(p_hd->host_cfg, INT_DMA_INT);\r
177         }\r
178         else {\r
179                 if (0 != (msg & INT_CMD_CMPLT)) {\r
180                         msg &= ~INT_CMD_TIMEOUT;\r
181                 }\r
182                 set_card_event(p_hd, msg);\r
183         }\r
184 } /* end of irq_card_proc */\r
185 \r
186 sdio_pal_err_e get_cmd_err_info(uint32 card_event)\r
187 {\r
188         uint32 err_st;\r
189 \r
190         err_st = ERR_NONE;\r
191         if (INT_ERR_INT & card_event) {\r
192                 err_st &= (card_event & 0x1FFF0000) >> 15;\r
193         }\r
194         return err_st;\r
195 }\r
196 \r
197 /*********************************************************************\r
198 **      Description :
199 **              This function used to register sdio.\r
200 **      Param :
201 **              slot_no                 : slot no.\r
202 **              base_clk                        : base clock must be set val in table.\r
203 **      Return :\r
204 **              p_hd                    : return sdio pal handle\r
205 **      Date                                    Author                          Operation
206 **      2013/09/12                      ypxie                           create\r
207 *********************************************************************/\r
208 sdio_pal_ptr sdio_pal_open (uint32 slot_no, uint32 base_clk)\r
209 {\r
210         if (slot_no >= SLOT_MAX_NUM) {\r
211                 return 0;\r
212         }\r
213 \r
214         /* step 1: init members */\r
215         pal_hd[slot_no].slot_no = slot_no;\r
216         pal_hd[slot_no].sdio_type = (sdio_type_e)(slot_no/3);\r
217         pal_hd[slot_no].sdio_version = sdhost_get_sdio_version(slot_no);\r
218         pal_hd[slot_no].card_event = 0;\r
219 \r
220         /* step 2: get base address */\r
221         pal_hd[slot_no].host_cfg = sdhost_get_base_addr(slot_no);\r
222         if (pal_hd[slot_no].host_cfg == 0) {\r
223                 return 0;\r
224         }\r
225 \r
226         /* step 3: select slot */\r
227         sdhost_slot_select(slot_no);\r
228 \r
229         /* step 4: enable sdio ahb clock */\r
230         sdhost_ahb_sdio_en(slot_no);\r
231 \r
232         /* step 5: disable sd clock for delete glitch in clock line. */\r
233         sdhost_set_sd_clk(pal_hd[slot_no].host_cfg, SDIO_OFF);\r
234 \r
235         /* step 6: ahb soft reset. */\r
236         sdhost_ahb_sdio_rst(slot_no);\r
237 \r
238         /* step 7: set base clock */\r
239         pal_hd[slot_no].base_clock = sdhost_set_base_clk(slot_no, base_clk);\r
240         if (pal_hd[slot_no].base_clock == 0) {\r
241                 return 0;\r
242         }\r
243 \r
244         return &pal_hd[slot_no];\r
245 } /* end of sdio_pal_open */\r
246 \r
247 /*********************************************************************
248 **      Description :
249 **              This function used to set power and clock, and set initialize freq, bus width.\r
250 **      Param :
251 **              p_hd                    : sdio pal handle.\r
252 **              onoff                   : power on or off\r
253 **      Return :\r
254 **              none
255 **      Date                                    Author                          Operation
256 **      2013/09/22                      ypxie                           create\r
257 **      2013/10/08                      ypxie                           alter return and added check handle.\r
258 *********************************************************************/\r
259 BOOLEAN sdio_pal_power (sdio_pal_ptr p_hd, sdio_onoff_e onoff)\r
260 {\r
261         if (p_hd == NULL){\r
262                 return FALSE;\r
263         }\r
264 \r
265         switch (onoff) {\r
266         case SDIO_ON:\r
267                 /* reset controller */\r
268                 sdhost_reset(p_hd->host_cfg, RST_ALL);\r
269 \r
270                 /* set power for sdio controller. */\r
271                 sdhost_set_voltage(p_hd->slot_no, 1800, 3000);\r
272                 sdhost_set_power(p_hd->slot_no, SDIO_ON);\r
273 \r
274                 /* set base bus width and speed */\r
275                 if (p_hd->sdio_version == SDIO_20) {\r
276                         sdhost_set_speed_mode_v20(p_hd->host_cfg, SDIO_LOWSPEED);\r
277                         sdhost_set_clk_freq_v20(p_hd->host_cfg, p_hd->base_clock, 400000);\r
278                         sdhost_set_bus_width_v20(p_hd->host_cfg, SDIO_BUS_1_BIT);\r
279                 }\r
280                 else if (p_hd->sdio_version == SDIO_30) {\r
281                         sdhost_set_speed_mode_v30(p_hd->host_cfg, SDIO_SDR13);\r
282                         sdhost_set_clk_freq_v30(p_hd->host_cfg, p_hd->base_clock, 400000);\r
283                         sdhost_set_bus_width_v30(p_hd->host_cfg, SDIO_BUS_1_BIT);\r
284                 }\r
285 \r
286                 /* open clock in sdio controller. */\r
287                 sdhost_set_internal_clk(p_hd->host_cfg, SDIO_ON);\r
288                 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_ON);\r
289                 break;\r
290 \r
291         case SDIO_OFF:\r
292                 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_OFF);\r
293                 sdhost_reset(p_hd->host_cfg, RST_ALL);\r
294                 sdhost_set_power(p_hd->slot_no, SDIO_OFF);\r
295                 break;\r
296 \r
297         default :\r
298                 return FALSE;\r
299                 break;\r
300         }\r
301 \r
302         return TRUE;\r
303 } /* end of sdio_pal_power */\r
304 \r
305 /*********************************************************************
306 **      Description :
307 **              This function used to set clock.\r
308 **      Param :
309 **              p_hd                    : sdio pal handle.\r
310 **              clk                             :       SDIO_CLK_400K,\r
311 **                                                      SDIO_CLK_13M,\r
312 **                                                      SDIO_CLK_26M,\r
313 **                                                      SDIO_CLK_52M,\r
314 **                                                      SDIO_CLK_104M,\r
315 **                                                      SDIO_CLK_200M,\r
316 **      Return :\r
317 **              none
318 **      Date                                    Author                          Operation
319 **      2013/09/22                      ypxie                           create\r
320 **      2013/10/08                      ypxie                           alter return and added check handle.\r
321 *********************************************************************/\r
322 BOOLEAN sdio_set_clk (sdio_pal_ptr p_hd, uint32 clk)\r
323 {
324         if (p_hd == NULL){\r
325                 return FALSE;\r
326         }\r
327 \r
328         sdhost_set_sd_clk(p_hd->host_cfg, SDIO_OFF);\r
329 \r
330         if (p_hd->sdio_version == SDIO_30) {\r
331                 p_hd->sd_clock = sdhost_set_clk_freq_v30(p_hd->host_cfg, p_hd->base_clock, clk);\r
332         }\r
333         else if (p_hd->sdio_version == SDIO_20) {\r
334                 p_hd->sd_clock = sdhost_set_clk_freq_v20(p_hd->host_cfg, p_hd->base_clock, clk);\r
335         }\r
336         else {\r
337                 return FALSE;\r
338         }\r
339         \r
340         sdhost_set_internal_clk(p_hd->host_cfg, SDIO_ON);\r
341         sdhost_set_sd_clk(p_hd->host_cfg, SDIO_ON);\r
342 \r
343         return TRUE;\r
344 } /* end of sdio_set_clk */\r
345 \r
346 /*********************************************************************
347 **      Description :
348 **              This function used to set bus width.\r
349 **      Param :
350 **              p_hd                    : sdio pal handle.\r
351 **              bus_type                        :       SDIO_BUS_1_BIT,\r
352 **                                                      SDIO_BUS_4_BIT,\r
353 **                                                      SDIO_BUS_8_BIT,\r
354 **      Return :\r
355 **              none
356 **      Date                                    Author                          Operation
357 **      2013/09/23                      ypxie                           create\r
358 **      2013/10/08                      ypxie                           alter return and added check handle.\r
359 *********************************************************************/\r
360 BOOLEAN sdio_set_bus_width (sdio_pal_ptr p_hd, sdio_buswidth_e bus_type)\r
361 {\r
362         if ((p_hd == NULL) || (bus_type > SDIO_BUS_8_BIT)) {\r
363                 return FALSE;\r
364         }\r
365 \r
366         if (p_hd->sdio_version == SDIO_30) {\r
367                 sdhost_set_bus_width_v30(p_hd->host_cfg, bus_type);\r
368                 p_hd->bus_width = bus_type;\r
369         }\r
370         else if (p_hd->sdio_version == SDIO_20) {\r
371                 sdhost_set_bus_width_v20(p_hd->host_cfg, bus_type);\r
372                 p_hd->bus_width = bus_type;\r
373         }\r
374         else {\r
375                 return FALSE;\r
376         }\r
377 \r
378         return TRUE;\r
379 }\r
380 \r
381 /*********************************************************************
382 **      Description :
383 **              This function used to set speed mode.\r
384 **      Param :
385 **              p_hd                    : sdio pal handle.\r
386 **              onoff                   :       SDIO_LOWSPEED,\r
387 **                                                      SDIO_HIGHSPEED,\r
388 **                                                      SDIO_SDR13,\r
389 **                                                      SDIO_SDR26,\r
390 **                                                      SDIO_SDR52,\r
391 **                                                      SDIO_SDR104,\r
392 **                                                      SDIO_DDR52,\r
393 **                                                      SDIO_HS200\r
394 **      Return :\r
395 **              none
396 **      Date                                    Author                          Operation
397 **      2013/09/23                      ypxie                           create\r
398 **      2013/10/08                      ypxie                           alter return and added check handle.\r
399 *********************************************************************/\r
400 BOOLEAN sdio_set_speed_mode (sdio_pal_ptr p_hd, sdio_speedmode_e spd_type)\r
401 {\r
402         if ((p_hd == NULL) || (spd_type > SDIO_HS200)) {\r
403                 return FALSE;\r
404         }\r
405 \r
406         if (p_hd->sdio_version == SDIO_30) {\r
407                 sdhost_set_speed_mode_v30(p_hd->host_cfg, spd_type);\r
408                 p_hd->spd_mode = spd_type;\r
409         }\r
410         else if (p_hd->sdio_version == SDIO_20) {\r
411                 sdhost_set_speed_mode_v20(p_hd->host_cfg, spd_type);\r
412                 p_hd->spd_mode = spd_type;\r
413         }\r
414         else {\r
415                 return FALSE;\r
416         }\r
417 \r
418         return TRUE;\r
419 }
420 \r
421 /*********************************************************************
422 **      Description :
423 **              This function used to send command to card\r
424 **      Param :
425 **              p_hd                    : sdio pal handle.\r
426 **              cmd                             : command index.\r
427 **              argu                            : argument of card.\r
428 **              data_param              : data information.\r
429 **              rsp_buf                 : used to store response data.\r
430 **      Return :\r
431 **              none
432 **      Date                                    Author                          Operation
433 **      2013/10/08                      ypxie                           create\r
434 *********************************************************************/\r
435 PUBLIC sdio_pal_err_e sdio_send_cmd (sdio_pal_ptr p_hd,\r
436                                                                 sdio_cmd_e cmd,\r
437                                                                 uint32 argu,\r
438                                                                 sdio_data_param_t *data_param,\r
439                                                                 uint8 *rsp_buf )\r
440 {\r
441         uint32 tmp_msg, ret_val;\r
442         int time_out = 0;\r
443         const cmd_ctl_flg_t* cmd_info = NULL;\r
444 \r
445         cmd_info = &s_cmdDetail[cmd];\r
446 \r
447         if ((cmd != cmd_info->cmd) || (p_hd == NULL)) {\r
448                 return ERR_BAD_PARAM;\r
449         }\r
450 \r
451         sdio_printf("%s : cmd:%x, cmdIndex:%x, argument:%x\r\n", __FUNCTION__,\r
452                                         cmd, cmd_info->cmd_index, argu);\r
453 \r
454         sdhost_int_st_clr(p_hd->host_cfg, INT_ALL);\r
455         sdhost_int_st_sig_dis(p_hd->host_cfg, INT_ALL);\r
456 \r
457         sdhost_set_data_timeout_value(p_hd->host_cfg, 0x0E);\r
458 \r
459         tmp_msg = cmd_info->int_filter;\r
460         if (NULL != cmd_info->err_filter) {\r
461                 tmp_msg |= cmd_info->err_filter;\r
462         }\r
463 \r
464         if (NULL != data_param) {\r
465                 tmp_msg |= INT_DMA_INT;\r
466         }\r
467 \r
468         sdhost_int_st_sig_en(p_hd->host_cfg, tmp_msg);\r
469 \r
470         init_card_event(p_hd);\r
471 \r
472         if (NULL != data_param) {\r
473                 uint32 buf_size = 0;\r
474 \r
475                 buf_size = data_param->blk_len  *  (data_param->blk_num);\r
476 \r
477                 /* enable mmu, must be update cache */\r
478                 Dcache_CleanRegion((unsigned int)(data_param->data_buf), buf_size);\r
479                 Dcache_InvalRegion((unsigned int)(data_param->data_buf), buf_size);\r
480 \r
481                 sdhost_set_dma_addr(p_hd->host_cfg, (uint32)(data_param->data_buf));\r
482                 sdhost_set_data_param(p_hd->host_cfg, data_param->blk_len,\r
483                                                         data_param->blk_num, SDIO_DMA_512K);\r
484         }\r
485 \r
486         sdhost_set_cmd_argu(p_hd->host_cfg, argu);\r
487         sdhost_set_cmd(p_hd->host_cfg, cmd_info->cmd_index, cmd_info->transmode,\r
488                                                         SDIO_CMD_TYPE_NML, cmd_info->response);\r
489 \r
490         while (0 != wait_card_event(p_hd, cmd_info->int_filter)) {\r
491                 irq_handle(p_hd->slot_no);\r
492 \r
493                 sdhost_delayus(100);\r
494                 time_out++;\r
495                 if (time_out > 100000) {\r
496                         break;\r
497                 }\r
498         }\r
499 \r
500         sdhost_reset (p_hd->host_cfg, RST_CMD_DAT_LINE);\r
501 \r
502         if (0 != (p_hd->card_event & INT_DATA_TIMEOUT))\r
503         {\r
504                 if ( CMD38_ERASE == cmd)\r
505                 {\r
506                         sdio_printf ("sdio may be erase R1b is too long");\r
507                         time_out = SCI_GetTickCount();\r
508 \r
509                         /* BIT_20 is data[0]'s pin status */\r
510                         while(0 == (BIT_20 & sdhost_get_pin_state(p_hd->host_cfg))) {\r
511                                 sdhost_delayus (1000);\r
512                                 if ((time_out + 20000) < SCI_GetTickCount()) {\r
513                                         sdhost_reset(p_hd->host_cfg, RST_CMD_DAT_LINE);\r
514                                         return ERR_DATA_TIMEOUT;\r
515                                 }\r
516                         }\r
517 \r
518                         p_hd->card_event &= ~INT_DATA_TIMEOUT;\r
519                 }\r
520                 else\r
521                 {\r
522                         sdio_printf ("SDIO_Card error = 0x%x", p_hd->card_event);\r
523                         return p_hd->card_event;\r
524                 }\r
525         }\r
526 \r
527         sdhost_get_response(p_hd->host_cfg, cmd_info->response, rsp_buf);\r
528 \r
529         sdio_printf(("resp[0-4]:%02X, %02X, %02X, %02X\r\n",\r
530                                 rsp_buf[0], rsp_buf[1], rsp_buf[2], rsp_buf[3]));\r
531         return get_cmd_err_info(p_hd->card_event);\r
532 } /* end of sdio_send_cmd */