Lines Matching +full:stm32mp1 +full:- +full:usbphyc
1 // SPDX-License-Identifier: GPL-2.0
60 struct stm32_usbphyc *usbphyc; member
99 * <=> PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16 in stm32_usbphyc_get_pll_params()
105 pll_params->ndiv = (u8)ndiv; in stm32_usbphyc_get_pll_params()
109 frac = frac - (ndiv * (1 << 16)); in stm32_usbphyc_get_pll_params()
110 pll_params->frac = (u16)frac; in stm32_usbphyc_get_pll_params()
113 static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) in stm32_usbphyc_pll_init() argument
116 u32 clk_rate = clk_get_rate(usbphyc->clk); in stm32_usbphyc_pll_init()
122 dev_err(usbphyc->dev, "input clk freq (%dHz) out of range\n", in stm32_usbphyc_pll_init()
124 return -EINVAL; in stm32_usbphyc_pll_init()
136 writel_relaxed(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL); in stm32_usbphyc_pll_init()
138 dev_dbg(usbphyc->dev, "input clk freq=%dHz, ndiv=%lu, frac=%lu\n", in stm32_usbphyc_pll_init()
145 static bool stm32_usbphyc_has_one_phy_active(struct stm32_usbphyc *usbphyc) in stm32_usbphyc_has_one_phy_active() argument
149 for (i = 0; i < usbphyc->nphys; i++) in stm32_usbphyc_has_one_phy_active()
150 if (usbphyc->phys[i]->active) in stm32_usbphyc_has_one_phy_active()
156 static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc) in stm32_usbphyc_pll_enable() argument
158 void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL; in stm32_usbphyc_pll_enable()
163 if (pllen && stm32_usbphyc_has_one_phy_active(usbphyc)) in stm32_usbphyc_pll_enable()
172 ret = stm32_usbphyc_pll_init(usbphyc); in stm32_usbphyc_pll_enable()
182 dev_err(usbphyc->dev, "PLLEN not set\n"); in stm32_usbphyc_pll_enable()
183 return -EIO; in stm32_usbphyc_pll_enable()
189 static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc) in stm32_usbphyc_pll_disable() argument
191 void __iomem *pll_reg = usbphyc->base + STM32_USBPHYC_PLL; in stm32_usbphyc_pll_disable()
194 if (stm32_usbphyc_has_one_phy_active(usbphyc)) in stm32_usbphyc_pll_disable()
202 dev_err(usbphyc->dev, "PLL not reset\n"); in stm32_usbphyc_pll_disable()
203 return -EIO; in stm32_usbphyc_pll_disable()
212 struct stm32_usbphyc *usbphyc = usbphyc_phy->usbphyc; in stm32_usbphyc_phy_init() local
215 ret = stm32_usbphyc_pll_enable(usbphyc); in stm32_usbphyc_phy_init()
219 usbphyc_phy->active = true; in stm32_usbphyc_phy_init()
227 struct stm32_usbphyc *usbphyc = usbphyc_phy->usbphyc; in stm32_usbphyc_phy_exit() local
229 usbphyc_phy->active = false; in stm32_usbphyc_phy_exit()
231 return stm32_usbphyc_pll_disable(usbphyc); in stm32_usbphyc_phy_exit()
238 return regulator_bulk_enable(NUM_SUPPLIES, usbphyc_phy->supplies); in stm32_usbphyc_phy_power_on()
245 return regulator_bulk_disable(NUM_SUPPLIES, usbphyc_phy->supplies); in stm32_usbphyc_phy_power_off()
256 static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc, in stm32_usbphyc_switch_setup() argument
260 stm32_usbphyc_clr_bits(usbphyc->base + STM32_USBPHYC_MISC, in stm32_usbphyc_switch_setup()
263 stm32_usbphyc_set_bits(usbphyc->base + STM32_USBPHYC_MISC, in stm32_usbphyc_switch_setup()
265 usbphyc->switch_setup = utmi_switch; in stm32_usbphyc_switch_setup()
271 struct stm32_usbphyc *usbphyc = dev_get_drvdata(dev); in stm32_usbphyc_of_xlate() local
273 struct device_node *phynode = args->np; in stm32_usbphyc_of_xlate()
276 for (port = 0; port < usbphyc->nphys; port++) { in stm32_usbphyc_of_xlate()
277 if (phynode == usbphyc->phys[port]->phy->dev.of_node) { in stm32_usbphyc_of_xlate()
278 usbphyc_phy = usbphyc->phys[port]; in stm32_usbphyc_of_xlate()
284 return ERR_PTR(-EINVAL); in stm32_usbphyc_of_xlate()
287 if (((usbphyc_phy->index == 0) && (args->args_count != 0)) || in stm32_usbphyc_of_xlate()
288 ((usbphyc_phy->index == 1) && (args->args_count != 1))) { in stm32_usbphyc_of_xlate()
290 usbphyc_phy->index); in stm32_usbphyc_of_xlate()
291 return ERR_PTR(-EINVAL); in stm32_usbphyc_of_xlate()
295 if (usbphyc_phy->index == 1) { in stm32_usbphyc_of_xlate()
296 if (usbphyc->switch_setup < 0) { in stm32_usbphyc_of_xlate()
297 stm32_usbphyc_switch_setup(usbphyc, args->args[0]); in stm32_usbphyc_of_xlate()
299 if (args->args[0] != usbphyc->switch_setup) { in stm32_usbphyc_of_xlate()
301 return ERR_PTR(-EBUSY); in stm32_usbphyc_of_xlate()
306 return usbphyc_phy->phy; in stm32_usbphyc_of_xlate()
311 struct stm32_usbphyc *usbphyc; in stm32_usbphyc_probe() local
312 struct device *dev = &pdev->dev; in stm32_usbphyc_probe()
313 struct device_node *child, *np = dev->of_node; in stm32_usbphyc_probe()
319 usbphyc = devm_kzalloc(dev, sizeof(*usbphyc), GFP_KERNEL); in stm32_usbphyc_probe()
320 if (!usbphyc) in stm32_usbphyc_probe()
321 return -ENOMEM; in stm32_usbphyc_probe()
322 usbphyc->dev = dev; in stm32_usbphyc_probe()
323 dev_set_drvdata(dev, usbphyc); in stm32_usbphyc_probe()
326 usbphyc->base = devm_ioremap_resource(dev, res); in stm32_usbphyc_probe()
327 if (IS_ERR(usbphyc->base)) in stm32_usbphyc_probe()
328 return PTR_ERR(usbphyc->base); in stm32_usbphyc_probe()
330 usbphyc->clk = devm_clk_get(dev, NULL); in stm32_usbphyc_probe()
331 if (IS_ERR(usbphyc->clk)) { in stm32_usbphyc_probe()
332 ret = PTR_ERR(usbphyc->clk); in stm32_usbphyc_probe()
337 ret = clk_prepare_enable(usbphyc->clk); in stm32_usbphyc_probe()
343 usbphyc->rst = devm_reset_control_get(dev, NULL); in stm32_usbphyc_probe()
344 if (!IS_ERR(usbphyc->rst)) { in stm32_usbphyc_probe()
345 reset_control_assert(usbphyc->rst); in stm32_usbphyc_probe()
347 reset_control_deassert(usbphyc->rst); in stm32_usbphyc_probe()
350 usbphyc->switch_setup = -EINVAL; in stm32_usbphyc_probe()
351 usbphyc->nphys = of_get_child_count(np); in stm32_usbphyc_probe()
352 usbphyc->phys = devm_kcalloc(dev, usbphyc->nphys, in stm32_usbphyc_probe()
353 sizeof(*usbphyc->phys), GFP_KERNEL); in stm32_usbphyc_probe()
354 if (!usbphyc->phys) { in stm32_usbphyc_probe()
355 ret = -ENOMEM; in stm32_usbphyc_probe()
368 if (ret != -EPROBE_DEFER) in stm32_usbphyc_probe()
377 ret = -ENOMEM; in stm32_usbphyc_probe()
382 usbphyc_phy->supplies[i].supply = supplies_names[i]; in stm32_usbphyc_probe()
384 ret = devm_regulator_bulk_get(&phy->dev, NUM_SUPPLIES, in stm32_usbphyc_probe()
385 usbphyc_phy->supplies); in stm32_usbphyc_probe()
387 if (ret != -EPROBE_DEFER) in stm32_usbphyc_probe()
388 dev_err(&phy->dev, in stm32_usbphyc_probe()
394 if (ret || index > usbphyc->nphys) { in stm32_usbphyc_probe()
395 dev_err(&phy->dev, "invalid reg property: %d\n", ret); in stm32_usbphyc_probe()
397 ret = -EINVAL; in stm32_usbphyc_probe()
401 usbphyc->phys[port] = usbphyc_phy; in stm32_usbphyc_probe()
405 usbphyc->phys[port]->phy = phy; in stm32_usbphyc_probe()
406 usbphyc->phys[port]->usbphyc = usbphyc; in stm32_usbphyc_probe()
407 usbphyc->phys[port]->index = index; in stm32_usbphyc_probe()
408 usbphyc->phys[port]->active = false; in stm32_usbphyc_probe()
421 version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION); in stm32_usbphyc_probe()
430 clk_disable_unprepare(usbphyc->clk); in stm32_usbphyc_probe()
437 struct stm32_usbphyc *usbphyc = dev_get_drvdata(&pdev->dev); in stm32_usbphyc_remove() local
439 clk_disable_unprepare(usbphyc->clk); in stm32_usbphyc_remove()
445 { .compatible = "st,stm32mp1-usbphyc", },
455 .name = "stm32-usbphyc",
460 MODULE_DESCRIPTION("STMicroelectronics STM32 USBPHYC driver");