blob: 03b4acc09df306f976ae934cd2cf5b233a8b39ee [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
3*
4* ÎļþÃû³Æ£º sdio.c
5* ÄÚÈÝÕªÒª£º
6* ÆäËü˵Ã÷£º
7* µ±Ç°°æ±¾£º 1.0
8* ×÷¡¡¡¡Õߣºcaidaofang
9* Íê³ÉÈÕÆÚ£º
10*
11*
12*******************************************************************************/
13#include <common.h>
14#include <linux/byteorder/generic.h>
15#include <asm/io.h>
16#include <sdio.h>
17#include <image.h>
18
19
20#define SYS_STD_CRM_BASE 0x1307000
21#define DMA_BUFFER_SIZE_16K (0x2<<1)
22
23#define DMA_BUFFER_SIZE_32K (0x3<<1)
24#define DMA_BUFFER_SIZE_64K (0x4<<1)
25
26#define DMA_BUFFER_SIZE_256K (0x6<<1)
27#define DMA_BUFFER_SIZE_512K (0x7<<1)
28#define SDIO_ERR -1
29#define SDIO_INPROGRESS -2
30
31uint32_t uboot_entry_point = 0;
32
33static void sdio_clk_reset(void)
34{
35// enable sdio clk 16,17 hclk
36 REG32(SYS_STD_CRM_BASE+0x44) |= (0x3<<16);
37 usdelay(80);
38// release reset sdio clk 16 ahb clk
39 REG32(SYS_STD_CRM_BASE+0x48) |= (0x1<<16);
40 usdelay(80);
41}
42
43/*²ÉÓÃCPU¶ÁÈ¡FIFO£¬½ûÖ¹ÖжÏ*/
44static void sdio_initial_setup(void)
45{
46 u32 val = 0;
47 REG32(SDIO_SLAVE_IOREADY) |= 0x3e;//ÅäÖÃ1-5bit
48
49 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0; //mask sdio int
50 REG32(SDIO_SLAVE_INTSTATUS) = 0xffffffff;//clear int
51
52 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff; //enable status int
53
54 //REG32(SDIO_SLAVE_INTSTATUS_EN) = 0x33C0181B; //enable status int
55 REG32(SDIO_SLAVE_INTSIGNAL_EN) = 0; //maskedÖжÏÐźÅ1£¬²»Éϱ¨¸øÖжϿØÖÆÆ÷
56 REG32(SDIO_SLAVE_INT_SIGNAL_EN2) = 0; //maskedÖжÏÐźÅ2£¬²»Éϱ¨¸øÖжϿØÖÆÆ÷
57 val = REG32(SDIO_SLAVE_SDIO_CCCR_CTRL);
58 REG32(SDIO_SLAVE_SDIO_CCCR_CTRL) = val;//0x3FF3E343;
59
60 REG32(0x1307080)= 0x7ffe0;
61
62 memset((u8*)0x20000000,0,1024*180);
63
64 val = REG32(SDIO_SLAVE_CARD_OCR);
65
66 REG32(SDIO_SLAVE_CARD_OCR) = val|0x01000000;
67
68/*dma*/
69 /*dma1 address register config*/
70 // REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE; //set dma address
71 /*adma/dma1 address register and buffer size is 0:not valid 1:valid,buffer size is 4K(default)*/
72 // REG32(SDIO_SLAVE_DMA1CTRL) |=0x1|DMA_BUFFER_SIZE_256K; //enable dma address
73 /*disable adma£¬enable dma ,sel one*/
74 REG32(SDIO_SLAVE_CTRL2) &=(~0x4);
75
76/*sdio slave config ready operate*/
77 REG32(SDIO_SLAVE_CTRL) |=0x4; //ÅäÖõÚ2bit£¬±íʾ׼±¸²Ù×÷
78
79
80
81}
82
83int Sdio_Slave_Read_4K(const u32 load_addr,u32 len)
84{
85 u32 status =0 ;
86 int ret = 0;
87
88 u32 dma_addr = (u32)CFG_SDIO_LOAD_BASE;
89
90 REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE; //CFG_SDIO_LOAD_BASE;
91 REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1; //|DMA_BUFFER_SIZE_512K; //256K
92
93 while(1)
94 {
95 status = REG32(SDIO_SLAVE_INTSTATUS);
96
97 if((status &SDIO_STS_DMA1)!=0)
98 {
99
100 dma_addr += 0x1000;
101 /*1,mask*/
102 REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_DMA1);
103 /*2,clear*/
104
105 REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_DMA1;
106 /*3,enalbe*/
107 REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_DMA1;
108
109 REG32(SDIO_SLAVE_DMA1ADDR) = dma_addr ;//CFG_SDIO_LOAD_BASE;
110 REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1;
111
112 }
113
114
115 if((status &SDIO_STS_TC)!=0)
116 {
117 // printf("SDIO xfer OK!\n");
118 break;
119 }
120
121 if((status &SDIO_STS_F_CRC_E)!=0)
122 {
123 printf("SDIO CRC Error!\n");
124
125 /*1,mask*/
126 REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_CRC_E);
127 /*2,clear*/
128 REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_CRC_E;
129 /*3,enalbe*/
130 REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_CRC_E;
131
132 ret = SDIO_ERR;
133 }
134
135 if((status &SDIO_STS_F_A)!=0)
136 {
137
138 /*1,mask*/
139 REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_A);
140 /*2,clear*/
141 //status = REG32(SDIO_SLAVE_INTSTATUS);
142 REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_A;
143 /*3,enalbe*/
144 REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_A;
145
146
147 printf("SDIO ABORT Xfer!\n");
148
149 }
150
151
152 }
153/*thansfer complete,write program done*/
154 REG32(SDIO_SLAVE_CTRL) |= 0x1;
155/*clear int status*/
156 /*1,mask*/
157 // REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~(SDIO_STS_TC|SDIO_STS_WS|SDIO_STS_DMA1|SDIO_STS_F_A|SDIO_STS_F_CRC_E));
158
159 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0;
160 /*2,clear*/
161 status = REG32(SDIO_SLAVE_INTSTATUS);
162 REG32(SDIO_SLAVE_INTSTATUS) = status;
163 /*3,enalbe*/
164 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff;
165
166 /*thansfer complete,write program done*/
167 // REG32(SDIO_SLAVE_CTRL) |= 0x1;
168
169 // REG32(SDIO_SLAVE_INTSTATUS_EN) = 0x33C0181B; //enable status int;
170 memcpy(load_addr,(u32)CFG_SDIO_LOAD_BASE,len);
171
172
173 return ret;
174}
175
176
177int Sdio_Slave_Write_Ack(void)
178{
179
180
181 u32 status = 0;
182 int ret = 0;
183
184 //u32 ack[2] = {0x11223344,0xAABBCCDD};
185 char *ack = "rxok";
186
187 memcpy((u32)CFG_SDIO_LOAD_BASE,ack,4);
188
189 printf("SDIO write ack\n");
190
191 REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE;
192 REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1;
193
194 while(1)
195 {
196 status = REG32(SDIO_SLAVE_INTSTATUS);
197
198
199 if((status &SDIO_STS_TC)!=0)
200 {
201 // printf("SDIO xfer OK!\n");
202 break;
203 }
204
205 if((status &SDIO_STS_F_CRC_E)!=0)
206 {
207 printf("SDIO CRC Error!\n");
208
209 /*1,mask*/
210 REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_CRC_E);
211 /*2,clear*/
212 REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_CRC_E;
213 /*3,enalbe*/
214 REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_CRC_E;
215
216 ret = SDIO_ERR;
217 }
218
219 if((status &SDIO_STS_F_A)!=0)
220 {
221
222 /*1,mask*/
223 REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_A);
224 /*2,clear*/
225 //status = REG32(SDIO_SLAVE_INTSTATUS);
226 REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_A;
227 /*3,enalbe*/
228 REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_A;
229
230
231 printf("SDIO ABORT Xfer!\n");
232
233 }
234
235
236 }
237/*thansfer complete,write program done*/
238 // REG32(SDIO_SLAVE_CTRL) |= 0x1;
239/*clear int status*/
240 /*1,mask*/
241
242 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0;
243 /*2,clear*/
244 status = REG32(SDIO_SLAVE_INTSTATUS);
245 REG32(SDIO_SLAVE_INTSTATUS) = status;
246 /*3,enalbe*/
247 REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff;
248
249 return ret;
250
251}
252
253
254static int sdio_slave_init(void)
255{
256
257 // SDIOÉèÖÃCPRMÄ£¿éµÄ´úÂë
258 //sdio_clk_reset();
259
260 // Initialize controller
261 sdio_initial_setup();
262
263
264
265}
266
267static int slave_size = 0;
268
269/************** success :return boot size ***********/
270int sdio_slave_read(const u32 load_addr)
271{
272 u32 dwInt_status = 0;
273 u32 dwCurrent_Cmd = 0;
274 u32 cmdreg =0;
275 u32 argreg = 0;
276 u32 cmd = 0;
277 u32 blksize = 0;
278 u32 blkcnt = 0;
279 u32 boot_size = 0;
280
281 int ret = SDIO_INPROGRESS;
282
283 while(1)
284 {
285 // dwCurrent_CmdΪ53ʱ£¬½øÐÐÊý¾Ýдor¶Á²Ù×÷
286
287 dwCurrent_Cmd = ((REG32(SDIO_SLAVE_CMD)>>13) & 0x3F);
288
289 switch(dwCurrent_Cmd)
290 {
291 case SDIO_CMD53:
292 {
293
294 dwInt_status = REG32(SDIO_SLAVE_INTSTATUS);
295
296
297 if((dwInt_status & SDIO_STS_WS) == SDIO_STS_WS)
298 {
299 cmdreg = REG32(SDIO_SLAVE_CMD);
300 argreg = REG32(SDIO_SLAVE_ARGU);
301
302 blksize = (cmdreg >>1) &0xFFF;
303
304 blkcnt = argreg & 0x1FF;
305
306 if(!(argreg & 0x08000000))
307 {
308
309 boot_size =blksize;
310 }
311 else
312 {
313 boot_size =blkcnt * blksize;
314 }
315
316 slave_size = boot_size;
317
318
319 ret = Sdio_Slave_Read_4K(load_addr,boot_size);
320
321 if(!ret)
322 return boot_size;
323 else if(ret == SDIO_ERR)
324 return SDIO_ERR;
325
326 }
327
328 break;
329 }
330 default:
331 break;
332 }
333
334 }
335
336 return boot_size;
337}
338
339int sdio_slave_write(void)
340{
341
342
343 u32 dwInt_status = 0;
344 u32 dwCurrent_Cmd = 0;
345 u32 cmdreg =0;
346 u32 argreg = 0;
347 u32 cmd = 0;
348 u32 blksize = 0;
349 u32 blkcnt = 0;
350 u32 boot_size = 0;
351
352 int ret = SDIO_INPROGRESS;
353
354 printf("SDIO slave write \n");
355
356 REG32(SDIO_SLAVE_FUN1CTRL) |= (0x4 & 0xFFFF);
357
358 while(1)
359 {
360 dwCurrent_Cmd = ((REG32(SDIO_SLAVE_CMD)>>13) & 0x3F);
361
362 switch(dwCurrent_Cmd)
363 {
364 case SDIO_CMD53:
365 {
366
367 dwInt_status = REG32(SDIO_SLAVE_INTSTATUS);
368
369
370 if((dwInt_status & SDIO_STS_RS) == SDIO_STS_RS)
371 {
372 cmdreg = REG32(SDIO_SLAVE_CMD);
373 argreg = REG32(SDIO_SLAVE_ARGU);
374
375 blksize = (cmdreg >>1) &0xFFF;
376
377 blkcnt = argreg & 0x1FF;
378
379 if(!(argreg & 0x08000000))
380 {
381
382 boot_size =blksize;
383 }
384 else
385 {
386 boot_size =blkcnt * blksize;
387 }
388
389
390 ret = Sdio_Slave_Write_Ack();
391
392 if(!ret)
393 return boot_size;
394 else if(ret == SDIO_ERR)
395 return SDIO_ERR;
396
397 }
398
399 break;
400 }
401 default:
402 break;
403 }
404
405
406 }
407
408 return boot_size;
409
410}
411
412
413/*******************************************************************************
414 * Function:
415 * Description:
416 * Parameters:
417 * Input:
418 *
419 * Output:
420 *
421 * Returns:
422 *
423 *
424 * Others:
425 ********************************************************************************/
426int sdio_slave_read_bin()
427{
428 int32_t len = 0;
429 uint32_t i =0;
430
431 /*1.µÚÒ»´Î½ÓÊÕ */
432 len = sdio_slave_read((u32)CFG_TEMP_ADDR);
433 if( len < 0 )
434 {
435 printf("sdio_slave: read first error\n");
436 goto sdio_error1;
437 }
438
439 /*2.»ñÈ¡°æ±¾ÐÅÏ¢ */
440 image_header_t *header = NULL;
441 header = (image_header_t *)CFG_TEMP_ADDR;
442 uint32_t header_size = sizeof(image_header_t);
443 uint32_t size = ___htonl(header->ih_size);
444 uint32_t load_addr = ___htonl(header->ih_load);
445 uboot_entry_point = ___htonl(header->ih_ep);
446
447 /*3.¿½±´µÚÒ»´ÎÊý¾Ý */
448 memcpy(load_addr, CFG_TEMP_ADDR+sizeof(image_header_t), len);
449 load_addr = load_addr + len - header_size;
450
451 /*4.¼ÆËã´«Êä´ÎÊý */
452 /* Èç¹ûµÚÒ»´Î´«ÊäµÄ×Ö½Ú´óÓÚ»òµÈÓÚ°æ±¾µÄ´óС£¬Ôò´«ÊäÍê³ÉÖ±½Ó·µ»Ø */
453 if( (len > size) || (len == size) )
454 {
455 printf("sdio_slave: first finsh and return\n");
456 return 0;
457 }
458
459 uint32_t left_times = size/CFG_SDIO_SLAVE_PACKAGE_LEN;
460 uint32_t mod = size%CFG_SDIO_SLAVE_PACKAGE_LEN;
461 if( mod == 0 )
462 {
463 left_times--;
464 }
465
466
467 /* debug */
468 printf("sdio_slave: display the transfer times\n");
469 for( i=0; i<left_times+1; i++ )
470 printf(" + ");
471 printf("\n");
472
473 /*5.½ÓÊÕÆäÓàµÄÊý¾Ý */
474 for( i=0; i<left_times; i++ )
475 {
476 len = sdio_slave_read(load_addr);
477 if( len < 0 )
478 {
479 printf("sdio_slave: read others error\n");
480 goto sdio_error1;
481 }
482 load_addr += len;
483 }
484
485 return 0;
486 sdio_error1:
487 return -1;
488}
489
490/*******************************************************************************
491 * Function:
492 * Description:
493 * Parameters:
494 * Input:
495 *
496 * Output:
497 *
498 * Returns:
499 *
500 *
501 * Others:
502 ********************************************************************************/
503void sdio_slave_process(void)
504{
505 int ret = 0;
506
507 //sdio_slave_init();
508 printf("run into sdio_slave_process\n");
509/* 1. ½ÓÊÕuboot */
510 ret = sdio_slave_read_bin();
511 if( ret != 0 )
512 {
513 printf("sdio_slave: read uboot error\n");
514 goto wait_error;
515 }
516 printf("sdio_slave: read uboot OK\n");
517
518
519
520 ret = sdio_slave_write();
521 if(ret > 0)
522 {
523
524 printf("sdio_slave: write ack success\n");
525 }
526
527
528
529 /* r7 Ìø×ªÆô¶¯´úÂë */
530 writel(0xE59ff000, 0x100000);
531 writel(uboot_entry_point, 0x100000 + 8);
532
533 printf("Start the uboot....\n");
534
535
536 writel(0xf, 0x130702c);
537
538 while(1);
539
540wait_error:
541 printf("sdio_slave: error wait\n");
542 while(1);
543}
544