X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fmmc%2Fsocfpga_dw_mmc.c;h=739c1629a2711f2aa6b30f0cf5142a9fba994988;hb=f541796af929fa28a78dc3162a0ba09d4fa3ce90;hp=0a22e582957fc24e00f05c56e956aa1fabfce479;hpb=4f892924d238cc415891dbea336a0fdaff2f853b;p=oweals%2Fu-boot.git diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 0a22e58295..739c1629a2 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -1,19 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include +#include #include #include #include #include -#include +#include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -34,6 +35,20 @@ struct dwmci_socfpga_priv_data { unsigned int smplsel; }; +static void socfpga_dwmci_reset(struct udevice *dev) +{ + struct reset_ctl_bulk reset_bulk; + int ret; + + ret = reset_get_bulk(dev, &reset_bulk); + if (ret) { + dev_warn(dev, "Can't get reset: %d\n", ret); + return; + } + + reset_deassert_bulk(&reset_bulk); +} + static void socfpga_dwmci_clksel(struct dwmci_host *host) { struct dwmci_socfpga_priv_data *priv = host->priv; @@ -56,21 +71,40 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host) CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); } -static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) +static int socfpga_dwmmc_get_clk_rate(struct udevice *dev) { - /* FIXME: probe from DT eventually too/ */ - const unsigned long clk = cm_get_mmc_controller_clk_hz(); - struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; - int fifo_depth; +#if CONFIG_IS_ENABLED(CLK) + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, 1, &clk); + if (ret) + return ret; - if (clk == 0) { + host->bus_hz = clk_get_rate(&clk); + + clk_free(&clk); +#else + /* Fixed clock divide by 4 which due to the SDMMC wrapper */ + host->bus_hz = cm_get_mmc_controller_clk_hz(); +#endif + if (host->bus_hz == 0) { printf("DWMMC: MMC clock is zero!"); return -EINVAL; } - fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + return 0; +} + +static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) +{ + struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev); + struct dwmci_host *host = &priv->host; + int fifo_depth; + + fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "fifo-depth", 0); if (fifo_depth < 0) { printf("DWMMC: Can't get FIFO depth\n"); @@ -78,8 +112,8 @@ static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) } host->name = dev->name; - host->ioaddr = (void *)dev_get_addr(dev); - host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + host->ioaddr = (void *)devfdt_get_addr(dev); + host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", 4); host->clksel = socfpga_dwmci_clksel; @@ -88,13 +122,11 @@ static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) * We only have one dwmmc block on gen5 SoCFPGA. */ host->dev_index = 0; - /* Fixed clock divide by 4 which due to the SDMMC wrapper */ - host->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2); - priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, + priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "drvsel", 3); - priv->smplsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, + priv->smplsel = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "smplsel", 0); host->priv = priv; @@ -109,12 +141,18 @@ static int socfpga_dwmmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; + int ret; + + ret = socfpga_dwmmc_get_clk_rate(dev); + if (ret) + return ret; + + socfpga_dwmci_reset(dev); #ifdef CONFIG_BLK dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000); host->mmc = &plat->mmc; #else - int ret; ret = add_dwmci(host, host->bus_hz, 400000); if (ret) @@ -124,7 +162,7 @@ static int socfpga_dwmmc_probe(struct udevice *dev) upriv->mmc = host->mmc; host->mmc->dev = dev; - return 0; + return dwmci_probe(dev); } static int socfpga_dwmmc_bind(struct udevice *dev)