186958dccSLiming Sun // SPDX-License-Identifier: GPL-2.0 286958dccSLiming Sun /* 386958dccSLiming Sun * Copyright (C) 2018 Mellanox Technologies. 486958dccSLiming Sun */ 586958dccSLiming Sun 686958dccSLiming Sun #include <linux/bitfield.h> 786958dccSLiming Sun #include <linux/bitops.h> 886958dccSLiming Sun #include <linux/mmc/host.h> 986958dccSLiming Sun #include <linux/mmc/mmc.h> 1086958dccSLiming Sun #include <linux/module.h> 1186958dccSLiming Sun #include <linux/of.h> 1286958dccSLiming Sun #include <linux/platform_device.h> 1386958dccSLiming Sun #include <linux/pm_runtime.h> 1486958dccSLiming Sun 1586958dccSLiming Sun #include "dw_mmc.h" 1686958dccSLiming Sun #include "dw_mmc-pltfm.h" 1786958dccSLiming Sun 1886958dccSLiming Sun #define UHS_REG_EXT_SAMPLE_MASK GENMASK(22, 16) 1986958dccSLiming Sun #define UHS_REG_EXT_DRIVE_MASK GENMASK(29, 23) 2086958dccSLiming Sun #define BLUEFIELD_UHS_REG_EXT_SAMPLE 2 2186958dccSLiming Sun #define BLUEFIELD_UHS_REG_EXT_DRIVE 4 2286958dccSLiming Sun 2386958dccSLiming Sun static void dw_mci_bluefield_set_ios(struct dw_mci *host, struct mmc_ios *ios) 2486958dccSLiming Sun { 2586958dccSLiming Sun u32 reg; 2686958dccSLiming Sun 2786958dccSLiming Sun /* Update the Drive and Sample fields in register UHS_REG_EXT. */ 2886958dccSLiming Sun reg = mci_readl(host, UHS_REG_EXT); 2986958dccSLiming Sun reg &= ~UHS_REG_EXT_SAMPLE_MASK; 3086958dccSLiming Sun reg |= FIELD_PREP(UHS_REG_EXT_SAMPLE_MASK, 3186958dccSLiming Sun BLUEFIELD_UHS_REG_EXT_SAMPLE); 3286958dccSLiming Sun reg &= ~UHS_REG_EXT_DRIVE_MASK; 3386958dccSLiming Sun reg |= FIELD_PREP(UHS_REG_EXT_DRIVE_MASK, BLUEFIELD_UHS_REG_EXT_DRIVE); 3486958dccSLiming Sun mci_writel(host, UHS_REG_EXT, reg); 3586958dccSLiming Sun } 3686958dccSLiming Sun 3786958dccSLiming Sun static const struct dw_mci_drv_data bluefield_drv_data = { 3886958dccSLiming Sun .set_ios = dw_mci_bluefield_set_ios 3986958dccSLiming Sun }; 4086958dccSLiming Sun 4186958dccSLiming Sun static const struct of_device_id dw_mci_bluefield_match[] = { 4286958dccSLiming Sun { .compatible = "mellanox,bluefield-dw-mshc", 4386958dccSLiming Sun .data = &bluefield_drv_data }, 4486958dccSLiming Sun {}, 4586958dccSLiming Sun }; 4686958dccSLiming Sun MODULE_DEVICE_TABLE(of, dw_mci_bluefield_match); 4786958dccSLiming Sun 4886958dccSLiming Sun static int dw_mci_bluefield_probe(struct platform_device *pdev) 4986958dccSLiming Sun { 503df407b2SLiming Sun return dw_mci_pltfm_register(pdev, &bluefield_drv_data); 5186958dccSLiming Sun } 5286958dccSLiming Sun 5386958dccSLiming Sun static struct platform_driver dw_mci_bluefield_pltfm_driver = { 5486958dccSLiming Sun .probe = dw_mci_bluefield_probe, 5586958dccSLiming Sun .remove = dw_mci_pltfm_remove, 5686958dccSLiming Sun .driver = { 5786958dccSLiming Sun .name = "dwmmc_bluefield", 58*a1a48919SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS, 5986958dccSLiming Sun .of_match_table = dw_mci_bluefield_match, 6086958dccSLiming Sun .pm = &dw_mci_pltfm_pmops, 6186958dccSLiming Sun }, 6286958dccSLiming Sun }; 6386958dccSLiming Sun 6486958dccSLiming Sun module_platform_driver(dw_mci_bluefield_pltfm_driver); 6586958dccSLiming Sun 6686958dccSLiming Sun MODULE_DESCRIPTION("BlueField DW Multimedia Card driver"); 6786958dccSLiming Sun MODULE_AUTHOR("Mellanox Technologies"); 6886958dccSLiming Sun MODULE_LICENSE("GPL v2"); 69