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

Reply via email to