/*caps defined in dts*/
tx_delay = <0>;
co_phase = <3>;
+ calc_f = <1>;
max_req_size = <0x20000>; /**128KB*/
gpio_dat3 = <&gpio BOOT_3 GPIO_ACTIVE_HIGH>;
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
/*caps defined in dts*/
tx_delay = <0>;
co_phase = <3>;
+ calc_f = <1>;
max_req_size = <0x20000>; /**128KB*/
gpio_dat3 = <&gpio BOOT_3 GPIO_ACTIVE_HIGH>;
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
{
u32 adj, dly1, dly2, intf3;
u32 vconf = 0, vclkc = 0;
+ struct sd_emmc_clock_v3 *clkc = (struct sd_emmc_clock_v3 *)&(vclkc);
struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
struct amlsd_platform *pdata = mmc_priv(mmc);
struct amlsd_host *host = pdata->host;
&& (pconf->stop_clk == pdata->stop_clk)
&& (mmc->actual_clock == clk_ios)
&& (vclkc == pdata->clkc)
+ && (clkc->irq_sdio_sleep == pdata->irq_sdio_sleep)
&& (adj == pdata->adj)
&& (dly1 == pdata->dly1)
&& (dly2 == pdata->dly2)
pconf->bl_len = pdata->bl_len;
pconf->stop_clk = pdata->stop_clk;
vclkc = pdata->clkc;
+ clkc->irq_sdio_sleep = pdata->irq_sdio_sleep;
adj = pdata->adj;
dly1 = pdata->dly1;
dly2 = pdata->dly2;
pclock->irq_sdio_sleep_ds = 0;
writel(vclkc, host->base + SD_EMMC_CLOCK);
}
- pdata->clkc = vclkc;
+ pdata->irq_sdio_sleep = 1;
if (enable)
spin_unlock_irqrestore(&host->mrq_lock, flags);
if (sdio_host) {
if (pdata->xfer_pre)
pdata->xfer_pre(mmc_priv(sdio_host));
+ aml_sd_emmc_save_host_val(sdio_host);
virqc = readl(host->base + SD_EMMC_IRQ_EN);
if (irqc->irq_sdio != host->sdio_irqen)
aml_sd_emmc_enable_sdio_irq(sdio_host,
pr_err("%s: warning... data crc, vstat:0x%x, virqc:%x",
mmc_hostname(host->mmc),
vstat, virqc);
- pr_err("@ cmd %d with %p; stop %d, status %d\n",
- mrq->cmd->opcode, mrq->data,
- host->cmd_is_stop,
+ pr_err("@ cmd %d arg %x with %p; stop %d, status %d\n",
+ mrq->cmd->opcode, mrq->cmd->arg,
+ mrq->data, host->cmd_is_stop,
host->status);
}
} else if (ista->desc_err) {
struct sd_emmc_status *ista = (struct sd_emmc_status *)&vstat;
u32 vconf;
struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
+ u32 virqc = 0;
+ struct sd_emmc_irq_en *irqc = (struct sd_emmc_irq_en *)&virqc;
if ((host->mem->start == host->data->port_b_base)
&& host->data->tdma_f
&& host->data->tdma_f)
host->init_volt = 0;
}
+
+ if ((host->mem->start == host->data->port_b_base)
+ && host->data->tdma_f
+ && strcmp(host->pinctrl_name, "sdio_")) {
+ if (sdio_host) {
+ if (pdata->xfer_pre)
+ pdata->xfer_pre(mmc_priv(sdio_host));
+ aml_sd_emmc_save_host_val(sdio_host);
+ virqc = readl(host->base + SD_EMMC_IRQ_EN);
+ if (irqc->irq_sdio != host->sdio_irqen)
+ aml_sd_emmc_enable_sdio_irq(sdio_host,
+ host->sdio_irqen);
+ }
+ }
+
if ((host->mem->start == host->data->port_b_base)
&& host->data->tdma_f
&& (host->init_volt == 0))
int aml_fixdiv_calc(unsigned int *fixdiv, struct clock_lay_t *clk)
{
int ret = 0;
- unsigned int full_div, source_cycle; /* in ns*/
- unsigned int sdclk_idx, todly_idx_max, todly_idx_min;
- unsigned int inv_idx_min, inv_idx_max;
- unsigned int val_idx_min, val_idx_max, val_idx_win, val_idx_sta;
+ unsigned int full_div = 0, source_cycle = 0; /* in ns*/
+ unsigned int sdclk_idx = 0, todly_idx_max = 0, todly_idx_min = 0;
+ unsigned int inv_idx_min = 0, inv_idx_max = 0;
+ unsigned int val_idx_min = 0, val_idx_max = 0;
+ unsigned int val_idx_win = 0, val_idx_sta = 0;
if (!fixdiv || !clk)
return -EPERM;
u32 vconf = 0;
struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf;
struct mmc_phase *init = &(host->data->sdmmc.init);
- struct mmc_phase *calc = &(host->data->sdmmc.calc);
writel(0, host->base + SD_EMMC_CLOCK_V3);
#ifndef SD_EMMC_CLK_CTRL
pclkc->core_phase = init->core_phase; /* 2: 180 phase */
pclkc->rx_phase = init->rx_phase;
pclkc->tx_phase = init->tx_phase;
- if (host->data->chip_type >= MMC_CHIP_G12A) {
- pclkc->core_phase = calc->core_phase;
- pclkc->tx_phase = calc->tx_phase;
- }
pclkc->always_on = 1; /* Keep clock always on */
writel(vclkc, host->base + SD_EMMC_CLOCK_V3);
#else
if (clk_ios == mmc->actual_clock) {
pr_debug("[%s] clk_ios: %lu, return .............. clock: 0x%x\n",
- __func__, clk_ios,
+ pdata->pinname, clk_ios,
readl(host->base + SD_EMMC_CLOCK_V3));
return 0;
}
} else
mmc->actual_clock = clk_ios;
- vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
- pdata->clk_lay.source = clk_get_rate(host->cfg_div_clk) * clkc->div;
- pdata->clk_lay.core = clk_get_rate(host->cfg_div_clk);
-
-
/* (re)start clock, if non-zero */
if (clk_ios) {
+ vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
+ pdata->clk_lay.source
+ = clk_get_rate(host->cfg_div_clk) * clkc->div;
+ pdata->clk_lay.core = clk_get_rate(host->cfg_div_clk);
+
vcfg = readl(host->base + SD_EMMC_CFG);
conf->stop_clk = 0;
writel(vcfg, host->base + SD_EMMC_CFG);
struct sd_emmc_config *ctrl = (struct sd_emmc_config *)&vctrl;
u32 vclkc = readl(host->base + SD_EMMC_CLOCK_V3);
struct sd_emmc_clock_v3 *clkc = (struct sd_emmc_clock_v3 *)&vclkc;
- u32 adjust;
+ u32 adjust = 0;
struct sd_emmc_adjust_v3 *gadjust = (struct sd_emmc_adjust_v3 *)&adjust;
u8 clk_div = 0;
struct para_e *para = &(host->data->sdmmc);
/* overide co-phase by dts */
if (pdata->co_phase)
clkc->core_phase = pdata->co_phase;
- if (host->data->chip_type >= MMC_CHIP_G12A) {
+ if (pdata->calc_f) {
clkc->core_phase = para->calc.core_phase;
clkc->tx_phase = para->calc.tx_phase;
}
} else if (timing == MMC_TIMING_SD_HS) {
if (aml_card_type_non_sdio(pdata))
clkc->core_phase = para->sd_hs.core_phase;
- if (host->data->chip_type >= MMC_CHIP_G12A) {
+ if (pdata->calc_f) {
clkc->core_phase = para->calc.core_phase;
clkc->tx_phase = para->calc.tx_phase;
}
} else if (timing == MMC_TIMING_UHS_SDR104) {
clkc->core_phase = para->sdr104.core_phase;
clkc->tx_phase = para->sdr104.tx_phase;
- } else
+ } else {
ctrl->ddr = 0;
+ /* timing == MMC_TIMING_LEGACY */
+ if (pdata->calc_f) {
+ clkc->core_phase = para->calc.core_phase;
+ clkc->tx_phase = para->calc.tx_phase;
+ }
+ }
- if (host->data->chip_type >= MMC_CHIP_G12A) {
+ if (pdata->calc_f) {
if (timing <= MMC_TIMING_SD_HS) {
ret = aml_fixdiv_calc(&fixdiv, &pdata->clk_lay);
if (!ret) {
struct amlsd_host *host = pdata->host;
int ret = 0;
- if ((host->mem->start == host->data->port_b_base)
- && host->data->tdma_f)
- wait_for_completion(&host->drv_completion);
-
mutex_lock(&pdata->in_out_lock);
if (card_dealed == 1) {
card_dealed = 0;
card_dealed = 0;
- if ((host->mem->start == host->data->port_b_base)
- && host->data->tdma_f)
- complete(&host->drv_completion);
-
return 0;
}
{
struct amlsd_platform *pdata = container_of(
work, struct amlsd_platform, cd_detect.work);
+ struct amlsd_host *host = pdata->host;
int i = 0, ret = 0;
+ if ((host->mem->start == host->data->port_b_base)
+ && host->data->tdma_f)
+ wait_for_completion(&host->drv_completion);
+
for (i = 0; i < 5; i++) {
ret = gpio_get_value(pdata->gpio_cd);
if (pdata->gpio_cd_sta != ret)
mdelay(1);
}
schedule_delayed_work(&pdata->cd_detect, 50);
+
+ if ((host->mem->start == host->data->port_b_base)
+ && host->data->tdma_f)
+ complete(&host->drv_completion);
}
#endif
prop, pdata->power_level);
SD_PARSE_GPIO_NUM_PROP(child, "gpio_power",
str, pdata->gpio_power);
+ SD_PARSE_U32_PROP_DEC(child, "calc_f",
+ prop, pdata->calc_f);
SD_PARSE_U32_PROP_DEC(child, "gpio_cd_level",
prop, pdata->gpio_cd_level);
unsigned int dly1;
unsigned int dly2;
unsigned int intf3;
+ unsigned int irq_sdio_sleep;
unsigned int clock;
/* signalling voltage (1.8V or 3.3V) */
unsigned char signal_voltage;
unsigned int gpio_cd_sta;
unsigned int gpio_power;
unsigned int power_level;
+ unsigned int calc_f;
unsigned int auto_clk_close;
unsigned int vol_switch;