diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_display.c')
-rw-r--r-- | drivers/gpu/drm/msm/dp/dp_display.c | 116 |
1 files changed, 43 insertions, 73 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index bce77935394f..bfd0aeff3f0d 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -131,35 +131,43 @@ struct msm_dp_config { size_t num_descs; }; +static const struct msm_dp_desc sc7180_dp_descs[] = { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, +}; + static const struct msm_dp_config sc7180_dp_cfg = { - .descs = (const struct msm_dp_desc[]) { - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, - }, - .num_descs = 1, + .descs = sc7180_dp_descs, + .num_descs = ARRAY_SIZE(sc7180_dp_descs), +}; + +static const struct msm_dp_desc sc7280_dp_descs[] = { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, }; static const struct msm_dp_config sc7280_dp_cfg = { - .descs = (const struct msm_dp_desc[]) { - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, - }, - .num_descs = 2, + .descs = sc7280_dp_descs, + .num_descs = ARRAY_SIZE(sc7280_dp_descs), +}; + +static const struct msm_dp_desc sc8180x_dp_descs[] = { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, }; static const struct msm_dp_config sc8180x_dp_cfg = { - .descs = (const struct msm_dp_desc[]) { - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, - [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, - [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, - }, - .num_descs = 3, + .descs = sc8180x_dp_descs, + .num_descs = ARRAY_SIZE(sc8180x_dp_descs), +}; + +static const struct msm_dp_desc sm8350_dp_descs[] = { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, }; static const struct msm_dp_config sm8350_dp_cfg = { - .descs = (const struct msm_dp_desc[]) { - [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, - }, - .num_descs = 1, + .descs = sm8350_dp_descs, + .num_descs = ARRAY_SIZE(sm8350_dp_descs), }; static const struct of_device_id dp_dt_match[] = { @@ -309,12 +317,15 @@ static void dp_display_unbind(struct device *dev, struct device *master, struct msm_drm_private *priv = dev_get_drvdata(master); /* disable all HPD interrupts */ - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); + if (dp->core_initialized) + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); kthread_stop(dp->ev_tsk); dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); + dp->drm_dev = NULL; + dp->aux->drm_dev = NULL; priv->dp[dp->id] = NULL; } @@ -607,9 +618,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) return 0; }; -static int dp_display_enable(struct dp_display_private *dp, u32 data); -static int dp_display_disable(struct dp_display_private *dp, u32 data); - static void dp_display_handle_plugged_change(struct msm_dp *dp_display, bool plugged) { @@ -856,12 +864,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display, return 0; } -static int dp_display_prepare(struct msm_dp *dp_display) -{ - return 0; -} - -static int dp_display_enable(struct dp_display_private *dp, u32 data) +static int dp_display_enable(struct dp_display_private *dp, bool force_link_train) { int rc = 0; struct msm_dp *dp_display = &dp->dp_display; @@ -872,7 +875,7 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data) return 0; } - rc = dp_ctrl_on_stream(dp->ctrl); + rc = dp_ctrl_on_stream(dp->ctrl, force_link_train); if (!rc) dp_display->power_on = true; @@ -898,7 +901,7 @@ static int dp_display_post_enable(struct msm_dp *dp_display) return 0; } -static int dp_display_disable(struct dp_display_private *dp, u32 data) +static int dp_display_disable(struct dp_display_private *dp) { struct msm_dp *dp_display = &dp->dp_display; @@ -937,11 +940,6 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data) return 0; } -static int dp_display_unprepare(struct msm_dp *dp_display) -{ - return 0; -} - int dp_display_set_plugged_cb(struct msm_dp *dp_display, hdmi_codec_plugged_cb fn, struct device *codec_dev) { @@ -989,7 +987,7 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) - return MODE_BAD; + return MODE_CLOCK_HIGH; dp_display = container_of(dp, struct dp_display_private, dp_display); link_info = &dp_display->panel->link_info; @@ -1457,21 +1455,9 @@ static int dp_pm_suspend(struct device *dev) return 0; } -static int dp_pm_prepare(struct device *dev) -{ - return 0; -} - -static void dp_pm_complete(struct device *dev) -{ - -} - static const struct dev_pm_ops dp_pm_ops = { .suspend = dp_pm_suspend, .resume = dp_pm_resume, - .prepare = dp_pm_prepare, - .complete = dp_pm_complete, }; static struct platform_driver dp_display_driver = { @@ -1621,8 +1607,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, return ret; } - dp_display->encoder = encoder; - ret = dp_display_get_next_bridge(dp_display); if (ret) return ret; @@ -1638,7 +1622,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, priv->bridges[priv->num_bridges++] = dp_display->bridge; - dp_display->connector = dp_drm_connector_init(dp_display); + dp_display->connector = dp_drm_connector_init(dp_display, encoder); if (IS_ERR(dp_display->connector)) { ret = PTR_ERR(dp_display->connector); DRM_DEV_ERROR(dev->dev, @@ -1659,6 +1643,7 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) int rc = 0; struct dp_display_private *dp_display; u32 state; + bool force_link_train = false; dp_display = container_of(dp, struct dp_display_private, dp_display); if (!dp_display->dp_mode.drm_mode.clock) { @@ -1684,31 +1669,21 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) return; } - rc = dp_display_prepare(dp); - if (rc) { - DRM_ERROR("DP display prepare failed, rc=%d\n", rc); - mutex_unlock(&dp_display->event_mutex); - return; - } - state = dp_display->hpd_state; - if (state == ST_DISPLAY_OFF) + if (state == ST_DISPLAY_OFF) { dp_display_host_phy_init(dp_display); + force_link_train = true; + } - dp_display_enable(dp_display, 0); + dp_display_enable(dp_display, force_link_train); rc = dp_display_post_enable(dp); if (rc) { DRM_ERROR("DP display post enable failed, rc=%d\n", rc); - dp_display_disable(dp_display, 0); - dp_display_unprepare(dp); + dp_display_disable(dp_display); } - /* manual kick off plug event to train link */ - if (state == ST_DISPLAY_OFF) - dp_add_event(dp_display, EV_IRQ_HPD_INT, 0, 0); - /* completed connection */ dp_display->hpd_state = ST_CONNECTED; @@ -1731,7 +1706,6 @@ void dp_bridge_post_disable(struct drm_bridge *drm_bridge) { struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = dp_bridge->dp_display; - int rc = 0; u32 state; struct dp_display_private *dp_display; @@ -1748,11 +1722,7 @@ void dp_bridge_post_disable(struct drm_bridge *drm_bridge) return; } - dp_display_disable(dp_display, 0); - - rc = dp_display_unprepare(dp); - if (rc) - DRM_ERROR("DP display unprepare failed, rc=%d\n", rc); + dp_display_disable(dp_display); state = dp_display->hpd_state; if (state == ST_DISCONNECT_PENDING) { |