Skip to content

Instantly share code, notes, and snippets.

@neheb
Created April 2, 2019 21:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neheb/3d9e4cbf966f8487114df19b49f28214 to your computer and use it in GitHub Desktop.
Save neheb/3d9e4cbf966f8487114df19b49f28214 to your computer and use it in GitHub Desktop.
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