Lines Matching +full:t +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright (C) 2017-2018 Bootlin
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
17 #include <linux/phy/phy.h>
18 #include <linux/phy/phy-mipi-dphy.h>
21 #define SUN6I_DPHY_GCTL_LANE_NUM(n) ((((n) - 1) & 3) << 4)
93 struct phy *phy; member
97 static int sun6i_dphy_init(struct phy *phy) in sun6i_dphy_init() argument
99 struct sun6i_dphy *dphy = phy_get_drvdata(phy); in sun6i_dphy_init()
101 reset_control_deassert(dphy->reset); in sun6i_dphy_init()
102 clk_prepare_enable(dphy->mod_clk); in sun6i_dphy_init()
103 clk_set_rate_exclusive(dphy->mod_clk, 150000000); in sun6i_dphy_init()
108 static int sun6i_dphy_configure(struct phy *phy, union phy_configure_opts *opts) in sun6i_dphy_configure() argument
110 struct sun6i_dphy *dphy = phy_get_drvdata(phy); in sun6i_dphy_configure()
113 ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy); in sun6i_dphy_configure()
117 memcpy(&dphy->config, opts, sizeof(dphy->config)); in sun6i_dphy_configure()
122 static int sun6i_dphy_power_on(struct phy *phy) in sun6i_dphy_power_on() argument
124 struct sun6i_dphy *dphy = phy_get_drvdata(phy); in sun6i_dphy_power_on()
125 u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0); in sun6i_dphy_power_on()
127 regmap_write(dphy->regs, SUN6I_DPHY_TX_CTL_REG, in sun6i_dphy_power_on()
130 regmap_write(dphy->regs, SUN6I_DPHY_TX_TIME0_REG, in sun6i_dphy_power_on()
135 regmap_write(dphy->regs, SUN6I_DPHY_TX_TIME1_REG, in sun6i_dphy_power_on()
141 regmap_write(dphy->regs, SUN6I_DPHY_TX_TIME2_REG, in sun6i_dphy_power_on()
144 regmap_write(dphy->regs, SUN6I_DPHY_TX_TIME3_REG, 0); in sun6i_dphy_power_on()
146 regmap_write(dphy->regs, SUN6I_DPHY_TX_TIME4_REG, in sun6i_dphy_power_on()
150 regmap_write(dphy->regs, SUN6I_DPHY_GCTL_REG, in sun6i_dphy_power_on()
151 SUN6I_DPHY_GCTL_LANE_NUM(dphy->config.lanes) | in sun6i_dphy_power_on()
154 regmap_write(dphy->regs, SUN6I_DPHY_ANA0_REG, in sun6i_dphy_power_on()
161 regmap_write(dphy->regs, SUN6I_DPHY_ANA1_REG, in sun6i_dphy_power_on()
165 regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG, in sun6i_dphy_power_on()
176 regmap_write(dphy->regs, SUN6I_DPHY_ANA2_REG, in sun6i_dphy_power_on()
180 regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG, in sun6i_dphy_power_on()
186 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA3_REG, in sun6i_dphy_power_on()
193 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA3_REG, in sun6i_dphy_power_on()
198 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA2_REG, in sun6i_dphy_power_on()
203 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA1_REG, in sun6i_dphy_power_on()
207 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA2_REG, in sun6i_dphy_power_on()
214 static int sun6i_dphy_power_off(struct phy *phy) in sun6i_dphy_power_off() argument
216 struct sun6i_dphy *dphy = phy_get_drvdata(phy); in sun6i_dphy_power_off()
218 regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA1_REG, in sun6i_dphy_power_off()
224 static int sun6i_dphy_exit(struct phy *phy) in sun6i_dphy_exit() argument
226 struct sun6i_dphy *dphy = phy_get_drvdata(phy); in sun6i_dphy_exit()
228 clk_rate_exclusive_put(dphy->mod_clk); in sun6i_dphy_exit()
229 clk_disable_unprepare(dphy->mod_clk); in sun6i_dphy_exit()
230 reset_control_assert(dphy->reset); in sun6i_dphy_exit()
249 .name = "mipi-dphy",
258 dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); in sun6i_dphy_probe()
260 return -ENOMEM; in sun6i_dphy_probe()
264 dev_err(&pdev->dev, "Couldn't map the DPHY encoder registers\n"); in sun6i_dphy_probe()
268 dphy->regs = devm_regmap_init_mmio_clk(&pdev->dev, "bus", in sun6i_dphy_probe()
270 if (IS_ERR(dphy->regs)) { in sun6i_dphy_probe()
271 dev_err(&pdev->dev, "Couldn't create the DPHY encoder regmap\n"); in sun6i_dphy_probe()
272 return PTR_ERR(dphy->regs); in sun6i_dphy_probe()
275 dphy->reset = devm_reset_control_get_shared(&pdev->dev, NULL); in sun6i_dphy_probe()
276 if (IS_ERR(dphy->reset)) { in sun6i_dphy_probe()
277 dev_err(&pdev->dev, "Couldn't get our reset line\n"); in sun6i_dphy_probe()
278 return PTR_ERR(dphy->reset); in sun6i_dphy_probe()
281 dphy->mod_clk = devm_clk_get(&pdev->dev, "mod"); in sun6i_dphy_probe()
282 if (IS_ERR(dphy->mod_clk)) { in sun6i_dphy_probe()
283 dev_err(&pdev->dev, "Couldn't get the DPHY mod clock\n"); in sun6i_dphy_probe()
284 return PTR_ERR(dphy->mod_clk); in sun6i_dphy_probe()
287 dphy->phy = devm_phy_create(&pdev->dev, NULL, &sun6i_dphy_ops); in sun6i_dphy_probe()
288 if (IS_ERR(dphy->phy)) { in sun6i_dphy_probe()
289 dev_err(&pdev->dev, "failed to create PHY\n"); in sun6i_dphy_probe()
290 return PTR_ERR(dphy->phy); in sun6i_dphy_probe()
293 phy_set_drvdata(dphy->phy, dphy); in sun6i_dphy_probe()
294 phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); in sun6i_dphy_probe()
300 { .compatible = "allwinner,sun6i-a31-mipi-dphy" },
308 .name = "sun6i-mipi-dphy",
315 MODULE_DESCRIPTION("Allwinner A31 MIPI D-PHY Driver");