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

andrew at sita.openmoko.org andrew at sita.openmoko.org
Thu Dec 27 03:56:23 CET 2007


Author: andrew
Date: 2007-12-27 03:56:21 +0100 (Thu, 27 Dec 2007)
New Revision: 3739

Modified:
   trunk/src/host/qemu-neo1973/hw/ar6000.c
   trunk/src/host/qemu-neo1973/hw/sd.h
Log:
FBR space registers.
Per-function CIS tuples of Atheros ar6k1, makes function PnP logic work.


Modified: trunk/src/host/qemu-neo1973/hw/ar6000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ar6000.c	2007-12-26 23:08:04 UTC (rev 3738)
+++ trunk/src/host/qemu-neo1973/hw/ar6000.c	2007-12-27 02:56:21 UTC (rev 3739)
@@ -58,6 +58,13 @@
         uint8_t speed;
     } cccr;
     struct {
+        uint8_t stdfn;
+        uint8_t ext_stdfn;
+        uint8_t power;
+        int cis_offset;
+        uint32_t csa_addr;
+        void (*csa_wr)(struct sdio_s *sd, uint8_t data);
+        uint8_t (*csa_rd)(struct sdio_s *sd);
     } fbr[7];
     const uint8_t *cis;
     int cislen;
@@ -250,6 +257,10 @@
     memset(&sd->fbr,  0, sizeof(sd->fbr));
     for (i = 0; i < 8; i ++)
         sd->blk_len[i] = 0;
+    for (i = 0; i < 7; i ++) {
+        sd->fbr[i].stdfn &= 0x4f;
+        sd->fbr[i].power = 0;
+    }
     if (sd->reset)
         sd->reset(sd);
 
@@ -639,7 +650,6 @@
         sd->blk_len[0] &= 0xff << 8;
         sd->blk_len[0] |= value;
         break;
-
     case 0x11:	/* Fn0 Block Size MSB */
         sd->blk_len[0] &= 0xff;
         sd->blk_len[0] |= value << 8;
@@ -708,7 +718,6 @@
 
     case 0x10:	/* Fn0 Block Size LSB */
         return (sd->blk_len[0] >> 0) & 0xff;
-
     case 0x11:	/* Fn0 Block Size MSB */
         return (sd->blk_len[0] >> 8) & 0xff;
 
@@ -727,8 +736,53 @@
 static void sdio_fbr_write(struct sdio_s *sd,
                 int fn, uint32_t offset, uint8_t value)
 {
+    typeof(*sd->fbr) *func = &sd->fbr[fn - 1];
+
     switch (offset) {
+    case 0x00:	/* Standard SDIO Function interface code */
+        if ((func->stdfn & (1 << 6)) && (value & (1 << 7)))	/* CSASupport */
+            func->stdfn |= 1 << 7;				/* CSAEnable */
+        else
+            func->stdfn &= ~(1 << 7);				/* CSAEnable */
+        break;
+
+    case 0x02:	/* Power Selection */
+        sd->cccr.power |= value & 0x02;				/* EPS */
+        break;
+
+    case 0x0c:	/* Function CSA Pointer */
+        func->csa_addr &= 0xffff00;
+        func->csa_addr |= value <<  0;
+        break;
+    case 0x0d:	/* Function CSA Pointer */
+        func->csa_addr &= 0xff00ff;
+        func->csa_addr |= value <<  8;
+        break;
+    case 0x0e:	/* Function CSA Pointer */
+        func->csa_addr &= 0x00ffff;
+        func->csa_addr |= value << 16;
+        break;
+
+    case 0x0f:	/* Data access window to function's CSA */
+        if (func->stdfn & (1 << 7)) {				/* CSAEnable */
+            if (func->csa_wr)
+                func->csa_wr(sd, value);
+            func->csa_addr ++;
+            break;
+        }
+        goto bad_reg;
+
+    case 0x10:	/* I/O Block Size LSB */
+        sd->blk_len[fn] &= 0xff << 8;
+        sd->blk_len[fn] |= value;
+        break;
+    case 0x11:	/* I/O Block Size MSB */
+        sd->blk_len[fn] &= 0xff;
+        sd->blk_len[fn] |= value << 8;
+        break;
+
     default:
+    bad_reg:
         printf("%s: unknown register %02x\n", __FUNCTION__, offset);
     }
 }
