Lines 1-4
Link Here
|
1 |
/* |
1 |
/* |
2 |
* |
2 |
* |
3 |
* Base on OpenBSD /sys/dev/pci/rtsx_pci.c & /dev/ic/rtsx.c |
3 |
* Base on OpenBSD /sys/dev/pci/rtsx_pci.c & /dev/ic/rtsx.c |
4 |
* on Linux /drivers/mmc/host/rtsx_pci_sdmmc.c, |
4 |
* on Linux /drivers/mmc/host/rtsx_pci_sdmmc.c, |
Lines 81-86
Link Here
|
81 |
|
81 |
|
82 |
/* The softc holds our per-instance data. */ |
82 |
/* The softc holds our per-instance data. */ |
83 |
struct rtsx_softc { |
83 |
struct rtsx_softc { |
|
|
84 |
int rtsx_double_clk; |
85 |
int rtsx_ssc_depth; |
86 |
int rtsx_vpclk; |
87 |
int rtsx_pcie_caps; |
84 |
struct mtx rtsx_mtx; /* device mutex */ |
88 |
struct mtx rtsx_mtx; /* device mutex */ |
85 |
device_t rtsx_dev; /* device */ |
89 |
device_t rtsx_dev; /* device */ |
86 |
int rtsx_flags; /* device flags */ |
90 |
int rtsx_flags; /* device flags */ |
Lines 167-172
static void rtsx_init_cmd(struct rtsx_softc *sc, struct mmc_command *cmd);
Link Here
|
167 |
static void rtsx_push_cmd(struct rtsx_softc *sc, uint8_t cmd, uint16_t reg, |
171 |
static void rtsx_push_cmd(struct rtsx_softc *sc, uint8_t cmd, uint16_t reg, |
168 |
uint8_t mask, uint8_t data); |
172 |
uint8_t mask, uint8_t data); |
169 |
static int rtsx_send_cmd(struct rtsx_softc *sc, struct mmc_command *cmd); |
173 |
static int rtsx_send_cmd(struct rtsx_softc *sc, struct mmc_command *cmd); |
|
|
174 |
static int rtsx_send_pci_cmd(struct rtsx_softc *sc); |
170 |
static void rtsx_send_cmd_nowait(struct rtsx_softc *sc, struct mmc_command *cmd); |
175 |
static void rtsx_send_cmd_nowait(struct rtsx_softc *sc, struct mmc_command *cmd); |
171 |
static void rtsx_req_done(struct rtsx_softc *sc); |
176 |
static void rtsx_req_done(struct rtsx_softc *sc); |
172 |
static void rtsx_soft_reset(struct rtsx_softc *sc); |
177 |
static void rtsx_soft_reset(struct rtsx_softc *sc); |
Lines 509-514
device_printf(sc->rtsx_dev, "FLAGS\n");
Link Here
|
509 |
device_printf(sc->rtsx_dev, "A\n"); |
514 |
device_printf(sc->rtsx_dev, "A\n"); |
510 |
rtsx_handle_card_present(sc); |
515 |
rtsx_handle_card_present(sc); |
511 |
} |
516 |
} |
|
|
517 |
#if 0 |
518 |
if (sc->rtsx_req == NULL) { |
519 |
device_printf(sc->rtsx_dev, "B\n"); |
520 |
#if 0 /* might have been SD int */ |
521 |
device_printf(sc->rtsx_dev, "Spurious interrupt - no active request\n"); |
522 |
#endif |
523 |
|
512 |
if (sc->rtsx_req == NULL) { |
524 |
if (sc->rtsx_req == NULL) { |
513 |
device_printf(sc->rtsx_dev, "B\n"); |
525 |
device_printf(sc->rtsx_dev, "B\n"); |
514 |
#if 0 /* might have been SD int */ |
526 |
#if 0 /* might have been SD int */ |
Lines 517-522
device_printf(sc->rtsx_dev, "B\n");
Link Here
|
517 |
RTSX_UNLOCK(sc); |
529 |
RTSX_UNLOCK(sc); |
518 |
return; |
530 |
return; |
519 |
} |
531 |
} |
|
|
532 |
#endif |
520 |
if (status & (RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT)) { |
533 |
if (status & (RTSX_TRANS_OK_INT | RTSX_TRANS_FAIL_INT)) { |
521 |
sc->rtsx_intr_status |= status; |
534 |
sc->rtsx_intr_status |= status; |
522 |
wakeup(&sc->rtsx_intr_status); |
535 |
wakeup(&sc->rtsx_intr_status); |
Lines 605-611
rtsx_init(struct rtsx_softc *sc)
Link Here
|
605 |
|
618 |
|
606 |
if (bootverbose) |
619 |
if (bootverbose) |
607 |
device_printf(sc->rtsx_dev, "rtsx_init() rtsx_flags = 0x%04x\n", sc->rtsx_flags); |
620 |
device_printf(sc->rtsx_dev, "rtsx_init() rtsx_flags = 0x%04x\n", sc->rtsx_flags); |
608 |
|
621 |
/* Power on SSC clock. */ |
|
|
622 |
RTSX_CLR(sc, RTSX_FPDCTL, RTSX_SSC_POWER_DOWN); |
623 |
error=0; |
624 |
if (sc->rtsx_flags & RTSX_F_5209) |
625 |
error = rtsx_write_phy(sc, 0x00, 0xB966); |
609 |
/* Enable interrupt write-clear (default is read-clear). */ |
626 |
/* Enable interrupt write-clear (default is read-clear). */ |
610 |
RTSX_CLR(sc, RTSX_NFTS_TX_CTRL, RTSX_INT_READ_CLR); |
627 |
RTSX_CLR(sc, RTSX_NFTS_TX_CTRL, RTSX_INT_READ_CLR); |
611 |
|
628 |
|
Lines 800-805
rtsx_write_phy(struct rtsx_softc *sc, uint8_t addr, uint16_t val)
Link Here
|
800 |
|
817 |
|
801 |
return (0); |
818 |
return (0); |
802 |
} |
819 |
} |
|
|
820 |
static int rtsx_pci_write_register(struct rtsx_softc *sc, u_int16_t addr, u_int8_t mask, u_int8_t data) |
821 |
{ |
822 |
printf("%s %s %d 0x%x 0x%x 0x%x\n",__FILE__,__FUNCTION__,__LINE__,addr,mask,data); |
823 |
int i; |
824 |
u_int32_t val = RTSX_HAIMR_WRITE_START; |
825 |
|
826 |
val |= (u_int32_t)(addr & 0x3FFF) << 16; |
827 |
val |= (u_int32_t)mask << 8; |
828 |
val |= (u_int32_t)data; |
829 |
|
830 |
WRITE4(sc, RTSX_HAIMR, val); |
831 |
|
832 |
for (i = 0; i < RTSX_MAX_RW_REG_CNT; i++) { |
833 |
val = READ4(sc, RTSX_HAIMR); |
834 |
if ((val & RTSX_HAIMR_TRANS_END) == 0) { |
835 |
if (data != (u_int8_t)val) |
836 |
return -EIO; |
837 |
return 0; |
838 |
} |
839 |
} |
840 |
|
841 |
return -ETIMEDOUT; |
842 |
} |
803 |
|
843 |
|
804 |
/* |
844 |
/* |
805 |
* Set or change SDCLK frequency or disable the SD clock. |
845 |
* Set or change SDCLK frequency or disable the SD clock. |
Lines 808-867
rtsx_write_phy(struct rtsx_softc *sc, uint8_t addr, uint16_t val)
Link Here
|
808 |
static int |
848 |
static int |
809 |
rtsx_set_sd_clock(struct rtsx_softc *sc, uint32_t freq) |
849 |
rtsx_set_sd_clock(struct rtsx_softc *sc, uint32_t freq) |
810 |
{ |
850 |
{ |
811 |
uint8_t n; |
851 |
switch (sc->rtsx_host.ios.timing) { |
812 |
int div; |
852 |
case bus_timing_uhs_sdr104: |
813 |
int mcu; |
853 |
case bus_timing_uhs_sdr50: |
814 |
int error = 0; |
854 |
sc->rtsx_ssc_depth = RTSX_SSC_DEPTH_2M; |
|
|
855 |
sc->rtsx_vpclk = 1; |
856 |
sc->rtsx_double_clk = 0; |
857 |
break; |
858 |
case bus_timing_mmc_ddr52: |
859 |
case bus_timing_uhs_ddr50: |
860 |
case bus_timing_uhs_sdr25: |
861 |
sc->rtsx_ssc_depth = RTSX_SSC_DEPTH_1M; |
862 |
break; |
863 |
default: |
864 |
sc->rtsx_ssc_depth = RTSX_SSC_DEPTH_500K; |
865 |
break; |
866 |
} |
867 |
int err, clk; |
868 |
u_int8_t n, clk_divider, mcu_cnt, div; |
869 |
int initial_mode = (sc->rtsx_host.ios.clock <= 1000000) ? 1 : 0; |
870 |
|
871 |
if (initial_mode) { |
872 |
clk_divider = RTSX_SD_CLK_DIVIDE_128; |
873 |
freq = 30000000; |
874 |
} else { |
875 |
clk_divider = RTSX_SD_CLK_DIVIDE_0; |
876 |
} |
877 |
err = rtsx_pci_write_register(sc, RTSX_SD_CFG1, |
878 |
RTSX_SD_CLK_DIVIDE_MASK, clk_divider); |
879 |
if (err < 0) |
880 |
return err; |
815 |
|
881 |
|
816 |
if (bootverbose) |
|
|
817 |
device_printf(sc->rtsx_dev, "rtsx_set_sd_clock(%u)\n", freq); |
818 |
|
882 |
|
819 |
if (freq == RTSX_SDCLK_OFF) { |
|
|
820 |
error = rtsx_stop_sd_clock(sc); |
821 |
goto done; |
822 |
} |
823 |
|
883 |
|
824 |
/* Round down to a supported frequency. */ |
884 |
freq /= 1000000; |
825 |
if (freq >= RTSX_SDCLK_50MHZ) |
885 |
device_printf(sc->rtsx_dev, "Switch card clock to %dMHz\n", freq); |
826 |
freq = RTSX_SDCLK_50MHZ; |
|
|
827 |
else if (freq >= RTSX_SDCLK_25MHZ) |
828 |
freq = RTSX_SDCLK_25MHZ; |
829 |
else |
830 |
freq = RTSX_SDCLK_400KHZ; |
831 |
|
886 |
|
832 |
/* |
887 |
clk = freq; |
833 |
* Configure the clock frequency. |
888 |
if (!initial_mode) |
834 |
*/ |
889 |
clk = freq * 2; |
835 |
switch (freq) { |
890 |
device_printf(sc->rtsx_dev, "Internal SSC clock: %dMHz (cur_clock = %d)\n", |
836 |
case RTSX_SDCLK_400KHZ: |
891 |
clk, sc->rtsx_host.ios.clock); |
837 |
n = 80; /* minimum */ |
|
|
838 |
div = RTSX_CLK_DIV_8; |
839 |
mcu = 7; |
840 |
RTSX_SET(sc, RTSX_SD_CFG1, RTSX_CLK_DIVIDE_128); |
841 |
break; |
842 |
case RTSX_SDCLK_25MHZ: |
843 |
n = 100; |
844 |
div = RTSX_CLK_DIV_4; |
845 |
mcu = 7; |
846 |
RTSX_CLR(sc, RTSX_SD_CFG1, RTSX_CLK_DIVIDE_MASK); |
847 |
break; |
848 |
case RTSX_SDCLK_50MHZ: |
849 |
n = 100; |
850 |
div = RTSX_CLK_DIV_2; |
851 |
mcu = 7; |
852 |
RTSX_CLR(sc, RTSX_SD_CFG1, RTSX_CLK_DIVIDE_MASK); |
853 |
break; |
854 |
default: |
855 |
error = EINVAL; |
856 |
goto done; |
857 |
} |
858 |
|
892 |
|
859 |
/* |
893 |
|
860 |
* Enable SD clock. |
894 |
n = (u_int8_t)(clk - 2); |
861 |
*/ |
895 |
if ((clk <= 2) || (n > RTSX_MAX_DIV_N_PCR)) |
862 |
error = rtsx_switch_sd_clock(sc, n, div, mcu); |
896 |
return -EINVAL; |
863 |
done: |
897 |
|
864 |
return error; |
898 |
mcu_cnt = (u_int8_t)(125/clk + 3); |
|
|
899 |
if (mcu_cnt > 15) |
900 |
mcu_cnt = 15; |
901 |
|
902 |
/* Make sure that the SSC clock div_n is not less than MIN_DIV_N_PCR */ |
903 |
div = RTSX_CLK_DIV_1; |
904 |
while ((n < RTSX_MIN_DIV_N_PCR) && (div < RTSX_CLK_DIV_8)) { |
905 |
n = (n + 2) * 2 - 2; |
906 |
div++; |
907 |
} |
908 |
device_printf(sc->rtsx_dev, "n = %d, div = %d\n", n, div); |
909 |
|
910 |
sc->rtsx_ssc_depth = (sc->rtsx_ssc_depth> 1) ? (sc->rtsx_ssc_depth - 1) : sc->rtsx_ssc_depth; |
911 |
if (div > RTSX_CLK_DIV_1) { |
912 |
if (sc->rtsx_ssc_depth > (div - 1)) |
913 |
sc->rtsx_ssc_depth -= (div - 1); |
914 |
else |
915 |
sc->rtsx_ssc_depth = RTSX_SSC_DEPTH_4M; |
916 |
} |
917 |
RTSX_LOCK(sc); |
918 |
sc->rtsx_cmd_index=0; |
919 |
|
920 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_CLK_CTL, |
921 |
RTSX_CLK_LOW_FREQ, RTSX_CLK_LOW_FREQ); |
922 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_CLK_DIV, |
923 |
0xFF, (div << 4) | mcu_cnt); |
924 |
device_printf(sc->rtsx_dev,"ssc depth 0x%x\n",sc->rtsx_ssc_depth); |
925 |
|
926 |
|
927 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SSC_CTL1, RTSX_SSC_RSTB, 0); |
928 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SSC_CTL2, |
929 |
RTSX_SSC_DEPTH_MASK, sc->rtsx_ssc_depth); |
930 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SSC_DIV_N_0, 0xFF, n); |
931 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SSC_CTL1, RTSX_SSC_RSTB, RTSX_SSC_RSTB); |
932 |
err = rtsx_send_pci_cmd(sc); |
933 |
RTSX_UNLOCK(sc); |
934 |
if (err > 0) |
935 |
return err; |
936 |
|
937 |
/* Wait SSC clock stable */ |
938 |
DELAY(200); |
939 |
err = rtsx_pci_write_register(sc, RTSX_CLK_CTL, RTSX_CLK_LOW_FREQ, 0); |
940 |
if (err < 0) |
941 |
return err; |
942 |
sc->rtsx_host.ios.clock=freq; |
943 |
return 0; |
865 |
} |
944 |
} |
866 |
|
945 |
|
867 |
static int |
946 |
static int |
Lines 1293-1299
rtsx_push_cmd(struct rtsx_softc *sc, uint8_t cmd, uint16_t reg,
Link Here
|
1293 |
---*/ |
1372 |
---*/ |
1294 |
|
1373 |
|
1295 |
} |
1374 |
} |
1296 |
|
1375 |
static int |
|
|
1376 |
rtsx_send_pci_cmd(struct rtsx_softc *sc) |
1377 |
{ |
1378 |
int error = 0; |
1379 |
|
1380 |
if (bootverbose) |
1381 |
device_printf(sc->rtsx_dev, "rtsx_send_pci_cmd()\n"); |
1382 |
|
1383 |
sc->rtsx_intr_status = 0; |
1384 |
|
1385 |
/* Sync command DMA buffer. */ |
1386 |
bus_dmamap_sync(sc->rtsx_cmd_dma_tag, sc->rtsx_cmd_dmamap, BUS_DMASYNC_PREREAD); |
1387 |
bus_dmamap_sync(sc->rtsx_cmd_dma_tag, sc->rtsx_cmd_dmamap, BUS_DMASYNC_PREWRITE); |
1388 |
/* Tell the chip where the command buffer is and run the commands. */ |
1389 |
WRITE4(sc, RTSX_HCBAR, (uint32_t)sc->rtsx_cmd_buffer); |
1390 |
WRITE4(sc, RTSX_HCBCTLR, |
1391 |
((sc->rtsx_cmd_index * 4 & 0x00ffffff) | RTSX_START_CMD | RTSX_HW_AUTO_RSP)); |
1392 |
if ((error = rtsx_wait_intr(sc, RTSX_TRANS_OK_INT, hz * sc->rtsx_timeout))) { |
1393 |
printf("ERRPR 0x%x\n",*((u_int32_t*)sc->rtsx_cmd_dmamem)); |
1394 |
return error; |
1395 |
} |
1396 |
bus_dmamap_sync(sc->rtsx_cmd_dma_tag, sc->rtsx_cmd_dmamap, BUS_DMASYNC_POSTREAD); |
1397 |
bus_dmamap_sync(sc->rtsx_cmd_dma_tag, sc->rtsx_cmd_dmamap, BUS_DMASYNC_POSTWRITE); |
1398 |
return (error); |
1399 |
} |
1297 |
/* Run the command queue and wait for completion. */ |
1400 |
/* Run the command queue and wait for completion. */ |
1298 |
static int |
1401 |
static int |
1299 |
rtsx_send_cmd(struct rtsx_softc *sc, struct mmc_command *cmd) |
1402 |
rtsx_send_cmd(struct rtsx_softc *sc, struct mmc_command *cmd) |
Lines 1464-1555
rtsx_send_req_get_resp(struct rtsx_softc *sc, struct mmc_command *cmd) {
Link Here
|
1464 |
static int |
1567 |
static int |
1465 |
rtsx_xfer_short(struct rtsx_softc *sc, struct mmc_command *cmd) |
1568 |
rtsx_xfer_short(struct rtsx_softc *sc, struct mmc_command *cmd) |
1466 |
{ |
1569 |
{ |
1467 |
uint8_t rsp_type; |
1570 |
int err; |
1468 |
int read; |
1571 |
u_int8_t trans_mode; |
1469 |
int tmode; |
|
|
1470 |
int error = 0; |
1471 |
|
1572 |
|
1472 |
if (cmd->data->xfer_len == 0) |
1573 |
device_printf(sc->rtsx_dev, "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
1473 |
cmd->data->xfer_len = (cmd->data->len > RTSX_MAX_DATA_BLKLEN) ? |
1574 |
__FUNCTION__, cmd->opcode, cmd->arg); |
1474 |
RTSX_MAX_DATA_BLKLEN : cmd->data->len; |
1575 |
//buf = malloc(sizeof(u_int32_t)*cmd->data->len, M_RTSX, M_NOWAIT); |
1475 |
|
|
|
1476 |
if (bootverbose) |
1477 |
device_printf(sc->rtsx_dev, "rtsx_xfer_short(): %ld bytes with block size %ld\n", |
1478 |
cmd->data->len, cmd->data->xfer_len); |
1479 |
|
1576 |
|
1480 |
if (cmd->data->len > 512) { |
1577 |
if (cmd->data->flags & MMC_DATA_READ) { |
1481 |
device_printf(sc->rtsx_dev, "rtsx_xfer_short() length too large: %ld > 512\n", |
1578 |
int initial_mode = (sc->rtsx_host.ios.clock <= 1000000) ? 1 : 0; |
1482 |
cmd->data->len); |
1579 |
if(initial_mode) |
1483 |
cmd->error = MMC_ERR_FAILED; |
1580 |
rtsx_pci_write_register(sc, RTSX_SD_CFG1, |
1484 |
return ENOMEM; |
1581 |
RTSX_SD_CLK_DIVIDE_MASK, RTSX_SD_CLK_DIVIDE_0); |
1485 |
} |
1582 |
else |
|
|
1583 |
rtsx_pci_write_register(sc, RTSX_SD_CFG1, |
1584 |
RTSX_SD_CLK_DIVIDE_MASK, RTSX_SD_CLK_DIVIDE_128); |
1486 |
|
1585 |
|
1487 |
rsp_type = rtsx_response_type(cmd->flags & MMC_RSP_MASK); |
|
|
1488 |
if (rsp_type == 0) { |
1489 |
device_printf(sc->rtsx_dev, "Unknown response type 0x%lx\n", (cmd->flags & MMC_RSP_MASK)); |
1490 |
cmd->error = MMC_ERR_FAILED; |
1491 |
return (EINVAL); |
1492 |
} |
1493 |
|
1494 |
read = ISSET(cmd->data->flags, MMC_DATA_READ); |
1495 |
if (!read && cmd->data != NULL && cmd->data->len > 0) { |
1496 |
error = rtsx_write_ppbuf(sc, cmd); |
1497 |
if (error) |
1498 |
return (error); |
1499 |
} |
1500 |
rtsx_init_cmd(sc, cmd); |
1501 |
|
1586 |
|
1502 |
/* Queue commands to configure data transfer size. */ |
|
|
1503 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_L, |
1504 |
0xff, (cmd->data->xfer_len & 0xff)); |
1505 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_H, |
1506 |
0xff, (cmd->data->xfer_len >> 8)); |
1507 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_L, |
1508 |
0xff, ((cmd->data->len / cmd->data->xfer_len) & 0xff)); |
1509 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_H, |
1510 |
0xff, ((cmd->data->len / cmd->data->xfer_len) >> 8)); |
1511 |
|
1587 |
|
1512 |
/* Queue command to set response type. */ |
|
|
1513 |
/*--- from netbsd --- |
1514 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CFG2, |
1515 |
0xff, rsp_type); |
1516 |
---*/ |
1517 |
|
1588 |
|
1518 |
/* from linux: rtsx_pci_sdmmc.c sd_read_data() */ |
|
|
1519 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CFG2, |
1520 |
0xff, RTSX_SD_CALCULATE_CRC7 | RTSX_SD_CHECK_CRC16 | |
1521 |
RTSX_SD_NO_WAIT_BUSY_END | RTSX_SD_CHECK_CRC7 | RTSX_SD_RSP_LEN_6); |
1522 |
|
1523 |
/* Use the ping-pong buffer (cmd buffer). */ |
1524 |
if (read) |
1525 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_CARD_DATA_SOURCE, |
1526 |
0x01, RTSX_PINGPONG_BUFFER); |
1527 |
|
1589 |
|
1528 |
/* Queue commands to perform SD transfer. */ |
|
|
1529 |
tmode = read ? RTSX_TM_NORMAL_READ : RTSX_TM_AUTO_WRITE2; |
1530 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_TRANSFER, |
1531 |
0xff, tmode | RTSX_SD_TRANSFER_START); |
1532 |
rtsx_push_cmd(sc, RTSX_CHECK_REG_CMD, RTSX_SD_TRANSFER, |
1533 |
RTSX_SD_TRANSFER_END, RTSX_SD_TRANSFER_END); |
1534 |
|
1590 |
|
1535 |
/* Run the command queue and wait for completion. */ |
1591 |
} |
1536 |
if ((error = rtsx_send_cmd(sc, cmd))) |
|
|
1537 |
return (error); |
1538 |
|
1592 |
|
1539 |
if (read && cmd->data != NULL && cmd->data->len > 0) { |
1593 |
trans_mode = RTSX_SD_TM_NORMAL_READ; |
1540 |
error = rtsx_read_ppbuf(sc, cmd); |
1594 |
|
1541 |
} |
1595 |
sc->rtsx_cmd_index=0; |
|
|
1596 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CMD0, 0xFF, |
1597 |
RTSX_SD_CMD_START | cmd->opcode); |
1598 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CMD1, 0xFF, cmd->arg >> 24); |
1599 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CMD2, 0xFF, cmd->arg >> 16); |
1600 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CMD3 , 0xFF, cmd->arg >> 8); |
1601 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CMD4 , 0xFF, cmd->arg); |
1602 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_L, 0xFF, 1); |
1603 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_H, 0xFF, 1 >> 8); |
1604 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_L, 0xFF, cmd->data->len); |
1605 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_H, 0xFF, cmd->data->len >> 8); |
1606 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CFG2, 0xFF, |
1607 |
RTSX_SD_CALCULATE_CRC7 | RTSX_SD_CHECK_CRC16 | |
1608 |
RTSX_SD_NO_WAIT_BUSY_END | RTSX_SD_CHECK_CRC7 | RTSX_SD_RSP_LEN_6); |
1609 |
|
1610 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, |
1611 |
RTSX_CARD_DATA_SOURCE, 0x01, RTSX_PINGPONG_BUFFER); |
1612 |
|
1613 |
rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_TRANSFER, |
1614 |
0xFF, trans_mode | RTSX_SD_TRANSFER_START); |
1615 |
rtsx_push_cmd(sc, RTSX_CHECK_REG_CMD, RTSX_SD_TRANSFER, |
1616 |
RTSX_SD_TRANSFER_END, RTSX_SD_TRANSFER_END); |
1617 |
|
1618 |
err = rtsx_send_pci_cmd(sc); |
1619 |
|
1620 |
if (err != 0) { |
1621 |
device_printf(sc->rtsx_dev, |
1622 |
"rtsx_pci_send_cmd fail (err = %d)\n", err); |
1623 |
return err; |
1624 |
} |
1542 |
|
1625 |
|
1543 |
if (bootverbose) { |
|
|
1544 |
uint32_t *data = (uint32_t *)cmd->data->data; |
1545 |
int i; |
1546 |
int n = (cmd->data->len > 64) ? 8 : ((cmd->data->len - 1) / 4) + 1; |
1547 |
device_printf(sc->rtsx_dev, "rtsx_xfer_short():\n"); |
1548 |
for (i = 0; i < n; i++) |
1549 |
device_printf(sc->rtsx_dev, "\t\t\t0x%08x\n", data[i]); |
1550 |
} |
1551 |
|
1626 |
|
1552 |
return (error); |
1627 |
if(err==0) { |
|
|
1628 |
err = rtsx_read_ppbuf(sc, cmd); |
1629 |
|
1630 |
if (err > 0) { |
1631 |
device_printf(sc->rtsx_dev, |
1632 |
"rtsx_pci_read_ppbuf fail (err = %d)\n", err); |
1633 |
return err; |
1634 |
} |
1635 |
return err; |
1636 |
} |
1637 |
return err; |
1553 |
} |
1638 |
} |
1554 |
|
1639 |
|
1555 |
/* Use ping-pong buffer (cmd buffer) for transfer */ |
1640 |
/* Use ping-pong buffer (cmd buffer) for transfer */ |