Add support for specifying `phys` in devicetree to pass handle to the DisplayPort PHY.
In order to retain compatibility with older devicetrees, check if `phys` was specified: if not, initialize the regmap_mmio with the legacy configuration and register the mediatek-dp-phy platform device from this driver, and get the PHY calibration data. Signed-off-by: AngeloGioacchino Del Regno <[email protected]> --- drivers/gpu/drm/mediatek/mtk_dp.c | 50 ++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 3b5348ab487d..bf3a4b15f3ec 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -426,6 +426,15 @@ static const struct regmap_config mtk_dp_regmap_legacy_config = { .name = "mtk-dp-registers", }; +static const struct regmap_config mtk_dp_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SEC_OFFSET + 0x90, + .name = "mtk-dp-registers", +}; + + static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b) { return container_of(b, struct mtk_dp, bridge); @@ -1298,7 +1307,13 @@ static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp, if (ret) return ret; - mtk_dp_set_calibration_data(mtk_dp); + /* + * For legacy, deprecated strategy, set partial PHY calibration here. + * New-style will set all PHY calibrations with phy ops instead. + */ + if (mtk_dp->phy_dev) + mtk_dp_set_calibration_data(mtk_dp); + mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK); @@ -2132,8 +2147,9 @@ static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wa static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, struct platform_device *pdev) { - struct device_node *endpoint; + const struct regmap_config *regmap_cfg; struct device *dev = &pdev->dev; + struct device_node *endpoint; int ret; void __iomem *base; u32 linkrate; @@ -2143,7 +2159,12 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, if (IS_ERR(base)) return PTR_ERR(base); - mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_legacy_config); + if (!mtk_dp->legacy_regoff) + regmap_cfg = &mtk_dp_regmap_config; + else + regmap_cfg = &mtk_dp_regmap_legacy_config; + + mtk_dp->regs = devm_regmap_init_mmio(dev, base, regmap_cfg); if (IS_ERR(mtk_dp->regs)) return PTR_ERR(mtk_dp->regs); @@ -2769,6 +2790,7 @@ static int mtk_dp_register_phy(struct mtk_dp *mtk_dp) "Failed to add phy unregister devm action"); } + /* PHY calibration data is in mtk_dp only for legacy devicetree */ mtk_dp_get_calibration_data(mtk_dp); mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp"); @@ -2821,7 +2843,12 @@ static int mtk_dp_probe(struct platform_device *pdev) mtk_dp->dev = dev; mtk_dp->data = (struct mtk_dp_data *)of_device_get_match_data(dev); - mtk_dp->legacy_regoff = MTK_DP_TOP_OFFSET_LEGACY; + + /* Prefer PHY from devicetree - if not found, this is legacy */ + if (of_property_present(dev->of_node, "phys")) + mtk_dp->legacy_regoff = 0; + else + mtk_dp->legacy_regoff = MTK_DP_TOP_OFFSET_LEGACY; ret = mtk_dp_dt_parse(mtk_dp, pdev); if (ret) @@ -2872,9 +2899,18 @@ static int mtk_dp_probe(struct platform_device *pdev) "Failed to register audio driver\n"); } - ret = mtk_dp_register_phy(mtk_dp); - if (ret) - return ret; + if (!mtk_dp->legacy_regoff) { + mtk_dp->phy = devm_phy_get(dev, NULL); + if (IS_ERR(mtk_dp->phy)) + return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), + "Failed to get phy\n"); + + mtk_dp->phy_dev = NULL; + } else { + ret = mtk_dp_register_phy(mtk_dp); + if (ret) + return ret; + } mtk_dp->bridge.of_node = dev->of_node; mtk_dp->bridge.type = mtk_dp->data->bridge_type; -- 2.54.0
