mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
SDMMC: 1.to identify eMMC. 2.add the trace log in rk_sdmmc driver.
This commit is contained in:
@@ -18,6 +18,34 @@
|
||||
|
||||
|
||||
/{
|
||||
emmc: rksdmmc@1021C000 {
|
||||
compatible = "rockchip,rk_mmc";
|
||||
reg = <0x1021C000 0x4000>;
|
||||
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;/*irq=57*/
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
//pinctrl-names = "default",,"suspend";
|
||||
//pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp &sd0_pwr &sd0_bus1 &sd0_bus4>;
|
||||
clocks = <&clk_gates2 14>;
|
||||
clock-frequency = <50000000>;
|
||||
clock-freq-min-max = <400000 50000000>;
|
||||
|
||||
num-slots = <1>;
|
||||
supports-highspeed;
|
||||
fifo-depth = <0x80>;
|
||||
|
||||
|
||||
mmc,caps = <(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)>;
|
||||
mmc,ocr = <(MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 |
|
||||
MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
|
||||
MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)>;
|
||||
mmc,use_dma = <MMC_USE_DMA 2>;
|
||||
mmc,dma_ch = <EMMC_DMA_CHN>;
|
||||
mmc,int = <CONTROLLER_INT_DETECT>;
|
||||
mmc,emmc_is_selected = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sdmmc: rksdmmc@10214000 {
|
||||
compatible = "rockchip,rk_mmc";
|
||||
reg = <0x10214000 0x4000>;
|
||||
@@ -47,9 +75,10 @@
|
||||
mmc,int = <CONTROLLER_INT_DETECT>;
|
||||
//mmc,int = <GPIO_INT_DETECT>;
|
||||
mmc,emmc_is_selected = <0>;
|
||||
status = "okay";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
sdio: rksdmmc@10218000 {
|
||||
compatible = "rockchip,rk_mmc";
|
||||
reg = <0x10218000 0x4000>;
|
||||
@@ -59,7 +88,7 @@
|
||||
pinctrl-names = "default","suspend";
|
||||
pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_wp &sd1_bus1 &sd1_bus4>;
|
||||
|
||||
clocks = <&clk_gates2 14>;
|
||||
clocks = <&clk_gates2 13>;
|
||||
clock-frequency = <50000000>;
|
||||
clock-freq-min-max = <200000 50000000>;
|
||||
|
||||
@@ -80,33 +109,5 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
emmc: rksdmmc@1021C000 {
|
||||
compatible = "rockchip,rk_mmc";
|
||||
reg = <0x1021C000 0x4000>;
|
||||
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
//pinctrl-names = "default",,"suspend";
|
||||
//pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp &sd0_pwr &sd0_bus1 &sd0_bus4>;
|
||||
clocks = <&clk_gates2 11>;
|
||||
clock-frequency = <200000000>;
|
||||
clock-freq-min-max = <400000 200000000>;
|
||||
|
||||
num-slots = <1>;
|
||||
supports-highspeed;
|
||||
fifo-depth = <0x100>;
|
||||
|
||||
|
||||
mmc,caps = <(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)>;
|
||||
mmc,ocr = <(MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 |
|
||||
MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
|
||||
MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)>;
|
||||
mmc,use_dma = <MMC_USE_DMA 2>;
|
||||
mmc,dma_ch = <EMMC_DMA_CHN>;
|
||||
mmc,int = <CONTROLLER_INT_DETECT>;
|
||||
//mmc,int = <GPIO_INT_DETECT>;
|
||||
mmc,emmc_is_selected = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
41
drivers/mmc/core/mmc.c
Normal file → Executable file
41
drivers/mmc/core/mmc.c
Normal file → Executable file
@@ -349,6 +349,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||
* There are two boot regions of equal size, defined in
|
||||
* multiples of 128K.
|
||||
*/
|
||||
#if 0
|
||||
//emmc: We do NOT alloc boot partition now. noted by xbw, at 2014-03-09
|
||||
card->ext_csd.boot_size = 0;
|
||||
#else
|
||||
if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) {
|
||||
for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
|
||||
part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
|
||||
@@ -358,6 +362,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||
MMC_BLK_DATA_AREA_BOOT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
card->ext_csd.raw_hc_erase_gap_size =
|
||||
@@ -462,24 +467,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||
*/
|
||||
card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
|
||||
card->ext_csd.boot_ro_lockable = true;
|
||||
|
||||
/* Save power class values */
|
||||
card->ext_csd.raw_pwr_cl_52_195 =
|
||||
ext_csd[EXT_CSD_PWR_CL_52_195];
|
||||
card->ext_csd.raw_pwr_cl_26_195 =
|
||||
ext_csd[EXT_CSD_PWR_CL_26_195];
|
||||
card->ext_csd.raw_pwr_cl_52_360 =
|
||||
ext_csd[EXT_CSD_PWR_CL_52_360];
|
||||
card->ext_csd.raw_pwr_cl_26_360 =
|
||||
ext_csd[EXT_CSD_PWR_CL_26_360];
|
||||
card->ext_csd.raw_pwr_cl_200_195 =
|
||||
ext_csd[EXT_CSD_PWR_CL_200_195];
|
||||
card->ext_csd.raw_pwr_cl_200_360 =
|
||||
ext_csd[EXT_CSD_PWR_CL_200_360];
|
||||
card->ext_csd.raw_pwr_cl_ddr_52_195 =
|
||||
ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
|
||||
card->ext_csd.raw_pwr_cl_ddr_52_360 =
|
||||
ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
|
||||
}
|
||||
|
||||
if (card->ext_csd.rev >= 5) {
|
||||
@@ -630,23 +617,7 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
|
||||
(card->ext_csd.raw_sectors[2] ==
|
||||
bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
|
||||
(card->ext_csd.raw_sectors[3] ==
|
||||
bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
|
||||
(card->ext_csd.raw_pwr_cl_52_195 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
|
||||
(card->ext_csd.raw_pwr_cl_26_195 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
|
||||
(card->ext_csd.raw_pwr_cl_52_360 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
|
||||
(card->ext_csd.raw_pwr_cl_26_360 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
|
||||
(card->ext_csd.raw_pwr_cl_200_195 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
|
||||
(card->ext_csd.raw_pwr_cl_200_360 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
|
||||
(card->ext_csd.raw_pwr_cl_ddr_52_195 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
|
||||
(card->ext_csd.raw_pwr_cl_ddr_52_360 ==
|
||||
bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]));
|
||||
bw_ext_csd[EXT_CSD_SEC_CNT + 3]));
|
||||
if (err)
|
||||
err = -EINVAL;
|
||||
|
||||
|
||||
@@ -114,6 +114,20 @@ static const u8 tuning_blk_pattern_8bit[] = {
|
||||
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
||||
};
|
||||
|
||||
/*printk the all register of current host*/
|
||||
static int dw_mci_regs_printk(struct dw_mci *host)
|
||||
{
|
||||
struct sdmmc_reg *regs = dw_mci_regs;
|
||||
|
||||
while( regs->name != 0 ){
|
||||
printk("%s: (0x%04x) = 0x%08x\n", regs->name, regs->addr, mci_readreg(host,regs->addr));
|
||||
regs++;
|
||||
}
|
||||
printk("=======printk %s-register end =========\n", mmc_hostname(host->mmc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static int dw_mci_req_show(struct seq_file *s, void *v)
|
||||
{
|
||||
@@ -251,15 +265,10 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
|
||||
|
||||
cmdr = cmd->opcode;
|
||||
|
||||
if (cmd->opcode == MMC_STOP_TRANSMISSION ||
|
||||
cmd->opcode == MMC_GO_IDLE_STATE ||
|
||||
cmd->opcode == MMC_GO_INACTIVE_STATE ||
|
||||
(cmd->opcode == SD_IO_RW_DIRECT &&
|
||||
((cmd->arg >> 9) & 0x1FFFF) == SDIO_CCCR_ABORT))
|
||||
if (cmdr == MMC_STOP_TRANSMISSION)
|
||||
cmdr |= SDMMC_CMD_STOP;
|
||||
else
|
||||
if (cmd->opcode != MMC_SEND_STATUS && cmd->data)
|
||||
cmdr |= SDMMC_CMD_PRV_DAT_WAIT;
|
||||
cmdr |= SDMMC_CMD_PRV_DAT_WAIT;
|
||||
|
||||
if (cmd->flags & MMC_RSP_PRESENT) {
|
||||
/* We expect a response, so set this bit */
|
||||
@@ -330,14 +339,15 @@ static void dw_mci_start_command(struct dw_mci *host,
|
||||
|
||||
mci_writel(host, CMDARG, cmd->arg);
|
||||
wmb();
|
||||
MMC_DBG_CMD_FUNC("%d..%s start cmd=%d, arg=0x%x[%s]",__LINE__, __FUNCTION__,cmd->opcode, cmd->arg,mmc_hostname(host->mmc));
|
||||
//dw_mci_regs_printk(host);
|
||||
|
||||
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
|
||||
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START|SDMMC_CMD_USE_HOLD_REG); //always use SDMMC_CMD_USE_HOLD_REG
|
||||
}
|
||||
|
||||
static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data)
|
||||
static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data)
|
||||
{
|
||||
struct mmc_command *stop = data->stop ? data->stop : &host->stop_abort;
|
||||
dw_mci_start_command(host, stop, host->stop_cmdr);
|
||||
dw_mci_start_command(host, data->stop, host->stop_cmdr);
|
||||
}
|
||||
|
||||
/* DMA interface functions */
|
||||
@@ -403,6 +413,8 @@ static void dw_mci_idmac_complete_dma(struct dw_mci *host)
|
||||
struct mmc_data *data = host->data;
|
||||
|
||||
dev_vdbg(host->dev, "DMA complete\n");
|
||||
MMC_DBG_CMD_FUNC(" DMA complete cmd=%d(arg=0x%x), blocks=%d,blksz=%d[%s]", \
|
||||
host->cmd->opcode,host->cmd->arg,data->blocks,data->blksz,mmc_hostname(host->mmc));
|
||||
|
||||
host->dma_ops->cleanup(host);
|
||||
|
||||
@@ -718,6 +730,9 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
|
||||
} else {
|
||||
host->dir_status = DW_MCI_SEND_STATUS;
|
||||
}
|
||||
|
||||
// MMC_DBG_CMD_FUNC(" cmd=%d(arg=0x%x),blocks=%d,blksz=%d [%s]",\
|
||||
// host->cmd->opcode, host->cmd->arg, data->blocks, data->blksz, mmc_hostname(host->mmc));
|
||||
|
||||
if (dw_mci_submit_data_dma(host, data)) {
|
||||
int flags = SG_MITER_ATOMIC;
|
||||
@@ -882,8 +897,6 @@ static void __dw_mci_start_request(struct dw_mci *host,
|
||||
|
||||
if (mrq->stop)
|
||||
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
|
||||
else
|
||||
host->stop_cmdr = dw_mci_prep_stop_abort(host, cmd);
|
||||
}
|
||||
|
||||
static void dw_mci_start_request(struct dw_mci *host,
|
||||
@@ -891,7 +904,10 @@ static void dw_mci_start_request(struct dw_mci *host,
|
||||
{
|
||||
struct mmc_request *mrq = slot->mrq;
|
||||
struct mmc_command *cmd;
|
||||
|
||||
|
||||
MMC_DBG_CMD_FUNC(" Begin to start the new request. cmd=%d(arg=0x%x)[%s]", \
|
||||
mrq->cmd->opcode, mrq->cmd->arg, mmc_hostname(host->mmc));
|
||||
|
||||
cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
|
||||
__dw_mci_start_request(host, slot, cmd);
|
||||
}
|
||||
@@ -930,9 +946,14 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) {
|
||||
spin_unlock_bh(&host->lock);
|
||||
mrq->cmd->error = -ENOMEDIUM;
|
||||
|
||||
MMC_DBG_CMD_FUNC("dw_mci_reqeust--reqeuest done, cmd=%d [%s]",mrq->cmd->opcode, mmc_hostname(host->mmc));
|
||||
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
MMC_DBG_CMD_FUNC("======>\n pull a new request from MMC-frame to dw_mci_queue. cmd=%d(arg=0x%x)[%s]", \
|
||||
mrq->cmd->opcode, mrq->cmd->arg, mmc_hostname(host->mmc));
|
||||
|
||||
dw_mci_queue_request(host, slot, mrq);
|
||||
|
||||
@@ -949,9 +970,11 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
case MMC_BUS_WIDTH_4:
|
||||
slot->ctype = SDMMC_CTYPE_4BIT;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_8:
|
||||
#if 0//test, use sd to emmc
|
||||
case MMC_BUS_WIDTH_8:
|
||||
slot->ctype = SDMMC_CTYPE_8BIT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* set default 1 bit mode */
|
||||
slot->ctype = SDMMC_CTYPE_1BIT;
|
||||
@@ -1159,6 +1182,13 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
|
||||
WARN_ON(host->cmd || host->data);
|
||||
|
||||
if(mrq->cmd)
|
||||
MMC_DBG_CMD_FUNC(" reqeust end--reqeuest done, cmd=%d, cmderr=%d, host->state=%d [%s]",\
|
||||
mrq->cmd->opcode,mrq->cmd->error, host->state,mmc_hostname(host->mmc));
|
||||
if(mrq->data)
|
||||
MMC_DBG_CMD_FUNC(" reqeust end--reqeuest done, cmd=%d, dataerr=%d, host->state=%d [%s]",\
|
||||
mrq->cmd->opcode,mrq->data->error, host->state, mmc_hostname(host->mmc));
|
||||
|
||||
host->cur_slot->mrq = NULL;
|
||||
host->mrq = NULL;
|
||||
if (!list_empty(&host->queue)) {
|
||||
@@ -1168,6 +1198,7 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
dev_vdbg(host->dev, "list not empty: %s is next\n",
|
||||
mmc_hostname(slot->mmc));
|
||||
host->state = STATE_SENDING_CMD;
|
||||
MMC_DBG_CMD_FUNC(" list is not empty. run the request in list. [%s]", mmc_hostname(host->mmc));
|
||||
dw_mci_start_request(host, slot);
|
||||
} else {
|
||||
dev_vdbg(host->dev, "list empty\n");
|
||||
@@ -1192,11 +1223,16 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd
|
||||
cmd->resp[2] = mci_readl(host, RESP1);
|
||||
cmd->resp[1] = mci_readl(host, RESP2);
|
||||
cmd->resp[0] = mci_readl(host, RESP3);
|
||||
|
||||
MMC_DBG_CMD_FUNC(" command complete [%s], \ncmd=%d,resp[3]=0x%x, resp[2]=0x%x,resp[1]=0x%x,resp[0]=0x%x", \
|
||||
mmc_hostname(host->mmc), cmd->opcode,cmd->resp[3], cmd->resp[2], cmd->resp[1], cmd->resp[0]);
|
||||
} else {
|
||||
cmd->resp[0] = mci_readl(host, RESP0);
|
||||
cmd->resp[1] = 0;
|
||||
cmd->resp[2] = 0;
|
||||
cmd->resp[3] = 0;
|
||||
cmd->resp[3] = 0;
|
||||
MMC_DBG_CMD_FUNC(" command complete [%s], cmd=%d,resp[0]=0x%x",\
|
||||
mmc_hostname(host->mmc),cmd->opcode, cmd->resp[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,6 +1244,7 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd
|
||||
cmd->error = -EIO;
|
||||
else
|
||||
cmd->error = 0;
|
||||
MMC_DBG_CMD_FUNC(" command complete, cmd=%d,cmdError=0x%x [%s]",cmd->opcode, cmd->error,mmc_hostname(host->mmc));
|
||||
|
||||
if (cmd->error) {
|
||||
/* newer ip versions need a delay between retries */
|
||||
@@ -1254,11 +1291,21 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (cmd->data && cmd->error) {
|
||||
if (cmd->data && cmd->error) {
|
||||
dw_mci_stop_dma(host);
|
||||
#if 1
|
||||
if (data->stop) {
|
||||
send_stop_cmd(host, data);
|
||||
state = STATE_SENDING_STOP;
|
||||
break;
|
||||
} else {
|
||||
host->data = NULL;
|
||||
}
|
||||
#else
|
||||
send_stop_abort(host, data);
|
||||
state = STATE_SENDING_STOP;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1274,15 +1321,24 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
if (test_and_clear_bit(EVENT_DATA_ERROR,
|
||||
&host->pending_events)) {
|
||||
dw_mci_stop_dma(host);
|
||||
#if 1
|
||||
if (data->stop)
|
||||
send_stop_cmd(host, data);
|
||||
#else
|
||||
send_stop_abort(host, data);
|
||||
#endif
|
||||
state = STATE_DATA_ERROR;
|
||||
break;
|
||||
}
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: STATE_SENDING_DATA, wait for EVENT_XFER_COMPLETE.[%s]",\
|
||||
prev_state,state, mmc_hostname(host->mmc));
|
||||
|
||||
if (!test_and_clear_bit(EVENT_XFER_COMPLETE,
|
||||
&host->pending_events))
|
||||
break;
|
||||
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: STATE_SENDING_DATA, wait for EVENT_DATA_COMPLETE. [%s]",\
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
set_bit(EVENT_XFER_COMPLETE, &host->completed_events);
|
||||
prev_state = state = STATE_DATA_BUSY;
|
||||
/* fall through */
|
||||
@@ -1291,13 +1347,17 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
if (!test_and_clear_bit(EVENT_DATA_COMPLETE,
|
||||
&host->pending_events))
|
||||
break;
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: STATE_DATA_BUSY, after EVENT_DATA_COMPLETE. [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
host->data = NULL;
|
||||
set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
|
||||
status = host->data_status;
|
||||
|
||||
if (status & DW_MCI_DATA_ERROR_FLAGS) {
|
||||
if (status & SDMMC_INT_DRTO) {
|
||||
if (status & DW_MCI_DATA_ERROR_FLAGS) {
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: DW_MCI_DATA_ERROR_FLAGS, datastatus=0x%x [%s]",\
|
||||
prev_state,state,status, mmc_hostname(host->mmc));
|
||||
if (status & SDMMC_INT_DRTO) {
|
||||
data->error = -ETIMEDOUT;
|
||||
} else if (status & SDMMC_INT_DCRC) {
|
||||
data->error = -EILSEQ;
|
||||
@@ -1334,30 +1394,49 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
data->error = 0;
|
||||
}
|
||||
|
||||
if (!data->stop && !data->error) {
|
||||
if (!data->stop) {
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: no stop and no dataerr, exit. [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
}
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: begin to stop . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
if (host->mrq->sbc && !data->error) {
|
||||
data->stop->error = 0;
|
||||
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: have stop and sbc, exit. [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
}
|
||||
printk("%d..%s: ===test===\n", __LINE__, __FUNCTION__);
|
||||
|
||||
prev_state = state = STATE_SENDING_STOP;
|
||||
if (!data->error)
|
||||
send_stop_cmd(host, data);
|
||||
#if 0
|
||||
if (data->stop && !data->error) {
|
||||
/* stop command for open-ended transfer*/
|
||||
|
||||
printk("%d..%s: ===test===\n", __LINE__, __FUNCTION__);
|
||||
send_stop_abort(host, data);
|
||||
}
|
||||
#endif
|
||||
/* fall through */
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: begin to STATE_SENDING_STOP . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
case STATE_SENDING_STOP:
|
||||
if (!test_and_clear_bit(EVENT_CMD_COMPLETE,
|
||||
&host->pending_events))
|
||||
break;
|
||||
MMC_DBG_CMD_FUNC("Pre-state[%d]-->NowState[%d]: begin to send cmd12 . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
/* CMD error in data command */
|
||||
/* CMD error in data command */
|
||||
if (host->mrq->cmd->error && host->mrq->data) {
|
||||
sg_miter_stop(&host->sg_miter);
|
||||
host->sg = NULL;
|
||||
@@ -1366,22 +1445,26 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
mci_writel(host, CTRL, ctrl);
|
||||
}
|
||||
|
||||
|
||||
host->cmd = NULL;
|
||||
host->data = NULL;
|
||||
|
||||
#if 1
|
||||
dw_mci_command_complete(host, host->mrq->stop);
|
||||
#else
|
||||
if (host->mrq->stop)
|
||||
dw_mci_command_complete(host, host->mrq->stop);
|
||||
else
|
||||
host->cmd_status = 0;
|
||||
|
||||
#endif
|
||||
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
printk("%d..%s: ===test===\n", __LINE__, __FUNCTION__);
|
||||
|
||||
case STATE_DATA_ERROR:
|
||||
if (!test_and_clear_bit(EVENT_XFER_COMPLETE,
|
||||
&host->pending_events))
|
||||
break;
|
||||
printk("%d..%s: ===test===\n", __LINE__, __FUNCTION__);
|
||||
|
||||
state = STATE_DATA_BUSY;
|
||||
break;
|
||||
@@ -1913,7 +1996,7 @@ static void dw_mci_work_routine_card(struct work_struct *work)
|
||||
{
|
||||
struct dw_mci *host = container_of(work, struct dw_mci, card_work);
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < host->num_slots; i++) {
|
||||
struct dw_mci_slot *slot = host->slot[i];
|
||||
struct mmc_host *mmc = slot->mmc;
|
||||
@@ -1925,6 +2008,8 @@ static void dw_mci_work_routine_card(struct work_struct *work)
|
||||
while (present != slot->last_detect_state) {
|
||||
dev_dbg(&slot->mmc->class_dev, "card %s\n",
|
||||
present ? "inserted" : "removed");
|
||||
MMC_DBG_BOOT_FUNC("card %s, devname=%s \n",
|
||||
present ? "inserted" : "removed", mmc_hostname(mmc));
|
||||
|
||||
spin_lock_bh(&host->lock);
|
||||
|
||||
@@ -1954,10 +2039,11 @@ static void dw_mci_work_routine_card(struct work_struct *work)
|
||||
case STATE_DATA_ERROR:
|
||||
if (mrq->data->error == -EINPROGRESS)
|
||||
mrq->data->error = -ENOMEDIUM;
|
||||
if (!mrq->stop)
|
||||
break;
|
||||
/* fall through */
|
||||
case STATE_SENDING_STOP:
|
||||
if (mrq->stop)
|
||||
mrq->stop->error = -ENOMEDIUM;
|
||||
mrq->stop->error = -ENOMEDIUM;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1969,6 +2055,8 @@ static void dw_mci_work_routine_card(struct work_struct *work)
|
||||
mrq->data->error = -ENOMEDIUM;
|
||||
if (mrq->stop)
|
||||
mrq->stop->error = -ENOMEDIUM;
|
||||
|
||||
MMC_DBG_CMD_FUNC("dw_mci_work--reqeuest done, cmd=%d [%s]",mrq->cmd->opcode, mmc_hostname(mmc));
|
||||
|
||||
spin_unlock(&host->lock);
|
||||
mmc_request_done(slot->mmc, mrq);
|
||||
@@ -2178,6 +2266,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
slot->mmc = mmc;
|
||||
slot->host = host;
|
||||
host->slot[id] = slot;
|
||||
host->mmc = mmc;
|
||||
|
||||
slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
|
||||
|
||||
@@ -2185,7 +2274,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
#if 0
|
||||
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
|
||||
mmc->f_max = host->bus_hz;
|
||||
printk("%d..%s: fmin=%d, fmax=%d, bus_hz=%d \n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max, host->bus_hz);
|
||||
printk("%d..%s: fmin=%d, fmax=%d, bus_hz=%d \n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max, host->bus_hz);
|
||||
#else
|
||||
if (of_property_read_u32_array(host->dev->of_node,
|
||||
"clock-freq-min-max", freq, 2)) {
|
||||
|
||||
@@ -68,6 +68,58 @@
|
||||
/* shift bit field */
|
||||
#define _SBF(f, v) ((v) << (f))
|
||||
|
||||
|
||||
struct sdmmc_reg
|
||||
{
|
||||
u32 addr;
|
||||
char * name;
|
||||
};
|
||||
|
||||
static struct sdmmc_reg dw_mci_regs[] =
|
||||
{
|
||||
{ 0x0000, " CTRL" },
|
||||
{ 0x0004, " PWREN" },
|
||||
{ 0x0008, " CLKDIV" },
|
||||
{ 0x000C, " CLKSRC" },
|
||||
{ 0x0010, " CLKENA" },
|
||||
{ 0x0014, " TMOUT" },
|
||||
{ 0x0018, " CTYPE" },
|
||||
{ 0x001C, " BLKSIZ" },
|
||||
{ 0x0020, " BYTCNT" },
|
||||
{ 0x0024, " INTMSK" },
|
||||
{ 0x0028, " CMDARG" },
|
||||
{ 0x002C, " CMD" },
|
||||
{ 0x0030, " RESP0" },
|
||||
{ 0x0034, " RESP1" },
|
||||
{ 0x0038, " RESP2" },
|
||||
{ 0x003C, " RESP3" },
|
||||
{ 0x0040, " MINSTS" },
|
||||
{ 0x0044, " RINTSTS" },
|
||||
{ 0x0048, " STATUS" },
|
||||
{ 0x004C, " FIFOTH" },
|
||||
{ 0x0050, " CDETECT" },
|
||||
{ 0x0054, " WRTPRT" },
|
||||
{ 0x0058, " GPIO" },
|
||||
{ 0x005C, " TCBCNT" },
|
||||
{ 0x0060, " TBBCNT" },
|
||||
{ 0x0064, " DEBNCE" },
|
||||
{ 0x0068, " USRID" },
|
||||
{ 0x006C, " VERID" },
|
||||
{ 0x0070, " HCON" },
|
||||
{ 0x0074, " UHS_REG" },
|
||||
{ 0x0078, " RST_n" },
|
||||
{ 0x0080, " BMOD" },
|
||||
{ 0x0084, " PLDMND" },
|
||||
{ 0x0088, " DBADDR" },
|
||||
{ 0x008C, " IDSTS" },
|
||||
{ 0x0090, " IDINTEN" },
|
||||
{ 0x0094, " DSCADDR" },
|
||||
{ 0x0098, " BUFADDR" },
|
||||
{ 0x0100, "CARDTHRCTL" },
|
||||
{ 0x0104, "BackEndPwr" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/* Control register defines */
|
||||
#define SDMMC_CTRL_USE_IDMAC BIT(25)
|
||||
#define SDMMC_CTRL_CEATA_INT_EN BIT(11)
|
||||
@@ -157,6 +209,8 @@
|
||||
__raw_readl((dev)->regs + SDMMC_##reg)
|
||||
#define mci_writel(dev, reg, value) \
|
||||
__raw_writel((value), (dev)->regs + SDMMC_##reg)
|
||||
#define mci_readreg(dev, addr) \
|
||||
__raw_readl((dev)->regs + addr)
|
||||
|
||||
/* 16-bit FIFO access macros */
|
||||
#define mci_readw(dev, reg) \
|
||||
|
||||
@@ -6,9 +6,10 @@ u32 mmc_debug_level;
|
||||
|
||||
static void rockchip_mmc_of_dump(struct rk_sdmmc_of *rk_mmc_property)
|
||||
{
|
||||
mmc_debug_level = MMC_DBG_ALL;//set the value refer to file rk_sdmmc_of.h
|
||||
mmc_debug_level = MMC_DBG_ERROR;//MMC_DBG_ALL;//set the value refer to file rk_sdmmc_of.h
|
||||
|
||||
MMC_DBG_BOOT_FUNC("=========rockchip mmc dts dump info start== 2014-03-05 16:08 ======");
|
||||
MMC_DBG_BOOT_FUNC("=========rockchip mmc dts dump info start== 2014-03-10 11:59 ======");
|
||||
/*
|
||||
MMC_DBG_BOOT_FUNC("mmc,caps: 0x%x",rk_mmc_property->mmc_caps);
|
||||
MMC_DBG_BOOT_FUNC("mmc,ocr: 0x%x",rk_mmc_property->mmc_ocr);
|
||||
MMC_DBG_BOOT_FUNC("mmc,int: 0x%x",rk_mmc_property->mmc_int_type);
|
||||
@@ -17,6 +18,7 @@ static void rockchip_mmc_of_dump(struct rk_sdmmc_of *rk_mmc_property)
|
||||
rk_mmc_property->mmc_dma_is_used[1]);
|
||||
MMC_DBG_BOOT_FUNC("mmc,dma_ch: %d",rk_mmc_property->mmc_dma_chn);
|
||||
MMC_DBG_BOOT_FUNC("=========rockchip mmc dts dump info end================");
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ extern u32 mmc_debug_level;
|
||||
#define MMC_DBG_WARN_FUNC(fmt, arg...) \
|
||||
if(mmc_debug_level >= MMC_DBG_WARN){ printk(DRIVER_PREFIX "WARNING " fmt "\n", ##arg);}
|
||||
#define MMC_DBG_INFO_FUNC(fmt, arg...) \
|
||||
if(mmc_debug_level >= MMC_DBG_INFO){ printk(DRIVER_PREFIX fmt "\n", ##arg);}
|
||||
if(mmc_debug_level >= MMC_DBG_INFO){ printk(DRIVER_PREFIX "INFO " fmt "\n", ##arg);}
|
||||
#define MMC_DBG_CMD_FUNC(fmt, arg...) \
|
||||
if(mmc_debug_level >= MMC_DBG_CMD){ printk(DRIVER_PREFIX "CMD " fmt "\n", ##arg);}
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@ struct dw_mci {
|
||||
struct clk *biu_clk;
|
||||
struct clk *ciu_clk;
|
||||
struct dw_mci_slot *slot[MAX_MCI_SLOTS];
|
||||
struct mmc_host *mmc;
|
||||
|
||||
/* FIFO push and pull */
|
||||
int fifo_depth;
|
||||
|
||||
Reference in New Issue
Block a user