• Home
  • Raw
  • Download

Lines Matching +full:t +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip emmc PHY driver
5 * Copyright (C) 2016 Shawn Lin <shawn.lin@rock-chips.com>
15 #include <linux/phy/phy.h>
20 * The higher 16-bit of this register is used for write protection
85 static int rockchip_emmc_phy_power(struct phy *phy, bool on_off) in rockchip_emmc_phy_power() argument
87 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); in rockchip_emmc_phy_power()
98 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power()
99 rk_phy->reg_offset + GRF_EMMCPHY_CON6, in rockchip_emmc_phy_power()
103 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power()
104 rk_phy->reg_offset + GRF_EMMCPHY_CON6, in rockchip_emmc_phy_power()
113 rate = clk_get_rate(rk_phy->emmcclk); in rockchip_emmc_phy_power()
138 rate - ideal_rate : ideal_rate - rate; in rockchip_emmc_phy_power()
143 * far off. Also warn if we're above the 200 MHz max. Don't in rockchip_emmc_phy_power()
144 * warn for really slow rates since we won't be tuning then. in rockchip_emmc_phy_power()
147 dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate); in rockchip_emmc_phy_power()
156 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power()
157 rk_phy->reg_offset + GRF_EMMCPHY_CON6, in rockchip_emmc_phy_power()
169 ret = regmap_read_poll_timeout(rk_phy->reg_base, in rockchip_emmc_phy_power()
170 rk_phy->reg_offset + GRF_EMMCPHY_STATUS, in rockchip_emmc_phy_power()
179 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power()
180 rk_phy->reg_offset + GRF_EMMCPHY_CON0, in rockchip_emmc_phy_power()
185 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power()
186 rk_phy->reg_offset + GRF_EMMCPHY_CON6, in rockchip_emmc_phy_power()
193 * clock might be turned on later. ...but we can't wait for the DLL in rockchip_emmc_phy_power()
198 * is turned on, but for now we won't. in rockchip_emmc_phy_power()
206 * with clock speed. If we are powering on the PHY and the card clock in rockchip_emmc_phy_power()
209 * Hopefully we won't be running at 100 kHz, but we should still make in rockchip_emmc_phy_power()
213 * extra long to lock for reasons that aren't understood. In some in rockchip_emmc_phy_power()
217 ret = regmap_read_poll_timeout(rk_phy->reg_base, in rockchip_emmc_phy_power()
218 rk_phy->reg_offset + GRF_EMMCPHY_STATUS, in rockchip_emmc_phy_power()
229 static int rockchip_emmc_phy_init(struct phy *phy) in rockchip_emmc_phy_init() argument
231 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); in rockchip_emmc_phy_init()
237 * - PHY driver to probe in rockchip_emmc_phy_init()
238 * - SDHCI driver to start probe in rockchip_emmc_phy_init()
239 * - SDHCI driver to register it's clock in rockchip_emmc_phy_init()
240 * - SDHCI driver to get the PHY in rockchip_emmc_phy_init()
241 * - SDHCI driver to init the PHY in rockchip_emmc_phy_init()
246 * NOTE: we don't do anything special for EPROBE_DEFER here. Given the in rockchip_emmc_phy_init()
247 * above expected use case, EPROBE_DEFER isn't sensible to expect, so in rockchip_emmc_phy_init()
250 rk_phy->emmcclk = clk_get_optional(&phy->dev, "emmcclk"); in rockchip_emmc_phy_init()
251 if (IS_ERR(rk_phy->emmcclk)) { in rockchip_emmc_phy_init()
252 ret = PTR_ERR(rk_phy->emmcclk); in rockchip_emmc_phy_init()
253 dev_err(&phy->dev, "Error getting emmcclk: %d\n", ret); in rockchip_emmc_phy_init()
254 rk_phy->emmcclk = NULL; in rockchip_emmc_phy_init()
260 static int rockchip_emmc_phy_exit(struct phy *phy) in rockchip_emmc_phy_exit() argument
262 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); in rockchip_emmc_phy_exit()
264 clk_put(rk_phy->emmcclk); in rockchip_emmc_phy_exit()
269 static int rockchip_emmc_phy_power_off(struct phy *phy) in rockchip_emmc_phy_power_off() argument
271 /* Power down emmc phy analog blocks */ in rockchip_emmc_phy_power_off()
272 return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_OFF); in rockchip_emmc_phy_power_off()
275 static int rockchip_emmc_phy_power_on(struct phy *phy) in rockchip_emmc_phy_power_on() argument
277 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); in rockchip_emmc_phy_power_on()
280 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power_on()
281 rk_phy->reg_offset + GRF_EMMCPHY_CON6, in rockchip_emmc_phy_power_on()
282 HIWORD_UPDATE(rk_phy->drive_impedance, in rockchip_emmc_phy_power_on()
287 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power_on()
288 rk_phy->reg_offset + GRF_EMMCPHY_CON0, in rockchip_emmc_phy_power_on()
294 regmap_write(rk_phy->reg_base, in rockchip_emmc_phy_power_on()
295 rk_phy->reg_offset + GRF_EMMCPHY_CON0, in rockchip_emmc_phy_power_on()
300 /* Power up emmc phy analog blocks */ in rockchip_emmc_phy_power_on()
301 return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON); in rockchip_emmc_phy_power_on()
327 dev_warn(&pdev->dev, "Invalid value %u for drive-impedance-ohm.\n", in convert_drive_impedance_ohm()
334 struct device *dev = &pdev->dev; in rockchip_emmc_phy_probe()
336 struct phy *generic_phy; in rockchip_emmc_phy_probe()
342 if (!dev->parent || !dev->parent->of_node) in rockchip_emmc_phy_probe()
343 return -ENODEV; in rockchip_emmc_phy_probe()
345 grf = syscon_node_to_regmap(dev->parent->of_node); in rockchip_emmc_phy_probe()
353 return -ENOMEM; in rockchip_emmc_phy_probe()
355 if (of_property_read_u32(dev->of_node, "reg", &reg_offset)) { in rockchip_emmc_phy_probe()
357 dev->of_node); in rockchip_emmc_phy_probe()
358 return -EINVAL; in rockchip_emmc_phy_probe()
361 rk_phy->reg_offset = reg_offset; in rockchip_emmc_phy_probe()
362 rk_phy->reg_base = grf; in rockchip_emmc_phy_probe()
363 rk_phy->drive_impedance = PHYCTRL_DR_50OHM; in rockchip_emmc_phy_probe()
365 if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val)) in rockchip_emmc_phy_probe()
366 rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val); in rockchip_emmc_phy_probe()
368 generic_phy = devm_phy_create(dev, dev->of_node, &ops); in rockchip_emmc_phy_probe()
370 dev_err(dev, "failed to create PHY\n"); in rockchip_emmc_phy_probe()
381 { .compatible = "rockchip,rk3399-emmc-phy" },
390 .name = "rockchip-emmc-phy",
397 MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>");
398 MODULE_DESCRIPTION("Rockchip EMMC PHY driver");