#include <linux/clk-private.h>
#include <linux/rockchip/cpu.h>
#include <linux/rfkill-wlan.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <linux/log2.h>
#include "rk_sdmmc.h"
#include "rk_sdmmc_dbg.h"
spin_unlock_bh(&host->lock);
if(test_bit(DW_MMC_CARD_PRESENT, &slot->flags)){
- if(__clk_is_enabled(host->hclk_mmc) == false)
+ if (!IS_ERR(host->hpclk_mmc) &&
+ __clk_is_enabled(host->hpclk_mmc) == false)
+ clk_prepare_enable(host->hpclk_mmc);
+ if (__clk_is_enabled(host->hclk_mmc) == false)
clk_prepare_enable(host->hclk_mmc);
- if(__clk_is_enabled(host->clk_mmc) == false)
+ if (__clk_is_enabled(host->clk_mmc) == false)
clk_prepare_enable(host->clk_mmc);
}else{
- if(__clk_is_enabled(host->clk_mmc) == true)
+ if (__clk_is_enabled(host->clk_mmc) == true)
clk_disable_unprepare(slot->host->clk_mmc);
- if(__clk_is_enabled(host->hclk_mmc) == true)
+ if (__clk_is_enabled(host->hclk_mmc) == true)
clk_disable_unprepare(slot->host->hclk_mmc);
+ if (!IS_ERR(host->hpclk_mmc) &&
+ __clk_is_enabled(host->hpclk_mmc) == true)
+ clk_disable_unprepare(slot->host->hpclk_mmc);
}
mmc_detect_change(slot->mmc, 20);
}
msleep(10);
if (gpio_val == gpio_get_value(gpio_cd)) {
- gpio_cd = gpio_get_value(gpio_cd) == 0 ? 1 : 0;
+ gpio_cd = (gpio_val == 0 ? 1 : 0);
if (gpio_cd == 0) {
irq_set_irq_type(irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT);
/* Enable force_jtag wihtout card in slot, ONLY for NCD-package */
*/
mci_writel(slot->host, PWREN, 0x0);
mci_writel(slot->host, RST_N, 0x0);
- dsb();
+ dsb(sy);
udelay(10); /* 10us for bad quality eMMc. */
mci_writel(slot->host, PWREN, 0x1);
mci_writel(slot->host, RST_N, 0x1);
- dsb();
+ dsb(sy);
usleep_range(500, 1000); /* at least 500(> 200us) */
}
break;
}
- if(cpu_is_rk3288()){
+ if (cpu_is_rk3288()) {
if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
grf_writel((voltage << 7) | (1 << 23), RK3288_GRF_IO_VSEL);
else
return ;
- }else{
+ } else if (host->cid == DW_MCI_TYPE_RK3368) {
+ if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
+ regmap_write(host->grf, 0x900, (voltage << 6) | (1 << 22));
+ else
+ return;
+ } else {
MMC_DBG_ERR_FUNC(host->mmc,"%s : unknown chip [%s]\n",
__FUNCTION__, mmc_hostname(host->mmc));
}
if (!(IS_ERR(host->pins_udbg)) && !(IS_ERR(host->pins_default))) {
if (present) {
if (pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
- dev_err(host->dev, "%s: Udbg pinctrl setting failed!\n",
+ dev_err(host->dev, "%s: Default pinctrl setting failed!\n",
mmc_hostname(host->mmc));
} else {
if (pinctrl_select_state(host->pinctrl, host->pins_udbg) < 0)
- dev_err(host->dev, "%s: Default pinctrl setting failed!\n",
+ dev_err(host->dev, "%s: Udbg pinctrl setting failed!\n",
mmc_hostname(host->mmc));
}
}
}
}
+ if (host->cid == DW_MCI_TYPE_RK3368) {
+ if (IS_ERR(host->grf))
+ pr_err("rk_sdmmc: dts couldn't find grf regmap for 3368\n");
+ else
+ /* Disable force_jtag */
+ regmap_write(host->grf, 0x43c, (1<<13)<<16 | (0 << 13));
+ }
+
/* We assume only low-level chip use gpio_cd */
if ((soc_is_rk3126() || soc_is_rk3126b() || soc_is_rk3036()) &&
(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)) {
__func__);
goto no_dma;
}
+ #ifdef CONFIG_ARM64
+ memset(host->sg_cpu, 0, PAGE_SIZE);
+ #endif
/* Determine which DMA interface to use */
#if defined(CONFIG_MMC_DW_IDMAC)
else
host->data_offset = DATA_240A_OFFSET;
+ //hpclk enable
+ host->hpclk_mmc= devm_clk_get(host->dev, "hpclk_mmc");
+ if (IS_ERR(host->hpclk_mmc)) {
+ dev_err(host->dev, "failed to get hpclk_mmc\n");
+ } else {
+ clk_prepare_enable(host->hpclk_mmc);
+ }
+
//hclk enable
host->hclk_mmc= devm_clk_get(host->dev, "hclk_mmc");
if (IS_ERR(host->hclk_mmc)) {
}
err_clk_mmc:
- if (!IS_ERR(host->clk_mmc))
+ if (!IS_ERR(host->clk_mmc))
clk_disable_unprepare(host->clk_mmc);
err_hclk_mmc:
- if (!IS_ERR(host->hclk_mmc))
+ if (!IS_ERR(host->hclk_mmc))
clk_disable_unprepare(host->hclk_mmc);
-
return ret;
}
EXPORT_SYMBOL(dw_mci_probe);
if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
unregister_pm_notifier(&host->mmc->pm_notify);
- if(host->use_dma && host->dma_ops->exit)
+ if (host->use_dma && host->dma_ops->exit)
host->dma_ops->exit(host);
if (gpio_is_valid(slot->cd_gpio))
dw_mci_of_free_cd_gpio_irq(host->dev, slot->cd_gpio, host->mmc);
- if(host->vmmc){
+ if (host->vmmc){
regulator_disable(host->vmmc);
regulator_put(host->vmmc);
}
- if(!IS_ERR(host->clk_mmc))
+ if (!IS_ERR(host->clk_mmc))
clk_disable_unprepare(host->clk_mmc);
- if(!IS_ERR(host->hclk_mmc))
+ if (!IS_ERR(host->hclk_mmc))
clk_disable_unprepare(host->hclk_mmc);
+ if (!IS_ERR(host->hpclk_mmc))
+ clk_disable_unprepare(host->hpclk_mmc);
}
EXPORT_SYMBOL(dw_mci_remove);
extern int get_wifi_chip_type(void);
int dw_mci_suspend(struct dw_mci *host)
{
+ int present = dw_mci_get_cd(host->mmc);
+
if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) &&
(get_wifi_chip_type() == WIFI_ESP8089 || get_wifi_chip_type() > WIFI_AP6XXX_SERIES))
return 0;
/*only for sdmmc controller*/
if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
disable_irq(host->irq);
- if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
- MMC_DBG_ERR_FUNC(host->mmc, "Idle pinctrl setting failed! [%s]",
- mmc_hostname(host->mmc));
+ if (present) {
+ if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
+ MMC_DBG_ERR_FUNC(host->mmc,
+ "Idle pinctrl setting failed! [%s]",
+ mmc_hostname(host->mmc));
+ }
mci_writel(host, RINTSTS, 0xFFFFFFFF);
mci_writel(host, INTMASK, 0x00);
int dw_mci_resume(struct dw_mci *host)
{
- int i, ret, retry_cnt = 0;
+ int i, ret;
u32 regs;
- struct dw_mci_slot *slot;
+ struct dw_mci_slot *slot;
+ int present = dw_mci_get_cd(host->mmc);
- if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) &&
- (get_wifi_chip_type() == WIFI_ESP8089 || get_wifi_chip_type() > WIFI_AP6XXX_SERIES))
+ if ((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) &&
+ (get_wifi_chip_type() == WIFI_ESP8089 ||
+ get_wifi_chip_type() > WIFI_AP6XXX_SERIES))
return 0;
-
-
if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) {
slot = mmc_priv(host->mmc);
- if(!test_bit(DW_MMC_CARD_PRESENT, &slot->flags))
+ if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags))
return 0;
}
disable_irq_wake(host->mmc->slot.cd_irq);
mmc_gpio_free_cd(host->mmc);
}
- if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
- MMC_DBG_ERR_FUNC(host->mmc, "Default pinctrl setting failed! [%s]",
- mmc_hostname(host->mmc));
+
+ if (!present) {
+ if (!IS_ERR(host->pins_udbg)) {
+ if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
+ MMC_DBG_ERR_FUNC(host->mmc,
+ "Idle pinctrl setting failed! [%s]",
+ mmc_hostname(host->mmc));
+ if (pinctrl_select_state(host->pinctrl, host->pins_udbg) < 0)
+ MMC_DBG_ERR_FUNC(host->mmc,
+ "%s: Udbg pinctrl setting failed! [%s]",
+ mmc_hostname(host->mmc));
+ } else {
+ if (pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
+ MMC_DBG_ERR_FUNC(host->mmc,
+ "Default pinctrl setting failed! [%s]",
+ mmc_hostname(host->mmc));
+ }
+ } else {
+ if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
+ MMC_DBG_ERR_FUNC(host->mmc,
+ "Default pinctrl setting failed! [%s]",
+ mmc_hostname(host->mmc));
+ }
/* Disable jtag*/
if(cpu_is_rk3288())
mci_writel(host, INTMASK, regs);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
/*only for sdmmc controller*/
- if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)&& (!retry_cnt)){
+ if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)){
enable_irq(host->irq);
}