1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * ZX Specific Extensions for Synopsys DW Multimedia Card Interface driver 4 * 5 * Copyright (C) 2016, Linaro Ltd. 6 * Copyright (C) 2016, ZTE Corp. 7 */ 8 9#include <linux/clk.h> 10#include <linux/mfd/syscon.h> 11#include <linux/mmc/host.h> 12#include <linux/mmc/mmc.h> 13#include <linux/module.h> 14#include <linux/of.h> 15#include <linux/platform_device.h> 16#include <linux/pm_runtime.h> 17#include <linux/regmap.h> 18#include <linux/slab.h> 19 20#include "dw_mmc.h" 21#include "dw_mmc-pltfm.h" 22#include "dw_mmc-zx.h" 23 24struct dw_mci_zx_priv_data { 25 struct regmap *sysc_base; 26}; 27 28enum delay_type { 29 DELAY_TYPE_READ, /* read dqs delay */ 30 DELAY_TYPE_CLK, /* clk sample delay */ 31}; 32 33static int dw_mci_zx_emmc_set_delay(struct dw_mci *host, unsigned int delay, 34 enum delay_type dflag) 35{ 36 struct dw_mci_zx_priv_data *priv = host->priv; 37 struct regmap *sysc_base = priv->sysc_base; 38 unsigned int clksel; 39 unsigned int loop = 1000; 40 int ret; 41 42 if (!sysc_base) 43 return -EINVAL; 44 45 ret = regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, 46 PARA_HALF_CLK_MODE | PARA_DLL_BYPASS_MODE | 47 PARA_PHASE_DET_SEL_MASK | 48 PARA_DLL_LOCK_NUM_MASK | 49 DLL_REG_SET | PARA_DLL_START_MASK, 50 PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4)); 51 if (ret) 52 return ret; 53 54 ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG1, &clksel); 55 if (ret) 56 return ret; 57 58 if (dflag == DELAY_TYPE_CLK) { 59 clksel &= ~CLK_SAMP_DELAY_MASK; 60 clksel |= CLK_SAMP_DELAY(delay); 61 } else { 62 clksel &= ~READ_DQS_DELAY_MASK; 63 clksel |= READ_DQS_DELAY(delay); 64 } 65 66 regmap_write(sysc_base, LB_AON_EMMC_CFG_REG1, clksel); 67 regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, 68 PARA_DLL_START_MASK | PARA_DLL_LOCK_NUM_MASK | 69 DLL_REG_SET, 70 PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4) | 71 DLL_REG_SET); 72 73 do { 74 ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG2, &clksel); 75 if (ret) 76 return ret; 77 78 } while (--loop && !(clksel & ZX_DLL_LOCKED)); 79 80 if (!loop) { 81 dev_err(host->dev, "Error: %s dll lock fail\n", __func__); 82 return -EIO; 83 } 84 85 return 0; 86} 87 88static int dw_mci_zx_emmc_execute_tuning(struct dw_mci_slot *slot, u32 opcode) 89{ 90 struct dw_mci *host = slot->host; 91 struct mmc_host *mmc = slot->mmc; 92 int ret, len = 0, start = 0, end = 0, delay, best = 0; 93 94 for (delay = 1; delay < 128; delay++) { 95 ret = dw_mci_zx_emmc_set_delay(host, delay, DELAY_TYPE_CLK); 96 if (!ret && mmc_send_tuning(mmc, opcode, NULL)) { 97 if (start >= 0) { 98 end = delay - 1; 99 /* check and update longest good range */ 100 if ((end - start) > len) { 101 best = (start + end) >> 1; 102 len = end - start; 103 } 104 } 105 start = -1; 106 end = 0; 107 continue; 108 } 109 if (start < 0) 110 start = delay; 111 } 112 113 if (start >= 0) { 114 end = delay - 1; 115 if ((end - start) > len) { 116 best = (start + end) >> 1; 117 len = end - start; 118 } 119 } 120 if (best < 0) 121 return -EIO; 122 123 dev_info(host->dev, "%s best range: start %d end %d\n", __func__, 124 start, end); 125 return dw_mci_zx_emmc_set_delay(host, best, DELAY_TYPE_CLK); 126} 127 128static int dw_mci_zx_prepare_hs400_tuning(struct dw_mci *host, 129 struct mmc_ios *ios) 130{ 131 int ret; 132 133 /* config phase shift as 90 degree */ 134 ret = dw_mci_zx_emmc_set_delay(host, 32, DELAY_TYPE_READ); 135 if (ret < 0) 136 return -EIO; 137 138 return 0; 139} 140 141static int dw_mci_zx_execute_tuning(struct dw_mci_slot *slot, u32 opcode) 142{ 143 struct dw_mci *host = slot->host; 144 145 if (host->verid == 0x290a) /* only for emmc */ 146 return dw_mci_zx_emmc_execute_tuning(slot, opcode); 147 /* TODO: Add 0x210a dedicated tuning for sd/sdio */ 148 149 return 0; 150} 151 152static int dw_mci_zx_parse_dt(struct dw_mci *host) 153{ 154 struct device_node *np = host->dev->of_node; 155 struct device_node *node; 156 struct dw_mci_zx_priv_data *priv; 157 struct regmap *sysc_base; 158 159 /* syscon is needed only by emmc */ 160 node = of_parse_phandle(np, "zte,aon-syscon", 0); 161 if (node) { 162 sysc_base = syscon_node_to_regmap(node); 163 of_node_put(node); 164 165 if (IS_ERR(sysc_base)) 166 return dev_err_probe(host->dev, PTR_ERR(sysc_base), 167 "Can't get syscon\n"); 168 } else { 169 return 0; 170 } 171 172 priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); 173 if (!priv) 174 return -ENOMEM; 175 priv->sysc_base = sysc_base; 176 host->priv = priv; 177 178 return 0; 179} 180 181static unsigned long zx_dwmmc_caps[3] = { 182 MMC_CAP_CMD23, 183 MMC_CAP_CMD23, 184 MMC_CAP_CMD23, 185}; 186 187static const struct dw_mci_drv_data zx_drv_data = { 188 .caps = zx_dwmmc_caps, 189 .num_caps = ARRAY_SIZE(zx_dwmmc_caps), 190 .execute_tuning = dw_mci_zx_execute_tuning, 191 .prepare_hs400_tuning = dw_mci_zx_prepare_hs400_tuning, 192 .parse_dt = dw_mci_zx_parse_dt, 193}; 194 195static const struct of_device_id dw_mci_zx_match[] = { 196 { .compatible = "zte,zx296718-dw-mshc", .data = &zx_drv_data}, 197 {}, 198}; 199MODULE_DEVICE_TABLE(of, dw_mci_zx_match); 200 201static int dw_mci_zx_probe(struct platform_device *pdev) 202{ 203 const struct dw_mci_drv_data *drv_data; 204 const struct of_device_id *match; 205 206 match = of_match_node(dw_mci_zx_match, pdev->dev.of_node); 207 drv_data = match->data; 208 209 return dw_mci_pltfm_register(pdev, drv_data); 210} 211 212static const struct dev_pm_ops dw_mci_zx_dev_pm_ops = { 213 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 214 pm_runtime_force_resume) 215 SET_RUNTIME_PM_OPS(dw_mci_runtime_suspend, 216 dw_mci_runtime_resume, 217 NULL) 218}; 219 220static struct platform_driver dw_mci_zx_pltfm_driver = { 221 .probe = dw_mci_zx_probe, 222 .remove = dw_mci_pltfm_remove, 223 .driver = { 224 .name = "dwmmc_zx", 225 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 226 .of_match_table = dw_mci_zx_match, 227 .pm = &dw_mci_zx_dev_pm_ops, 228 }, 229}; 230 231module_platform_driver(dw_mci_zx_pltfm_driver); 232 233MODULE_DESCRIPTION("ZTE emmc/sd driver"); 234MODULE_LICENSE("GPL v2"); 235