X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmmc%2Frockchip_dw_mmc.c;h=cb9e1048d0351041e54817e0dc4ab4130ada53ac;hb=d9a3bec682f9756621615f4306718a356a3230e3;hp=f11c8e003958fbbf1fe4805f10388fec7e98b004;hpb=c9feb427aba860ebc79f9851a1bb49cc456a2d48;p=u-boot diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index f11c8e0039..cb9e1048d0 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -18,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; struct rockchip_dwmmc_priv { struct udevice *clk; - struct rk3288_grf *grf; + int periph; struct dwmci_host host; }; @@ -28,8 +30,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq) struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); int ret; - ret = clk_set_periph_rate(priv->clk, PERIPH_ID_SDMMC0 + host->dev_index, - freq); + ret = clk_set_periph_rate(priv->clk, priv->periph, freq); if (ret < 0) { debug("%s: err=%d\n", __func__, ret); return ret; @@ -50,8 +51,11 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev) host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk; host->priv = dev; - /* TODO(sjg@chromium.org): Remove the need for this hack */ - host->dev_index = (ulong)host->ioaddr == 0xff0f0000 ? 0 : 1; + /* use non-removeable as sdcard and emmc as judgement */ + if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "non-removable")) + host->dev_index = 0; + else + host->dev_index = 1; return 0; } @@ -61,20 +65,42 @@ static int rockchip_dwmmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; + struct udevice *pwr_dev __maybe_unused; u32 minmax[2]; int ret; + int fifo_depth; - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - if (IS_ERR(priv->grf)) - return PTR_ERR(priv->grf); - ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk); - if (ret) + ret = clk_get_by_index(dev, 0, &priv->clk); + if (ret < 0) return ret; - - ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, - "clock-freq-min-max", minmax, 2); - if (!ret) - ret = add_dwmci(host, minmax[1], minmax[0]); + priv->periph = ret; + + if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, + "clock-freq-min-max", minmax, 2)) + return -EINVAL; + + fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "fifo-depth", 0); + if (fifo_depth < 0) + return -EINVAL; + + host->fifoth_val = MSIZE(0x2) | + RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2); + + if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "fifo-mode")) + host->fifo_mode = true; + +#ifdef CONFIG_PWRSEQ + /* Enable power if needed */ + ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq", + &pwr_dev); + if (!ret) { + ret = pwrseq_set_power(pwr_dev, true); + if (ret) + return ret; + } +#endif + ret = add_dwmci(host, minmax[1], minmax[0]); if (ret) return ret; @@ -96,3 +122,37 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = { .probe = rockchip_dwmmc_probe, .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv), }; + +#ifdef CONFIG_PWRSEQ +static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable) +{ + struct gpio_desc reset; + int ret; + + ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); + if (ret) + return ret; + dm_gpio_set_value(&reset, 1); + udelay(1); + dm_gpio_set_value(&reset, 0); + udelay(200); + + return 0; +} + +static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = { + .set_power = rockchip_dwmmc_pwrseq_set_power, +}; + +static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = { + { .compatible = "mmc-pwrseq-emmc" }, + { } +}; + +U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = { + .name = "mmc_pwrseq_emmc", + .id = UCLASS_PWRSEQ, + .of_match = rockchip_dwmmc_pwrseq_ids, + .ops = &rockchip_dwmmc_pwrseq_ops, +}; +#endif