r3724 - trunk/src/host/qemu-neo1973/hw

andrew at sita.openmoko.org andrew at sita.openmoko.org
Sat Dec 22 03:24:39 CET 2007


Author: andrew
Date: 2007-12-22 03:24:37 +0100 (Sat, 22 Dec 2007)
New Revision: 3724

Modified:
   trunk/src/host/qemu-neo1973/hw/sd.c
   trunk/src/host/qemu-neo1973/hw/sd.h
Log:
Make sd_state_e global, implement SD CMD8 and R7 from SD spec 2.00.


Modified: trunk/src/host/qemu-neo1973/hw/sd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sd.c	2007-12-22 01:16:13 UTC (rev 3723)
+++ trunk/src/host/qemu-neo1973/hw/sd.c	2007-12-22 02:24:37 UTC (rev 3724)
@@ -51,6 +51,7 @@
     sd_r2_s,      /* CSD register */
     sd_r3,        /* OCR register */
     sd_r6 = 6,    /* Published RCA response */
+    sd_r7,        /* Operating voltage */
     sd_r1b = -1,
 } sd_rsp_type_t;
 
@@ -60,18 +61,7 @@
         sd_card_identification_mode,
         sd_data_transfer_mode,
     } mode;
-    enum {
-        sd_inactive_state = -1,
-        sd_idle_state = 0,
-        sd_ready_state,
-        sd_identification_state,
-        sd_standby_state,
-        sd_transfer_state,
-        sd_sendingdata_state,
-        sd_receivingdata_state,
-        sd_programming_state,
-        sd_disconnect_state,
-    } state;
+    enum st_state_e state;
     uint32_t ocr;
     uint8_t scr[8];
     uint8_t cid[16];
@@ -79,6 +69,7 @@
     uint16_t rca;
     uint32_t card_status;
     uint8_t sd_status[64];
+    uint32_t vhs;
     int wp_switch;
     int *wp_groups;
     uint32_t size;
@@ -128,9 +119,9 @@
     sd->card_status |= sd->state << 9;
 }
 
-const sd_cmd_type_t sd_cmd_type[64] = {
+static const sd_cmd_type_t sd_cmd_type[64] = {
     sd_bc,   sd_none, sd_bcr,  sd_bcr,  sd_none, sd_none, sd_none, sd_ac,
-    sd_none, sd_ac,   sd_ac,   sd_adtc, sd_ac,   sd_ac,   sd_none, sd_ac,
+    sd_bcr,  sd_ac,   sd_ac,   sd_adtc, sd_ac,   sd_ac,   sd_none, sd_ac,
     sd_ac,   sd_adtc, sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none,
     sd_adtc, sd_adtc, sd_adtc, sd_adtc, sd_ac,   sd_ac,   sd_adtc, sd_none,
     sd_ac,   sd_ac,   sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
@@ -139,7 +130,7 @@
     sd_adtc, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_none,
 };
 
-const sd_cmd_type_t sd_acmd_type[64] = {
+static const sd_cmd_type_t sd_acmd_type[64] = {
     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_ac,   sd_none,
     sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_none, sd_none,
     sd_none, sd_none, sd_none, sd_none, sd_none, sd_none, sd_adtc, sd_ac,
@@ -192,6 +183,7 @@
 
 static void sd_set_ocr(SDState *sd)
 {
+    /* All voltages OK, card power-up OK, Standard Capacity SD Memory Card */
     sd->ocr = 0x80ffff80;
 }
 
@@ -286,10 +278,6 @@
     sd->rca += 0x4567;
 }
 
-#define CARD_STATUS_A	0x02004100
-#define CARD_STATUS_B	0x00c01e00
-#define CARD_STATUS_C	0xfd39a028
-
 static void sd_set_cardstatus(SDState *sd)
 {
     sd->card_status = 0x00000100;
@@ -351,6 +339,14 @@
     response[3] = status & 0xff;
 }
 
+static void sd_response_r7_make(SDState *sd, uint8_t *response)
+{
+    response[0] = (sd->vhs >> 24) & 0xff;
+    response[1] = (sd->vhs >> 16) & 0xff;
+    response[2] = (sd->vhs >>  8) & 0xff;
+    response[3] = (sd->vhs >>  0) & 0xff;
+}
+
 static void sd_reset(SDState *sd, BlockDriverState *bdrv)
 {
     uint32_t size;
@@ -662,6 +658,25 @@
         }
         break;
 
+    case 8:	/* CMD8:   SEND_IF_COND */
+        /* Physical Layer Specification Version 2.00 command */
+        switch (sd->state) {
+        case sd_idle_state:
+            sd->vhs = 0;
+
+            /* No response if not exactly one VHS bit is set.  */
+            if (!(req.arg >> 8) || (req.arg >> ffs(req.arg & ~0xff)))
+                return sd->spi ? sd_r7 : sd_r0;
+
+            /* Accept.  */
+            sd->vhs = req.arg;
+            return sd_r7;
+
+        default:
+            break;
+        }
+        break;
+
     case 9:	/* CMD9:   SEND_CSD */
         switch (sd->state) {
         case sd_standby_state:
@@ -1234,6 +1249,11 @@
         rsplen = 4;
         break;
 
+    case sd_r7:
+        sd_response_r7_make(sd, response);
+        rsplen = 4;
+        break;
+
     case sd_r0:
     default:
         rsplen = 0;

Modified: trunk/src/host/qemu-neo1973/hw/sd.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sd.h	2007-12-22 01:16:13 UTC (rev 3723)
+++ trunk/src/host/qemu-neo1973/hw/sd.h	2007-12-22 02:24:37 UTC (rev 3724)
@@ -46,11 +46,17 @@
 #define WP_ERASE_SKIP		(1 << 15)
 #define CARD_ECC_DISABLED	(1 << 14)
 #define ERASE_RESET		(1 << 13)
-#define CURRENT_STATE		(7 << 9)
+#define CURRENT_STATE		(15 << 9)
 #define READY_FOR_DATA		(1 << 8)
 #define APP_CMD			(1 << 5)
 #define AKE_SEQ_ERROR		(1 << 3)
 
+#define CARD_STATUS_A		0x02004100
+#define CARD_STATUS_B		0x00c01e00
+#define CARD_STATUS_C		0xfd39a028
+
+#define CARD_STATUS_SDIO_MASK	0x80c81e04
+
 typedef enum {
     sd_none = -1,
     sd_bc = 0,	/* broadcast -- no response */
@@ -65,6 +71,22 @@
     uint8_t crc;
 };
 
+enum sd_state_e {
+    sd_inactive_state = -1,	/* No-exit state */
+    sd_idle_state = 0,
+    sd_ready_state,
+    sd_identification_state,
+    sd_standby_state,
+    sd_transfer_state,
+    sd_sendingdata_state,
+    sd_receivingdata_state,
+    sd_programming_state,
+    sd_disconnect_state,
+    /* SDIO only */
+    sd_command_state,
+    sd_initialization_state = sd_idle_state,
+};
+
 typedef struct sd_card_s {
     void *opaque;
     int (*do_command)(void *opaque, struct sd_request_s *req,
@@ -104,4 +126,7 @@
 int ssi_sd_xfer(void *opaque, int val);
 void *ssi_sd_init(BlockDriverState *bs);
 
+/* ar6000.c */
+struct sd_card_s *ar6k_init(NICInfo *nd);
+
 #endif	/* __hw_sd_h */





More information about the commitlog mailing list