mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
mmc: host: rk_sdmmc:
Support physical level three transfer.
This commit is contained in:
18
drivers/mmc/core/sdio.c
Normal file → Executable file
18
drivers/mmc/core/sdio.c
Normal file → Executable file
@@ -673,6 +673,17 @@ try_again:
|
||||
* systems that claim 1.8v signalling in fact do not support
|
||||
* it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fixme: ap6335 should not set S18A=1 if mmc I/F voltage
|
||||
* has been 1.8v yet.
|
||||
*/
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
#ifdef CONFIG_AP6335
|
||||
rocr &= ~R4_18V_PRESENT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) {
|
||||
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
|
||||
ocr);
|
||||
@@ -688,7 +699,12 @@ try_again:
|
||||
}
|
||||
err = 0;
|
||||
} else {
|
||||
ocr &= ~R4_18V_PRESENT;
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
#ifdef CONFIG_AP6335
|
||||
#else
|
||||
ocr &= ~R4_18V_PRESENT;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -556,6 +556,15 @@ config MMC_DW_ROCKCHIP
|
||||
Synopsys DesignWare Memory Card Interface driver. Select this option
|
||||
for platforms based on RK32XX SoC's.
|
||||
|
||||
config MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
tristate "Supoort voltage switch for higher level standard"
|
||||
depends on MMC_DW_ROCKCHIP
|
||||
default n
|
||||
help
|
||||
This selects support for Rockchip RK32XX Soc specific extensions to voltage
|
||||
switch squence
|
||||
|
||||
|
||||
config MMC_DW_EXYNOS
|
||||
tristate "Exynos specific extensions for Synopsys DW Memory Card Interface"
|
||||
depends on MMC_DW
|
||||
|
||||
@@ -464,10 +464,12 @@ static int dw_mci_rockchip_execute_tuning(struct dw_mci_slot *slot, u32 opcode,
|
||||
goto done;
|
||||
#endif
|
||||
}else{
|
||||
MMC_DBG_ERR_FUNC(host->mmc,
|
||||
MMC_DBG_ERR_FUNC(host->mmc,
|
||||
"execute tuning: candidates_degree beyong limited case! [%s]",
|
||||
mmc_hostname(host->mmc));
|
||||
BUG();
|
||||
mmc_hostname(host->mmc));
|
||||
if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
|
||||
BUG();
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
delayline:
|
||||
|
||||
@@ -67,11 +67,12 @@
|
||||
#define DW_MCI_FREQ_MAX 50000000//200000000 /* unit: HZ */
|
||||
#define DW_MCI_FREQ_MIN 300000//400000 /* unit: HZ */
|
||||
|
||||
#define SDMMC_DATA_TIMEOUT_SD 500; /*max is 250ms showed in Spec; Maybe adapt the value for the sick card.*/
|
||||
/*max is 250ms showed in Spec; Maybe adapt the value for the sick card.*/
|
||||
#define SDMMC_DATA_TIMEOUT_SD 500
|
||||
#define SDMMC_DATA_TIMEOUT_SDIO 250
|
||||
#define SDMMC_DATA_TIMEOUT_EMMC 2500
|
||||
|
||||
#define SDMMC_CMD_RTO_MAX_HOLD 200
|
||||
#define SDMMC_CMD_RTO_MAX_HOLD 200
|
||||
#define SDMMC_WAIT_FOR_UNBUSY 2500
|
||||
|
||||
#ifdef CONFIG_MMC_DW_IDMAC
|
||||
@@ -867,15 +868,18 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
|
||||
u32 div;
|
||||
u32 clk_en_a;
|
||||
u32 sdio_int;
|
||||
|
||||
|
||||
MMC_DBG_INFO_FUNC(host->mmc,"%d..%s: clock=%d, current_speed=%d, bus_hz=%d,forc=%d[%s]\n",
|
||||
__LINE__, __FUNCTION__, clock, host->current_speed,host->bus_hz,force_clkinit,mmc_hostname(host->mmc));
|
||||
|
||||
if (!clock) {
|
||||
mci_writel(host, CLKENA, 0);
|
||||
mci_send_cmd(slot,
|
||||
SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
|
||||
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
if(host->svi_flags == 0)
|
||||
mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
|
||||
#else
|
||||
mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
|
||||
#endif
|
||||
} else if (clock != host->current_speed || force_clkinit) {
|
||||
div = host->bus_hz / clock;
|
||||
if (host->bus_hz % clock && host->bus_hz > clock)
|
||||
@@ -1016,12 +1020,13 @@ static void dw_mci_wait_unbusy(struct dw_mci *host)
|
||||
time_loop = jiffies + msecs_to_jiffies(timeout);
|
||||
do {
|
||||
status = mci_readl(host, STATUS);
|
||||
if (!(status & (SDMMC_STAUTS_DATA_BUSY|SDMMC_STAUTS_MC_BUSY)))
|
||||
if (!(status & (SDMMC_STAUTS_DATA_BUSY | SDMMC_STAUTS_MC_BUSY)))
|
||||
break;
|
||||
//MMC_DBG_INFO_FUNC("dw_mci_wait_unbusy, waiting for......");
|
||||
} while (time_before(jiffies, time_loop));
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
/*
|
||||
* result:
|
||||
* 0--status is busy.
|
||||
@@ -1031,34 +1036,24 @@ int dw_mci_card_busy(struct mmc_host *mmc)
|
||||
{
|
||||
struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
struct dw_mci *host = slot->host;
|
||||
unsigned int timeout= SDMMC_DATA_TIMEOUT_SDIO;
|
||||
unsigned long time_loop;
|
||||
unsigned int status;
|
||||
int ret= 0;
|
||||
|
||||
MMC_DBG_INFO_FUNC(host->mmc, "dw_mci_card_busy: svi_flags = %d [%s]", \
|
||||
host->svi_flags, mmc_hostname(host->mmc));
|
||||
|
||||
if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
|
||||
timeout = SDMMC_DATA_TIMEOUT_EMMC;
|
||||
else if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
|
||||
timeout = SDMMC_DATA_TIMEOUT_SD;
|
||||
timeout = 250*1000;//test
|
||||
time_loop = jiffies + msecs_to_jiffies(timeout);
|
||||
/* svi toggle*/
|
||||
if(host->svi_flags == 0){
|
||||
/*first svi*/
|
||||
host->svi_flags = 1;
|
||||
return host->svi_flags;
|
||||
|
||||
MMC_DBG_INFO_FUNC(host->mmc, "line%d: dw_mci_wait_unbusy,timeloop=%lu, status=0x%x ",
|
||||
__LINE__, time_loop, mci_readl(host, STATUS));
|
||||
do {
|
||||
status = mci_readl(host, STATUS);
|
||||
if (!(status & (SDMMC_STAUTS_DATA_BUSY|SDMMC_STAUTS_MC_BUSY))){
|
||||
ret = 1;//card is unbusy.
|
||||
break;
|
||||
}else{
|
||||
host->svi_flags = 0;
|
||||
return host->svi_flags;
|
||||
}
|
||||
//MMC_DBG_INFO_FUNC("dw_mci_wait_unbusy, waiting for......");
|
||||
} while (time_before(jiffies, time_loop));
|
||||
MMC_DBG_INFO_FUNC(host->mmc, "line%d: dw_mci_wait_unbusy,ret=%d, status=0x%x ",
|
||||
__LINE__,ret,mci_readl(host, STATUS));
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
static void __dw_mci_start_request(struct dw_mci *host,
|
||||
struct dw_mci_slot *slot,
|
||||
struct mmc_command *cmd)
|
||||
@@ -1073,15 +1068,8 @@ static void __dw_mci_start_request(struct dw_mci *host,
|
||||
|
||||
host->cur_slot = slot;
|
||||
host->mrq = mrq;
|
||||
#if 0 //add by xbw,at 2014-03-12
|
||||
/*clean FIFO if it is a new request*/
|
||||
if(!(mrq->cmd->opcode & SDMMC_CMD_STOP)) {
|
||||
MMC_DBG_INFO_FUNC("%d..%s: reset the ctrl.", __LINE__, __FUNCTION__);
|
||||
mci_writel(host, CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET |
|
||||
SDMMC_CTRL_DMA_RESET));
|
||||
}
|
||||
#endif
|
||||
dw_mci_wait_unbusy(host);
|
||||
|
||||
dw_mci_wait_unbusy(host);
|
||||
|
||||
host->pending_events = 0;
|
||||
host->completed_events = 0;
|
||||
@@ -1116,9 +1104,9 @@ static void dw_mci_start_request(struct dw_mci *host,
|
||||
{
|
||||
struct mmc_request *mrq = slot->mrq;
|
||||
struct mmc_command *cmd;
|
||||
|
||||
MMC_DBG_INFO_FUNC(host->mmc, " Begin to start the new request. cmd=%d(arg=0x%x)[%s]", \
|
||||
mrq->cmd->opcode, mrq->cmd->arg, mmc_hostname(host->mmc));
|
||||
|
||||
MMC_DBG_INFO_FUNC(host->mmc, " 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);
|
||||
@@ -1164,8 +1152,9 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
mmc_request_done(mmc, mrq);
|
||||
return;
|
||||
}
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "======>\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));
|
||||
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "======>\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);
|
||||
|
||||
@@ -1175,12 +1164,25 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
{
|
||||
struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
struct dw_mci *host = slot->host;
|
||||
#endif
|
||||
const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
|
||||
u32 regs;
|
||||
#ifdef SDMMC_WAIT_FOR_UNBUSY
|
||||
unsigned long time_loop = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
|
||||
|
||||
#ifdef SDMMC_WAIT_FOR_UNBUSY
|
||||
unsigned long time_loop;
|
||||
bool ret = true;
|
||||
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
if(host->svi_flags == 1)
|
||||
time_loop = jiffies + msecs_to_jiffies(SDMMC_DATA_TIMEOUT_SD);
|
||||
else
|
||||
time_loop = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
|
||||
#else
|
||||
time_loop = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
|
||||
#endif
|
||||
|
||||
if(!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)){
|
||||
printk("%d..%s: no card. [%s]\n", \
|
||||
__LINE__, __FUNCTION__, mmc_hostname(mmc));
|
||||
@@ -1197,11 +1199,15 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
if(false == ret)
|
||||
{
|
||||
printk("slot->flags = %lu ", slot->flags);
|
||||
dump_stack();
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
if(host->svi_flags != 1)
|
||||
#endif
|
||||
dump_stack();
|
||||
printk("%d..%s: wait for unbusy timeout....... STATUS = 0x%x [%s]\n", \
|
||||
__LINE__, __FUNCTION__, regs, mmc_hostname(mmc));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch (ios->bus_width) {
|
||||
case MMC_BUS_WIDTH_4:
|
||||
slot->ctype = SDMMC_CTYPE_4BIT;
|
||||
@@ -1241,25 +1247,25 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
|
||||
EXIT_POWER:
|
||||
switch (ios->power_mode) {
|
||||
case MMC_POWER_UP:
|
||||
set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
|
||||
/* Power up slot */
|
||||
if (slot->host->pdata->setpower)
|
||||
slot->host->pdata->setpower(slot->id, mmc->ocr_avail);
|
||||
regs = mci_readl(slot->host, PWREN);
|
||||
regs |= (1 << slot->id);
|
||||
mci_writel(slot->host, PWREN, regs);
|
||||
break;
|
||||
case MMC_POWER_OFF:
|
||||
/* Power down slot */
|
||||
if (slot->host->pdata->setpower)
|
||||
slot->host->pdata->setpower(slot->id, 0);
|
||||
regs = mci_readl(slot->host, PWREN);
|
||||
regs &= ~(1 << slot->id);
|
||||
mci_writel(slot->host, PWREN, regs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case MMC_POWER_UP:
|
||||
set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
|
||||
/* Power up slot */
|
||||
if (slot->host->pdata->setpower)
|
||||
slot->host->pdata->setpower(slot->id, mmc->ocr_avail);
|
||||
regs = mci_readl(slot->host, PWREN);
|
||||
regs |= (1 << slot->id);
|
||||
mci_writel(slot->host, PWREN, regs);
|
||||
break;
|
||||
case MMC_POWER_OFF:
|
||||
/* Power down slot */
|
||||
if(slot->host->pdata->setpower)
|
||||
slot->host->pdata->setpower(slot->id, 0);
|
||||
regs = mci_readl(slot->host, PWREN);
|
||||
regs &= ~(1 << slot->id);
|
||||
mci_writel(slot->host, PWREN, regs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,11 +1276,11 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
|
||||
struct dw_mci_board *brd = slot->host->pdata;
|
||||
|
||||
/* Use platform get_ro function, else try on board write protect */
|
||||
if (slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT)
|
||||
if(slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT)
|
||||
read_only = 0;
|
||||
else if (brd->get_ro)
|
||||
else if(brd->get_ro)
|
||||
read_only = brd->get_ro(slot->id);
|
||||
else if (gpio_is_valid(slot->wp_gpio))
|
||||
else if(gpio_is_valid(slot->wp_gpio))
|
||||
read_only = gpio_get_value(slot->wp_gpio);
|
||||
else
|
||||
read_only =
|
||||
@@ -1324,8 +1330,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
|
||||
struct dw_mci *host = slot->host;
|
||||
int gpio_cd = mmc_gpio_get_cd(mmc);
|
||||
|
||||
if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
|
||||
return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
|
||||
return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
|
||||
/* Use platform get_cd function, else try onboard card detect */
|
||||
if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
|
||||
@@ -1477,7 +1483,7 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
||||
/* Enable/disable Slot Specific SDIO interrupt */
|
||||
int_mask = mci_readl(host, INTMASK);
|
||||
|
||||
if (host->verid < DW_MMC_240A)
|
||||
if (host->verid < DW_MMC_240A)
|
||||
sdio_int = SDMMC_INT_SDIO(slot->id);
|
||||
else
|
||||
sdio_int = SDMMC_INT_SDIO((slot->id) + 8);
|
||||
@@ -1499,7 +1505,32 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
enum{
|
||||
IO_DOMAIN_12 = 1200,
|
||||
IO_DOMAIN_18 = 1800,
|
||||
IO_DOMAIN_33 = 3300,
|
||||
};
|
||||
static void dw_mci_do_grf_io_domain_switch(struct dw_mci *host, u32 voltage)
|
||||
{
|
||||
if(cpu_is_rk3288()){
|
||||
if(voltage == IO_DOMAIN_33)
|
||||
voltage = 0;
|
||||
else if(voltage == IO_DOMAIN_18)
|
||||
voltage = 1;
|
||||
else
|
||||
MMC_DBG_ERR_FUNC(host->mmc,"%s : err io domain voltage [%s]\n",
|
||||
__FUNCTION__, mmc_hostname(host->mmc));
|
||||
if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
|
||||
grf_writel((voltage << 7) | (1 << 23), RK3288_GRF_IO_VSEL);
|
||||
else
|
||||
return ;
|
||||
}else{
|
||||
MMC_DBG_ERR_FUNC(host->mmc,"%s : unknown chip [%s]\n",
|
||||
__FUNCTION__, mmc_hostname(host->mmc));
|
||||
}
|
||||
}
|
||||
|
||||
static int dw_mci_do_start_signal_voltage_switch(struct dw_mci *host,
|
||||
struct mmc_ios *ios)
|
||||
{
|
||||
@@ -1514,76 +1545,80 @@ static int dw_mci_do_start_signal_voltage_switch(struct dw_mci *host,
|
||||
return 0;
|
||||
|
||||
uhs_reg = mci_readl(host, UHS_REG);
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: vol=%d.[%s]\n",
|
||||
__LINE__, __FUNCTION__,ios->signal_voltage, mmc_hostname(host->mmc));
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: vol=%d.[%s]\n",
|
||||
__LINE__, __FUNCTION__,ios->signal_voltage, mmc_hostname(host->mmc));
|
||||
|
||||
switch (ios->signal_voltage) {
|
||||
case MMC_SIGNAL_VOLTAGE_330:
|
||||
/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
|
||||
if (host->vmmc) {
|
||||
ret = io_domain_regulator_set_voltage(host->vmmc, 3300000, 3300000);
|
||||
//regulator_put(host->vmmc); //to be done in remove function.
|
||||
/* regulator_put(host->vmmc); //to be done in remove function. */
|
||||
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%s =%dmV set 3.3end, ret=%d \n",
|
||||
__func__, regulator_get_voltage(host->vmmc), ret);
|
||||
if (ret) {
|
||||
pr_warning("%s: Switching to 3.3V signalling voltage "
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc, "%s: Switching to 3.3V signalling voltage "
|
||||
" failed\n", mmc_hostname(host->mmc));
|
||||
return -EIO;
|
||||
}
|
||||
dw_mci_do_grf_io_domain_switch(host, IO_DOMAIN_33);
|
||||
}
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: [%s]\n",__LINE__, __FUNCTION__, mmc_hostname(host->mmc));
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: [%s]\n",__LINE__,
|
||||
__FUNCTION__, mmc_hostname(host->mmc));
|
||||
|
||||
//set High-power mode
|
||||
/* set High-power mode */
|
||||
value = mci_readl(host, CLKENA);
|
||||
mci_writel(host,CLKENA , value& ~SDMMC_CLKEN_LOW_PWR);
|
||||
//SDMMC_UHS_REG
|
||||
mci_writel(host,UHS_REG , uhs_reg & ~SDMMC_UHS_VOLT_REG_18);
|
||||
value &= ~SDMMC_CLKEN_LOW_PWR;
|
||||
mci_writel(host,CLKENA , value);
|
||||
/* SDMMC_UHS_REG */
|
||||
uhs_reg &= ~SDMMC_UHS_VOLT_REG_18;
|
||||
mci_writel(host,UHS_REG , uhs_reg);
|
||||
|
||||
/* Wait for 5ms */
|
||||
usleep_range(5000, 5500);
|
||||
|
||||
/* 3.3V regulator output should be stable within 5 ms */
|
||||
uhs_reg = mci_readl(host, UHS_REG);
|
||||
if( !(uhs_reg & SDMMC_UHS_VOLT_REG_18))
|
||||
return 0;
|
||||
if( !(uhs_reg & SDMMC_UHS_VOLT_REG_18))
|
||||
return 0;
|
||||
|
||||
pr_warning("%s: 3.3V regulator output did not became stable\n",
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc, "%s: 3.3V regulator output did not became stable\n",
|
||||
mmc_hostname(host->mmc));
|
||||
|
||||
return -EAGAIN;
|
||||
case MMC_SIGNAL_VOLTAGE_180:
|
||||
if (host->vmmc) {
|
||||
ret = io_domain_regulator_set_voltage(host->vmmc,1800000, 1800000);
|
||||
// regulator_put(host->vmmc);//to be done in remove function.
|
||||
/* regulator_put(host->vmmc);//to be done in remove function. */
|
||||
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s =%dmV set 1.8end, ret=%d . \n",
|
||||
__LINE__, __func__, regulator_get_voltage(host->vmmc), ret);
|
||||
if (ret) {
|
||||
pr_warning("%s: Switching to 1.8V signalling voltage "
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc, "%s: Switching to 1.8V signalling voltage "
|
||||
" failed\n", mmc_hostname(host->mmc));
|
||||
return -EIO;
|
||||
}
|
||||
dw_mci_do_grf_io_domain_switch(host, IO_DOMAIN_18);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable 1.8V Signal Enable in the Host Control2
|
||||
* register
|
||||
*/
|
||||
mci_writel(host,UHS_REG , uhs_reg | SDMMC_UHS_VOLT_REG_18);
|
||||
mci_writel(host,UHS_REG , uhs_reg | SDMMC_UHS_VOLT_REG_18);
|
||||
|
||||
/* Wait for 5ms */
|
||||
usleep_range(5000, 5500);
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: .[%s]\n",__LINE__, __FUNCTION__,mmc_hostname(host->mmc));
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc,"%d..%s: .[%s]\n",__LINE__,
|
||||
__FUNCTION__,mmc_hostname(host->mmc));
|
||||
|
||||
/* 1.8V regulator output should be stable within 5 ms */
|
||||
uhs_reg = mci_readl(host, UHS_REG);
|
||||
if( uhs_reg & SDMMC_UHS_VOLT_REG_18){
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_warning("%s: 1.8V regulator output did not became stable\n",
|
||||
if(uhs_reg & SDMMC_UHS_VOLT_REG_18)
|
||||
return 0;
|
||||
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc, "%s: 1.8V regulator output did not became stable\n",
|
||||
mmc_hostname(host->mmc));
|
||||
|
||||
return -EAGAIN;
|
||||
@@ -1591,7 +1626,7 @@ static int dw_mci_do_start_signal_voltage_switch(struct dw_mci *host,
|
||||
if (host->vmmc) {
|
||||
ret = io_domain_regulator_set_voltage(host->vmmc, 1200000, 1200000);
|
||||
if (ret) {
|
||||
pr_warning("%s: Switching to 1.2V signalling voltage "
|
||||
MMC_DBG_SW_VOL_FUNC(host->mmc, "%s: Switching to 1.2V signalling voltage "
|
||||
" failed\n", mmc_hostname(host->mmc));
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1613,12 +1648,13 @@ static int dw_mci_start_signal_voltage_switch(struct mmc_host *mmc,
|
||||
|
||||
if (host->verid < DW_MMC_240A)
|
||||
return 0;
|
||||
//sdhci_runtime_pm_get(host);
|
||||
|
||||
err = dw_mci_do_start_signal_voltage_switch(host, ios);
|
||||
//sdhci_runtime_pm_put(host);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
{
|
||||
struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
@@ -1680,9 +1716,12 @@ static const struct mmc_host_ops dw_mci_ops = {
|
||||
.hw_reset = dw_mci_hw_reset,
|
||||
.enable_sdio_irq = dw_mci_enable_sdio_irq,
|
||||
.execute_tuning = dw_mci_execute_tuning,
|
||||
//.start_signal_voltage_switch = dw_mci_start_signal_voltage_switch,
|
||||
//.card_busy = dw_mci_card_busy,
|
||||
#ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
|
||||
.start_signal_voltage_switch = dw_mci_start_signal_voltage_switch,
|
||||
.card_busy = dw_mci_card_busy,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
static void dw_mci_enable_irq(struct dw_mci *host, bool irqflag)
|
||||
{
|
||||
@@ -1707,11 +1746,12 @@ static void dw_mci_enable_irq(struct dw_mci *host, bool irqflag)
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dw_mci_deal_data_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
__releases(&host->lock)
|
||||
__acquires(&host->lock)
|
||||
{
|
||||
if(DW_MCI_SEND_STATUS == host->dir_status){
|
||||
if(DW_MCI_SEND_STATUS == host->dir_status){
|
||||
#if 0
|
||||
if( MMC_BUS_TEST_W != host->cmd->opcode){
|
||||
if(host->data_status & SDMMC_INT_DCRC)
|
||||
@@ -1724,8 +1764,7 @@ static void dw_mci_deal_data_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
#else
|
||||
dw_mci_wait_unbusy(host);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
@@ -1737,14 +1776,14 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
|
||||
WARN_ON(host->cmd || host->data);
|
||||
|
||||
dw_mci_deal_data_end(host, mrq);
|
||||
dw_mci_deal_data_end(host, mrq);
|
||||
|
||||
if(mrq->cmd)
|
||||
MMC_DBG_CMD_FUNC(host->mmc, " 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(host->mmc, " reqeust end--reqeuest done, cmd=%d, dataerr=%d, host->state=%d [%s]",\
|
||||
mrq->cmd->opcode,mrq->data->error, host->state, mmc_hostname(host->mmc));
|
||||
if(mrq->cmd)
|
||||
MMC_DBG_CMD_FUNC(host->mmc, " 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(host->mmc, " 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;
|
||||
@@ -1762,7 +1801,7 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
|
||||
host->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
spin_unlock(&host->lock);
|
||||
spin_unlock(&host->lock);
|
||||
mmc_request_done(prev_mmc, mrq);
|
||||
spin_lock(&host->lock);
|
||||
}
|
||||
@@ -1806,15 +1845,16 @@ 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(host->mmc, " command complete, cmd=%d,cmdError=%d [%s]",cmd->opcode, cmd->error,mmc_hostname(host->mmc));
|
||||
MMC_DBG_CMD_FUNC(host->mmc, " command complete, cmd=%d,cmdError=%d [%s]",
|
||||
cmd->opcode, cmd->error,mmc_hostname(host->mmc));
|
||||
|
||||
if (cmd->error) {
|
||||
if(MMC_SEND_STATUS != cmd->opcode)
|
||||
if(host->cmd_rto >= SDMMC_CMD_RTO_MAX_HOLD){
|
||||
MMC_DBG_ERR_FUNC(host->mmc, " command complete, cmd=%d,cmdError=%d [%s]",\
|
||||
cmd->opcode, cmd->error,mmc_hostname(host->mmc));
|
||||
host->cmd_rto = 0;
|
||||
}
|
||||
MMC_DBG_ERR_FUNC(host->mmc, " command complete, cmd=%d,cmdError=%d [%s]",\
|
||||
cmd->opcode, cmd->error,mmc_hostname(host->mmc));
|
||||
host->cmd_rto = 0;
|
||||
}
|
||||
|
||||
/* newer ip versions need a delay between retries */
|
||||
if (host->quirks & DW_MCI_QUIRK_RETRY_DELAY)
|
||||
@@ -1826,7 +1866,7 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd
|
||||
static void dw_mci_tasklet_func(unsigned long priv)
|
||||
{
|
||||
struct dw_mci *host = (struct dw_mci *)priv;
|
||||
struct dw_mci_slot *slot = mmc_priv(host->mmc);
|
||||
struct dw_mci_slot *slot = mmc_priv(host->mmc);
|
||||
struct mmc_data *data;
|
||||
struct mmc_command *cmd;
|
||||
enum dw_mci_state state;
|
||||
@@ -1880,7 +1920,6 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (!host->mrq->data || cmd->error) {
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
@@ -1896,32 +1935,32 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
if (data->stop){
|
||||
send_stop_cmd(host, data);
|
||||
}else{
|
||||
/*single block read/write, send stop cmd manually to prevent host controller halt*/
|
||||
MMC_DBG_INFO_FUNC(host->mmc, "%s status 1 0x%08x [%s]\n",
|
||||
__func__, mci_readl(host, STATUS), mmc_hostname(host->mmc));
|
||||
/*single block read/write, send stop cmd manually to prevent host controller halt*/
|
||||
MMC_DBG_INFO_FUNC(host->mmc, "%s status 1 0x%08x [%s]\n",
|
||||
__func__, mci_readl(host, STATUS), mmc_hostname(host->mmc));
|
||||
|
||||
mci_writel(host, CMDARG, 0);
|
||||
wmb();
|
||||
cmd_flags = SDMMC_CMD_STOP |SDMMC_CMD_RESP_CRC|SDMMC_CMD_RESP_EXP|MMC_STOP_TRANSMISSION;
|
||||
|
||||
if(host->mmc->hold_reg_flag)
|
||||
cmd_flags |= SDMMC_CMD_USE_HOLD_REG;
|
||||
mci_writel(host, CMDARG, 0);
|
||||
wmb();
|
||||
cmd_flags = SDMMC_CMD_STOP | SDMMC_CMD_RESP_CRC
|
||||
| SDMMC_CMD_RESP_EXP | MMC_STOP_TRANSMISSION;
|
||||
|
||||
if(host->mmc->hold_reg_flag)
|
||||
cmd_flags |= SDMMC_CMD_USE_HOLD_REG;
|
||||
|
||||
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
|
||||
wmb();
|
||||
timeout = jiffies + msecs_to_jiffies(500);
|
||||
mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START);
|
||||
wmb();
|
||||
timeout = jiffies + msecs_to_jiffies(500);
|
||||
|
||||
while(ret){
|
||||
ret = time_before(jiffies, timeout);
|
||||
if(!(mci_readl(host, CMD) & SDMMC_CMD_START))
|
||||
break;
|
||||
}
|
||||
|
||||
if(false == ret)
|
||||
MMC_DBG_ERR_FUNC(host->mmc,
|
||||
"%s EVENT_DATA_ERROR recovery failed!!! [%s]\n",
|
||||
__func__, mmc_hostname(host->mmc));
|
||||
}
|
||||
while(ret){
|
||||
ret = time_before(jiffies, timeout);
|
||||
if(!(mci_readl(host, CMD) & SDMMC_CMD_START))
|
||||
break;
|
||||
}
|
||||
if(false == ret)
|
||||
MMC_DBG_ERR_FUNC(host->mmc,
|
||||
"%s EVENT_DATA_ERROR recovery failed!!! [%s]\n",
|
||||
__func__, mmc_hostname(host->mmc));
|
||||
}
|
||||
#else
|
||||
send_stop_abort(host, data);
|
||||
#endif
|
||||
@@ -2002,14 +2041,14 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
}
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: begin to stop . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "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(host->mmc, "Pre-state[%d]-->NowState[%d]: have stop and sbc, exit. [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "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;
|
||||
@@ -2026,31 +2065,31 @@ static void dw_mci_tasklet_func(unsigned long priv)
|
||||
}
|
||||
#endif
|
||||
/* fall through */
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: begin to STATE_SENDING_STOP . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "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))
|
||||
if (!test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events))
|
||||
break;
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "Pre-state[%d]-->NowState[%d]: begin to send cmd12 . [%s]", \
|
||||
prev_state,state,mmc_hostname(host->mmc));
|
||||
|
||||
MMC_DBG_CMD_FUNC(host->mmc, "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) {
|
||||
dw_mci_fifo_reset(host);
|
||||
}
|
||||
|
||||
host->cmd = NULL;
|
||||
host->data = NULL;
|
||||
#if 1
|
||||
dw_mci_command_complete(host, host->mrq->stop);
|
||||
#else
|
||||
#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
|
||||
#endif
|
||||
|
||||
dw_mci_request_end(host, host->mrq);
|
||||
goto unlock;
|
||||
@@ -2955,8 +2994,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
if (drv_data && drv_data->hold_reg_flag)
|
||||
mmc->hold_reg_flag |= drv_data->hold_reg_flag[ctrl_id];
|
||||
|
||||
//set the compatibility of driver.
|
||||
mmc->caps |= MMC_CAP_UHS_SDR12|MMC_CAP_UHS_SDR25|MMC_CAP_UHS_SDR50|MMC_CAP_UHS_SDR104|MMC_CAP_ERASE ;
|
||||
/* set the compatibility of driver. */
|
||||
mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50
|
||||
| MMC_CAP_UHS_SDR104 | MMC_CAP_ERASE ;
|
||||
|
||||
if (host->pdata->caps2)
|
||||
mmc->caps2 = host->pdata->caps2;
|
||||
@@ -2969,13 +3009,14 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
bus_width = 1;
|
||||
|
||||
switch (bus_width) {
|
||||
case 8:
|
||||
mmc->caps |= MMC_CAP_8_BIT_DATA;
|
||||
case 4:
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
case 8:
|
||||
mmc->caps |= MMC_CAP_8_BIT_DATA;
|
||||
case 4:
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
}
|
||||
|
||||
if (of_find_property(host->dev->of_node, "cap-power-off-card", NULL))
|
||||
mmc->caps |= MMC_CAP_POWER_OFF_CARD;
|
||||
mmc->caps |= MMC_CAP_POWER_OFF_CARD;
|
||||
if (of_find_property(host->dev->of_node, "cap-sdio-irq", NULL))
|
||||
mmc->caps |= MMC_CAP_SDIO_IRQ;
|
||||
if (of_find_property(host->dev->of_node, "poll-hw-reset", NULL))
|
||||
@@ -2984,12 +3025,12 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
mmc->caps2 |= MMC_CAP2_FULL_PWR_CYCLE;
|
||||
if (of_find_property(host->dev->of_node, "keep-power-in-suspend", NULL))
|
||||
mmc->pm_caps |= MMC_PM_KEEP_POWER;
|
||||
if (of_find_property(host->dev->of_node, "ignore-pm-notify", NULL))
|
||||
mmc->pm_caps |= MMC_PM_IGNORE_PM_NOTIFY;
|
||||
if (of_find_property(host->dev->of_node, "ignore-pm-notify", NULL))
|
||||
mmc->pm_caps |= MMC_PM_IGNORE_PM_NOTIFY;
|
||||
if (of_find_property(host->dev->of_node, "enable-sdio-wakeup", NULL))
|
||||
mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
|
||||
/*Assign pm_caps pass to pm_flags*/
|
||||
/*Assign pm_caps pass to pm_flags*/
|
||||
mmc->pm_flags = mmc->pm_caps;
|
||||
|
||||
if (host->pdata->blk_settings) {
|
||||
@@ -3014,74 +3055,72 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
mmc->max_seg_size = mmc->max_req_size;
|
||||
#endif /* CONFIG_MMC_DW_IDMAC */
|
||||
}
|
||||
//pwr_en
|
||||
slot->pwr_en_gpio = dw_mci_of_get_pwr_en_gpio(host->dev, slot->id);
|
||||
/* pwr_en */
|
||||
slot->pwr_en_gpio = dw_mci_of_get_pwr_en_gpio(host->dev, slot->id);
|
||||
|
||||
if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD))//(gpio_is_valid(slot->pwr_en_gpio))
|
||||
{
|
||||
host->vmmc = NULL;
|
||||
}else{
|
||||
|
||||
if(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
|
||||
if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD))
|
||||
{
|
||||
host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
|
||||
}
|
||||
else
|
||||
{
|
||||
host->vmmc = NULL;
|
||||
}
|
||||
host->vmmc = NULL;
|
||||
}else{
|
||||
|
||||
if(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
|
||||
host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
|
||||
else
|
||||
host->vmmc = NULL;
|
||||
|
||||
if (IS_ERR(host->vmmc)) {
|
||||
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
|
||||
host->vmmc = NULL;
|
||||
} else {
|
||||
ret = regulator_enable(host->vmmc);
|
||||
if (ret) {
|
||||
dev_err(host->dev,
|
||||
"failed to enable regulator: %d\n", ret);
|
||||
goto err_setup_bus;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IS_ERR(host->vmmc)) {
|
||||
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
|
||||
host->vmmc = NULL;
|
||||
}else{
|
||||
ret = regulator_enable(host->vmmc);
|
||||
if (ret) {
|
||||
dev_err(host->dev,
|
||||
"failed to enable regulator: %d\n", ret);
|
||||
host->vmmc = NULL;
|
||||
goto err_setup_bus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id);
|
||||
slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id);
|
||||
|
||||
if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
|
||||
clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
|
||||
clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
goto err_setup_bus;
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
goto err_setup_bus;
|
||||
|
||||
/* Pinctrl set default iomux state to fucntion port.
|
||||
* Fixme: DON'T TOUCH EMMC SETTING!
|
||||
*/
|
||||
if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC))
|
||||
{
|
||||
host->pinctrl = devm_pinctrl_get(host->dev);
|
||||
if(IS_ERR(host->pinctrl))
|
||||
printk("%s: Warning : No pinctrl used!\n",mmc_hostname(host->mmc));
|
||||
else
|
||||
/* Pinctrl set default iomux state to fucntion port.
|
||||
* Fixme: DON'T TOUCH EMMC SETTING!
|
||||
*/
|
||||
if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC))
|
||||
{
|
||||
host->pins_idle= pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_IDLE);
|
||||
if(IS_ERR(host->pins_default))
|
||||
printk("%s: Warning : No IDLE pinctrl matched!\n", mmc_hostname(host->mmc));
|
||||
else
|
||||
{
|
||||
if(pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
|
||||
printk("%s: Warning : Idle pinctrl setting failed!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
host->pinctrl = devm_pinctrl_get(host->dev);
|
||||
if(IS_ERR(host->pinctrl)){
|
||||
printk("%s: Warning : No pinctrl used!\n",mmc_hostname(host->mmc));
|
||||
}else{
|
||||
host->pins_idle= pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_IDLE);
|
||||
if(IS_ERR(host->pins_default)){
|
||||
printk("%s: Warning : No IDLE pinctrl matched!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
|
||||
printk("%s: Warning : Idle pinctrl setting failed!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
|
||||
host->pins_default = pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_DEFAULT);
|
||||
if(IS_ERR(host->pins_default))
|
||||
printk("%s: Warning : No default pinctrl matched!\n", mmc_hostname(host->mmc));
|
||||
else
|
||||
{
|
||||
if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
|
||||
printk("%s: Warning : Default pinctrl setting failed!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
}
|
||||
}
|
||||
host->pins_default = pinctrl_lookup_state(host->pinctrl,PINCTRL_STATE_DEFAULT);
|
||||
if(IS_ERR(host->pins_default)){
|
||||
printk("%s: Warning : No default pinctrl matched!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
|
||||
printk("%s: Warning : Default pinctrl setting failed!\n", mmc_hostname(host->mmc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
@@ -3375,6 +3414,7 @@ int dw_mci_probe(struct dw_mci *host)
|
||||
host->irq_state = true;
|
||||
host->set_speed = 0;
|
||||
host->set_div = 0;
|
||||
host->svi_flags = 0;
|
||||
|
||||
spin_lock_init(&host->lock);
|
||||
INIT_LIST_HEAD(&host->queue);
|
||||
|
||||
@@ -193,7 +193,7 @@ struct dw_mci {
|
||||
/* Workaround flags */
|
||||
u32 quirks;
|
||||
bool irq_state;
|
||||
|
||||
u32 svi_flags; /*switch voltage interrupt flags*/
|
||||
struct regulator *vmmc; /* Power regulator */
|
||||
unsigned long irq_flags; /* IRQ flags */
|
||||
int irq;
|
||||
|
||||
Reference in New Issue
Block a user