1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Universal Flash Storage Host controller Platform bus based glue driver 4 * Copyright (C) 2011-2013 Samsung India Software Operations 5 * 6 * Authors: 7 * Santosh Yaraganavi <santosh.sy@samsung.com> 8 * Vinayak Holikatti <h.vinayak@samsung.com> 9 */ 10 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <linux/pm_runtime.h> 14 #include <linux/of.h> 15 16 #include <ufs/ufshcd.h> 17 #include "ufshcd-pltfrm.h" 18 #include <ufs/unipro.h> 19 20 #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 21 22 static int ufshcd_parse_clock_info(struct ufs_hba *hba) 23 { 24 int ret = 0; 25 int cnt; 26 int i; 27 struct device *dev = hba->dev; 28 struct device_node *np = dev->of_node; 29 char *name; 30 u32 *clkfreq = NULL; 31 struct ufs_clk_info *clki; 32 int len = 0; 33 size_t sz = 0; 34 35 if (!np) 36 goto out; 37 38 cnt = of_property_count_strings(np, "clock-names"); 39 if (!cnt || (cnt == -EINVAL)) { 40 dev_info(dev, "%s: Unable to find clocks, assuming enabled\n", 41 __func__); 42 } else if (cnt < 0) { 43 dev_err(dev, "%s: count clock strings failed, err %d\n", 44 __func__, cnt); 45 ret = cnt; 46 } 47 48 if (cnt <= 0) 49 goto out; 50 51 if (!of_get_property(np, "freq-table-hz", &len)) { 52 dev_info(dev, "freq-table-hz property not specified\n"); 53 goto out; 54 } 55 56 if (len <= 0) 57 goto out; 58 59 sz = len / sizeof(*clkfreq); 60 if (sz != 2 * cnt) { 61 dev_err(dev, "%s len mismatch\n", "freq-table-hz"); 62 ret = -EINVAL; 63 goto out; 64 } 65 66 clkfreq = devm_kcalloc(dev, sz, sizeof(*clkfreq), 67 GFP_KERNEL); 68 if (!clkfreq) { 69 ret = -ENOMEM; 70 goto out; 71 } 72 73 ret = of_property_read_u32_array(np, "freq-table-hz", 74 clkfreq, sz); 75 if (ret && (ret != -EINVAL)) { 76 dev_err(dev, "%s: error reading array %d\n", 77 "freq-table-hz", ret); 78 return ret; 79 } 80 81 for (i = 0; i < sz; i += 2) { 82 ret = of_property_read_string_index(np, 83 "clock-names", i/2, (const char **)&name); 84 if (ret) 85 goto out; 86 87 clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); 88 if (!clki) { 89 ret = -ENOMEM; 90 goto out; 91 } 92 93 clki->min_freq = clkfreq[i]; 94 clki->max_freq = clkfreq[i+1]; 95 clki->name = devm_kstrdup(dev, name, GFP_KERNEL); 96 if (!clki->name) { 97 ret = -ENOMEM; 98 goto out; 99 } 100 101 if (!strcmp(name, "ref_clk")) 102 clki->keep_link_active = true; 103 dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz", 104 clki->min_freq, clki->max_freq, clki->name); 105 list_add_tail(&clki->list, &hba->clk_list_head); 106 } 107 out: 108 return ret; 109 } 110 111 static bool phandle_exists(const struct device_node *np, 112 const char *phandle_name, int index) 113 { 114 struct device_node *parse_np = of_parse_phandle(np, phandle_name, index); 115 116 if (parse_np) 117 of_node_put(parse_np); 118 119 return parse_np != NULL; 120 } 121 122 #define MAX_PROP_SIZE 32 123 static int ufshcd_populate_vreg(struct device *dev, const char *name, 124 struct ufs_vreg **out_vreg) 125 { 126 char prop_name[MAX_PROP_SIZE]; 127 struct ufs_vreg *vreg = NULL; 128 struct device_node *np = dev->of_node; 129 130 if (!np) { 131 dev_err(dev, "%s: non DT initialization\n", __func__); 132 goto out; 133 } 134 135 snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name); 136 if (!phandle_exists(np, prop_name, 0)) { 137 dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n", 138 __func__, prop_name); 139 goto out; 140 } 141 142 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); 143 if (!vreg) 144 return -ENOMEM; 145 146 vreg->name = devm_kstrdup(dev, name, GFP_KERNEL); 147 if (!vreg->name) 148 return -ENOMEM; 149 150 snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); 151 if (of_property_read_u32(np, prop_name, &vreg->max_uA)) { 152 dev_info(dev, "%s: unable to find %s\n", __func__, prop_name); 153 vreg->max_uA = 0; 154 } 155 out: 156 *out_vreg = vreg; 157 return 0; 158 } 159 160 /** 161 * ufshcd_parse_regulator_info - get regulator info from device tree 162 * @hba: per adapter instance 163 * 164 * Get regulator info from device tree for vcc, vccq, vccq2 power supplies. 165 * If any of the supplies are not defined it is assumed that they are always-on 166 * and hence return zero. If the property is defined but parsing is failed 167 * then return corresponding error. 168 */ 169 static int ufshcd_parse_regulator_info(struct ufs_hba *hba) 170 { 171 int err; 172 struct device *dev = hba->dev; 173 struct ufs_vreg_info *info = &hba->vreg_info; 174 175 err = ufshcd_populate_vreg(dev, "vdd-hba", &info->vdd_hba); 176 if (err) 177 goto out; 178 179 err = ufshcd_populate_vreg(dev, "vcc", &info->vcc); 180 if (err) 181 goto out; 182 183 err = ufshcd_populate_vreg(dev, "vccq", &info->vccq); 184 if (err) 185 goto out; 186 187 err = ufshcd_populate_vreg(dev, "vccq2", &info->vccq2); 188 out: 189 return err; 190 } 191 192 void ufshcd_pltfrm_shutdown(struct platform_device *pdev) 193 { 194 ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); 195 } 196 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); 197 198 static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba) 199 { 200 struct device *dev = hba->dev; 201 int ret; 202 203 ret = of_property_read_u32(dev->of_node, "lanes-per-direction", 204 &hba->lanes_per_direction); 205 if (ret) { 206 dev_dbg(hba->dev, 207 "%s: failed to read lanes-per-direction, ret=%d\n", 208 __func__, ret); 209 hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION; 210 } 211 } 212 213 /** 214 * ufshcd_get_pwr_dev_param - get finally agreed attributes for 215 * power mode change 216 * @pltfrm_param: pointer to platform parameters 217 * @dev_max: pointer to device attributes 218 * @agreed_pwr: returned agreed attributes 219 * 220 * Returns 0 on success, non-zero value on failure 221 */ 222 int ufshcd_get_pwr_dev_param(struct ufs_dev_params *pltfrm_param, 223 struct ufs_pa_layer_attr *dev_max, 224 struct ufs_pa_layer_attr *agreed_pwr) 225 { 226 int min_pltfrm_gear; 227 int min_dev_gear; 228 bool is_dev_sup_hs = false; 229 bool is_pltfrm_max_hs = false; 230 231 if (dev_max->pwr_rx == FAST_MODE) 232 is_dev_sup_hs = true; 233 234 if (pltfrm_param->desired_working_mode == UFS_HS_MODE) { 235 is_pltfrm_max_hs = true; 236 min_pltfrm_gear = min_t(u32, pltfrm_param->hs_rx_gear, 237 pltfrm_param->hs_tx_gear); 238 } else { 239 min_pltfrm_gear = min_t(u32, pltfrm_param->pwm_rx_gear, 240 pltfrm_param->pwm_tx_gear); 241 } 242 243 /* 244 * device doesn't support HS but 245 * pltfrm_param->desired_working_mode is HS, 246 * thus device and pltfrm_param don't agree 247 */ 248 if (!is_dev_sup_hs && is_pltfrm_max_hs) { 249 pr_info("%s: device doesn't support HS\n", 250 __func__); 251 return -ENOTSUPP; 252 } else if (is_dev_sup_hs && is_pltfrm_max_hs) { 253 /* 254 * since device supports HS, it supports FAST_MODE. 255 * since pltfrm_param->desired_working_mode is also HS 256 * then final decision (FAST/FASTAUTO) is done according 257 * to pltfrm_params as it is the restricting factor 258 */ 259 agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_hs; 260 agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; 261 } else { 262 /* 263 * here pltfrm_param->desired_working_mode is PWM. 264 * it doesn't matter whether device supports HS or PWM, 265 * in both cases pltfrm_param->desired_working_mode will 266 * determine the mode 267 */ 268 agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_pwm; 269 agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; 270 } 271 272 /* 273 * we would like tx to work in the minimum number of lanes 274 * between device capability and vendor preferences. 275 * the same decision will be made for rx 276 */ 277 agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx, 278 pltfrm_param->tx_lanes); 279 agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx, 280 pltfrm_param->rx_lanes); 281 282 /* device maximum gear is the minimum between device rx and tx gears */ 283 min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); 284 285 /* 286 * if both device capabilities and vendor pre-defined preferences are 287 * both HS or both PWM then set the minimum gear to be the chosen 288 * working gear. 289 * if one is PWM and one is HS then the one that is PWM get to decide 290 * what is the gear, as it is the one that also decided previously what 291 * pwr the device will be configured to. 292 */ 293 if ((is_dev_sup_hs && is_pltfrm_max_hs) || 294 (!is_dev_sup_hs && !is_pltfrm_max_hs)) { 295 agreed_pwr->gear_rx = 296 min_t(u32, min_dev_gear, min_pltfrm_gear); 297 } else if (!is_dev_sup_hs) { 298 agreed_pwr->gear_rx = min_dev_gear; 299 } else { 300 agreed_pwr->gear_rx = min_pltfrm_gear; 301 } 302 agreed_pwr->gear_tx = agreed_pwr->gear_rx; 303 304 agreed_pwr->hs_rate = pltfrm_param->hs_rate; 305 306 return 0; 307 } 308 EXPORT_SYMBOL_GPL(ufshcd_get_pwr_dev_param); 309 310 void ufshcd_init_pwr_dev_param(struct ufs_dev_params *dev_param) 311 { 312 *dev_param = (struct ufs_dev_params){ 313 .tx_lanes = 2, 314 .rx_lanes = 2, 315 .hs_rx_gear = UFS_HS_G3, 316 .hs_tx_gear = UFS_HS_G3, 317 .pwm_rx_gear = UFS_PWM_G4, 318 .pwm_tx_gear = UFS_PWM_G4, 319 .rx_pwr_pwm = SLOW_MODE, 320 .tx_pwr_pwm = SLOW_MODE, 321 .rx_pwr_hs = FAST_MODE, 322 .tx_pwr_hs = FAST_MODE, 323 .hs_rate = PA_HS_MODE_B, 324 .desired_working_mode = UFS_HS_MODE, 325 }; 326 } 327 EXPORT_SYMBOL_GPL(ufshcd_init_pwr_dev_param); 328 329 /** 330 * ufshcd_pltfrm_init - probe routine of the driver 331 * @pdev: pointer to Platform device handle 332 * @vops: pointer to variant ops 333 * 334 * Returns 0 on success, non-zero value on failure 335 */ 336 int ufshcd_pltfrm_init(struct platform_device *pdev, 337 const struct ufs_hba_variant_ops *vops) 338 { 339 struct ufs_hba *hba; 340 void __iomem *mmio_base; 341 int irq, err; 342 struct device *dev = &pdev->dev; 343 344 mmio_base = devm_platform_ioremap_resource(pdev, 0); 345 if (IS_ERR(mmio_base)) { 346 err = PTR_ERR(mmio_base); 347 goto out; 348 } 349 350 irq = platform_get_irq(pdev, 0); 351 if (irq < 0) { 352 err = irq; 353 goto out; 354 } 355 356 err = ufshcd_alloc_host(dev, &hba); 357 if (err) { 358 dev_err(dev, "Allocation failed\n"); 359 goto out; 360 } 361 362 hba->vops = vops; 363 364 err = ufshcd_parse_clock_info(hba); 365 if (err) { 366 dev_err(dev, "%s: clock parse failed %d\n", 367 __func__, err); 368 goto dealloc_host; 369 } 370 err = ufshcd_parse_regulator_info(hba); 371 if (err) { 372 dev_err(dev, "%s: regulator init failed %d\n", 373 __func__, err); 374 goto dealloc_host; 375 } 376 377 ufshcd_init_lanes_per_dir(hba); 378 379 err = ufshcd_init(hba, mmio_base, irq); 380 if (err) { 381 dev_err(dev, "Initialization failed\n"); 382 goto dealloc_host; 383 } 384 385 pm_runtime_set_active(dev); 386 pm_runtime_enable(dev); 387 388 return 0; 389 390 dealloc_host: 391 ufshcd_dealloc_host(hba); 392 out: 393 return err; 394 } 395 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init); 396 397 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>"); 398 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>"); 399 MODULE_DESCRIPTION("UFS host controller Platform bus based glue driver"); 400 MODULE_LICENSE("GPL"); 401