162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2018 Mellanox Technologies. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/bitfield.h> 762306a36Sopenharmony_ci#include <linux/bitops.h> 862306a36Sopenharmony_ci#include <linux/mmc/host.h> 962306a36Sopenharmony_ci#include <linux/mmc/mmc.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/of.h> 1262306a36Sopenharmony_ci#include <linux/platform_device.h> 1362306a36Sopenharmony_ci#include <linux/pm_runtime.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "dw_mmc.h" 1662306a36Sopenharmony_ci#include "dw_mmc-pltfm.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define UHS_REG_EXT_SAMPLE_MASK GENMASK(22, 16) 1962306a36Sopenharmony_ci#define UHS_REG_EXT_DRIVE_MASK GENMASK(29, 23) 2062306a36Sopenharmony_ci#define BLUEFIELD_UHS_REG_EXT_SAMPLE 2 2162306a36Sopenharmony_ci#define BLUEFIELD_UHS_REG_EXT_DRIVE 4 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic void dw_mci_bluefield_set_ios(struct dw_mci *host, struct mmc_ios *ios) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci u32 reg; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci /* Update the Drive and Sample fields in register UHS_REG_EXT. */ 2862306a36Sopenharmony_ci reg = mci_readl(host, UHS_REG_EXT); 2962306a36Sopenharmony_ci reg &= ~UHS_REG_EXT_SAMPLE_MASK; 3062306a36Sopenharmony_ci reg |= FIELD_PREP(UHS_REG_EXT_SAMPLE_MASK, 3162306a36Sopenharmony_ci BLUEFIELD_UHS_REG_EXT_SAMPLE); 3262306a36Sopenharmony_ci reg &= ~UHS_REG_EXT_DRIVE_MASK; 3362306a36Sopenharmony_ci reg |= FIELD_PREP(UHS_REG_EXT_DRIVE_MASK, BLUEFIELD_UHS_REG_EXT_DRIVE); 3462306a36Sopenharmony_ci mci_writel(host, UHS_REG_EXT, reg); 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic const struct dw_mci_drv_data bluefield_drv_data = { 3862306a36Sopenharmony_ci .set_ios = dw_mci_bluefield_set_ios 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic const struct of_device_id dw_mci_bluefield_match[] = { 4262306a36Sopenharmony_ci { .compatible = "mellanox,bluefield-dw-mshc", 4362306a36Sopenharmony_ci .data = &bluefield_drv_data }, 4462306a36Sopenharmony_ci {}, 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, dw_mci_bluefield_match); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic int dw_mci_bluefield_probe(struct platform_device *pdev) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci return dw_mci_pltfm_register(pdev, &bluefield_drv_data); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistatic struct platform_driver dw_mci_bluefield_pltfm_driver = { 5462306a36Sopenharmony_ci .probe = dw_mci_bluefield_probe, 5562306a36Sopenharmony_ci .remove_new = dw_mci_pltfm_remove, 5662306a36Sopenharmony_ci .driver = { 5762306a36Sopenharmony_ci .name = "dwmmc_bluefield", 5862306a36Sopenharmony_ci .probe_type = PROBE_PREFER_ASYNCHRONOUS, 5962306a36Sopenharmony_ci .of_match_table = dw_mci_bluefield_match, 6062306a36Sopenharmony_ci .pm = &dw_mci_pltfm_pmops, 6162306a36Sopenharmony_ci }, 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cimodule_platform_driver(dw_mci_bluefield_pltfm_driver); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciMODULE_DESCRIPTION("BlueField DW Multimedia Card driver"); 6762306a36Sopenharmony_ciMODULE_AUTHOR("Mellanox Technologies"); 6862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 69