summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/dir_uncached.c4
-rw-r--r--firmware/common/file.c4
-rw-r--r--firmware/drivers/fat.c14
-rw-r--r--firmware/export/config-ondavx747.h10
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c335
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h13
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h25
7 files changed, 281 insertions, 124 deletions
diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c
index 25677a0903..dd157f0ade 100644
--- a/firmware/common/dir_uncached.c
+++ b/firmware/common/dir_uncached.c
@@ -74,7 +74,11 @@ int release_dirs(int volume)
74 int closed = 0; 74 int closed = 0;
75 for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++) 75 for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
76 { 76 {
77#ifdef HAVE_MULTIVOLUME
77 if (pdir->fatdir.file.volume == volume) 78 if (pdir->fatdir.file.volume == volume)
79#else
80 (void)volume;
81#endif
78 { 82 {
79 pdir->busy = false; /* mark as available, no further action */ 83 pdir->busy = false; /* mark as available, no further action */
80 closed++; 84 closed++;
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 3d7722f687..770930d80a 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -782,7 +782,11 @@ int release_files(int volume)
782 int closed = 0; 782 int closed = 0;
783 for ( fd=0; fd<MAX_OPEN_FILES; fd++, pfile++) 783 for ( fd=0; fd<MAX_OPEN_FILES; fd++, pfile++)
784 { 784 {
785#ifdef HAVE_MULTIVOLUME
785 if (pfile->fatfile.volume == volume) 786 if (pfile->fatfile.volume == volume)
787#else
788 (void)volume;
789#endif
786 { 790 {
787 pfile->busy = false; /* mark as available, no further action */ 791 pfile->busy = false; /* mark as available, no further action */
788 closed++; 792 closed++;
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index b5f6e77837..169672f08e 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -458,11 +458,15 @@ int fat_mount(IF_MV2(int volume,) IF_MD2(int drive,) long startsector)
458int fat_unmount(int volume, bool flush) 458int fat_unmount(int volume, bool flush)
459{ 459{
460 int rc; 460 int rc;
461#ifdef HAVE_MULTIVOLUME
461 struct bpb* fat_bpb = &fat_bpbs[volume]; 462 struct bpb* fat_bpb = &fat_bpbs[volume];
463#else
464 (void)volume;
465#endif
462 466
463 if(flush) 467 if(flush)
464 { 468 {
465 rc = flush_fat(fat_bpb); /* the clean way, while still alive */ 469 rc = flush_fat(IF_MV(fat_bpb)); /* the clean way, while still alive */
466 } 470 }
467 else 471 else
468 { /* volume is not accessible any more, e.g. MMC removed */ 472 { /* volume is not accessible any more, e.g. MMC removed */
@@ -471,7 +475,11 @@ int fat_unmount(int volume, bool flush)
471 for(i = 0;i < FAT_CACHE_SIZE;i++) 475 for(i = 0;i < FAT_CACHE_SIZE;i++)
472 { 476 {
473 struct fat_cache_entry *fce = &fat_cache[i]; 477 struct fat_cache_entry *fce = &fat_cache[i];
474 if(fce->inuse && fce->fat_vol == fat_bpb) 478 if(fce->inuse
479#ifdef HAVE_MULTIVOLUME
480 && fce->fat_vol == fat_bpb
481#endif
482 )
475 { 483 {
476 fce->inuse = false; /* discard all from that volume */ 484 fce->inuse = false; /* discard all from that volume */
477 fce->dirty = false; 485 fce->dirty = false;
@@ -480,7 +488,9 @@ int fat_unmount(int volume, bool flush)
480 mutex_unlock(&cache_mutex); 488 mutex_unlock(&cache_mutex);
481 rc = 0; 489 rc = 0;
482 } 490 }
491#ifdef HAVE_MULTIVOLUME
483 fat_bpb->mounted = false; 492 fat_bpb->mounted = false;
493#endif
484 return rc; 494 return rc;
485} 495}
486#endif /* #ifdef HAVE_HOTSWAP */ 496#endif /* #ifdef HAVE_HOTSWAP */
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h
index c4fc39bfc0..046aeff5c8 100644
--- a/firmware/export/config-ondavx747.h
+++ b/firmware/export/config-ondavx747.h
@@ -167,11 +167,19 @@
167 167
168#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */ 168#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */
169 169
170/*
171No access to the NAND yet..
172
170#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) 173#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD)
171#define NUM_DRIVES 2 174#define NUM_DRIVES 2
175*/
176#define CONFIG_STORAGE (STORAGE_SD)
177#define NUM_DRIVES 1
178#define HAVE_HOTSWAP_STORAGE_AS_MAIN
179#define INCLUDE_TIMEOUT_API
172 180
173/* Define this if media can be exchanged on the fly */ 181/* Define this if media can be exchanged on the fly */
174//#define HAVE_HOTSWAP 182#define HAVE_HOTSWAP
175 183
176/* Define this if you have a Ingenic JZ4732 */ 184/* Define this if you have a Ingenic JZ4732 */
177#define CONFIG_CPU JZ4732 185#define CONFIG_CPU JZ4732
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index f3d67aec51..454d7a51f2 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -22,25 +22,40 @@
22#include "config.h" 22#include "config.h"
23#include "jz4740.h" 23#include "jz4740.h"
24#include "ata.h" 24#include "ata.h"
25#include "ata_idle_notify.h"
25#include "ata-sd-target.h" 26#include "ata-sd-target.h"
27#include "disk.h"
28#include "fat.h"
29#include "led.h"
30#include "hotswap.h"
26#include "logf.h" 31#include "logf.h"
27#include "sd.h" 32#include "sd.h"
28#include "system.h" 33#include "system.h"
29#include "kernel.h" 34#include "kernel.h"
30#include "panic.h"
31#include "debug.h"
32#include "storage.h" 35#include "storage.h"
33#include "string.h" 36#include "string.h"
34#include "led.h" 37#include "usb.h"
38
39static long last_disk_activity = -1;
40static int sd_drive_nr = 0;
41static tCardInfo card;
35 42
36static struct wakeup sd_wakeup; 43static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
37static long last_disk_activity = -1; 44static const char sd_thread_name[] = "ata/sd";
38static tCardInfo card; 45static struct event_queue sd_queue;
46static struct mutex sd_mtx;
47static struct wakeup sd_wakeup;
48static void sd_thread(void) __attribute__((noreturn));
49
50static int use_4bit;
51static int num_6;
52static int sd2_0;
39 53
40//#define SD_DMA_ENABLE 54//#define SD_DMA_ENABLE
41#define SD_DMA_INTERRUPT 0 55#define SD_DMA_INTERRUPT 0
42 56
43#define DEBUG(x...) logf(x) 57//#define DEBUG(x...) logf(x)
58#define DEBUG(x, ...)
44 59
45#define SD_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) 60#define SD_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN)
46#define SD_RESET() __msc_reset() 61#define SD_RESET() __msc_reset()
@@ -117,7 +132,6 @@ enum sd_rsp_t
117 RESPONSE_R7 = 9, 132 RESPONSE_R7 = 9,
118}; 133};
119 134
120
121/* 135/*
122 MMC status in R1 136 MMC status in R1
123 Type 137 Type
@@ -199,10 +213,6 @@ struct sd_request
199#define SD_EVENT_TX_DATA_DONE 0x02 /* Tx data done */ 213#define SD_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
200#define SD_EVENT_PROG_DONE 0x04 /* Programming is done */ 214#define SD_EVENT_PROG_DONE 0x04 /* Programming is done */
201 215
202static int use_4bit = 1; /* Use 4-bit data bus */
203static int num_6 = 0;
204static int sd2_0 = 0;
205
206/************************************************************************** 216/**************************************************************************
207 * Utility functions 217 * Utility functions
208 **************************************************************************/ 218 **************************************************************************/
@@ -214,7 +224,7 @@ static int sd2_0 = 0;
214#define PARSE_U16(_buf,_index) \ 224#define PARSE_U16(_buf,_index) \
215 (((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]); 225 (((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]);
216 226
217int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1) 227static int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1)
218{ 228{
219 unsigned char *buf = request->response; 229 unsigned char *buf = request->response;
220 230
@@ -253,32 +263,22 @@ int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1)
253 return 0; 263 return 0;
254} 264}
255 265
256int sd_unpack_scr(struct sd_request *request, struct sd_response_r1 *r1, unsigned int *scr) 266static int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, unsigned long *rca)
257{
258 unsigned char *buf = request->response;
259 if (request->result)
260 return request->result;
261
262 *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
263 return sd_unpack_r1(request, r1);
264}
265
266static inline int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, unsigned long *rca)
267{ 267{
268 unsigned char *buf = request->response; 268 unsigned char *buf = request->response;
269 269
270 if (request->result) 270 if (request->result)
271 return request->result; 271 return request->result;
272 272
273 *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ 273 *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
274 274
275 *(buf+1) = 0; 275 *(buf+1) = 0;
276 *(buf+2) = 0; 276 *(buf+2) = 0;
277 277
278 return sd_unpack_r1(request, r1); 278 return sd_unpack_r1(request, r1);
279} 279}
280 280
281int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3) 281static int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3)
282{ 282{
283 unsigned char *buf = request->response; 283 unsigned char *buf = request->response;
284 284
@@ -287,7 +287,9 @@ int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3)
287 r3->ocr = PARSE_U32(buf,1); 287 r3->ocr = PARSE_U32(buf,1);
288 DEBUG("sd_unpack_r3: ocr=%08x", r3->ocr); 288 DEBUG("sd_unpack_r3: ocr=%08x", r3->ocr);
289 289
290 if (buf[0] != 0x3f) return SD_ERROR_HEADER_MISMATCH; 290 if (buf[0] != 0x3f)
291 return SD_ERROR_HEADER_MISMATCH;
292
291 return 0; 293 return 0;
292} 294}
293 295
@@ -917,7 +919,6 @@ static void jz_sd_tx_handler(unsigned int arg)
917 } 919 }
918 if (__dmac_channel_transmit_end_detected(arg)) 920 if (__dmac_channel_transmit_end_detected(arg))
919 { 921 {
920
921 __dmac_channel_clear_transmit_end(arg); 922 __dmac_channel_clear_transmit_end(arg);
922 OSSemPost(sd_dma_tx_sem); 923 OSSemPost(sd_dma_tx_sem);
923 } 924 }
@@ -945,6 +946,14 @@ void MSC(void)
945 logf("MSC interrupt"); 946 logf("MSC interrupt");
946} 947}
947 948
949static void sd_gpio_setup_irq(bool inserted)
950{
951 if(inserted)
952 __gpio_as_irq_rise_edge(MMC_CD_PIN);
953 else
954 __gpio_as_irq_fall_edge(MMC_CD_PIN);
955}
956
948/******************************************************************************************************************* 957/*******************************************************************************************************************
949** Name: void sd_hardware_init() 958** Name: void sd_hardware_init()
950** Function: initialize the hardware condiction that access sd card 959** Function: initialize the hardware condiction that access sd card
@@ -954,7 +963,8 @@ void MSC(void)
954static void jz_sd_hardware_init(void) 963static void jz_sd_hardware_init(void)
955{ 964{
956 __cpm_start_msc(); /* enable mmc clock */ 965 __cpm_start_msc(); /* enable mmc clock */
957 mmc_init_gpio(); /* init GPIO */ 966 sd_init_gpio(); /* init GPIO */
967 sd_gpio_setup_irq(jz_sd_chkcard());
958#ifdef SD_POWER_ON 968#ifdef SD_POWER_ON
959 SD_POWER_ON(); /* turn on power of card */ 969 SD_POWER_ON(); /* turn on power of card */
960#endif 970#endif
@@ -1000,7 +1010,6 @@ static void sd_simple_cmd(struct sd_request *request, int cmd, unsigned int arg,
1000#define SD_INIT_DOING 0 1010#define SD_INIT_DOING 0
1001#define SD_INIT_PASSED 1 1011#define SD_INIT_PASSED 1
1002#define SD_INIT_FAILED 2 1012#define SD_INIT_FAILED 2
1003
1004static int sd_init_card_state(struct sd_request *request) 1013static int sd_init_card_state(struct sd_request *request)
1005{ 1014{
1006 struct sd_response_r1 r1; 1015 struct sd_response_r1 r1;
@@ -1026,41 +1035,42 @@ static int sd_init_card_state(struct sd_request *request)
1026 retval); 1035 retval);
1027 limit_41++; 1036 limit_41++;
1028 sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3); 1037 sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3);
1029 } else if (limit_41 < 100) { 1038 }
1039 else if (limit_41 < 100)
1040 {
1030 limit_41++; 1041 limit_41++;
1031 sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3); 1042 sd_simple_cmd(request, SD_APP_OP_COND, ocr, RESPONSE_R3);
1032 } else{ 1043 }
1044 else
1033 /* reset the card to idle*/ 1045 /* reset the card to idle*/
1034 sd_simple_cmd(request, SD_GO_IDLE_STATE, 0, RESPONSE_NONE); 1046 sd_simple_cmd(request, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
1035 }
1036 break; 1047 break;
1037 1048
1038 case SD_APP_OP_COND: 1049 case SD_APP_OP_COND:
1039 retval = sd_unpack_r3(request, &r3); 1050 retval = sd_unpack_r3(request, &r3);
1040 if (retval) 1051 if (retval)
1041 {
1042 break; 1052 break;
1043 }
1044 1053
1045 DEBUG("sd_init_card_state: read ocr value = 0x%08x", r3.ocr); 1054 DEBUG("sd_init_card_state: read ocr value = 0x%08x", r3.ocr);
1046 card.ocr = r3.ocr; 1055 card.ocr = r3.ocr;
1047 1056
1048 if(!(r3.ocr & SD_CARD_BUSY || ocr == 0)){ 1057 if(!(r3.ocr & SD_CARD_BUSY || ocr == 0))
1049 udelay(10000); 1058 {
1059 sleep(HZ / 100);
1050 sd_simple_cmd(request, SD_APP_CMD, 0, RESPONSE_R1); 1060 sd_simple_cmd(request, SD_APP_CMD, 0, RESPONSE_R1);
1051 } 1061 }
1052 else 1062 else
1053 { 1063 {
1054 /* Set the data bus width to 4 bits */ 1064 /* Set the data bus width to 4 bits */
1055 use_4bit = 1; 1065 use_4bit = 1;
1056 sd_simple_cmd(request, SD_ALL_SEND_CID, 0, RESPONSE_R2_CID); 1066 sd_simple_cmd(request, SD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
1057 } 1067 }
1058 break; 1068 break;
1059 1069
1060 case SD_ALL_SEND_CID: 1070 case SD_ALL_SEND_CID:
1061 for(i=0; i<4; i++) 1071 for(i=0; i<4; i++)
1062 card.cid[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) | 1072 card.cid[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) |
1063 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1073 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1064 1074
1065 logf("CID: %08lx%08lx%08lx%08lx", card.cid[0], card.cid[1], card.cid[2], card.cid[3]); 1075 logf("CID: %08lx%08lx%08lx%08lx", card.cid[0], card.cid[1], card.cid[2], card.cid[3]);
1066 sd_simple_cmd(request, SD_SEND_RELATIVE_ADDR, 0, RESPONSE_R6); 1076 sd_simple_cmd(request, SD_SEND_RELATIVE_ADDR, 0, RESPONSE_R6);
@@ -1068,7 +1078,7 @@ static int sd_init_card_state(struct sd_request *request)
1068 case SD_SEND_RELATIVE_ADDR: 1078 case SD_SEND_RELATIVE_ADDR:
1069 retval = sd_unpack_r6(request, &r1, &card.rca); 1079 retval = sd_unpack_r6(request, &r1, &card.rca);
1070 card.rca = card.rca << 16; 1080 card.rca = card.rca << 16;
1071 DEBUG("sd_init_card_state: Get RCA from SD: 0x%04x Status: %x", card.rca, r1.status); 1081 DEBUG("sd_init_card_state: Get RCA from SD: 0x%04lx Status: %x", card.rca, r1.status);
1072 if (retval) 1082 if (retval)
1073 { 1083 {
1074 DEBUG("sd_init_card_state: unable to SET_RELATIVE_ADDR error=%d", 1084 DEBUG("sd_init_card_state: unable to SET_RELATIVE_ADDR error=%d",
@@ -1082,7 +1092,7 @@ static int sd_init_card_state(struct sd_request *request)
1082 case SD_SEND_CSD: 1092 case SD_SEND_CSD:
1083 for(i=0; i<4; i++) 1093 for(i=0; i<4; i++)
1084 card.csd[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) | 1094 card.csd[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) |
1085 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1095 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1086 1096
1087 sd_parse_csd(&card); 1097 sd_parse_csd(&card);
1088 sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1); 1098 sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1);
@@ -1091,6 +1101,7 @@ static int sd_init_card_state(struct sd_request *request)
1091 DEBUG("SD card is ready"); 1101 DEBUG("SD card is ready");
1092 jz_sd_set_clock(SD_CLOCK_FAST); 1102 jz_sd_set_clock(SD_CLOCK_FAST);
1093 return SD_INIT_PASSED; 1103 return SD_INIT_PASSED;
1104
1094 default: 1105 default:
1095 DEBUG("sd_init_card_state: error! Illegal last cmd %d", request->cmd); 1106 DEBUG("sd_init_card_state: error! Illegal last cmd %d", request->cmd);
1096 return SD_INIT_FAILED; 1107 return SD_INIT_FAILED;
@@ -1110,7 +1121,7 @@ static int sd_switch(struct sd_request *request, int mode, int group,
1110 arg &= ~(0xF << (group * 4)); 1121 arg &= ~(0xF << (group * 4));
1111 arg |= value << (group * 4); 1122 arg |= value << (group * 4);
1112 sd_send_cmd(request, 6, arg, 1, 64, RESPONSE_R1, resp); 1123 sd_send_cmd(request, 6, arg, 1, 64, RESPONSE_R1, resp);
1113 1124
1114 return 0; 1125 return 0;
1115} 1126}
1116 1127
@@ -1123,7 +1134,7 @@ static int sd_read_switch(struct sd_request *request)
1123 1134
1124 memset((unsigned char *)status, 0, 64); 1135 memset((unsigned char *)status, 0, 64);
1125 sd_switch(request, 0, 0, 1, (unsigned char*) status); 1136 sd_switch(request, 0, 0, 1, (unsigned char*) status);
1126 1137
1127 if (((unsigned char *)status)[13] & 0x02) 1138 if (((unsigned char *)status)[13] & 0x02)
1128 return 0; 1139 return 0;
1129 else 1140 else
@@ -1141,7 +1152,7 @@ static int sd_switch_hs(struct sd_request *request)
1141 return 0; 1152 return 0;
1142} 1153}
1143 1154
1144int sd_select_card(void) 1155static int sd_select_card(void)
1145{ 1156{
1146 struct sd_request request; 1157 struct sd_request request;
1147 struct sd_response_r1 r1; 1158 struct sd_response_r1 r1;
@@ -1173,31 +1184,57 @@ int sd_select_card(void)
1173 if (retval) 1184 if (retval)
1174 return retval; 1185 return retval;
1175 1186
1187 card.initialized = 1;
1188
1176 return 0; 1189 return 0;
1177} 1190}
1178 1191
1179int sd_init(void) 1192static int sd_init_device(void)
1180{ 1193{
1181 int retval; 1194 int retval;
1182 static bool inited = false;
1183 struct sd_request init_req; 1195 struct sd_request init_req;
1196
1197 mutex_lock(&sd_mtx);
1198
1199 /* Initialise card data as blank */
1200 memset(&card, 0, sizeof(tCardInfo));
1201
1202 sd2_0 = 0;
1203 num_6 = 0;
1204 use_4bit = 0;
1205
1206 /* reset mmc/sd controller */
1207 jz_sd_hardware_init();
1208
1209 sd_simple_cmd(&init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
1210 sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
1211
1212 sleep(HZ/2); /* Give the card/controller some rest */
1213
1214 while((retval = sd_init_card_state(&init_req)) == SD_INIT_DOING);
1215 retval = (retval == SD_INIT_PASSED ? sd_select_card() : -1);
1216
1217 mutex_unlock(&sd_mtx);
1218
1219 return retval;
1220}
1221
1222int sd_init(void)
1223{
1224 static bool inited = false;
1184 if(!inited) 1225 if(!inited)
1185 { 1226 {
1186 jz_sd_hardware_init();
1187 wakeup_init(&sd_wakeup); 1227 wakeup_init(&sd_wakeup);
1188 num_6 = 0; 1228 mutex_init(&sd_mtx);
1229 queue_init(&sd_queue, true);
1230 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
1231 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1232 IF_COP(, CPU));
1233
1189 inited = true; 1234 inited = true;
1190 } 1235 }
1191
1192 sd_simple_cmd(&init_req, SD_CIM_RESET, 0, RESPONSE_NONE);
1193 sd_simple_cmd(&init_req, SD_GO_IDLE_STATE, 0, RESPONSE_NONE);
1194
1195 while ((retval = sd_init_card_state(&init_req)) == SD_INIT_DOING);
1196 1236
1197 if (retval == SD_INIT_PASSED) 1237 return sd_init_device();
1198 return sd_select_card();
1199 else
1200 return -1;
1201} 1238}
1202 1239
1203static inline bool card_detect_target(void) 1240static inline bool card_detect_target(void)
@@ -1205,20 +1242,6 @@ static inline bool card_detect_target(void)
1205 return (jz_sd_chkcard() == 1); 1242 return (jz_sd_chkcard() == 1);
1206} 1243}
1207 1244
1208#ifdef HAVE_HOTSWAP
1209void card_enable_monitoring_target(bool on)
1210{
1211 if(on)
1212 {
1213
1214 }
1215 else
1216 {
1217
1218 }
1219}
1220#endif
1221
1222tCardInfo* card_get_info_target(int card_no) 1245tCardInfo* card_get_info_target(int card_no)
1223{ 1246{
1224 (void)card_no; 1247 (void)card_no;
@@ -1230,30 +1253,34 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf
1230#ifdef HAVE_MULTIVOLUME 1253#ifdef HAVE_MULTIVOLUME
1231 (void)drive; 1254 (void)drive;
1232#endif 1255#endif
1256 mutex_lock(&sd_mtx);
1233 led(true); 1257 led(true);
1234 1258
1235 struct sd_request request; 1259 struct sd_request request;
1236 struct sd_response_r1 r1; 1260 struct sd_response_r1 r1;
1237 int retval; 1261 int retval = -1;
1238 1262
1239 if (!card_detect_target() || count == 0 || start > card.numblocks) 1263 if (!card_detect_target() || count == 0 || start > card.numblocks)
1240 return -1; 1264 goto err;
1241 1265
1266 if(card.initialized == 0 && !sd_init_device())
1267 goto err;
1268
1242 sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1); 1269 sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1);
1243 retval = sd_unpack_r1(&request, &r1); 1270 retval = sd_unpack_r1(&request, &r1);
1244 if (retval && (retval != SD_ERROR_STATE_MISMATCH)) 1271 if (retval && (retval != SD_ERROR_STATE_MISMATCH))
1245 return retval; 1272 goto err;
1246 1273
1247 sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1); 1274 sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1);
1248 if ((retval = sd_unpack_r1(&request, &r1))) 1275 if ((retval = sd_unpack_r1(&request, &r1)))
1249 return retval; 1276 goto err;
1250 1277
1251 if (sd2_0) 1278 if (sd2_0)
1252 { 1279 {
1253 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, 1280 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
1254 count, SD_BLOCK_SIZE, RESPONSE_R1, buf); 1281 count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
1255 if ((retval = sd_unpack_r1(&request, &r1))) 1282 if ((retval = sd_unpack_r1(&request, &r1)))
1256 return retval; 1283 goto err;
1257 } 1284 }
1258 else 1285 else
1259 { 1286 {
@@ -1261,16 +1288,18 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf
1261 start * SD_BLOCK_SIZE, count, 1288 start * SD_BLOCK_SIZE, count,
1262 SD_BLOCK_SIZE, RESPONSE_R1, buf); 1289 SD_BLOCK_SIZE, RESPONSE_R1, buf);
1263 if ((retval = sd_unpack_r1(&request, &r1))) 1290 if ((retval = sd_unpack_r1(&request, &r1)))
1264 return retval; 1291 goto err;
1265 } 1292 }
1266 1293
1267 last_disk_activity = current_tick; 1294 last_disk_activity = current_tick;
1268 1295
1269 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); 1296 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
1270 if ((retval = sd_unpack_r1(&request, &r1))) 1297 if ((retval = sd_unpack_r1(&request, &r1)))
1271 return retval; 1298 goto err;
1272 1299
1300err:
1273 led(false); 1301 led(false);
1302 mutex_unlock(&sd_mtx);
1274 1303
1275 return retval; 1304 return retval;
1276} 1305}
@@ -1280,23 +1309,27 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
1280#ifdef HAVE_MULTIVOLUME 1309#ifdef HAVE_MULTIVOLUME
1281 (void)drive; 1310 (void)drive;
1282#endif 1311#endif
1312 mutex_lock(&sd_mtx);
1283 led(true); 1313 led(true);
1284 1314
1285 struct sd_request request; 1315 struct sd_request request;
1286 struct sd_response_r1 r1; 1316 struct sd_response_r1 r1;
1287 int retval; 1317 int retval = -1;
1288 1318
1289 if (!card_detect_target() || count == 0 || start > card.numblocks) 1319 if (!card_detect_target() || count == 0 || start > card.numblocks)
1290 return -1; 1320 goto err;
1321
1322 if(card.initialized == 0 && !sd_init_device())
1323 goto err;
1291 1324
1292 sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1); 1325 sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1);
1293 retval = sd_unpack_r1(&request, &r1); 1326 retval = sd_unpack_r1(&request, &r1);
1294 if (retval && (retval != SD_ERROR_STATE_MISMATCH)) 1327 if (retval && (retval != SD_ERROR_STATE_MISMATCH))
1295 return retval; 1328 goto err;
1296 1329
1297 sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1); 1330 sd_simple_cmd(&request, SD_SET_BLOCKLEN, SD_BLOCK_SIZE, RESPONSE_R1);
1298 if ((retval = sd_unpack_r1(&request, &r1))) 1331 if ((retval = sd_unpack_r1(&request, &r1)))
1299 return retval; 1332 goto err;
1300 1333
1301 if (sd2_0) 1334 if (sd2_0)
1302 { 1335 {
@@ -1304,7 +1337,7 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
1304 count, SD_BLOCK_SIZE, RESPONSE_R1, 1337 count, SD_BLOCK_SIZE, RESPONSE_R1,
1305 (void*)buf); 1338 (void*)buf);
1306 if ((retval = sd_unpack_r1(&request, &r1))) 1339 if ((retval = sd_unpack_r1(&request, &r1)))
1307 return retval; 1340 goto err;
1308 } 1341 }
1309 else 1342 else
1310 { 1343 {
@@ -1312,13 +1345,18 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo
1312 start * SD_BLOCK_SIZE, count, 1345 start * SD_BLOCK_SIZE, count,
1313 SD_BLOCK_SIZE, RESPONSE_R1, (void*)buf); 1346 SD_BLOCK_SIZE, RESPONSE_R1, (void*)buf);
1314 if ((retval = sd_unpack_r1(&request, &r1))) 1347 if ((retval = sd_unpack_r1(&request, &r1)))
1315 return retval; 1348 goto err;
1316 } 1349 }
1350
1351 last_disk_activity = current_tick;
1352
1317 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); 1353 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
1318 if ((retval = sd_unpack_r1(&request, &r1))) 1354 if ((retval = sd_unpack_r1(&request, &r1)))
1319 return retval; 1355 goto err;
1320 1356
1357err:
1321 led(false); 1358 led(false);
1359 mutex_unlock(&sd_mtx);
1322 1360
1323 return retval; 1361 return retval;
1324} 1362}
@@ -1342,10 +1380,9 @@ void sd_sleepnow(void)
1342{ 1380{
1343} 1381}
1344 1382
1345/* TODO */
1346bool sd_disk_is_active(void) 1383bool sd_disk_is_active(void)
1347{ 1384{
1348 return false; 1385 return sd_mtx.locked;
1349} 1386}
1350 1387
1351int sd_soft_reset(void) 1388int sd_soft_reset(void)
@@ -1359,8 +1396,39 @@ bool sd_removable(IF_MV_NONVOID(int drive))
1359#ifdef HAVE_MULTIVOLUME 1396#ifdef HAVE_MULTIVOLUME
1360 (void)drive; 1397 (void)drive;
1361#endif 1398#endif
1362 //return true; 1399 return true;
1363 return false; 1400}
1401
1402void card_enable_monitoring_target(bool on)
1403{
1404 if(on)
1405 sd_gpio_setup_irq(card_detect_target());
1406 else
1407 __gpio_mask_irq(MMC_CD_PIN);
1408}
1409
1410static int sd_oneshot_callback(struct timeout *tmo)
1411{
1412 (void)tmo;
1413 int state = card_detect_target();
1414
1415 /* This is called only if the state was stable for 300ms - check state
1416 * and post appropriate event. */
1417 if (state)
1418 queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
1419 else
1420 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1421
1422 sd_gpio_setup_irq(state);
1423
1424 return 0;
1425}
1426
1427/* called on insertion/removal interrupt */
1428void MMC_CD_IRQ(void)
1429{
1430 static struct timeout sd_oneshot;
1431 timeout_register(&sd_oneshot, sd_oneshot_callback, (3*HZ/10), 0);
1364} 1432}
1365#endif 1433#endif
1366 1434
@@ -1375,9 +1443,72 @@ bool sd_present(IF_MV_NONVOID(int drive))
1375#ifdef CONFIG_STORAGE_MULTI 1443#ifdef CONFIG_STORAGE_MULTI
1376int sd_num_drives(int first_drive) 1444int sd_num_drives(int first_drive)
1377{ 1445{
1378 /* We don't care which logical drive number(s) we have been assigned */ 1446 sd_drive_nr = first_drive;
1379 (void)first_drive;
1380
1381 return 1; 1447 return 1;
1382} 1448}
1383#endif 1449#endif
1450
1451static void sd_thread(void)
1452{
1453 struct queue_event ev;
1454 bool idle_notified = false;
1455
1456 while (1)
1457 {
1458 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1459
1460 switch (ev.id)
1461 {
1462#ifdef HAVE_HOTSWAP
1463 case SYS_HOTSWAP_INSERTED:
1464 case SYS_HOTSWAP_EXTRACTED:
1465 fat_lock(); /* lock-out FAT activity first -
1466 prevent deadlocking via disk_mount that
1467 would cause a reverse-order attempt with
1468 another thread */
1469 mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
1470 into driver that bypass the fat cache */
1471
1472 /* We now have exclusive control of fat cache and ata */
1473
1474 disk_unmount(sd_drive_nr); /* release "by force", ensure file
1475 descriptors aren't leaked and any busy
1476 ones are invalid if mounting */
1477
1478 /* Force card init for new card, re-init for re-inserted one or
1479 * clear if the last attempt to init failed with an error. */
1480 card.initialized = 0;
1481
1482 if(ev.id == SYS_HOTSWAP_INSERTED)
1483 disk_mount(sd_drive_nr);
1484
1485 queue_broadcast(SYS_FS_CHANGED, 0);
1486
1487 /* Access is now safe */
1488 mutex_unlock(&sd_mtx);
1489 fat_unlock();
1490 break;
1491#endif
1492 case SYS_TIMEOUT:
1493 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1494 idle_notified = false;
1495 else
1496 {
1497 if (!idle_notified)
1498 {
1499 call_storage_idle_notifys(false);
1500 idle_notified = true;
1501 }
1502 }
1503 break;
1504 case SYS_USB_CONNECTED:
1505 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1506 /* Wait until the USB cable is extracted again */
1507 usb_wait_for_disconnect(&sd_queue);
1508 break;
1509 case SYS_USB_DISCONNECTED:
1510 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
1511 break;
1512 }
1513 }
1514}
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h
index c0f2c11956..757a12d9f2 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h
@@ -22,20 +22,19 @@
22#ifndef ATA_SD_TARGET_H 22#ifndef ATA_SD_TARGET_H
23#define ATA_SD_TARGET_H 23#define ATA_SD_TARGET_H
24 24
25#include "inttypes.h"
26#include "hotswap.h"
27#include "jz4740.h" 25#include "jz4740.h"
28 26#include "system.h"
29int _sd_read_sectors(unsigned long start, int count, void* buf);
30int _sd_write_sectors(unsigned long start, int count, const void* buf);
31int _sd_init(void);
32 27
33#define MMC_CD_PIN (32*1 + 29) /* Pin to check card insertion */ 28#define MMC_CD_PIN (32*1 + 29) /* Pin to check card insertion */
29#define MMC_CD_IRQ GPIO61
34 30
35static inline void mmc_init_gpio(void) 31static inline void sd_init_gpio(void)
36{ 32{
37 __gpio_as_msc(); 33 __gpio_as_msc();
34 __gpio_enable_pull(MMC_CD_PIN);
38 __gpio_as_input(MMC_CD_PIN); 35 __gpio_as_input(MMC_CD_PIN);
36 __gpio_mask_irq(MMC_CD_PIN);
37 system_enable_irq(GPIO_IRQ(MMC_CD_PIN));
39} 38}
40 39
41#endif 40#endif
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index b2d960ef54..232412d0c7 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -33,14 +33,14 @@
33/* This one returns the old status */ 33/* This one returns the old status */
34static inline int set_interrupt_status(int status, int mask) 34static inline int set_interrupt_status(int status, int mask)
35{ 35{
36 unsigned int res, oldstatus; 36 unsigned int res, oldstatus;
37 37
38 res = oldstatus = read_c0_status(); 38 res = oldstatus = read_c0_status();
39 res &= ~mask; 39 res &= ~mask;
40 res |= (status & mask); 40 res |= (status & mask);
41 write_c0_status(res); 41 write_c0_status(res);
42 42
43 return oldstatus; 43 return oldstatus;
44} 44}
45 45
46static inline void enable_interrupt(void) 46static inline void enable_interrupt(void)
@@ -71,9 +71,9 @@ static inline void restore_interrupt(int status)
71#define set_irq_level(status) set_interrupt_status((status), ST0_IE) 71#define set_irq_level(status) set_interrupt_status((status), ST0_IE)
72#define disable_irq_save() disable_interrupt_save(ST0_IE) 72#define disable_irq_save() disable_interrupt_save(ST0_IE)
73#define restore_irq(c0_status) restore_interrupt(c0_status) 73#define restore_irq(c0_status) restore_interrupt(c0_status)
74 74
75#define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff) 75#define swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
76#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \ 76#define swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \
77 ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff) 77 ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
78 78
79#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) 79#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000)
@@ -94,6 +94,7 @@ void dma_disable(void);
94#define XDMA_CALLBACK(n) DMA ## n 94#define XDMA_CALLBACK(n) DMA ## n
95#define DMA_CALLBACK(n) XDMA_CALLBACK(n) 95#define DMA_CALLBACK(n) XDMA_CALLBACK(n)
96 96
97#define DMA_IRQ(n) (IRQ_DMA_0 + n) 97#define DMA_IRQ(n) (IRQ_DMA_0 + (n))
98#define GPIO_IRQ(n) (IRQ_GPIO_0 + (n))
98 99
99#endif /* __SYSTEM_TARGET_H_ */ 100#endif /* __SYSTEM_TARGET_H_ */