// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2015 Linaro * peter.griffin */ #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; struct hi6220_dwmmc_plat { struct mmc_config cfg; struct mmc mmc; }; struct hi6220_dwmmc_priv_data { struct dwmci_host host; }; struct hisi_mmc_data { unsigned int clock; bool use_fifo; }; static int hi6220_dwmmc_of_to_plat(struct udevice *dev) { struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; host->name = dev->name; host->ioaddr = dev_read_addr_ptr(dev); host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", 4); /* use non-removable property for differentiating SD card and eMMC */ if (dev_read_bool(dev, "non-removable")) host->dev_index = 0; else host->dev_index = 1; host->priv = priv; return 0; } static int hi6220_dwmmc_probe(struct udevice *dev) { struct hi6220_dwmmc_plat *plat = dev_get_plat(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; struct hisi_mmc_data *mmc_data; mmc_data = (struct hisi_mmc_data *)dev_get_driver_data(dev); /* Use default bus speed due to absence of clk driver */ host->bus_hz = mmc_data->clock; dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000); host->mmc = &plat->mmc; host->fifo_mode = mmc_data->use_fifo; host->mmc->priv = &priv->host; upriv->mmc = host->mmc; host->mmc->dev = dev; return dwmci_probe(dev); } static int hi6220_dwmmc_bind(struct udevice *dev) { struct hi6220_dwmmc_plat *plat = dev_get_plat(dev); int ret; ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); if (ret) return ret; return 0; } static const struct hisi_mmc_data hi3660_mmc_data = { .clock = 3200000, .use_fifo = true, }; static const struct hisi_mmc_data hi6220_mmc_data = { .clock = 50000000, .use_fifo = false, }; static const struct udevice_id hi6220_dwmmc_ids[] = { { .compatible = "hisilicon,hi6220-dw-mshc", .data = (ulong)&hi6220_mmc_data }, { .compatible = "hisilicon,hi3798cv200-dw-mshc", .data = (ulong)&hi6220_mmc_data }, { .compatible = "hisilicon,hi3798mv200-dw-mshc", .data = (ulong)&hi6220_mmc_data }, { .compatible = "hisilicon,hi3660-dw-mshc", .data = (ulong)&hi3660_mmc_data }, { } }; U_BOOT_DRIVER(hi6220_dwmmc_drv) = { .name = "hi6220_dwmmc", .id = UCLASS_MMC, .of_match = hi6220_dwmmc_ids, .of_to_plat = hi6220_dwmmc_of_to_plat, .ops = &dm_dwmci_ops, .bind = hi6220_dwmmc_bind, .probe = hi6220_dwmmc_probe, .priv_auto = sizeof(struct hi6220_dwmmc_priv_data), .plat_auto = sizeof(struct hi6220_dwmmc_plat), };