Lines Matching +full:hdmi +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0+
126 static void sun8i_hdmi_phy_set_polarity(struct sun8i_hdmi_phy *phy, in sun8i_hdmi_phy_set_polarity() argument
131 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in sun8i_hdmi_phy_set_polarity()
134 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in sun8i_hdmi_phy_set_polarity()
137 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG, in sun8i_hdmi_phy_set_polarity()
141 static int sun8i_a83t_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, in sun8i_a83t_hdmi_phy_config() argument
145 unsigned int clk_rate = mode->crtc_clock * 1000; in sun8i_a83t_hdmi_phy_config()
146 struct sun8i_hdmi_phy *phy = data; in sun8i_a83t_hdmi_phy_config() local
148 sun8i_hdmi_phy_set_polarity(phy, mode); in sun8i_a83t_hdmi_phy_config()
150 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, in sun8i_a83t_hdmi_phy_config()
155 dw_hdmi_phy_gen2_txpwron(hdmi, 0); in sun8i_a83t_hdmi_phy_config()
156 dw_hdmi_phy_gen2_pddq(hdmi, 1); in sun8i_a83t_hdmi_phy_config()
158 dw_hdmi_phy_gen2_reset(hdmi); in sun8i_a83t_hdmi_phy_config()
160 dw_hdmi_phy_gen2_pddq(hdmi, 0); in sun8i_a83t_hdmi_phy_config()
162 dw_hdmi_phy_i2c_set_addr(hdmi, I2C_ADDR); in sun8i_a83t_hdmi_phy_config()
165 * Values are taken from BSP HDMI driver. Although AW didn't in sun8i_a83t_hdmi_phy_config()
170 dw_hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); in sun8i_a83t_hdmi_phy_config()
171 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); in sun8i_a83t_hdmi_phy_config()
172 dw_hdmi_phy_i2c_write(hdmi, 0x08da, 0x10); in sun8i_a83t_hdmi_phy_config()
173 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19); in sun8i_a83t_hdmi_phy_config()
174 dw_hdmi_phy_i2c_write(hdmi, 0x0318, 0x0e); in sun8i_a83t_hdmi_phy_config()
175 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09); in sun8i_a83t_hdmi_phy_config()
177 dw_hdmi_phy_i2c_write(hdmi, 0x0540, 0x06); in sun8i_a83t_hdmi_phy_config()
178 dw_hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); in sun8i_a83t_hdmi_phy_config()
179 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10); in sun8i_a83t_hdmi_phy_config()
180 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19); in sun8i_a83t_hdmi_phy_config()
181 dw_hdmi_phy_i2c_write(hdmi, 0x02b5, 0x0e); in sun8i_a83t_hdmi_phy_config()
182 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09); in sun8i_a83t_hdmi_phy_config()
184 dw_hdmi_phy_i2c_write(hdmi, 0x04a0, 0x06); in sun8i_a83t_hdmi_phy_config()
185 dw_hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); in sun8i_a83t_hdmi_phy_config()
186 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10); in sun8i_a83t_hdmi_phy_config()
187 dw_hdmi_phy_i2c_write(hdmi, 0x0002, 0x19); in sun8i_a83t_hdmi_phy_config()
188 dw_hdmi_phy_i2c_write(hdmi, 0x0021, 0x0e); in sun8i_a83t_hdmi_phy_config()
189 dw_hdmi_phy_i2c_write(hdmi, 0x8029, 0x09); in sun8i_a83t_hdmi_phy_config()
191 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x06); in sun8i_a83t_hdmi_phy_config()
192 dw_hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); in sun8i_a83t_hdmi_phy_config()
193 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10); in sun8i_a83t_hdmi_phy_config()
194 dw_hdmi_phy_i2c_write(hdmi, 0x0002, 0x19); in sun8i_a83t_hdmi_phy_config()
195 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x0e); in sun8i_a83t_hdmi_phy_config()
196 dw_hdmi_phy_i2c_write(hdmi, 0x802b, 0x09); in sun8i_a83t_hdmi_phy_config()
199 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x1e); in sun8i_a83t_hdmi_phy_config()
200 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); in sun8i_a83t_hdmi_phy_config()
201 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x17); in sun8i_a83t_hdmi_phy_config()
203 dw_hdmi_phy_gen2_txpwron(hdmi, 1); in sun8i_a83t_hdmi_phy_config()
208 static void sun8i_a83t_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) in sun8i_a83t_hdmi_phy_disable() argument
210 struct sun8i_hdmi_phy *phy = data; in sun8i_a83t_hdmi_phy_disable() local
212 dw_hdmi_phy_gen2_txpwron(hdmi, 0); in sun8i_a83t_hdmi_phy_disable()
213 dw_hdmi_phy_gen2_pddq(hdmi, 1); in sun8i_a83t_hdmi_phy_disable()
215 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, in sun8i_a83t_hdmi_phy_disable()
227 static int sun8i_h3_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, in sun8i_h3_hdmi_phy_config() argument
231 unsigned int clk_rate = mode->crtc_clock * 1000; in sun8i_h3_hdmi_phy_config()
232 struct sun8i_hdmi_phy *phy = data; in sun8i_h3_hdmi_phy_config() local
241 if (phy->variant->has_phy_clk) in sun8i_h3_hdmi_phy_config()
242 clk_set_rate(phy->clk_phy, clk_rate); in sun8i_h3_hdmi_phy_config()
244 sun8i_hdmi_phy_set_polarity(phy, mode); in sun8i_h3_hdmi_phy_config()
303 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal); in sun8i_h3_hdmi_phy_config()
313 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal); in sun8i_h3_hdmi_phy_config()
339 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_h3_hdmi_phy_config()
343 * NOTE: We have to be careful not to overwrite PHY parent in sun8i_h3_hdmi_phy_config()
346 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, in sun8i_h3_hdmi_phy_config()
349 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG, in sun8i_h3_hdmi_phy_config()
353 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG3_REG, in sun8i_h3_hdmi_phy_config()
355 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, in sun8i_h3_hdmi_phy_config()
361 regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val); in sun8i_h3_hdmi_phy_config()
366 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, in sun8i_h3_hdmi_phy_config()
371 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, in sun8i_h3_hdmi_phy_config()
375 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, ana_cfg1_end); in sun8i_h3_hdmi_phy_config()
376 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG2_REG, ana_cfg2_init); in sun8i_h3_hdmi_phy_config()
377 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG3_REG, ana_cfg3_init); in sun8i_h3_hdmi_phy_config()
382 static void sun8i_h3_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) in sun8i_h3_hdmi_phy_disable() argument
384 struct sun8i_hdmi_phy *phy = data; in sun8i_h3_hdmi_phy_disable() local
386 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_h3_hdmi_phy_disable()
390 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, 0); in sun8i_h3_hdmi_phy_disable()
401 static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy) in sun8i_hdmi_phy_unlock() argument
403 /* enable read access to HDMI controller */ in sun8i_hdmi_phy_unlock()
404 regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG, in sun8i_hdmi_phy_unlock()
408 regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG, in sun8i_hdmi_phy_unlock()
412 static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy) in sun50i_hdmi_phy_init_h6() argument
414 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, in sun50i_hdmi_phy_init_h6()
418 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, in sun50i_hdmi_phy_init_h6()
422 static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy) in sun8i_hdmi_phy_init_a83t() argument
424 sun8i_hdmi_phy_unlock(phy); in sun8i_hdmi_phy_init_a83t()
426 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG, in sun8i_hdmi_phy_init_a83t()
431 * Set PHY I2C address. It must match to the address set by in sun8i_hdmi_phy_init_a83t()
434 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG, in sun8i_hdmi_phy_init_a83t()
439 static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy) in sun8i_hdmi_phy_init_h3() argument
443 sun8i_hdmi_phy_unlock(phy); in sun8i_hdmi_phy_init_h3()
445 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, 0); in sun8i_hdmi_phy_init_h3()
446 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
450 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
453 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
457 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
461 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
465 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
469 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
472 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
481 regmap_read_poll_timeout(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, val, in sun8i_hdmi_phy_init_h3()
485 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
488 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, in sun8i_hdmi_phy_init_h3()
499 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG3_REG, in sun8i_hdmi_phy_init_h3()
505 /* reset PHY PLL clock parent */ in sun8i_hdmi_phy_init_h3()
506 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, in sun8i_hdmi_phy_init_h3()
510 regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, 0); in sun8i_hdmi_phy_init_h3()
513 regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val); in sun8i_hdmi_phy_init_h3()
514 phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2; in sun8i_hdmi_phy_init_h3()
517 int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) in sun8i_hdmi_phy_init() argument
521 ret = reset_control_deassert(phy->rst_phy); in sun8i_hdmi_phy_init()
523 dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret); in sun8i_hdmi_phy_init()
527 ret = clk_prepare_enable(phy->clk_bus); in sun8i_hdmi_phy_init()
529 dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret); in sun8i_hdmi_phy_init()
533 ret = clk_prepare_enable(phy->clk_mod); in sun8i_hdmi_phy_init()
535 dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret); in sun8i_hdmi_phy_init()
539 if (phy->variant->has_phy_clk) { in sun8i_hdmi_phy_init()
540 ret = sun8i_phy_clk_create(phy, phy->dev, in sun8i_hdmi_phy_init()
541 phy->variant->has_second_pll); in sun8i_hdmi_phy_init()
543 dev_err(phy->dev, "Couldn't create the PHY clock\n"); in sun8i_hdmi_phy_init()
547 clk_prepare_enable(phy->clk_phy); in sun8i_hdmi_phy_init()
550 phy->variant->phy_init(phy); in sun8i_hdmi_phy_init()
555 clk_disable_unprepare(phy->clk_mod); in sun8i_hdmi_phy_init()
557 clk_disable_unprepare(phy->clk_bus); in sun8i_hdmi_phy_init()
559 reset_control_assert(phy->rst_phy); in sun8i_hdmi_phy_init()
564 void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy) in sun8i_hdmi_phy_deinit() argument
566 clk_disable_unprepare(phy->clk_mod); in sun8i_hdmi_phy_deinit()
567 clk_disable_unprepare(phy->clk_bus); in sun8i_hdmi_phy_deinit()
568 clk_disable_unprepare(phy->clk_phy); in sun8i_hdmi_phy_deinit()
570 reset_control_assert(phy->rst_phy); in sun8i_hdmi_phy_deinit()
573 void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, in sun8i_hdmi_phy_set_ops() argument
576 const struct sun8i_hdmi_phy_variant *variant = phy->variant; in sun8i_hdmi_phy_set_ops()
578 if (variant->phy_ops) { in sun8i_hdmi_phy_set_ops()
579 plat_data->phy_ops = variant->phy_ops; in sun8i_hdmi_phy_set_ops()
580 plat_data->phy_name = "sun8i_dw_hdmi_phy"; in sun8i_hdmi_phy_set_ops()
581 plat_data->phy_data = phy; in sun8i_hdmi_phy_set_ops()
583 plat_data->mpll_cfg = variant->mpll_cfg; in sun8i_hdmi_phy_set_ops()
584 plat_data->cur_ctr = variant->cur_ctr; in sun8i_hdmi_phy_set_ops()
585 plat_data->phy_config = variant->phy_cfg; in sun8i_hdmi_phy_set_ops()
594 .name = "phy"
630 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
634 .compatible = "allwinner,sun8i-h3-hdmi-phy",
638 .compatible = "allwinner,sun8i-r40-hdmi-phy",
642 .compatible = "allwinner,sun50i-a64-hdmi-phy",
646 .compatible = "allwinner,sun50i-h6-hdmi-phy",
652 int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node) in sun8i_hdmi_phy_get() argument
655 struct sun8i_hdmi_phy *phy; in sun8i_hdmi_phy_get() local
658 return -EPROBE_DEFER; in sun8i_hdmi_phy_get()
660 phy = platform_get_drvdata(pdev); in sun8i_hdmi_phy_get()
661 if (!phy) { in sun8i_hdmi_phy_get()
662 put_device(&pdev->dev); in sun8i_hdmi_phy_get()
663 return -EPROBE_DEFER; in sun8i_hdmi_phy_get()
666 hdmi->phy = phy; in sun8i_hdmi_phy_get()
668 put_device(&pdev->dev); in sun8i_hdmi_phy_get()
675 struct device *dev = &pdev->dev; in sun8i_hdmi_phy_probe()
676 struct sun8i_hdmi_phy *phy; in sun8i_hdmi_phy_probe() local
679 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); in sun8i_hdmi_phy_probe()
680 if (!phy) in sun8i_hdmi_phy_probe()
681 return -ENOMEM; in sun8i_hdmi_phy_probe()
683 phy->variant = of_device_get_match_data(dev); in sun8i_hdmi_phy_probe()
684 phy->dev = dev; in sun8i_hdmi_phy_probe()
689 "Couldn't map the HDMI PHY registers\n"); in sun8i_hdmi_phy_probe()
691 phy->regs = devm_regmap_init_mmio(dev, regs, in sun8i_hdmi_phy_probe()
693 if (IS_ERR(phy->regs)) in sun8i_hdmi_phy_probe()
694 return dev_err_probe(dev, PTR_ERR(phy->regs), in sun8i_hdmi_phy_probe()
695 "Couldn't create the HDMI PHY regmap\n"); in sun8i_hdmi_phy_probe()
697 phy->clk_bus = devm_clk_get(dev, "bus"); in sun8i_hdmi_phy_probe()
698 if (IS_ERR(phy->clk_bus)) in sun8i_hdmi_phy_probe()
699 return dev_err_probe(dev, PTR_ERR(phy->clk_bus), in sun8i_hdmi_phy_probe()
702 phy->clk_mod = devm_clk_get(dev, "mod"); in sun8i_hdmi_phy_probe()
703 if (IS_ERR(phy->clk_mod)) in sun8i_hdmi_phy_probe()
704 return dev_err_probe(dev, PTR_ERR(phy->clk_mod), in sun8i_hdmi_phy_probe()
707 if (phy->variant->has_phy_clk) { in sun8i_hdmi_phy_probe()
708 phy->clk_pll0 = devm_clk_get(dev, "pll-0"); in sun8i_hdmi_phy_probe()
709 if (IS_ERR(phy->clk_pll0)) in sun8i_hdmi_phy_probe()
710 return dev_err_probe(dev, PTR_ERR(phy->clk_pll0), in sun8i_hdmi_phy_probe()
711 "Could not get pll-0 clock\n"); in sun8i_hdmi_phy_probe()
713 if (phy->variant->has_second_pll) { in sun8i_hdmi_phy_probe()
714 phy->clk_pll1 = devm_clk_get(dev, "pll-1"); in sun8i_hdmi_phy_probe()
715 if (IS_ERR(phy->clk_pll1)) in sun8i_hdmi_phy_probe()
716 return dev_err_probe(dev, PTR_ERR(phy->clk_pll1), in sun8i_hdmi_phy_probe()
717 "Could not get pll-1 clock\n"); in sun8i_hdmi_phy_probe()
721 phy->rst_phy = devm_reset_control_get_shared(dev, "phy"); in sun8i_hdmi_phy_probe()
722 if (IS_ERR(phy->rst_phy)) in sun8i_hdmi_phy_probe()
723 return dev_err_probe(dev, PTR_ERR(phy->rst_phy), in sun8i_hdmi_phy_probe()
724 "Could not get phy reset control\n"); in sun8i_hdmi_phy_probe()
726 platform_set_drvdata(pdev, phy); in sun8i_hdmi_phy_probe()
734 .name = "sun8i-hdmi-phy",