Created
April 2, 2019 21:56
-
-
Save neheb/3d9e4cbf966f8487114df19b49f28214 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c | |
index 6457a7d8880f..01ad733da8b2 100644 | |
--- a/drivers/mmc/host/mtk-sd.c | |
+++ b/drivers/mmc/host/mtk-sd.c | |
@@ -438,11 +438,24 @@ static const struct mtk_mmc_compatible mt2712_compat = { | |
.enhance_rx = true, | |
}; | |
+static const struct mtk_mmc_compatible mt7620_compat = { | |
+ .clk_div_bits = 8, | |
+ .hs400_tune = false, | |
+ .pad_tune_reg = MSDC_PAD_TUNE, | |
+ .async_fifo = false, | |
+ .data_tune = false, | |
+ .busy_check = false, | |
+ .stop_clk_fix = false, | |
+ .enhance_rx = false, | |
+}; | |
+ | |
+ | |
static const struct of_device_id msdc_of_ids[] = { | |
{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat}, | |
{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat}, | |
{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat}, | |
{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat}, | |
+ { .compatible = "ralink,mt7620-sdhci", .data = &mt7620_compat}, | |
{} | |
}; | |
MODULE_DEVICE_TABLE(of, msdc_of_ids); | |
@@ -570,23 +583,25 @@ static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) | |
{ | |
struct mmc_data *data = mrq->data; | |
+ bool read = (data->flags & MMC_DATA_READ) != 0; | |
+ | |
if (!(data->host_cookie & MSDC_PREPARE_FLAG)) { | |
data->host_cookie |= MSDC_PREPARE_FLAG; | |
data->sg_count = dma_map_sg(host->dev, data->sg, data->sg_len, | |
- mmc_get_dma_dir(data)); | |
+ read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | |
} | |
} | |
static void msdc_unprepare_data(struct msdc_host *host, struct mmc_request *mrq) | |
{ | |
struct mmc_data *data = mrq->data; | |
- | |
+ bool read = (data->flags & MMC_DATA_READ) != 0; | |
if (data->host_cookie & MSDC_ASYNC_FLAG) | |
return; | |
if (data->host_cookie & MSDC_PREPARE_FLAG) { | |
dma_unmap_sg(host->dev, data->sg, data->sg_len, | |
- mmc_get_dma_dir(data)); | |
+ read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | |
data->host_cookie &= ~MSDC_PREPARE_FLAG; | |
} | |
} | |
@@ -645,7 +660,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |
u32 tune_reg = host->dev_comp->pad_tune_reg; | |
if (!hz) { | |
- dev_dbg(host->dev, "set mclk to 0\n"); | |
+ dev_err(host->dev, "set mclk to 0\n"); | |
host->mclk = 0; | |
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); | |
return; | |
@@ -705,10 +720,12 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |
* As src_clk/HCLK use the same bit to gate/ungate, | |
* So if want to only gate src_clk, need gate its parent(mux). | |
*/ | |
+#if 0 | |
if (host->src_clk_cg) | |
clk_disable_unprepare(host->src_clk_cg); | |
else | |
clk_disable_unprepare(clk_get_parent(host->src_clk)); | |
+#endif | |
if (host->dev_comp->clk_div_bits == 8) | |
sdr_set_field(host->base + MSDC_CFG, | |
MSDC_CFG_CKMOD | MSDC_CFG_CKDIV, | |
@@ -717,17 +734,19 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |
sdr_set_field(host->base + MSDC_CFG, | |
MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA, | |
(mode << 12) | div); | |
+#if 0 | |
if (host->src_clk_cg) | |
clk_prepare_enable(host->src_clk_cg); | |
else | |
clk_prepare_enable(clk_get_parent(host->src_clk)); | |
- | |
+#endif | |
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) | |
cpu_relax(); | |
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); | |
host->sclk = sclk; | |
host->mclk = hz; | |
host->timing = timing; | |
+ printk("Set clk %dhz\n", sclk); | |
/* need because clk changed. */ | |
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); | |
sdr_set_bits(host->base + MSDC_INTEN, flags); | |
@@ -916,6 +935,8 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, | |
unsigned long flags; | |
u32 *rsp = cmd->resp; | |
+// printk("Cmd done\n"); | |
+ | |
if (mrq->sbc && cmd == mrq->cmd && | |
(events & (MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | |
| MSDC_INT_ACMDTMO))) | |
@@ -965,9 +986,8 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, | |
host->error |= REQ_CMD_TMO; | |
} | |
} | |
- if (cmd->error) | |
- dev_dbg(host->dev, | |
- "%s: cmd=%d arg=%08X; rsp %08X; cmd_error=%d\n", | |
+ if(cmd->error) | |
+ printk( "%s: cmd=%d arg=%08X; rsp %08X; cmd_error=%d\n", | |
__func__, cmd->opcode, cmd->arg, rsp[0], | |
cmd->error); | |
@@ -1076,7 +1096,7 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) | |
msdc_start_command(host, mrq, mrq->cmd); | |
} | |
-static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq) | |
+static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, bool is_first_req) | |
{ | |
struct msdc_host *host = mmc_priv(mmc); | |
struct mmc_data *data = mrq->data; | |
@@ -1174,6 +1194,7 @@ static void msdc_set_buswidth(struct msdc_host *host, u32 width) | |
val &= ~SDC_CFG_BUSWIDTH; | |
+ | |
switch (width) { | |
default: | |
case MMC_BUS_WIDTH_1: | |
@@ -1188,7 +1209,7 @@ static void msdc_set_buswidth(struct msdc_host *host, u32 width) | |
} | |
writel(val, host->base + SDC_CFG); | |
- dev_dbg(host->dev, "Bus Width = %d", width); | |
+ dev_err(host->dev, "Bus Width = %d", width); | |
} | |
static int msdc_ops_switch_volt(struct mmc_host *mmc, struct mmc_ios *ios) | |
@@ -1196,6 +1217,8 @@ static int msdc_ops_switch_volt(struct mmc_host *mmc, struct mmc_ios *ios) | |
struct msdc_host *host = mmc_priv(mmc); | |
int ret = 0; | |
+ printk("Volt switch %d\n", ios->signal_voltage); | |
+ | |
if (!IS_ERR(mmc->supply.vqmmc)) { | |
if (ios->signal_voltage != MMC_SIGNAL_VOLTAGE_330 && | |
ios->signal_voltage != MMC_SIGNAL_VOLTAGE_180) { | |
@@ -1824,11 +1847,15 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
if (!mmc) | |
return -ENOMEM; | |
+ printk("of parse\n"); | |
+ | |
host = mmc_priv(mmc); | |
ret = mmc_of_parse(mmc); | |
if (ret) | |
goto host_free; | |
+ | |
+ printk("mem\n"); | |
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
host->base = devm_ioremap_resource(&pdev->dev, res); | |
if (IS_ERR(host->base)) { | |
@@ -1836,20 +1863,24 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
goto host_free; | |
} | |
+ printk("reg\n"); | |
+ | |
ret = mmc_regulator_get_supply(mmc); | |
if (ret) | |
goto host_free; | |
+ printk("source\n"); | |
+ | |
host->src_clk = devm_clk_get(&pdev->dev, "source"); | |
if (IS_ERR(host->src_clk)) { | |
- ret = PTR_ERR(host->src_clk); | |
- goto host_free; | |
+ host->src_clk = NULL; | |
} | |
+ printk("hclk\n"); | |
+ | |
host->h_clk = devm_clk_get(&pdev->dev, "hclk"); | |
if (IS_ERR(host->h_clk)) { | |
- ret = PTR_ERR(host->h_clk); | |
- goto host_free; | |
+ host->h_clk = NULL; | |
} | |
/*source clock control gate is optional clock*/ | |
@@ -1857,12 +1888,16 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
if (IS_ERR(host->src_clk_cg)) | |
host->src_clk_cg = NULL; | |
+ printk("irq\n"); | |
+ | |
host->irq = platform_get_irq(pdev, 0); | |
if (host->irq < 0) { | |
ret = -EINVAL; | |
goto host_free; | |
} | |
+ printk("pinctrl\n"); | |
+ | |
host->pinctrl = devm_pinctrl_get(&pdev->dev); | |
if (IS_ERR(host->pinctrl)) { | |
ret = PTR_ERR(host->pinctrl); | |
@@ -1870,6 +1905,8 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
goto host_free; | |
} | |
+ printk("default\n"); | |
+ | |
host->pins_default = pinctrl_lookup_state(host->pinctrl, "default"); | |
if (IS_ERR(host->pins_default)) { | |
ret = PTR_ERR(host->pins_default); | |
@@ -1877,19 +1914,21 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
goto host_free; | |
} | |
+ printk("uhs\n"); | |
+ | |
host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs"); | |
if (IS_ERR(host->pins_uhs)) { | |
- ret = PTR_ERR(host->pins_uhs); | |
- dev_err(&pdev->dev, "Cannot find pinctrl uhs!\n"); | |
- goto host_free; | |
+ host->pins_uhs = NULL; | |
} | |
+ printk("props\n"); | |
+ | |
msdc_of_property_parse(pdev, host); | |
host->dev = &pdev->dev; | |
host->dev_comp = of_id->data; | |
host->mmc = mmc; | |
- host->src_clk_freq = clk_get_rate(host->src_clk); | |
+ host->src_clk_freq = 48000000; | |
/* Set host parameters to mmc */ | |
mmc->ops = &mt_msdc_ops; | |
if (host->dev_comp->clk_div_bits == 8) | |
@@ -1897,13 +1936,18 @@ static int msdc_drv_probe(struct platform_device *pdev) | |
else | |
mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095); | |
- mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | |
+ mmc->f_max = host->src_clk_freq; | |
+ mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; | |
/* MMC core transfer sizes tunable parameters */ | |
mmc->max_segs = MAX_BD_NUM; | |
mmc->max_seg_size = BDMA_DESC_BUFLEN; | |
mmc->max_blk_size = 2048; | |
mmc->max_req_size = 512 * 1024; | |
mmc->max_blk_count = mmc->max_req_size / 512; | |
+ | |
+#define MSDC_OCR_AVAIL (MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33) | |
+ mmc->ocr_avail = MSDC_OCR_AVAIL; | |
+ | |
host->dma_mask = DMA_BIT_MASK(32); | |
mmc_dev(mmc)->dma_mask = &host->dma_mask; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment