Commit b465646e authored by Hans de Goede's avatar Hans de Goede Committed by Ulf Hansson

mmc: sunxi: sun4i / sun5i do not have sample clocks

It turns out that sun4i (A10) and sun5i (A13 & co) do not have sample
clocks, so add a new sun7i-a20-mmc compatible and do not try to use
sample clocks on sun4i / sun5i.

Since sun4i / sun5i do not have sample clocks, they cannot (reliably) do
DDR rates, so only set MMC_CAP_1_8V_DDR when we do have sample clks.

Note this patch leaves the clk_prepare_enable() / clk_disable_unprepare()
calls to the sample clks as-is, without adding checks for them being
NULL. All the clk_foo calls accept a NULL clk and will return success when
called with a NULL clk.
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent f2cecb70
...@@ -8,7 +8,11 @@ as the speed of SD standard 3.0. ...@@ -8,7 +8,11 @@ as the speed of SD standard 3.0.
Absolute maximum transfer rate is 200MB/s Absolute maximum transfer rate is 200MB/s
Required properties: Required properties:
- compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc" - compatible : should be one of:
* "allwinner,sun4i-a10-mmc"
* "allwinner,sun5i-a13-mmc"
* "allwinner,sun7i-a20-mmc"
* "allwinner,sun9i-a80-mmc"
- reg : mmc controller base registers - reg : mmc controller base registers
- clocks : a list with 4 phandle + clock specifier pairs - clocks : a list with 4 phandle + clock specifier pairs
- clock-names : must contain "ahb", "mmc", "output" and "sample" - clock-names : must contain "ahb", "mmc", "output" and "sample"
......
...@@ -662,6 +662,9 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host, ...@@ -662,6 +662,9 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host,
{ {
int index; int index;
if (!host->cfg->clk_delays)
return 0;
/* determine delays */ /* determine delays */
if (rate <= 400000) { if (rate <= 400000) {
index = SDXC_CLK_400K; index = SDXC_CLK_400K;
...@@ -978,10 +981,15 @@ static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = { ...@@ -978,10 +981,15 @@ static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = {
static const struct sunxi_mmc_cfg sun4i_a10_cfg = { static const struct sunxi_mmc_cfg sun4i_a10_cfg = {
.idma_des_size_bits = 13, .idma_des_size_bits = 13,
.clk_delays = sunxi_mmc_clk_delays, .clk_delays = NULL,
}; };
static const struct sunxi_mmc_cfg sun5i_a13_cfg = { static const struct sunxi_mmc_cfg sun5i_a13_cfg = {
.idma_des_size_bits = 16,
.clk_delays = NULL,
};
static const struct sunxi_mmc_cfg sun7i_a20_cfg = {
.idma_des_size_bits = 16, .idma_des_size_bits = 16,
.clk_delays = sunxi_mmc_clk_delays, .clk_delays = sunxi_mmc_clk_delays,
}; };
...@@ -994,6 +1002,7 @@ static const struct sunxi_mmc_cfg sun9i_a80_cfg = { ...@@ -994,6 +1002,7 @@ static const struct sunxi_mmc_cfg sun9i_a80_cfg = {
static const struct of_device_id sunxi_mmc_of_match[] = { static const struct of_device_id sunxi_mmc_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg }, { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
{ .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg }, { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
{ .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg },
{ .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg },
{ /* sentinel */ } { /* sentinel */ }
}; };
...@@ -1032,16 +1041,18 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, ...@@ -1032,16 +1041,18 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
return PTR_ERR(host->clk_mmc); return PTR_ERR(host->clk_mmc);
} }
host->clk_output = devm_clk_get(&pdev->dev, "output"); if (host->cfg->clk_delays) {
if (IS_ERR(host->clk_output)) { host->clk_output = devm_clk_get(&pdev->dev, "output");
dev_err(&pdev->dev, "Could not get output clock\n"); if (IS_ERR(host->clk_output)) {
return PTR_ERR(host->clk_output); dev_err(&pdev->dev, "Could not get output clock\n");
} return PTR_ERR(host->clk_output);
}
host->clk_sample = devm_clk_get(&pdev->dev, "sample"); host->clk_sample = devm_clk_get(&pdev->dev, "sample");
if (IS_ERR(host->clk_sample)) { if (IS_ERR(host->clk_sample)) {
dev_err(&pdev->dev, "Could not get sample clock\n"); dev_err(&pdev->dev, "Could not get sample clock\n");
return PTR_ERR(host->clk_sample); return PTR_ERR(host->clk_sample);
}
} }
host->reset = devm_reset_control_get_optional(&pdev->dev, "ahb"); host->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
...@@ -1144,9 +1155,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) ...@@ -1144,9 +1155,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
mmc->f_min = 400000; mmc->f_min = 400000;
mmc->f_max = 52000000; mmc->f_max = 52000000;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_1_8V_DDR |
MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
if (host->cfg->clk_delays)
mmc->caps |= MMC_CAP_1_8V_DDR;
ret = mmc_of_parse(mmc); ret = mmc_of_parse(mmc);
if (ret) if (ret)
goto error_free_dma; goto error_free_dma;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment