diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_display.c')
-rw-r--r-- | drivers/gpu/drm/msm/dp/dp_display.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index e4433891becb..d80f89581760 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -111,7 +111,7 @@ struct dp_display_private { struct dp_event event_list[DP_EVENT_Q_MAX]; spinlock_t event_lock; - bool wide_bus_en; + bool wide_bus_supported; struct dp_audio *audio; }; @@ -120,7 +120,7 @@ struct msm_dp_desc { phys_addr_t io_start; unsigned int id; unsigned int connector_type; - bool wide_bus_en; + bool wide_bus_supported; }; static const struct msm_dp_desc sc7180_dp_descs[] = { @@ -129,8 +129,8 @@ static const struct msm_dp_desc sc7180_dp_descs[] = { }; static const struct msm_dp_desc sc7280_dp_descs[] = { - { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, + { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_supported = true }, {} }; @@ -142,22 +142,22 @@ static const struct msm_dp_desc sc8180x_dp_descs[] = { }; static const struct msm_dp_desc sc8280xp_dp_descs[] = { - { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, - { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true }, + { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, + { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_supported = true }, {} }; static const struct msm_dp_desc sc8280xp_edp_descs[] = { - { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, - { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, - { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, - { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true }, + { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_supported = true }, + { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_supported = true }, + { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_supported = true }, + { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_supported = true }, {} }; @@ -766,10 +766,6 @@ static int dp_init_sub_modules(struct dp_display_private *dp) goto error_ctrl; } - /* populate wide_bus_en to differernt layers */ - dp->ctrl->wide_bus_en = dp->wide_bus_en; - dp->catalog->wide_bus_en = dp->wide_bus_en; - return rc; error_ctrl: @@ -790,6 +786,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display, drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode); dp->panel->dp_mode.bpp = mode->bpp; dp->panel->dp_mode.capabilities = mode->capabilities; + dp->panel->dp_mode.out_fmt_is_yuv_420 = mode->out_fmt_is_yuv_420; dp_panel_init_panel_info(dp->panel); return 0; } @@ -918,6 +915,10 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge, dp_display = container_of(dp, struct dp_display_private, dp_display); link_info = &dp_display->panel->link_info; + if (drm_mode_is_420_only(&dp->connector->display_info, mode) && + dp_display->panel->vsc_sdp_supported) + mode_pclk_khz /= 2; + mode_bpp = dp->connector->display_info.bpc * num_components; if (!mode_bpp) mode_bpp = default_bpp; @@ -1247,7 +1248,7 @@ static int dp_display_probe(struct platform_device *pdev) dp->name = "drm_dp"; dp->id = desc->id; dp->dp_display.connector_type = desc->connector_type; - dp->wide_bus_en = desc->wide_bus_en; + dp->wide_bus_supported = desc->wide_bus_supported; dp->dp_display.is_edp = (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); @@ -1375,13 +1376,34 @@ void __exit msm_dp_unregister(void) platform_driver_unregister(&dp_display_driver); } +bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display, + const struct drm_display_mode *mode) +{ + struct dp_display_private *dp; + const struct drm_display_info *info; + + dp = container_of(dp_display, struct dp_display_private, dp_display); + info = &dp_display->connector->display_info; + + return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode); +} + +bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display, + const struct drm_display_mode *mode) +{ + return msm_dp_is_yuv_420_enabled(dp_display, mode); +} + bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) { struct dp_display_private *dp; dp = container_of(dp_display, struct dp_display_private, dp_display); - return dp->wide_bus_en; + if (dp->dp_mode.out_fmt_is_yuv_420) + return false; + + return dp->wide_bus_supported; } void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, bool is_edp) @@ -1404,7 +1426,7 @@ void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, boo } int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, - struct drm_encoder *encoder) + struct drm_encoder *encoder, bool yuv_supported) { struct dp_display_private *dp_priv; int ret; @@ -1420,7 +1442,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, return ret; } - dp_display->connector = dp_drm_connector_init(dp_display, encoder); + dp_display->connector = dp_drm_connector_init(dp_display, encoder, yuv_supported); if (IS_ERR(dp_display->connector)) { ret = PTR_ERR(dp_display->connector); DRM_DEV_ERROR(dev->dev, @@ -1550,8 +1572,10 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge, struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = dp_bridge->dp_display; struct dp_display_private *dp_display; + struct dp_panel *dp_panel; dp_display = container_of(dp, struct dp_display_private, dp_display); + dp_panel = dp_display->panel; memset(&dp_display->dp_mode, 0x0, sizeof(struct dp_display_mode)); @@ -1570,6 +1594,16 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge, dp_display->dp_mode.h_active_low = !!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC); + + dp_display->dp_mode.out_fmt_is_yuv_420 = + drm_mode_is_420_only(&dp->connector->display_info, adjusted_mode) && + dp_panel->vsc_sdp_supported; + + /* populate wide_bus_support to different layers */ + dp_display->ctrl->wide_bus_en = + dp_display->dp_mode.out_fmt_is_yuv_420 ? false : dp_display->wide_bus_supported; + dp_display->catalog->wide_bus_en = + dp_display->dp_mode.out_fmt_is_yuv_420 ? false : dp_display->wide_bus_supported; } void dp_bridge_hpd_enable(struct drm_bridge *bridge) |