diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 4dd6ae1..2357680 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3430,6 +3430,9 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, SDE_ATRACE_BEGIN("sde_crtc_prepare_commit"); + if (crtc->state->event && crtc->state->active) + drm_crtc_vblank_get(crtc); + /* identify connectors attached to this crtc */ cstate->num_connectors = 0; @@ -3909,6 +3912,9 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc, if (!sde_kms) return; + if (crtc->state->event && crtc->state->active) + drm_crtc_vblank_put(crtc); + for (i = 0; i < MAX_DSI_DISPLAYS; i++) { splash_display = &sde_kms->splash_data.splash_display[i]; if (splash_display->cont_splash_enabled && splash_display->encoder && diff --git a/msm/sde/sde_formats.c b/msm/sde/sde_formats.c index 65f4084..b18afd6 100644 --- a/msm/sde/sde_formats.c +++ b/msm/sde/sde_formats.c @@ -8,6 +8,7 @@ #include #include +#include #include "sde_kms.h" #include "sde_formats.h" @@ -1446,36 +1447,56 @@ const struct msm_format *sde_get_msm_format( return NULL; } +static int __format_list_cmp(const void *a, const void *b) { + + struct sde_format_extended *format_a = (struct sde_format_extended *)a; + struct sde_format_extended *format_b = (struct sde_format_extended *)b; + + return (format_a->fourcc_format - format_b->fourcc_format); +} + uint32_t sde_populate_formats( const struct sde_format_extended *format_list, uint32_t *pixel_formats, uint64_t *pixel_modifiers, uint32_t pixel_formats_max) { - uint32_t i, fourcc_format; + uint32_t i, j, fourcc_format, format_list_size = 0; + struct sde_format_extended *temp_format_list; if (!format_list || !pixel_formats) return 0; - for (i = 0, fourcc_format = 0; - format_list->fourcc_format && i < pixel_formats_max; - ++format_list) { - /* verify if listed format is in sde_format_map? */ + while (format_list[format_list_size].fourcc_format) + ++format_list_size; + + temp_format_list = kcalloc(format_list_size, + sizeof(struct sde_format_extended), GFP_KERNEL); + sde_copy_formats(temp_format_list, format_list_size, 0, format_list, + format_list_size); + sort(temp_format_list, format_list_size, sizeof(*temp_format_list), + __format_list_cmp, NULL); + for (i = 0, j = 0, fourcc_format = 0; + j < format_list_size && i < pixel_formats_max; + j++) { + + /* verify if listed format is in sde_format_map? */ /* optionally return modified formats */ if (pixel_modifiers) { /* assume same modifier for all fb planes */ - pixel_formats[i] = format_list->fourcc_format; - pixel_modifiers[i++] = format_list->modifier; + pixel_formats[i] = temp_format_list[j].fourcc_format; + pixel_modifiers[i++] = temp_format_list[j].modifier; } else { /* assume base formats grouped together */ - if (fourcc_format != format_list->fourcc_format) { - fourcc_format = format_list->fourcc_format; + if (fourcc_format != temp_format_list[j].fourcc_format) { + fourcc_format = temp_format_list[j].fourcc_format; pixel_formats[i++] = fourcc_format; } } } + kfree(temp_format_list); return i; } diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index dd8b944..2b700d0 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2409,58 +2409,6 @@ static int _sde_kms_setup_displays(struct drm_device *dev, SDE_ERROR("capping number of displays to %d", max_encoders); } - /* wb */ - for (i = 0; i < sde_kms->wb_display_count && - priv->num_encoders < max_encoders; ++i) { - display = sde_kms->wb_displays[i]; - encoder = NULL; - - memset(&info, 0x0, sizeof(info)); - rc = sde_wb_get_info(NULL, &info, display); - if (rc) { - SDE_ERROR("wb get_info %d failed\n", i); - continue; - } - - snprintf(cesta_client_name, sizeof(cesta_client_name), "wb%u", i); - cesta_client = sde_cesta_create_client(DPUID(dev), cesta_client_name); - - encoder = sde_encoder_init(dev, &info, cesta_client); - if (IS_ERR_OR_NULL(encoder)) { - SDE_ERROR("encoder init failed for wb %d\n", i); - continue; - } - - rc = sde_wb_drm_init(display, encoder); - if (rc) { - SDE_ERROR("wb bridge %d init failed, %d\n", i, rc); - sde_encoder_destroy(encoder); - continue; - } - - connector_poll = (info.capabilities & MSM_DISPLAY_CAP_HOT_PLUG) ? - DRM_CONNECTOR_POLL_HPD : 0; - - connector = sde_connector_init(dev, - encoder, - 0, - display, - &wb_ops, - connector_poll, - test_bit(SDE_FEATURE_VIRTUAL_CONNECTOR_WB, - sde_kms->catalog->features) ? - DRM_MODE_CONNECTOR_WRITEBACK : - DRM_MODE_CONNECTOR_VIRTUAL, false); - if (!IS_ERR_OR_NULL(connector)) { - priv->encoders[priv->num_encoders++] = encoder; - priv->connectors[priv->num_connectors++] = connector; - } else { - SDE_ERROR("wb %d connector init failed\n", i); - sde_wb_drm_deinit(display); - sde_encoder_destroy(encoder); - } - } - /* dsi */ for (i = 0; i < sde_kms->dsi_display_count && priv->num_encoders < max_encoders; ++i) { @@ -2541,6 +2489,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, if (sde_kms->catalog->allowed_dsc_reservation_switch & SDE_DP_DSC_RESERVATION_SWITCH) max_dp_dsc_count = sde_kms->catalog->dsc_count; + /* dp */ if (IS_DISP_OP_HFI(priv->disp_op)) goto skip_dp; @@ -2628,6 +2577,58 @@ static int _sde_kms_setup_displays(struct drm_device *dev, } } + /* wb */ + for (i = 0; i < sde_kms->wb_display_count && + priv->num_encoders < max_encoders; ++i) { + display = sde_kms->wb_displays[i]; + encoder = NULL; + + memset(&info, 0x0, sizeof(info)); + rc = sde_wb_get_info(NULL, &info, display); + if (rc) { + SDE_ERROR("wb get_info %d failed\n", i); + continue; + } + + snprintf(cesta_client_name, sizeof(cesta_client_name), "wb%u", i); + cesta_client = sde_cesta_create_client(DPUID(dev), cesta_client_name); + + encoder = sde_encoder_init(dev, &info, cesta_client); + if (IS_ERR_OR_NULL(encoder)) { + SDE_ERROR("encoder init failed for wb %d\n", i); + continue; + } + + rc = sde_wb_drm_init(display, encoder); + if (rc) { + SDE_ERROR("wb bridge %d init failed, %d\n", i, rc); + sde_encoder_destroy(encoder); + continue; + } + + connector_poll = (info.capabilities & MSM_DISPLAY_CAP_HOT_PLUG) ? + DRM_CONNECTOR_POLL_HPD : 0; + + connector = sde_connector_init(dev, + encoder, + 0, + display, + &wb_ops, + connector_poll, + test_bit(SDE_FEATURE_VIRTUAL_CONNECTOR_WB, + sde_kms->catalog->features) ? + DRM_MODE_CONNECTOR_WRITEBACK : + DRM_MODE_CONNECTOR_VIRTUAL, false); + if (!IS_ERR_OR_NULL(connector)) { + priv->encoders[priv->num_encoders++] = encoder; + priv->connectors[priv->num_connectors++] = connector; + } else { + SDE_ERROR("wb %d connector init failed\n", i); + sde_wb_drm_deinit(display); + sde_encoder_destroy(encoder); + } + } + skip_dp: setup_hdmi_displays(dev, priv, sde_kms, max_encoders, max_dp_mixer_count, max_dp_dsc_count);