Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: rockchip-emmc: Allow to set drive impedance via DTS.

The rockchip-emmc PHY can be configured with different
drive impedance values. Currenlty a value of 50 Ohm is
hard coded into the driver.

This patch introduces the DTS property 'drive-impedance-ohm'
for the rockchip-emmc phy node, which uses the value from the DTS
to setup the drive impedance accordingly.

Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Christoph Muellner and committed by
Kishon Vijay Abraham I
043f42ed 3f6d1767

+28 -2
+28 -2
drivers/phy/rockchip/phy-rockchip-emmc.c
··· 87 87 unsigned int reg_offset; 88 88 struct regmap *reg_base; 89 89 struct clk *emmcclk; 90 + unsigned int drive_impedance; 90 91 }; 91 92 92 93 static int rockchip_emmc_phy_power(struct phy *phy, bool on_off) ··· 282 281 { 283 282 struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); 284 283 285 - /* Drive impedance: 50 Ohm */ 284 + /* Drive impedance: from DTS */ 286 285 regmap_write(rk_phy->reg_base, 287 286 rk_phy->reg_offset + GRF_EMMCPHY_CON6, 288 - HIWORD_UPDATE(PHYCTRL_DR_50OHM, 287 + HIWORD_UPDATE(rk_phy->drive_impedance, 289 288 PHYCTRL_DR_MASK, 290 289 PHYCTRL_DR_SHIFT)); 291 290 ··· 315 314 .owner = THIS_MODULE, 316 315 }; 317 316 317 + static u32 convert_drive_impedance_ohm(struct platform_device *pdev, u32 dr_ohm) 318 + { 319 + switch (dr_ohm) { 320 + case 100: 321 + return PHYCTRL_DR_100OHM; 322 + case 66: 323 + return PHYCTRL_DR_66OHM; 324 + case 50: 325 + return PHYCTRL_DR_50OHM; 326 + case 40: 327 + return PHYCTRL_DR_40OHM; 328 + case 33: 329 + return PHYCTRL_DR_33OHM; 330 + } 331 + 332 + dev_warn(&pdev->dev, "Invalid value %u for drive-impedance-ohm.\n", 333 + dr_ohm); 334 + return PHYCTRL_DR_50OHM; 335 + } 336 + 318 337 static int rockchip_emmc_phy_probe(struct platform_device *pdev) 319 338 { 320 339 struct device *dev = &pdev->dev; ··· 343 322 struct phy_provider *phy_provider; 344 323 struct regmap *grf; 345 324 unsigned int reg_offset; 325 + u32 val; 346 326 347 327 if (!dev->parent || !dev->parent->of_node) 348 328 return -ENODEV; ··· 366 344 367 345 rk_phy->reg_offset = reg_offset; 368 346 rk_phy->reg_base = grf; 347 + rk_phy->drive_impedance = PHYCTRL_DR_50OHM; 348 + 349 + if (!of_property_read_u32(dev->of_node, "drive-impedance-ohm", &val)) 350 + rk_phy->drive_impedance = convert_drive_impedance_ohm(pdev, val); 369 351 370 352 generic_phy = devm_phy_create(dev, dev->of_node, &ops); 371 353 if (IS_ERR(generic_phy)) {