diff --git a/rtsx.c b/rtsx.c index ef7bccc..a5f91dd 100644 --- a/rtsx.c +++ b/rtsx.c @@ -216,7 +216,7 @@ static void rtsx_handle_card_present(struct rtsx_softc *sc); #define RTSX_DMA_MAX_SEGSIZE 0x80000 #define RTSX_HOSTCMD_MAX 256 #define RTSX_HOSTCMD_BUFSIZE (sizeof(uint32_t) * RTSX_HOSTCMD_MAX) -#define RTSX_DMA_DATA_BUFSIZE MAXPHYS / 4 +#define RTSX_DMA_DATA_BUFSIZE MAXPHYS #define RTSX_ADMA_DESC_SIZE (sizeof(uint64_t) * SDMMC_MAXNSEGS) #define RTSX_NREG ((0XFDAE - 0XFDA0) + (0xFD69 - 0xFD32) + (0xFE34 - 0xFE20)) @@ -1630,6 +1630,7 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) cmd->data->xfer_len = (cmd->data->len > RTSX_MAX_DATA_BLKLEN) ? RTSX_MAX_DATA_BLKLEN : cmd->data->len; + RTSX_CLR(sc,RTSX_SD_CFG1,RTSX_CLK_DIVIDE_MASK); if (bootverbose) device_printf(sc->rtsx_dev, "rtsx_xfer() - %s xfer: %ld bytes with block size %ld\n", read ? "Read" : "Write", @@ -1643,7 +1644,7 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) } /* Configure DMA transfer mode parameters. */ - cfg2 = RTSX_SD_NO_CHECK_WAIT_CRC_TO | RTSX_SD_CHECK_CRC16 | + cfg2 = RTSX_SD_CHECK_CRC16 | RTSX_SD_NO_WAIT_BUSY_END | RTSX_SD_RSP_LEN_0; if (read) { dma_dir = RTSX_DMA_DIR_FROM_CARD; @@ -1652,7 +1653,12 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) * sent the read command and gotten the response, and will * send CMD 12 manually after reading multiple blocks. */ - tmode = RTSX_TM_AUTO_READ3; + tmode = RTSX_TM_AUTO_READ1; + if(cmd->opcode == 18) { + cfg2 = 0x1; /*RTSX_SD_NO_CHECK_WAIT_CRC_TO|RTSX_SD_CHECK_CRC16 |*/ + //RTSX_SD_NO_WAIT_BUSY_END | RTSX_SD_RSP_LEN_0; + tmode = RTSX_TM_AUTO_READ1; + } cfg2 |= RTSX_SD_CALCULATE_CRC7 | RTSX_SD_CHECK_CRC7; } else { dma_dir = RTSX_DMA_DIR_TO_CARD; @@ -1661,44 +1667,46 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) * sent the write command and gotten the response, and will * send CMD 12 manually after writing multiple blocks. */ - tmode = RTSX_TM_AUTO_WRITE3; + tmode = RTSX_TM_AUTO_WRITE1; cfg2 |= RTSX_SD_NO_CALCULATE_CRC7 | RTSX_SD_NO_CHECK_CRC7; } - sc->rtsx_cmd_index = 0; - - /* Queue command to set response type. */ - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CFG2, - 0xff, cfg2); - + //sc->rtsx_cmd_index = 0; + rtsx_init_cmd(sc,cmd); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_L, + 0xff, ((cmd->data->len / cmd->data->xfer_len) & 0xff)); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_H, + 0xff, ((cmd->data->len / cmd->data->xfer_len) >> 8)); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_L, + 0xff, (cmd->data->xfer_len & 0xff)); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_H, + 0xff, (cmd->data->xfer_len >> 8)); + + /* Configure DMA controller. */ + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_IRQSTAT0, + RTSX_DMA_DONE_INT, RTSX_DMA_DONE_INT); /* Queue commands to configure data transfer size. */ - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_L, - 0xff, (cmd->data->xfer_len & 0xff)); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BYTE_CNT_H, - 0xff, (cmd->data->xfer_len >> 8)); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_L, - 0xff, ((cmd->data->len / cmd->data->xfer_len) & 0xff)); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_BLOCK_CNT_H, - 0xff, ((cmd->data->len / cmd->data->xfer_len) >> 8)); + + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC3, + 0xff, cmd->data->len >> 24); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC2, + 0xff, cmd->data->len >> 16); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC1, + 0xff, cmd->data->len >> 8); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC0, + 0xff, cmd->data->len); + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMACTL, + RTSX_DMA_EN | RTSX_DMA_DIR | RTSX_DMA_PACK_SIZE_MASK, + RTSX_DMA_EN | dma_dir | RTSX_DMA_512); /* Use the DMA ring buffer for commands which transfer data. */ rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_CARD_DATA_SOURCE, 0x01, RTSX_RING_BUFFER); + /* Queue command to set response type. */ + rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_CFG2, + 0xff, cfg2); + - /* Configure DMA controller. */ - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_IRQSTAT0, - RTSX_DMA_DONE_INT, RTSX_DMA_DONE_INT); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC3, - 0xff, cmd->data->len >> 24); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC2, - 0xff, cmd->data->len >> 16); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC1, - 0xff, cmd->data->len >> 8); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMATC0, - 0xff, cmd->data->len); - rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_DMACTL, - RTSX_DMA_EN | RTSX_DMA_DIR | RTSX_DMA_PACK_SIZE_MASK, - RTSX_DMA_EN | dma_dir | RTSX_DMA_512); /* Queue commands to perform SD transfer. */ rtsx_push_cmd(sc, RTSX_WRITE_REG_CMD, RTSX_SD_TRANSFER, @@ -1717,8 +1725,8 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) /* Tell the chip where the data buffer is and run the transfer. */ WRITE4(sc, RTSX_HDBAR, sc->rtsx_data_buffer); - WRITE4(sc, RTSX_HDBCTLR, RTSX_TRIG_DMA | (read ? RTSX_DMA_READ : 0) | - (cmd->data->len & 0x00ffffff)); + WRITE4(sc, RTSX_HDBCTLR, RTSX_TRIG_DMA | (read ? RTSX_DMA_READ : 0) | + (cmd->data->len & 0x00ffffff)); if ((error = rtsx_wait_intr(sc, RTSX_TRANS_OK_INT, hz * sc->rtsx_timeout))) { cmd->error = MMC_ERR_TIMEOUT; @@ -1727,10 +1735,12 @@ rtsx_xfer(struct rtsx_softc *sc, struct mmc_command *cmd) /* Sync command DMA buffer. */ bus_dmamap_sync(sc->rtsx_data_dma_tag, sc->rtsx_data_dmamap, BUS_DMASYNC_POSTREAD); - bus_dmamap_sync(sc->rtsx_data_dma_tag, sc->rtsx_data_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_sync(sc->rtsx_data_dma_tag, sc->rtsx_data_dmamap, BUS_DMASYNC_POSTWRITE); + if(read) + memcpy(cmd->data->data, sc->rtsx_data_dmamem, cmd->data->len); + else + memcpy(sc->rtsx_data_dmamem,cmd->data->data,cmd->data->len); - memcpy(cmd->data->data, sc->rtsx_data_dmamem, cmd->data->len); - return (error); } @@ -1870,7 +1880,7 @@ rtsx_mmcbr_update_ios(device_t bus, device_t child) case bus_width_1: bus_width = RTSX_BUS_WIDTH_1; break; - case bus_width_4: + case bus_width_4: bus_width = RTSX_BUS_WIDTH_4; break; case bus_width_8: @@ -1899,19 +1909,19 @@ rtsx_mmcbr_update_ios(device_t bus, device_t child) break; case power_up: if (sc->rtsx_power_mode != power_up) { - rtsx_bus_power_up(sc); - sc->rtsx_power_mode = power_up; + rtsx_bus_power_on(sc); + sc->rtsx_power_mode = power_up; } break; case power_on: if (sc->rtsx_power_mode != power_on) { - rtsx_bus_power_on(sc); + rtsx_bus_power_up(sc); sc->rtsx_power_mode = power_on; } break; }; - return (0); + return (0); } /* Set output stage logic power voltage */ @@ -1946,11 +1956,12 @@ rtsx_mmcbr_switch_vccq(device_t bus, device_t child __unused) if (bootverbose) device_printf(sc->rtsx_dev, "rtsx_mmcbr_switch_vccq(%d)\n", vccq); - rtsx_bus_power_off(sc); - DELAY(200); + //rtsx_bus_power_off(sc); + + //DELAY(200); - rtsx_bus_power_on(sc); + //rtsx_bus_power_on(sc); sc->rtsx_power_mode = power_on; return (0); @@ -1966,7 +1977,7 @@ rtsx_mmcbr_tune(device_t bus, device_t child __unused, bool hs400 __unused) if (bootverbose) device_printf(sc->rtsx_dev, "rtsx_mmcbr_tune()\n"); - + sc->rtsx_host.ios.clock=RTSX_SDCLK_50MHZ; return (0); } @@ -2019,8 +2030,8 @@ rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *re } if (cmd->data == NULL) { - error = rtsx_send_req_get_resp(sc, cmd); - } else if (cmd->data->len <= 512) { + error = rtsx_send_req_get_resp(sc, cmd); + } else if (cmd->data->len < 512) { error = rtsx_xfer_short(sc, cmd); if (error) { uint8_t stat1; @@ -2031,9 +2042,7 @@ rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *re } } } else { - error = rtsx_send_req_get_resp(sc, cmd); - if (!error) { - error = rtsx_xfer(sc, cmd); + error = rtsx_xfer(sc, cmd); if (error) { uint8_t stat1; if (rtsx_read(sc, RTSX_SD_STAT1, &stat1) == 0 && @@ -2042,7 +2051,6 @@ rtsx_mmcbr_request(device_t bus, device_t child __unused, struct mmc_request *re cmd->error = MMC_ERR_BADCRC; } } - } } done: