}
if (__predict_false(mmc_debug > 2 || (mmc_debug > 0 &&
req->cmd->error != MMC_ERR_NONE)))
- device_printf(sc->dev, "CMD%d RESULT: %d\n",
- req->cmd->opcode, req->cmd->error);
+ device_printf(sc->dev, "CMD%d RESULT: %d, ret = 0x%x\n",
+ req->cmd->opcode, req->cmd->error, ret);
return (0);
}
}
static uint32_t
-mmc_select_compat_volt(struct mmc_softc *sc, device_t dev, uint32_t card_ocr, uint32_t host_ocr)
+mmc_select_compat_volt(struct mmc_softc *sc, device_t dev, uint32_t card_ocr, uint32_t host_ocr, uint8_t power_reset)
{
uint32_t temp_ocr = card_ocr & MMC_OCR_VOLTAGE;
int lsb;
* boot-loader without power-off the card when the loader exist.
* some cards will failed being initiated, cus it is already initiated.
*/
- mmc_power_down(sc);
- /* Wait at least 1ms according to SD spec. */
- dpal_mdelay(1);
- mmc_power_up(sc);
+ if (power_reset) {
+ mmc_power_down(sc);
+ /* Wait at least 1ms according to SD spec. */
+ dpal_mdelay(1);
+ mmc_power_up(sc);
+ }
mmcbr_set_vdd(dev, lsb);
mmcbr_update_ios(dev);
#endif
if (sdio_io_card_reset(sc) != 0)
dev_logi(sc->dev, "SDIO reset failed\n");
- ocr = mmc_select_compat_volt(sc, dev, ocr, host_ocr);
+ ocr = mmc_select_compat_volt(sc, dev, ocr, host_ocr, true);
}
#endif
} else {
dev_logi(dev, "sd card supports 1.8v, but host can't do.\n");
ocr &= ~MMC_OCR_LOW_VOLTAGE;
}
- ocr = mmc_select_compat_volt(sc, dev, ocr, host_ocr); /* Check ocr if the host supports */
+ ocr = mmc_select_compat_volt(sc, dev, ocr, host_ocr, true); /* Check ocr if the host supports */
}
sc->squelched--;
mmcbr_set_ocr(dev, (int)ocr);
uint32_t ret_ocr, ocr;
uint32_t resp;
struct mmc_softc *sc;
+ struct mmc_ivars *ivar;
if (func == NULL || func->sc == NULL || func->sc->dev == NULL)
return (-EIO);
if (sc == NULL || sc->dev == NULL)
return (-EIO);
- power_cycle(sc);
host_hw_init(device_get_ivars(sc->dev));
sc->last_rca = 0;
- sc->card_init_status = MMC_CARD_UNINIT; // 需要, 否则中间过程时钟会被关掉
+
+ mmc_acquire_bus(sc->dev, sc->dev);
mmc_idle_cards(sc);
if (ret)
goto err;
- ocr = mmc_select_compat_volt(sc, sc->dev, ocr, (uint32_t)mmcbr_get_host_ocr(sc->dev));
+ /* caller may ctrl power cycle when necessary, here do not power cycle again */
+ ocr = mmc_select_compat_volt(sc, sc->dev, ocr, (uint32_t)mmcbr_get_host_ocr(sc->dev), false);
+
ret = sdio_io_send_op_cond(sc, ocr, &ret_ocr);
if (ret)
goto err;
if (ret)
goto err;
- ret = mmc_select_card(sc, (resp >> 16));
+ ivar = device_get_ivars(func->sc->dev);
+ ivar->rca = resp >> 16;
+ ret = mmc_select_card(sc, ivar->rca);
if (ret)
goto err;
mmc_calculate_clock(sc);
+
+ mmc_release_bus(sc->dev, sc->dev);
+
return (0);
err:
+ mmc_release_bus(sc->dev, sc->dev);
dev_loge(sc->dev, "sdio_reset_comm error, return ret:%d\n", ret);
return (ret);
}
#include "sdio.h"
#include "sdio_func.h"
-struct sdio_param {
- uint8_t fn;
- uint16_t blksz;
- uint32_t addr;
- bool wr;
- bool incaddr;
-};
-
-static int
-sdio_io_rwv_extended(const struct sdio_softc *sc, const struct sdio_param *param, uint32_t blocks, struct mmc_sg *sg, uint32_t sg_nums)
-{
-#define SDIO_ADDR_MASK (~0x1FFFF)
-
- device_t mmcbus = sc->mmcbus;
- device_t child = sc->dev;
- int err;
- struct mmc_data data;
- struct mmc_command cmd = {0};
- struct mmc_request req = {0};
-
- if ((param->addr & SDIO_ADDR_MASK) || blocks == 0) {
- dev_loge(child, "invalid sdio card addr.\n ");
- return (-EINVAL);
- }
- req.cmd = &cmd;
- cmd.data = &data;
- cmd.opcode = SD_IO_RW_EXTENDED;
- cmd.flags = MMC_RSP_R5 | MMC_CMD_ADTC;
- cmd.arg = SD_IO_RW_FUNC(param->fn) | SD_IO_RW_ADR(param->addr);
- if (param->wr)
- cmd.arg |= SD_IO_RW_WR;
- if (param->incaddr)
- cmd.arg |= SD_IO_RW_INCR;
-
- if ((blocks == 1) && (param->blksz <= MMC_SDIO_BLOCK_SIZE))
- cmd.arg |= (param->blksz == MMC_SDIO_BLOCK_SIZE) ? 0 : param->blksz;
- else
- cmd.arg |= SD_IOE_RW_BLK | blocks;
-
- data.blk_num = blocks;
- data.blk_size = param->blksz;
- data.len = blocks * param->blksz;
-
- data.sg = sg;
- data.sg_count = sg_nums;
-
- if (param->wr)
- data.flags = MMC_DATA_WRITE;
- else
- data.flags = MMC_DATA_READ;
-
- if (blocks > 1)
- data.flags |= MMC_DATA_MULTI;
-
- data.flags |= MMC_DATA_SDIO;
- data.flags |= MMC_DATA_SG;
-
- MMCBUS_ACQUIRE_BUS(mmcbus, child);
- err = MMCBUS_WAIT_FOR_REQUEST(mmcbus, child, &req);
- MMCBUS_RELEASE_BUS(mmcbus, child);
- if (err != 0)
- return (-EIO);
- if (cmd.error != MMC_ERR_NONE) {
- dev_loge(child, "Error indicated: %d.\n", cmd.error);
- return (cmd.error);
- }
- if (cmd.resp[0] & R5_RESP_CHECK)
- return (-EPERM);
-
- return (0);
-}
-
static int
sdio_io_rw_extended(struct sdio_softc *sc, uint8_t fn, uint32_t addr, bool wr,
bool incaddr, uint32_t b_count, uint16_t blksz, uint8_t *buffer)
func->cur_blk_size = (uint16_t)blk_size;
return (0);
}
+#ifdef DPALCFG_SDIO_SCATTER_LIST_SUPPORT
+struct sdio_param {
+ uint8_t fn;
+ uint16_t blksz;
+ uint32_t addr;
+ bool wr;
+ bool incaddr;
+};
+
+static int
+sdio_io_rwv_extended(const struct sdio_softc *sc, const struct sdio_param *param, uint32_t blocks, struct mmc_sg *sg, uint32_t sg_nums)
+{
+#define SDIO_ADDR_MASK (~0x1FFFF)
+
+ device_t mmcbus = sc->mmcbus;
+ device_t child = sc->dev;
+ int err;
+ struct mmc_data data;
+ struct mmc_command cmd = {0};
+ struct mmc_request req = {0};
+
+ if ((param->addr & SDIO_ADDR_MASK) || blocks == 0) {
+ dev_loge(child, "invalid sdio card addr.\n ");
+ return (-EINVAL);
+ }
+ req.cmd = &cmd;
+ cmd.data = &data;
+ cmd.opcode = SD_IO_RW_EXTENDED;
+ cmd.flags = MMC_RSP_R5 | MMC_CMD_ADTC;
+ cmd.arg = SD_IO_RW_FUNC(param->fn) | SD_IO_RW_ADR(param->addr);
+ if (param->wr)
+ cmd.arg |= SD_IO_RW_WR;
+ if (param->incaddr)
+ cmd.arg |= SD_IO_RW_INCR;
+
+ if ((blocks == 1) && (param->blksz <= MMC_SDIO_BLOCK_SIZE))
+ cmd.arg |= (param->blksz == MMC_SDIO_BLOCK_SIZE) ? 0 : param->blksz;
+ else
+ cmd.arg |= SD_IOE_RW_BLK | blocks;
+
+ data.blk_num = blocks;
+ data.blk_size = param->blksz;
+ data.len = blocks * param->blksz;
+
+ data.sg = sg;
+ data.sg_count = sg_nums;
+
+ if (param->wr)
+ data.flags = MMC_DATA_WRITE;
+ else
+ data.flags = MMC_DATA_READ;
+
+ if (blocks > 1)
+ data.flags |= MMC_DATA_MULTI;
+
+ data.flags |= MMC_DATA_SDIO;
+ data.flags |= MMC_DATA_SG;
+
+ MMCBUS_ACQUIRE_BUS(mmcbus, child);
+ err = MMCBUS_WAIT_FOR_REQUEST(mmcbus, child, &req);
+ MMCBUS_RELEASE_BUS(mmcbus, child);
+ if (err != 0)
+ return (-EIO);
+ if (cmd.error != MMC_ERR_NONE) {
+ dev_loge(child, "Error indicated: %d.\n", cmd.error);
+ return (cmd.error);
+ }
+ if (cmd.resp[0] & R5_RESP_CHECK)
+ return (-EPERM);
+
+ return (0);
+}
static inline int
sdio_rwv_multi_blocks(const struct sdio_func *func, struct sdio_param *param,
return (error);
}
+#endif
int
sdio_readv_incr_block(const struct sdio_func *func, uint32_t addr, struct mmc_sg *sg, uint32_t sg_nums)
{
+#ifdef DPALCFG_SDIO_SCATTER_LIST_SUPPORT
struct sdio_param param = {
.fn = 0,
.blksz = 0,
};
return (sdio_rwv_multi_blocks(func, ¶m, sg, sg_nums));
+#else
+ mmc_err("DPALCFG_SDIO_SCATTER_LIST_SUPPORT not defined!\n");
+ return 0;
+#endif
}
int
sdio_writev_incr_block(const struct sdio_func *func, uint32_t addr, struct mmc_sg *sg, uint32_t sg_nums)
{
+#ifdef DPALCFG_SDIO_SCATTER_LIST_SUPPORT
struct sdio_param param = {
.fn = 0,
.blksz = 0,
};
return (sdio_rwv_multi_blocks(func, ¶m, sg, sg_nums));
+#else
+ mmc_err("DPALCFG_SDIO_SCATTER_LIST_SUPPORT not defined!\n");
+ return 0;
+#endif
}
int
sdio_readv_fifo_block(const struct sdio_func *func, uint32_t addr, struct mmc_sg *sg, uint32_t sg_nums)
{
+#ifdef DPALCFG_SDIO_SCATTER_LIST_SUPPORT
struct sdio_param param = {
.fn = 0,
.blksz = 0,
};
return (sdio_rwv_multi_blocks(func, ¶m, sg, sg_nums));
+#else
+ mmc_err("DPALCFG_SDIO_SCATTER_LIST_SUPPORT not defined!\n");
+ return 0;
+#endif
}
int
sdio_writev_fifo_block(const struct sdio_func *func, uint32_t addr, struct mmc_sg *sg, uint32_t sg_nums)
{
+#ifdef DPALCFG_SDIO_SCATTER_LIST_SUPPORT
struct sdio_param param = {
.fn = 0,
.blksz = 0,
};
return (sdio_rwv_multi_blocks(func, ¶m, sg, sg_nums));
+#else
+ mmc_err("DPALCFG_SDIO_SCATTER_LIST_SUPPORT not defined!\n");
+ return 0;
+#endif
}
int
#define __predict_true(exp) exp
#define __predict_false(exp) exp
-#ifdef DPALCFG_DRIVERS_MMC_DBG
+#ifdef DPALCFG_DRIVERS_SDHCI_DBG
static void
sdhci_dump_irqstatus(const struct sdhci_slot *slot)
{
}
#ifndef TRUNCATE
-#define truncate(addr, size) ((uintptr_t)(addr) & ~((size) - 1))
+#define TRUNCATE(addr, size) ((uintptr_t)(addr) & ~((size) - 1))
#endif
#ifndef IS_ALIGNED
-#define is_aligned(value, align_size) ((((uintptr_t)(value)) & ((uintptr_t)((align_size) - 1))) == 0)
+#define IS_ALIGNED(value, align_size) ((((uintptr_t)(value)) & ((uintptr_t)((align_size) - 1))) == 0)
#endif
static void sdhci_dump_mem_byte(size_t length, uintptr_t addr)
{
uint32_t count = 0;
data_len = dpal_align(length, sizeof(uintptr_t));
- align_addr = (uintptr_t *)truncate(addr, sizeof(uintptr_t));
+ align_addr = (uintptr_t *)TRUNCATE(addr, sizeof(uintptr_t));
if ((data_len == 0) || (align_addr == NULL)) {
return;
}
while (data_len != 0) {
- if (is_aligned(count, sizeof(char *))) {
+ if (IS_ALIGNED(count, sizeof(char *))) {
dprintf("\n 0x%lx :", align_addr);
}
#ifdef __LP64__
void
sdhci_dump_regs(const struct sdhci_slot *slot)
{
-#ifdef DPALCFG_DRIVERS_MMC_DBG
+#ifdef DPALCFG_DRIVERS_SDHCI_DBG
device_t dev = slot->bus;
struct hci_softc *sc = device_get_softc(dev);
if (sc == NULL) {
RD2(slot, SDHCI_EMMC_CTRL), RD4(slot, SDHCI_MULTI_CYCLE));
slot_printf(slot, "ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
RD4(slot, SDHCI_ADMA_ERR), RD4(slot, SDHCI_ADMA_ADDRESS_LO));
- /* 0x80: length of former host register */
- sdhci_dump_mem_byte(0x80, (uintptr_t)sc->base);
- /* 0x50: length of latter host register (offset 0x500) */
- sdhci_dump_mem_byte(0x50, (uintptr_t)sc->base + 0x500);
+
slot_printf(slot, "==================BOARD REGS ==============\n");
if (slot->ops->dump_regs != NULL) {
slot->ops->dump_regs(sc);
*/
if (slot->opt & SDHCI_PLATFORM_TRANSFER)
slot->opt &= ~SDHCI_HAVE_DMA;
-#ifdef DPALCFG_DRIVERS_MMC_DBG
- if (bootverbose || sdhci_debug) {
+#ifdef DPALCFG_DRIVERS_SDHCI_DBG
+ if (__predict_false(sdhci_debug > 1)) {
slot_printf(slot,
"%uMHz%s %s VDD:%s%s%s VCCQ: 3.3V%s%s DRV: B%s%s%s %s %s\n",
slot->max_clk / 1000000,
uint8_t extra;
if (__predict_false(sdhci_debug > 1))
- slot_printf(slot, "%s: called, err %d flags %u\n",
+ slot_printf(slot, "%s: called, err %d flags 0x%x\n",
__func__, slot->curcmd->error, slot->curcmd->flags);
slot->cmd_done = 1;
/*
WR2(slot, SDHCI_BLOCK_COUNT, (data->len + 511) / 512);
}
if (__predict_false(sdhci_debug > 1))
- slot_printf(slot, "Blk size: 0x%08x | Blk cnt: 0x%08x\n",
- SDHCI_BLOCK_SIZE, SDHCI_BLOCK_COUNT);
+ slot_printf(slot, "Blk size:0x%x | Blk cnt:0x%x | flags:0x%x | data len:0x%x\n",
+ RD2(slot, SDHCI_BLOCK_SIZE), RD2(slot, SDHCI_BLOCK_COUNT), slot->flags, data->len);
}
void