hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/phy/rockchip/phy-rockchip-emmc.c
....@@ -1,17 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Rockchip emmc PHY driver
34 *
45 * Copyright (C) 2016 Shawn Lin <shawn.lin@rock-chips.com>
56 * Copyright (C) 2016 ROCKCHIP, Inc.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
179 #include <linux/clk.h>
....@@ -87,6 +79,7 @@
8779 unsigned int reg_offset;
8880 struct regmap *reg_base;
8981 struct clk *emmcclk;
82
+ unsigned int drive_impedance;
9083 };
9184
9285 static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
....@@ -176,7 +169,7 @@
176169 ret = regmap_read_poll_timeout(rk_phy->reg_base,
177170 rk_phy->reg_offset + GRF_EMMCPHY_STATUS,
178171 caldone, PHYCTRL_IS_CALDONE(caldone),
179
- 0, 500);
172
+ 0, 50);
180173 if (ret) {
181174 pr_err("%s: caldone failed, ret=%d\n", __func__, ret);
182175 return ret;
....@@ -247,15 +240,17 @@
247240 * - SDHCI driver to get the PHY
248241 * - SDHCI driver to init the PHY
249242 *
250
- * The clock is optional, so upon any error we just set to NULL.
243
+ * The clock is optional, using clk_get_optional() to get the clock
244
+ * and do error processing if the return value != NULL
251245 *
252246 * NOTE: we don't do anything special for EPROBE_DEFER here. Given the
253247 * above expected use case, EPROBE_DEFER isn't sensible to expect, so
254248 * it's just like any other error.
255249 */
256
- rk_phy->emmcclk = clk_get(&phy->dev, "emmcclk");
250
+ rk_phy->emmcclk = clk_get_optional(&phy->dev, "emmcclk");
257251 if (IS_ERR(rk_phy->emmcclk)) {
258
- dev_dbg(&phy->dev, "Error getting emmcclk: %d\n", ret);
252
+ ret = PTR_ERR(rk_phy->emmcclk);
253
+ dev_err(&phy->dev, "Error getting emmcclk: %d\n", ret);
259254 rk_phy->emmcclk = NULL;
260255 }
261256
....@@ -281,10 +276,10 @@
281276 {
282277 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
283278
284
- /* Drive impedance: 50 Ohm */
279
+ /* Drive impedance: from DTS */
285280 regmap_write(rk_phy->reg_base,
286281 rk_phy->reg_offset + GRF_EMMCPHY_CON6,
287
- HIWORD_UPDATE(PHYCTRL_DR_50OHM,
282
+ HIWORD_UPDATE(rk_phy->drive_impedance,
288283 PHYCTRL_DR_MASK,
289284 PHYCTRL_DR_SHIFT));
290285
....@@ -314,6 +309,26 @@
314309 .owner = THIS_MODULE,
315310 };
316311
312
+static u32 convert_drive_impedance_ohm(struct platform_device *pdev, u32 dr_ohm)
313
+{
314
+ switch (dr_ohm) {
315
+ case 100:
316
+ return PHYCTRL_DR_100OHM;
317
+ case 66:
318
+ return PHYCTRL_DR_66OHM;
319
+ case 50:
320
+ return PHYCTRL_DR_50OHM;
321
+ case 40:
322
+ return PHYCTRL_DR_40OHM;
323
+ case 33:
324
+ return PHYCTRL_DR_33OHM;
325
+ }
326
+
327
+ dev_warn(&pdev->dev, "Invalid value %u for drive-impedance-ohm.\n",
328
+ dr_ohm);
329
+ return PHYCTRL_DR_50OHM;
330
+}
331
+
317332 static int rockchip_emmc_phy_probe(struct platform_device *pdev)
318333 {
319334 struct device *dev = &pdev->dev;
....@@ -322,6 +337,7 @@
322337 struct phy_provider *phy_provider;
323338 struct regmap *grf;
324339 unsigned int reg_offset;
340
+ u32 val;
325341
326342 if (!dev->parent || !dev->parent->of_node)
327343 return -ENODEV;
....@@ -337,13 +353,17 @@
337353 return -ENOMEM;
338354
339355 if (of_property_read_u32(dev->of_node, "reg", &reg_offset)) {
340
- dev_err(dev, "missing reg property in node %s\n",
341
- dev->of_node->name);
356
+ dev_err(dev, "missing reg property in node %pOFn\n",
357
+ dev->of_node);
342358 return -EINVAL;
343359 }
344360
345361 rk_phy->reg_offset = reg_offset;
346362 rk_phy->reg_base = grf;
363
+ rk_phy->drive_impedance = PHYCTRL_DR_50OHM;
364
+
365
+ if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val))
366
+ rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val);
347367
348368 generic_phy = devm_phy_create(dev, dev->of_node, &ops);
349369 if (IS_ERR(generic_phy)) {