lkml.org 
[lkml]   [2022]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v10 19/21] drm/mediatek: Add mt8195 External DisplayPort support
    Date
    This patch adds External DisplayPort support to the mt8195 eDP driver.

    Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
    ---
    drivers/gpu/drm/mediatek/mtk_dp.c | 104 +++++++++++++++++++++++-------
    1 file changed, 81 insertions(+), 23 deletions(-)

    diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
    index 8eb17ae82bfd..4789853ec5ff 100644
    --- a/drivers/gpu/drm/mediatek/mtk_dp.c
    +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
    @@ -164,6 +164,11 @@ static struct regmap_config mtk_dp_regmap_config = {
    .name = "mtk-dp-registers",
    };

    +static bool mtk_dp_is_edp(struct mtk_dp *mtk_dp)
    +{
    + return mtk_dp->next_bridge;
    +}
    +
    static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
    {
    return container_of(b, struct mtk_dp, bridge);
    @@ -1054,26 +1059,49 @@ static int mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp)
    if (!cal_data->ln_tx_impsel_pmos)
    return -ENOMEM;

    - cal_data->glb_bias_trim =
    - check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
    - cal_data->clktx_impse =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_pmos[0] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_nmos[0] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_pmos[1] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_nmos[1] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_pmos[2] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_nmos[2] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_pmos[3] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
    - cal_data->ln_tx_impsel_nmos[3] =
    - check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
    + if (mtk_dp_is_edp(mtk_dp)) {
    + cal_data->glb_bias_trim =
    + check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[3] >> 27) & 0x1f, 0xf);
    + cal_data->clktx_impse =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 9) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[0] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 28) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[0] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 24) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[1] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 20) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[1] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 16) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[2] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 12) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[2] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 8) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[3] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[2] >> 4) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[3] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, buf[2] & 0xf, 0x8);
    + } else {
    + cal_data->glb_bias_trim =
    + check_cal_data_valid(mtk_dp, 1, 0x1e, (buf[0] >> 27) & 0x1f, 0xf);
    + cal_data->clktx_impse =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[0] >> 13) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[0] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 28) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[0] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 24) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[1] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 20) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[1] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 16) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[2] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 12) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[2] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 8) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_pmos[3] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, (buf[1] >> 4) & 0xf, 0x8);
    + cal_data->ln_tx_impsel_nmos[3] =
    + check_cal_data_valid(mtk_dp, 1, 0xe, buf[1] & 0xf, 0x8);
    + }

    kfree(buf);

    @@ -1224,7 +1252,10 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
    VIDEO_MUTE_SEL_DP_ENC0_P0_MASK |
    VIDEO_MUTE_SW_DP_ENC0_P0_MASK);

    - mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
    + if (mtk_dp_is_edp(mtk_dp))
    + mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE, enable);
    + else
    + mtk_dp_sip_atf_call(MTK_DP_SIP_ATF_VIDEO_UNMUTE, enable);
    }

    static int mtk_dp_power_enable(struct mtk_dp *mtk_dp)
    @@ -2066,6 +2097,24 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
    return ret;
    }

    +static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
    +{
    + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
    + enum drm_connector_status ret = connector_status_disconnected;
    + u8 sink_count = 0;
    +
    + if (mtk_dp_is_edp(mtk_dp))
    + return connector_status_connected;
    +
    + if (mtk_dp_plug_state(mtk_dp)) {
    + drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
    + if (DP_GET_SINK_COUNT(sink_count))
    + ret = connector_status_connected;
    + }
    +
    + return ret;
    +}
    +
    static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
    struct drm_connector *connector)
    {
    @@ -2422,6 +2471,7 @@ static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
    .atomic_disable = mtk_dp_bridge_atomic_disable,
    .mode_valid = mtk_dp_bridge_mode_valid,
    .get_edid = mtk_dp_get_edid,
    + .detect = mtk_dp_bdg_detect,
    };

    static int mtk_dp_probe(struct platform_device *pdev)
    @@ -2443,7 +2493,11 @@ static int mtk_dp_probe(struct platform_device *pdev)


    mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
    - if (IS_ERR(mtk_dp->next_bridge)) {
    + if (IS_ERR(mtk_dp->next_bridge) && PTR_ERR(mtk_dp->next_bridge) == -ENODEV) {
    + dev_info(dev,
    + "No panel connected in devicetree, continuing as external DP\n");
    + mtk_dp->next_bridge = NULL;
    + } else if (IS_ERR(mtk_dp->next_bridge)) {
    return dev_err_probe(dev, PTR_ERR(mtk_dp->next_bridge), "Failed to get bridge\n");
    }

    @@ -2488,7 +2542,10 @@ static int mtk_dp_probe(struct platform_device *pdev)
    mtk_dp->bridge.ops =
    DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
    drm_bridge_add(&mtk_dp->bridge);
    - mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
    + if (mtk_dp_is_edp(mtk_dp))
    + mtk_dp->bridge.type = DRM_MODE_CONNECTOR_eDP;
    + else
    + mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;

    pm_runtime_enable(dev);
    pm_runtime_get_sync(dev);
    @@ -2550,6 +2607,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);

    static const struct of_device_id mtk_dp_of_match[] = {
    { .compatible = "mediatek,mt8195-edp-tx" },
    + { .compatible = "mediatek,mt8195-dp-tx" },
    {},
    };
    MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
    --
    2.35.1
    \
     
     \ /
      Last update: 2022-05-23 12:54    [W:5.286 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site