Lines Matching full:combophy
3 * STMicroelectronics COMBOPHY STM32MP25 Controller driver.
116 static int stm32_impedance_tune(struct stm32_combophy *combophy) in stm32_impedance_tune() argument
127 if (!of_property_read_u32(combophy->dev->of_node, "st,output-micro-ohms", &val)) { in stm32_impedance_tune()
129 dev_err(combophy->dev, "Invalid value %u for output ohm\n", val); in stm32_impedance_tune()
140 dev_dbg(combophy->dev, "Set %u micro-ohms output impedance\n", in stm32_impedance_tune()
143 regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR, in stm32_impedance_tune()
149 if (!of_property_read_u32(combophy->dev->of_node, "st,output-vswing-microvolt", &val)) { in stm32_impedance_tune()
153 dev_err(combophy->dev, "Invalid value %u for output vswing\n", val); in stm32_impedance_tune()
164 dev_dbg(combophy->dev, "Set %u microvolt swing\n", in stm32_impedance_tune()
167 regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR, in stm32_impedance_tune()
175 static int stm32_combophy_pll_init(struct stm32_combophy *combophy) in stm32_combophy_pll_init() argument
183 if (combophy->have_pad_clk) in stm32_combophy_pll_init()
184 clk = combophy->clks[PAD_CLK].clk; in stm32_combophy_pll_init()
186 clk = combophy->clks[KER_CLK].clk; in stm32_combophy_pll_init()
190 dev_dbg(combophy->dev, "%s pll init rate %d\n", in stm32_combophy_pll_init()
191 combophy->have_pad_clk ? "External" : "Ker", clk_rate); in stm32_combophy_pll_init()
193 if (combophy->type != PHY_TYPE_PCIE) { in stm32_combophy_pll_init()
198 if (of_property_present(combophy->dev->of_node, "st,ssc-on")) { in stm32_combophy_pll_init()
199 dev_dbg(combophy->dev, "Enabling clock with SSC\n"); in stm32_combophy_pll_init()
231 dev_err(combophy->dev, "Invalid rate 0x%x\n", clk_rate); in stm32_combophy_pll_init()
246 * before using the ComboPHY. in stm32_combophy_pll_init()
248 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2, in stm32_combophy_pll_init()
251 reset_control_assert(combophy->phy_reset); in stm32_combophy_pll_init()
253 if (combophy->type == PHY_TYPE_PCIE) { in stm32_combophy_pll_init()
254 ret = stm32_impedance_tune(combophy); in stm32_combophy_pll_init()
259 cr1_val |= combophy->have_pad_clk ? SYSCFG_COMBOPHY_CR1_REFUSEPAD : 0; in stm32_combophy_pll_init()
262 if (!of_property_read_u32(combophy->dev->of_node, "st,rx-equalizer", &val)) { in stm32_combophy_pll_init()
263 dev_dbg(combophy->dev, "Set RX equalizer %u\n", val); in stm32_combophy_pll_init()
265 dev_err(combophy->dev, "Invalid value %u for rx0 equalizer\n", val); in stm32_combophy_pll_init()
270 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR4, in stm32_combophy_pll_init()
274 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, cr1_mask, cr1_val); in stm32_combophy_pll_init()
280 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR5, in stm32_combophy_pll_init()
283 reset_control_deassert(combophy->phy_reset); in stm32_combophy_pll_init()
285 ret = regmap_read_poll_timeout(combophy->regmap, SYSCFG_COMBOPHY_SR, val, in stm32_combophy_pll_init()
289 dev_err(combophy->dev, "timeout, cannot lock PLL\n"); in stm32_combophy_pll_init()
290 if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk) in stm32_combophy_pll_init()
291 regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR, in stm32_combophy_pll_init()
294 if (combophy->type != PHY_TYPE_PCIE) in stm32_combophy_pll_init()
295 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, in stm32_combophy_pll_init()
302 if (combophy->type == PHY_TYPE_PCIE) { in stm32_combophy_pll_init()
303 if (!combophy->have_pad_clk) in stm32_combophy_pll_init()
304 regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR, in stm32_combophy_pll_init()
307 val = readl_relaxed(combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL); in stm32_combophy_pll_init()
310 writel_relaxed(val, combophy->base + COMBOPHY_SUP_ANA_MPLL_LOOP_CTL); in stm32_combophy_pll_init()
316 reset_control_deassert(combophy->phy_reset); in stm32_combophy_pll_init()
319 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2, in stm32_combophy_pll_init()
328 struct stm32_combophy *combophy = dev_get_drvdata(dev); in stm32_combophy_xlate() local
342 if (combophy->have_pad_clk && type != PHY_TYPE_PCIE) { in stm32_combophy_xlate()
347 combophy->type = type; in stm32_combophy_xlate()
349 return combophy->phy; in stm32_combophy_xlate()
352 static int stm32_combophy_set_mode(struct stm32_combophy *combophy) in stm32_combophy_set_mode() argument
354 int type = combophy->type; in stm32_combophy_set_mode()
359 dev_dbg(combophy->dev, "setting PCIe ComboPHY\n"); in stm32_combophy_set_mode()
363 dev_dbg(combophy->dev, "setting USB3 ComboPHY\n"); in stm32_combophy_set_mode()
367 dev_err(combophy->dev, "Invalid PHY mode %d\n", type); in stm32_combophy_set_mode()
371 return regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2, in stm32_combophy_set_mode()
377 struct stm32_combophy *combophy = dev_get_drvdata(dev); in stm32_combophy_suspend_noirq() local
384 if (combophy->is_init) { in stm32_combophy_suspend_noirq()
385 clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks); in stm32_combophy_suspend_noirq()
388 enable_irq_wake(combophy->irq_wakeup); in stm32_combophy_suspend_noirq()
396 struct stm32_combophy *combophy = dev_get_drvdata(dev); in stm32_combophy_resume_noirq() local
404 if (combophy->is_init) { in stm32_combophy_resume_noirq()
406 disable_irq_wake(combophy->irq_wakeup); in stm32_combophy_resume_noirq()
408 ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks); in stm32_combophy_resume_noirq()
420 struct stm32_combophy *combophy = phy_get_drvdata(phy); in stm32_combophy_exit() local
421 struct device *dev = combophy->dev; in stm32_combophy_exit()
423 combophy->is_init = false; in stm32_combophy_exit()
425 if (combophy->type == PHY_TYPE_PCIE && !combophy->have_pad_clk) in stm32_combophy_exit()
426 regmap_update_bits(combophy->regmap, SYSCFG_PCIEPRGCR, in stm32_combophy_exit()
429 if (combophy->type != PHY_TYPE_PCIE) in stm32_combophy_exit()
430 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR1, in stm32_combophy_exit()
433 regmap_update_bits(combophy->regmap, SYSCFG_COMBOPHY_CR2, in stm32_combophy_exit()
436 clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks); in stm32_combophy_exit()
445 struct stm32_combophy *combophy = phy_get_drvdata(phy); in stm32_combophy_init() local
446 struct device *dev = combophy->dev; in stm32_combophy_init()
451 ret = clk_bulk_prepare_enable(combophy->num_clks, combophy->clks); in stm32_combophy_init()
458 ret = stm32_combophy_set_mode(combophy); in stm32_combophy_init()
460 dev_err(dev, "combophy mode not set\n"); in stm32_combophy_init()
461 clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks); in stm32_combophy_init()
466 ret = stm32_combophy_pll_init(combophy); in stm32_combophy_init()
468 clk_bulk_disable_unprepare(combophy->num_clks, combophy->clks); in stm32_combophy_init()
477 combophy->is_init = true; in stm32_combophy_init()
493 static int stm32_combophy_get_clocks(struct stm32_combophy *combophy) in stm32_combophy_get_clocks() argument
498 combophy->clks[i].id = combophy_clks[i]; in stm32_combophy_get_clocks()
500 combophy->num_clks = ARRAY_SIZE(combophy_clks) - 1; in stm32_combophy_get_clocks()
502 ret = devm_clk_bulk_get(combophy->dev, combophy->num_clks, combophy->clks); in stm32_combophy_get_clocks()
506 ret = devm_clk_bulk_get_optional(combophy->dev, 1, combophy->clks + combophy->num_clks); in stm32_combophy_get_clocks()
510 if (combophy->clks[combophy->num_clks].clk != NULL) { in stm32_combophy_get_clocks()
511 combophy->have_pad_clk = true; in stm32_combophy_get_clocks()
512 combophy->num_clks++; in stm32_combophy_get_clocks()
520 struct stm32_combophy *combophy; in stm32_combophy_probe() local
525 combophy = devm_kzalloc(dev, sizeof(*combophy), GFP_KERNEL); in stm32_combophy_probe()
526 if (!combophy) in stm32_combophy_probe()
529 combophy->dev = dev; in stm32_combophy_probe()
531 dev_set_drvdata(dev, combophy); in stm32_combophy_probe()
533 combophy->base = devm_platform_ioremap_resource(pdev, 0); in stm32_combophy_probe()
534 if (IS_ERR(combophy->base)) in stm32_combophy_probe()
535 return PTR_ERR(combophy->base); in stm32_combophy_probe()
537 ret = stm32_combophy_get_clocks(combophy); in stm32_combophy_probe()
541 combophy->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); in stm32_combophy_probe()
542 if (IS_ERR(combophy->phy_reset)) in stm32_combophy_probe()
543 return dev_err_probe(dev, PTR_ERR(combophy->phy_reset), in stm32_combophy_probe()
546 combophy->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg"); in stm32_combophy_probe()
547 if (IS_ERR(combophy->regmap)) in stm32_combophy_probe()
548 return dev_err_probe(dev, PTR_ERR(combophy->regmap), in stm32_combophy_probe()
551 combophy->phy = devm_phy_create(dev, NULL, &stm32_combophy_phy_data); in stm32_combophy_probe()
552 if (IS_ERR(combophy->phy)) in stm32_combophy_probe()
553 return dev_err_probe(dev, PTR_ERR(combophy->phy), in stm32_combophy_probe()
554 "failed to create PCIe/USB3 ComboPHY\n"); in stm32_combophy_probe()
560 combophy->irq_wakeup = irq; in stm32_combophy_probe()
562 ret = devm_request_threaded_irq(dev, combophy->irq_wakeup, NULL, in stm32_combophy_probe()
567 combophy->irq_wakeup); in stm32_combophy_probe()
574 phy_set_drvdata(combophy->phy, combophy); in stm32_combophy_probe()
587 { .compatible = "st,stm32mp25-combophy", },
595 .name = "stm32-combophy",
604 MODULE_DESCRIPTION("STM32MP25 Combophy USB3/PCIe controller driver");