summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/ata-sd-pp.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pp/ata-sd-pp.c')
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c274
1 files changed, 94 insertions, 180 deletions
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index edb806ab96..fb0a9e150e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -24,16 +24,10 @@
24#ifdef HAVE_HOTSWAP 24#ifdef HAVE_HOTSWAP
25#include "sd-pp-target.h" 25#include "sd-pp-target.h"
26#endif 26#endif
27#include "ata_idle_notify.h"
28#include "system.h" 27#include "system.h"
29#include <string.h> 28#include <string.h>
30#include "thread.h"
31#include "led.h" 29#include "led.h"
32#include "disk.h"
33#include "cpu.h" 30#include "cpu.h"
34#include "panic.h"
35#include "usb.h"
36#include "sd.h"
37#include "storage.h" 31#include "storage.h"
38#include "fs_defines.h" 32#include "fs_defines.h"
39 33
@@ -151,12 +145,6 @@
151/* for compatibility */ 145/* for compatibility */
152static long last_disk_activity = -1; 146static long last_disk_activity = -1;
153 147
154/** static, private data **/
155static bool initialized = false;
156static unsigned int sd_thread_id = 0;
157
158#define Q_CLOSE 1
159
160static long next_yield = 0; 148static long next_yield = 0;
161#define MIN_YIELD_PERIOD 1000 149#define MIN_YIELD_PERIOD 1000
162 150
@@ -177,30 +165,28 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
177#endif 165#endif
178}; 166};
179 167
180/* Shoot for around 75% usage */ 168static struct mutex sd_mtx SHAREDBSS_ATTR;
181static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
182static const char sd_thread_name[] = "ata/sd";
183static struct mutex sd_mtx SHAREDBSS_ATTR;
184static struct event_queue sd_queue SHAREDBSS_ATTR;
185 169
186#ifdef HAVE_HOTSWAP 170#ifdef HAVE_HOTSWAP
187static int sd_first_drive = 0; 171static int sd_first_drive = 0;
188#endif 172#endif
189 173
190/* Posted when card plugged status has changed */
191#define SD_HOTSWAP 1
192/* Actions taken by sd_thread when card status has changed */
193enum sd_thread_actions
194{
195 SDA_NONE = 0x0,
196 SDA_UNMOUNTED = 0x1,
197 SDA_MOUNTED = 0x2
198};
199
200/* Private Functions */ 174/* Private Functions */
201 175
202static unsigned int check_time[NUM_EC]; 176static unsigned int check_time[NUM_EC];
203 177
178static inline void enable_controller(bool on)
179{
180 if(on)
181 {
182 DEV_EN |= DEV_ATA; /* Enable controller */
183 }
184 else
185 {
186 DEV_EN &= ~DEV_ATA; /* Disable controller */
187 }
188}
189
204static inline bool sd_check_timeout(long timeout, int id) 190static inline bool sd_check_timeout(long timeout, int id)
205{ 191{
206 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout); 192 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
@@ -876,7 +862,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
876 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
877 863
878 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
879 sd_enable(true); 865 enable_controller(true);
880 led(true); 866 led(true);
881 867
882sd_read_retry: 868sd_read_retry:
@@ -964,7 +950,7 @@ sd_read_retry:
964 while (1) 950 while (1)
965 { 951 {
966 led(false); 952 led(false);
967 sd_enable(false); 953 enable_controller(false);
968 mutex_unlock(&sd_mtx); 954 mutex_unlock(&sd_mtx);
969 955
970 return ret; 956 return ret;
@@ -994,7 +980,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
994 unsigned int bank; 980 unsigned int bank;
995 981
996 mutex_lock(&sd_mtx); 982 mutex_lock(&sd_mtx);
997 sd_enable(true); 983 enable_controller(true);
998 led(true); 984 led(true);
999 985
1000sd_write_retry: 986sd_write_retry:
@@ -1092,7 +1078,7 @@ sd_write_retry:
1092 while (1) 1078 while (1)
1093 { 1079 {
1094 led(false); 1080 led(false);
1095 sd_enable(false); 1081 enable_controller(false);
1096 mutex_unlock(&sd_mtx); 1082 mutex_unlock(&sd_mtx);
1097 1083
1098 return ret; 1084 return ret;
@@ -1108,182 +1094,79 @@ sd_write_error:
1108 } 1094 }
1109} 1095}
1110 1096
1111#ifndef SD_DRIVER_CLOSE
1112static void sd_thread(void) NORETURN_ATTR;
1113#endif
1114static void sd_thread(void)
1115{
1116 struct queue_event ev;
1117 bool idle_notified = false;
1118
1119 while (1)
1120 {
1121 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1122
1123 switch ( ev.id )
1124 {
1125#ifdef HAVE_HOTSWAP
1126 case SYS_HOTSWAP_INSERTED:
1127 case SYS_HOTSWAP_EXTRACTED:;
1128 int success = 1;
1129
1130 disk_unmount(sd_first_drive+1); /* release "by force" */
1131
1132 mutex_lock(&sd_mtx); /* lock-out card activity */
1133
1134 /* Force card init for new card, re-init for re-inserted one or
1135 * clear if the last attempt to init failed with an error. */
1136 card_info[1].initialized = 0;
1137 sd_status[1].retry = 0;
1138
1139 /* Access is now safe */
1140 mutex_unlock(&sd_mtx);
1141
1142 if (ev.id == SYS_HOTSWAP_INSERTED)
1143 success = disk_mount(sd_first_drive+1); /* 0 if fail */
1144
1145 if (success)
1146 queue_broadcast(SYS_FS_CHANGED, 0);
1147 break;
1148#endif /* HAVE_HOTSWAP */
1149 case SYS_TIMEOUT:
1150 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1151 {
1152 idle_notified = false;
1153 }
1154 else
1155 {
1156 /* never let a timer wrap confuse us */
1157 next_yield = USEC_TIMER;
1158
1159 if (!idle_notified)
1160 {
1161 call_storage_idle_notifys(false);
1162 idle_notified = true;
1163 }
1164 }
1165 break;
1166 case SYS_USB_CONNECTED:
1167 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1168 /* Wait until the USB cable is extracted again */
1169 usb_wait_for_disconnect(&sd_queue);
1170 break;
1171
1172#ifdef SD_DRIVER_CLOSE
1173 case Q_CLOSE:
1174 return;
1175#endif
1176 }
1177 }
1178}
1179
1180#ifdef SD_DRIVER_CLOSE
1181void sd_close(void)
1182{
1183 unsigned int thread_id = sd_thread_id;
1184
1185 if (thread_id == 0)
1186 return;
1187
1188 sd_thread_id = 0;
1189
1190 queue_post(&sd_queue, Q_CLOSE, 0);
1191 thread_wait(thread_id);
1192}
1193#endif /* SD_DRIVER_CLOSE */
1194
1195void sd_enable(bool on) 1097void sd_enable(bool on)
1196{ 1098{
1197 if(on) 1099 mutex_lock(&sd_mtx);
1198 { 1100 enable_controller(on);
1199 DEV_EN |= DEV_ATA; /* Enable controller */ 1101 mutex_unlock(&sd_mtx);
1200 }
1201 else
1202 {
1203 DEV_EN &= ~DEV_ATA; /* Disable controller */
1204 }
1205} 1102}
1206 1103
1207
1208int sd_init(void) 1104int sd_init(void)
1209{ 1105{
1210 int ret = 0; 1106 int ret = 0;
1211 1107
1212 if (!initialized) 1108 mutex_init(&sd_mtx);
1213 mutex_init(&sd_mtx);
1214
1215 mutex_lock(&sd_mtx);
1216 1109
1217 led(false); 1110 led(false);
1218 1111
1219 if (!initialized) 1112 /* init controller */
1220 {
1221 initialized = true;
1222
1223 /* init controller */
1224#if defined(PHILIPS_SA9200) 1113#if defined(PHILIPS_SA9200)
1225 GPIOA_ENABLE = 0x00; 1114 GPIOA_ENABLE = 0x00;
1226 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01); 1115 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
1227#else 1116#else
1228 outl(inl(0x70000088) & ~(0x4), 0x70000088); 1117 outl(inl(0x70000088) & ~(0x4), 0x70000088);
1229 outl(inl(0x7000008c) & ~(0x4), 0x7000008c); 1118 outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
1230 GPO32_ENABLE |= 0x4; 1119 GPO32_ENABLE |= 0x4;
1231 1120
1232 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5)); 1121 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
1233 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5)); 1122 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
1234 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5)); 1123 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
1235#endif 1124#endif
1236 1125
1237#ifdef HAVE_HOTSWAP 1126#ifdef HAVE_HOTSWAP
1238 /* enable card detection port - mask interrupt first */ 1127 /* enable card detection port - mask interrupt first */
1239#ifdef SANSA_E200 1128#ifdef SANSA_E200
1240 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80); 1129 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1241 1130
1242 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80); 1131 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
1243 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80); 1132 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
1244#elif defined SANSA_C200 1133#elif defined SANSA_C200
1245 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08); 1134 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1246 1135
1247 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08); 1136 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
1248 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08); 1137 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
1249#endif 1138#endif
1250#endif 1139#endif
1251 sd_select_device(0); 1140 sd_select_device(0);
1252
1253 if (currcard->initialized < 0)
1254 ret = currcard->initialized;
1255 1141
1256 queue_init(&sd_queue, true); 1142 if (currcard->initialized < 0)
1257 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack), 1143 ret = currcard->initialized;
1258 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1259 IF_COP(, CPU));
1260 1144
1261 /* enable interupt for the mSD card */ 1145 /* enable interupt for the mSD card */
1262 sleep(HZ/10); 1146 sleep(HZ/10);
1263#ifdef HAVE_HOTSWAP 1147#ifdef HAVE_HOTSWAP
1264#ifdef SANSA_E200 1148#ifdef SANSA_E200
1265 CPU_INT_EN = HI_MASK; 1149 CPU_INT_EN = HI_MASK;
1266 CPU_HI_INT_EN = GPIO0_MASK; 1150 CPU_HI_INT_EN = GPIO0_MASK;
1267 1151
1268 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80); 1152 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1269 1153
1270 GPIOA_INT_CLR = 0x80; 1154 GPIOA_INT_CLR = 0x80;
1271 1155
1272 /* enable the card detect interrupt */ 1156 /* enable the card detect interrupt */
1273 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); 1157 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1274#elif defined SANSA_C200 1158#elif defined SANSA_C200
1275 CPU_INT_EN = HI_MASK; 1159 CPU_INT_EN = HI_MASK;
1276 CPU_HI_INT_EN = GPIO2_MASK; 1160 CPU_HI_INT_EN = GPIO2_MASK;
1277 1161
1278 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08); 1162 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1279 1163
1280 GPIOL_INT_CLR = 0x08; 1164 GPIOL_INT_CLR = 0x08;
1281 1165
1282 /* enable the card detect interrupt */ 1166 /* enable the card detect interrupt */
1283 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); 1167 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1284#endif
1285#endif 1168#endif
1286 } 1169#endif /* HAVE_HOTSWAP */
1287 1170
1288 mutex_unlock(&sd_mtx); 1171 mutex_unlock(&sd_mtx);
1289 1172
@@ -1294,19 +1177,17 @@ tCardInfo *card_get_info_target(int card_no)
1294{ 1177{
1295 return &card_info[card_no]; 1178 return &card_info[card_no];
1296} 1179}
1180
1297#ifdef HAVE_HOTSWAP 1181#ifdef HAVE_HOTSWAP
1298static int sd1_oneshot_callback(struct timeout *tmo) 1182static int sd1_oneshot_callback(struct timeout *tmo)
1299{ 1183{
1300 (void)tmo;
1301
1302 /* This is called only if the state was stable for 300ms - check state 1184 /* This is called only if the state was stable for 300ms - check state
1303 * and post appropriate event. */ 1185 * and post appropriate event. */
1304 if (card_detect_target()) 1186 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
1305 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1187 SYS_HOTSWAP_EXTRACTED,
1306 else 1188 sd_first_drive+1);
1307 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1308
1309 return 0; 1189 return 0;
1190 (void)tmo;
1310} 1191}
1311 1192
1312/* called on insertion/removal interrupt */ 1193/* called on insertion/removal interrupt */
@@ -1377,3 +1258,36 @@ int sd_num_drives(int first_drive)
1377#endif 1258#endif
1378} 1259}
1379#endif 1260#endif
1261
1262int sd_event(long id, intptr_t data)
1263{
1264 int rc = 0;
1265
1266 switch (id)
1267 {
1268#ifdef HAVE_HOTSWAP
1269 case SYS_HOTSWAP_INSERTED:
1270 case SYS_HOTSWAP_EXTRACTED:
1271 mutex_lock(&sd_mtx); /* lock-out card activity */
1272
1273 /* Force card init for new card, re-init for re-inserted one or
1274 * clear if the last attempt to init failed with an error. */
1275 card_info[data].initialized = 0;
1276 sd_status[data].retry = 0;
1277
1278 /* Access is now safe */
1279 mutex_unlock(&sd_mtx);
1280 break;
1281#endif /* HAVE_HOTSWAP */
1282
1283 case Q_STORAGE_TICK:
1284 /* never let a timer wrap confuse us */
1285 next_yield = USEC_TIMER;
1286 default:
1287 rc = storage_event_default_handler(id, data, last_disk_activity,
1288 STORAGE_SD);
1289 break;
1290 }
1291
1292 return rc;
1293}