@@ -736,7 +790,44 @@
 static uint8_t sdio_fbr_read(struct sdio_s *sd,
                 int fn, uint32_t offset)
 {
+    typeof(*sd->fbr) *func = &sd->fbr[fn - 1];
+
     switch (offset) {
+    case 0x00:	/* Standard SDIO Function interface code */
+        return func->stdfn;
+
+    case 0x01:	/* Extended standard SDIO Function interface code */
+        return func->ext_stdfn;
+
+    case 0x02:	/* Power Selection */
+        return func->power | 0x01;
+
+    case 0x09:	/* Function CIS Pointer */
+        return ((SDIO_CIS_START + func->cis_offset) >>  0) & 0xff;
+    case 0x0a:	/* Function CIS Pointer */
+        return ((SDIO_CIS_START + func->cis_offset) >>  8) & 0xff;
+    case 0x0b:	/* Function CIS Pointer */
+        return ((SDIO_CIS_START + func->cis_offset) >> 16) & 0xff;
+
+    case 0x0c:	/* Function CSA Pointer */
+        return (func->csa_addr >>  0) & 0xff;
+    case 0x0d:	/* Function CSA Pointer */
+        return (func->csa_addr >>  8) & 0xff;
+    case 0x0e:	/* Function CSA Pointer */
+        return (func->csa_addr >> 16) & 0xff;
+
+    case 0x0f:	/* Data access window to function's CSA */
+        if ((func->stdfn & (1 << 7)) && func->csa_rd)		/* CSAEnable */
+            return func->csa_rd(sd);
+        if (func->stdfn & (1 << 7))
+            func->csa_addr ++;
+        return 0x00;
+
+    case 0x10:	/* I/O Block Size LSB */
+        return (sd->blk_len[fn] >> 0) & 0xff;
+    case 0x11:	/* I/O Block Size MSB */
+        return (sd->blk_len[fn] >> 8) & 0xff;
+
     default:
         printf("%s: unknown register %02x\n", __FUNCTION__, offset);
         return 0;
@@ -845,6 +936,7 @@
 struct ar6k_s {
     struct sdio_s sd;
     NICInfo *nd;
+    uint8_t cis[0];
 };
 
 static void ar6k_set_ioocr(struct sdio_s *sd)
@@ -879,16 +971,62 @@
     CISTPL_END, 0xff,
 };
 
+const static uint8_t ar6k_fn1_cis[] = {
+    CISTPL_MANFID, 4,
+    0x71, 0x02,			/* SDIO Card manufacturer code */
+    0x0a, 0x01,			/* Manufacturer information (Part No, Rev) */
+
+    CISTPL_FUNCID, 2,
+    0x0c,			/* TODO Card funcion code: SDIO */
+    0x00,			/* TODO System initialization mask */
+
+    CISTPL_FUNCE, 42,
+    0x01,			/* Type of extended data: Function 1-7 */
+    0x01,			/* Function information bitmask: has Wake-up */
+    0x11,			/* Application Specification version level */
+    0x00, 0x00, 0x00, 0x00,	/* Product Serial Number: unsupported */
+    0x00, 0x00, 0x00, 0x00,	/* CSA space size: no CSA */
+    0x00,			/* CSA space properties: no CSA */
+    0x00, 0x08,			/* Maximum block size/byte count: 2048 */
+    0x00, 0x00, 0xff, 0x00,	/* OCR value: 2.8 - 3.6 V */
+    0x00,			/* Minimum required current: above 200mA */
+    0x00,			/* Average required current: above 200mA */
+    0x00,			/* Maximum required current: above 200mA */
+    0x00,			/* Minimum standby current: none */
+    0x01,			/* Average standby current: 1mA */
+    0x0a,			/* Maximum standby current: 10mA */
+    0x00, 0x00,			/* Minimum transfer bandwidth: no minimum */
+    0x00, 0x00,			/* Optimum transfer bandwidth: no optimum */
+    0x00, 0x00,			/* Ready timeout: no timeout */
+    0x00, 0x00,			/* Average required current: above 200mA */
+    0x00, 0x00,			/* Maximum required current: above 200mA */
+    0x01, 0x01,			/* Average HC-mode current: 256mA */
+    0x00, 0x01,			/* Maximum HC-mode current: 256mA */
+    0x00, 0x01,			/* Average LC-mode current: 256mA */
+    0x00, 0x01,			/* Maximum LC-mode current: 256mA */
+
+    CISTPL_END, 0xff,
+};
+
 struct sd_card_s *ar6k_init(NICInfo *nd)
 {
-    struct ar6k_s *s = (struct ar6k_s *) qemu_mallocz(sizeof(struct ar6k_s));
+    struct ar6k_s *s = (struct ar6k_s *) qemu_mallocz(sizeof(struct ar6k_s) +
+			    sizeof(ar6k_cis) + sizeof(ar6k_fn1_cis));
     struct sd_card_s *ret = sdio_init(&s->sd);
 
     s->nd = nd;
     s->sd.reset = (void *) ar6k_reset;
-    s->sd.cis = ar6k_cis;
-    s->sd.cislen = sizeof(ar6k_cis);
+    s->sd.fbr[0].stdfn = 0 | sdio_fn_none;
+    s->sd.fbr[0].ext_stdfn = sdio_ext_fn_none;
 
+    s->sd.cis = s->cis;
+    s->sd.cislen = sizeof(ar6k_cis) + sizeof(ar6k_fn1_cis);
+    s->sd.fbr[0].cis_offset = sizeof(ar6k_cis);
+
+    memcpy(s->cis + 0, ar6k_cis, sizeof(ar6k_cis));
+    memcpy(s->cis + s->sd.fbr[0].cis_offset,
+                    ar6k_fn1_cis, sizeof(ar6k_fn1_cis));
+
     ar6k_reset(s);
 
     return ret;

Modified: trunk/src/host/qemu-neo1973/hw/sd.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sd.h	2007-12-26 23:08:04 UTC (rev 3738)
+++ trunk/src/host/qemu-neo1973/hw/sd.h	2007-12-27 02:56:21 UTC (rev 3739)
@@ -87,6 +87,22 @@
     sd_initialization_state = sd_idle_state,
 };
 
+enum sdio_stdfn_e {
+    sdio_fn_none = 0,
+    sdio_fn_uart,	/* Standard UART */
+    sdio_fn_bt_a,	/* Type A for Bluetooth standard interface */
+    sdio_fn_bt_b,	/* Type B for Bluetooth standard interface */
+    sdio_fn_gps,
+    sdio_fn_camera,
+    sdio_fn_phs,
+    sdio_fn_wlan,
+    sdio_fn_ext = 0xf,	/* Extended SDIO Standard Function (below) */
+};
+
+enum sdio_ext_stdfn_e {
+    sdio_ext_fn_none = 0,
+};
+
 typedef struct sd_card_s {
     void *opaque;
     int (*do_command)(void *opaque, struct sd_request_s *req,





More information about the commitlog mailing list