From d92000cdd455dd28ea0feef60d4fec4ebe9fc79a Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Wed, 22 May 2019 15:13:44 -0400 Subject: [PATCH] disp: msm: add resource caps structure and api changes Create a data structure to maintain available hardware resources and track capabilities. This data structure is used to send the current available resources and caps information to connector ops get_mode_info, get_modes and validate_mode to process the display mode. Change-Id: If38fc628ee5ab4729821f88c0050ab45375187b8 Signed-off-by: Nilaan Gunabalachandran --- msm/dp/dp_drm.c | 13 ++++----- msm/dp/dp_drm.h | 16 ++++++----- msm/dp/dp_mst_drm.c | 11 ++++---- msm/dsi/dsi_display.c | 17 +++++++----- msm/dsi/dsi_drm.c | 7 ++--- msm/dsi/dsi_drm.h | 12 +++++---- msm/msm_drv.h | 16 +++++++++++ msm/sde/sde_connector.c | 59 ++++++++++++++++++++++++++++++++++++----- msm/sde/sde_connector.h | 30 ++++++++++++++++----- msm/sde/sde_crtc.c | 4 +-- msm/sde/sde_encoder.c | 16 +++++------ msm/sde/sde_wb.c | 11 +++++--- msm/sde/sde_wb.h | 13 +++++---- 13 files changed, 158 insertions(+), 67 deletions(-) diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index b3b116a874..2bc30fc518 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -357,7 +357,7 @@ end: int dp_connector_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, const struct msm_resource_caps_info *avail_res) { const u32 dual_lm = 2; const u32 single_lm = 1; @@ -369,8 +369,8 @@ int dp_connector_get_mode_info(struct drm_connector *connector, struct dp_display_mode dp_mode; struct dp_display *dp_disp = display; - if (!drm_mode || !mode_info || !max_mixer_width || !connector || - !display) { + if (!drm_mode || !mode_info || !avail_res || + !avail_res->max_mixer_width || !connector || !display) { pr_err("invalid params\n"); return -EINVAL; } @@ -381,7 +381,7 @@ int dp_connector_get_mode_info(struct drm_connector *connector, dp_panel = sde_conn->drv_panel; topology = &mode_info->topology; - topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ? + topology->num_lm = (avail_res->max_mixer_width <= drm_mode->hdisplay) ? dual_lm : single_lm; topology->num_enc = no_enc; topology->num_intf = single_intf; @@ -472,7 +472,7 @@ void dp_connector_post_open(struct drm_connector *connector, void *display) } int dp_connector_get_modes(struct drm_connector *connector, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { int rc = 0; struct dp_display *dp; @@ -580,7 +580,8 @@ void dp_drm_bridge_deinit(void *data) } enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode, void *display) + struct drm_display_mode *mode, void *display, + const struct msm_resource_caps_info *avail_res) { struct dp_display *dp_disp; struct sde_connector *sde_conn; diff --git a/msm/dp/dp_drm.h b/msm/dp/dp_drm.h index f887f82b7b..13c1a059b3 100644 --- a/msm/dp/dp_drm.h +++ b/msm/dp/dp_drm.h @@ -60,35 +60,37 @@ enum drm_connector_status dp_connector_detect(struct drm_connector *conn, * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add() * @connector: Pointer to drm connector structure * @display: Pointer to private display handle + * @avail_res: Pointer with curr available resources * Returns: Number of modes added */ int dp_connector_get_modes(struct drm_connector *connector, - void *display); + void *display, const struct msm_resource_caps_info *avail_res); /** * dp_connector_mode_valid - callback to determine if specified mode is valid * @connector: Pointer to drm connector structure * @mode: Pointer to drm mode structure * @display: Pointer to private display handle + * @avail_res: Pointer with curr available resources * Returns: Validity status for specified mode */ enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode, - void *display); + void *display, const struct msm_resource_caps_info *avail_res); /** * dp_connector_get_mode_info - retrieve information of the mode selected * @connector: Pointer to drm connector structure * @drm_mode: Display mode set for the display * @mode_info: Out parameter. Information of the mode - * @max_mixer_width: max width supported by HW layer mixer * @display: Pointer to private display structure + * @avail_res: Pointer with curr available resources * Returns: zero on success */ int dp_connector_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display); + void *display, const struct msm_resource_caps_info *avail_res); /** * dp_connector_get_info - retrieve connector display info @@ -177,7 +179,7 @@ static inline enum drm_connector_status dp_connector_detect( static inline int dp_connector_get_modes(struct drm_connector *connector, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { return 0; } @@ -185,7 +187,7 @@ static inline int dp_connector_get_modes(struct drm_connector *connector, static inline enum drm_mode_status dp_connector_mode_valid( struct drm_connector *connector, struct drm_display_mode *mode, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { return MODE_OK; } @@ -193,7 +195,7 @@ static inline enum drm_mode_status dp_connector_mode_valid( static inline int dp_connector_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, const struct msm_resource_caps_info *avail_res) { return 0; } diff --git a/msm/dp/dp_mst_drm.c b/msm/dp/dp_mst_drm.c index 4f1cfda737..2a84db42b9 100644 --- a/msm/dp/dp_mst_drm.c +++ b/msm/dp/dp_mst_drm.c @@ -1075,7 +1075,7 @@ dp_mst_connector_detect(struct drm_connector *connector, bool force, } static int dp_mst_connector_get_modes(struct drm_connector *connector, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { struct sde_connector *c_conn = to_sde_connector(connector); struct dp_display *dp_display = display; @@ -1102,7 +1102,7 @@ static int dp_mst_connector_get_modes(struct drm_connector *connector, enum drm_mode_status dp_mst_connector_mode_valid( struct drm_connector *connector, struct drm_display_mode *mode, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { struct dp_display *dp_display = display; struct dp_mst_private *mst; @@ -1153,7 +1153,7 @@ enum drm_mode_status dp_mst_connector_mode_valid( return MODE_BAD; } - return dp_connector_mode_valid(connector, mode, display); + return dp_connector_mode_valid(connector, mode, display, avail_res); } int dp_mst_connector_get_info(struct drm_connector *connector, @@ -1187,14 +1187,15 @@ int dp_mst_connector_get_info(struct drm_connector *connector, int dp_mst_connector_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, + const struct msm_resource_caps_info *avail_res) { int rc; DP_MST_DEBUG("enter:\n"); rc = dp_connector_get_mode_info(connector, drm_mode, mode_info, - max_mixer_width, display); + display, avail_res); DP_MST_DEBUG("mst connector:%d get mode info. rc:%d\n", connector->base.id, rc); diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index d23fffa053..d51d151d60 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -5134,7 +5134,8 @@ static enum drm_connector_status dsi_display_drm_ext_detect( } static int dsi_display_drm_ext_get_modes( - struct drm_connector *connector, void *disp) + struct drm_connector *connector, void *disp, + const struct msm_resource_caps_info *avail_res) { struct dsi_display *display = disp; struct drm_display_mode *pmode, *pt; @@ -5142,7 +5143,7 @@ static int dsi_display_drm_ext_get_modes( /* if there are modes defined in panel, ignore external modes */ if (display->panel->num_timing_nodes) - return dsi_connector_get_modes(connector, disp); + return dsi_connector_get_modes(connector, disp, avail_res); count = display->ext_conn->helper_private->get_modes( display->ext_conn); @@ -5160,13 +5161,13 @@ static int dsi_display_drm_ext_get_modes( static enum drm_mode_status dsi_display_drm_ext_mode_valid( struct drm_connector *connector, struct drm_display_mode *mode, - void *disp) + void *disp, const struct msm_resource_caps_info *avail_res) { struct dsi_display *display = disp; enum drm_mode_status status; /* always do internal mode_valid check */ - status = dsi_conn_mode_valid(connector, mode, disp); + status = dsi_conn_mode_valid(connector, mode, disp, avail_res); if (status != MODE_OK) return status; @@ -5228,11 +5229,12 @@ static int dsi_display_ext_get_info(struct drm_connector *connector, static int dsi_display_ext_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, const struct msm_resource_caps_info *avail_res) { struct msm_display_topology *topology; - if (!drm_mode || !mode_info) + if (!drm_mode || !mode_info || + !avail_res || !avail_res->max_mixer_width) return -EINVAL; memset(mode_info, 0, sizeof(*mode_info)); @@ -5240,7 +5242,8 @@ static int dsi_display_ext_get_mode_info(struct drm_connector *connector, mode_info->vtotal = drm_mode->vtotal; topology = &mode_info->topology; - topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ? 2 : 1; + topology->num_lm = (avail_res->max_mixer_width + <= drm_mode->hdisplay) ? 2 : 1; topology->num_enc = 0; topology->num_intf = topology->num_lm; diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 3dafde7603..3d494154c6 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -459,7 +459,7 @@ u64 dsi_drm_find_bit_clk_rate(void *display, int dsi_conn_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, const struct msm_resource_caps_info *avail_res) { struct dsi_display_mode dsi_mode; struct dsi_mode_info *timing; @@ -790,7 +790,8 @@ static void dsi_drm_update_checksum(struct edid *edid) edid->checksum = 0x100 - (sum & 0xFF); } -int dsi_connector_get_modes(struct drm_connector *connector, void *data) +int dsi_connector_get_modes(struct drm_connector *connector, void *data, + const struct msm_resource_caps_info *avail_res) { int rc, i; u32 count = 0, edid_size; @@ -871,7 +872,7 @@ end: enum drm_mode_status dsi_conn_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode, - void *display) + void *display, const struct msm_resource_caps_info *avail_res) { struct dsi_display_mode dsi_mode; int rc; diff --git a/msm/dsi/dsi_drm.h b/msm/dsi/dsi_drm.h index 8b0b135d72..8e3386d56d 100644 --- a/msm/dsi/dsi_drm.h +++ b/msm/dsi/dsi_drm.h @@ -51,10 +51,11 @@ enum drm_connector_status dsi_conn_detect(struct drm_connector *conn, * dsi_connector_get_modes - callback to add drm modes via drm_mode_probed_add() * @connector: Pointer to drm connector structure * @display: Pointer to private display handle + * @avail_res: Pointer with curr available resources * Returns: Number of modes added */ int dsi_connector_get_modes(struct drm_connector *connector, - void *display); + void *display, const struct msm_resource_caps_info *avail_res); /** * dsi_connector_put_modes - callback to free up drm modes of the connector @@ -68,25 +69,26 @@ void dsi_connector_put_modes(struct drm_connector *connector, * dsi_conn_get_mode_info - retrieve information on the mode selected * @drm_mode: Display mode set for the display * @mode_info: Out parameter. information of the mode. - * @max_mixer_width: max width supported by HW layer mixer * @display: Pointer to private display structure + * @avail_res: Pointer with curr available resources * Returns: Zero on success */ int dsi_conn_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, - struct msm_mode_info *mode_info, u32 max_mixer_width, - void *display); + struct msm_mode_info *mode_info, + void *display, const struct msm_resource_caps_info *avail_res); /** * dsi_conn_mode_valid - callback to determine if specified mode is valid * @connector: Pointer to drm connector structure * @mode: Pointer to drm mode structure * @display: Pointer to private display handle + * @avail_res: Pointer with curr available resources * Returns: Validity status for specified mode */ enum drm_mode_status dsi_conn_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode, - void *display); + void *display, const struct msm_resource_caps_info *avail_res); /** * dsi_conn_enable_event - callback to notify DSI driver of event registration diff --git a/msm/msm_drv.h b/msm/msm_drv.h index d959aeaa21..264c69f001 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -473,6 +473,22 @@ struct msm_mode_info { u32 mdp_transfer_time_us; }; +/** + * struct msm_resource_caps_info - defines hw resources + * @num_lm number of layer mixers available + * @num_dsc number of dsc available + * @num_ctl number of ctl available + * @num_3dmux number of 3d mux available + * @max_mixer_width: max width supported by layer mixer + */ +struct msm_resource_caps_info { + uint32_t num_lm; + uint32_t num_dsc; + uint32_t num_ctl; + uint32_t num_3dmux; + uint32_t max_mixer_width; +}; + /** * struct msm_display_info - defines display properties * @intf_type: DRM_MODE_CONNECTOR_ display type diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index fc7ad9b0e0..431d7b79de 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -365,7 +365,45 @@ int sde_connector_get_dither_cfg(struct drm_connector *conn, return 0; } -int sde_connector_get_mode_info(struct drm_connector_state *conn_state, +static void sde_connector_get_avail_res_info(struct drm_connector *conn, + struct msm_resource_caps_info *avail_res) +{ + struct msm_drm_private *priv; + struct sde_kms *sde_kms; + + if (!conn || !conn->dev || !conn->dev->dev_private) + return; + + priv = conn->dev->dev_private; + sde_kms = to_sde_kms(priv->kms); + + if (!sde_kms) + return; + + avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; +} + +int sde_connector_get_mode_info(struct drm_connector *conn, + const struct drm_display_mode *drm_mode, + struct msm_mode_info *mode_info) +{ + struct sde_connector *sde_conn; + struct msm_resource_caps_info avail_res; + + memset(&avail_res, 0, sizeof(avail_res)); + + sde_conn = to_sde_connector(conn); + + if (!sde_conn) + return -EINVAL; + + sde_connector_get_avail_res_info(conn, &avail_res); + + return sde_conn->ops.get_mode_info(conn, drm_mode, + mode_info, sde_conn->display, &avail_res); +} + +int sde_connector_state_get_mode_info(struct drm_connector_state *conn_state, struct msm_mode_info *mode_info) { struct sde_connector_state *sde_conn_state = NULL; @@ -1826,6 +1864,7 @@ static const struct drm_connector_funcs sde_connector_ops = { static int sde_connector_get_modes(struct drm_connector *connector) { struct sde_connector *c_conn; + struct msm_resource_caps_info avail_res; int mode_count = 0; if (!connector) { @@ -1839,7 +1878,11 @@ static int sde_connector_get_modes(struct drm_connector *connector) return 0; } - mode_count = c_conn->ops.get_modes(connector, c_conn->display); + memset(&avail_res, 0, sizeof(avail_res)); + sde_connector_get_avail_res_info(connector, &avail_res); + + mode_count = c_conn->ops.get_modes(connector, c_conn->display, + &avail_res); if (!mode_count) { SDE_ERROR_CONN(c_conn, "failed to get modes\n"); return 0; @@ -1856,6 +1899,7 @@ sde_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct sde_connector *c_conn; + struct msm_resource_caps_info avail_res; if (!connector || !mode) { SDE_ERROR("invalid argument(s), conn %pK, mode %pK\n", @@ -1865,8 +1909,12 @@ sde_connector_mode_valid(struct drm_connector *connector, c_conn = to_sde_connector(connector); + memset(&avail_res, 0, sizeof(avail_res)); + sde_connector_get_avail_res_info(connector, &avail_res); + if (c_conn->ops.mode_valid) - return c_conn->ops.mode_valid(connector, mode, c_conn->display); + return c_conn->ops.mode_valid(connector, mode, c_conn->display, + &avail_res); /* assume all modes okay by default */ return MODE_OK; @@ -2080,9 +2128,8 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn, memset(&mode_info, 0, sizeof(mode_info)); - rc = c_conn->ops.get_mode_info(&c_conn->base, mode, &mode_info, - sde_kms->catalog->max_mixer_width, - c_conn->display); + rc = sde_connector_get_mode_info(&c_conn->base, mode, + &mode_info); if (rc) { SDE_ERROR_CONN(c_conn, "failed to get mode info for mode %s\n", diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 8ba3f9fa23..1eb09589a8 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -64,10 +64,12 @@ struct sde_connector_ops { * get_modes - add drm modes via drm_mode_probed_add() * @connector: Pointer to drm connector structure * @display: Pointer to private display handle + * @avail_res: Pointer with current available resources * Returns: Number of modes added */ int (*get_modes)(struct drm_connector *connector, - void *display); + void *display, + const struct msm_resource_caps_info *avail_res); /** * update_pps - update pps command for the display panel @@ -84,11 +86,13 @@ struct sde_connector_ops { * @connector: Pointer to drm connector structure * @mode: Pointer to drm mode structure * @display: Pointer to private display handle + * @avail_res: Pointer with curr available resources * Returns: Validity status for specified mode */ enum drm_mode_status (*mode_valid)(struct drm_connector *connector, struct drm_display_mode *mode, - void *display); + void *display, + const struct msm_resource_caps_info *avail_res); /** * set_property - set property value @@ -135,14 +139,15 @@ struct sde_connector_ops { * @connector: Pointer to drm connector structure * @drm_mode: Display mode set for the display * @mode_info: Out parameter. information of the display mode - * @max_mixer_width: max width supported by HW layer mixer * @display: Pointer to private display structure + * @avail_res: Pointer with curr available resources * Returns: Zero on success */ int (*get_mode_info)(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display); + void *display, + const struct msm_resource_caps_info *avail_res); /** * enable_event - notify display of event registration/unregistration @@ -859,14 +864,25 @@ int sde_connector_helper_reset_custom_properties( struct drm_connector_state *connector_state); /** - * sde_connector_get_mode_info - get information of the current mode in the - * given connector state. + * sde_connector_state_get_mode_info - get information of the current mode + * in the given connector state. * conn_state: Pointer to the DRM connector state object * mode_info: Pointer to the mode info structure */ -int sde_connector_get_mode_info(struct drm_connector_state *conn_state, +int sde_connector_state_get_mode_info(struct drm_connector_state *conn_state, struct msm_mode_info *mode_info); +/** +* sde_connector_get_mode_info - retrieve mode info for given mode +* @connector: Pointer to drm connector structure +* @drm_mode: Display mode set for the display +* @mode_info: Out parameter. information of the display mode +* Returns: Zero on success +*/ +int sde_connector_get_mode_info(struct drm_connector *conn, + const struct drm_display_mode *drm_mode, + struct msm_mode_info *mode_info); + /** * sde_conn_timeline_status - current buffer timeline status * conn: Pointer to drm_connector struct diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 1eb6ac9dcb..c5a994e709 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -723,7 +723,7 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc, if (!conn_state || conn_state->crtc != crtc) continue; - rc = sde_connector_get_mode_info(conn_state, &mode_info); + rc = sde_connector_state_get_mode_info(conn_state, &mode_info); if (rc) { SDE_ERROR("failed to get mode info\n"); return -EINVAL; @@ -1066,7 +1066,7 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc, if (!conn || !conn->state) continue; - rc = sde_connector_get_mode_info(conn->state, &mode_info); + rc = sde_connector_state_get_mode_info(conn->state, &mode_info); if (rc) { SDE_ERROR("failed to get mode info\n"); return -EINVAL; diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index bc81d1abd0..0f7af239a4 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -687,7 +687,7 @@ void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc, * called from atomic_check phase. Use the below API to get mode * information of the temporary conn_state passed */ - sde_connector_get_mode_info(conn_state, &mode_info); + sde_connector_state_get_mode_info(conn_state, &mode_info); hw_res->topology = mode_info.topology; hw_res->display_type = sde_enc->disp_info.display_type; } @@ -985,10 +985,8 @@ static int _sde_encoder_atomic_check_reserve(struct drm_encoder *drm_enc, if (sde_conn && drm_atomic_crtc_needs_modeset(crtc_state)) { struct msm_display_topology *topology = NULL; - ret = sde_conn->ops.get_mode_info(&sde_conn->base, adj_mode, - &sde_conn_state->mode_info, - sde_kms->catalog->max_mixer_width, - sde_conn->display); + ret = sde_connector_get_mode_info(&sde_conn->base, + adj_mode, &sde_conn_state->mode_info); if (ret) { SDE_ERROR_ENC(sde_enc, "failed to get mode info, rc = %d\n", ret); @@ -2820,7 +2818,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, intf_mode = sde_encoder_get_intf_mode(drm_enc); /* store the mode_info */ - sde_connector_get_mode_info(conn->state, &sde_enc->mode_info); + sde_connector_state_get_mode_info(conn->state, &sde_enc->mode_info); /* release resources before seamless mode change */ if (msm_is_mode_seamless_dms(adj_mode) || @@ -5845,11 +5843,9 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder, return -EINVAL; } - ret = sde_conn->ops.get_mode_info(&sde_conn->base, + ret = sde_connector_get_mode_info(&sde_conn->base, &encoder->crtc->state->adjusted_mode, - &sde_conn_state->mode_info, - sde_kms->catalog->max_mixer_width, - sde_conn->display); + &sde_conn_state->mode_info); if (ret) { SDE_ERROR_ENC(sde_enc, "conn: ->get_mode_info failed. ret=%d\n", ret); diff --git a/msm/sde/sde_wb.c b/msm/sde/sde_wb.c index 8157789506..4fcc2c316d 100644 --- a/msm/sde/sde_wb.c +++ b/msm/sde/sde_wb.c @@ -61,7 +61,8 @@ sde_wb_connector_detect(struct drm_connector *connector, return rc; } -int sde_wb_connector_get_modes(struct drm_connector *connector, void *display) +int sde_wb_connector_get_modes(struct drm_connector *connector, void *display, + const struct msm_resource_caps_info *avail_res) { struct sde_wb_device *wb_dev; int num_modes = 0; @@ -318,7 +319,7 @@ int sde_wb_get_info(struct drm_connector *connector, int sde_wb_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, struct msm_mode_info *mode_info, - u32 max_mixer_width, void *display) + void *display, const struct msm_resource_caps_info *avail_res) { const u32 dual_lm = 2; const u32 single_lm = 1; @@ -329,7 +330,8 @@ int sde_wb_get_mode_info(struct drm_connector *connector, u16 hdisplay; int i; - if (!drm_mode || !mode_info || !max_mixer_width || !display) { + if (!drm_mode || !mode_info || !avail_res || + !avail_res->max_mixer_width || !display) { pr_err("invalid params\n"); return -EINVAL; } @@ -341,7 +343,8 @@ int sde_wb_get_mode_info(struct drm_connector *connector, hdisplay = max(hdisplay, wb_dev->modes[i].hdisplay); topology = &mode_info->topology; - topology->num_lm = (max_mixer_width <= hdisplay) ? dual_lm : single_lm; + topology->num_lm = (avail_res->max_mixer_width <= hdisplay) ? + dual_lm : single_lm; topology->num_enc = no_enc; topology->num_intf = single_intf; diff --git a/msm/sde/sde_wb.h b/msm/sde/sde_wb.h index cade68388d..a27aa28752 100644 --- a/msm/sde/sde_wb.h +++ b/msm/sde/sde_wb.h @@ -158,12 +158,14 @@ sde_wb_connector_detect(struct drm_connector *connector, * sde_wb_connector_get_modes - get display modes of connector * @connector: Pointer to connector * @display: Pointer to writeback device + * @avail_res: Pointer with curr available resources * Returns: Number of modes * * If display modes are not specified in writeback configuration IOCTL, this * function will install default EDID modes up to maximum resolution support. */ -int sde_wb_connector_get_modes(struct drm_connector *connector, void *display); +int sde_wb_connector_get_modes(struct drm_connector *connector, void *display, + const struct msm_resource_caps_info *avail_res); /** * sde_wb_connector_set_property - set atomic connector property @@ -195,14 +197,14 @@ int sde_wb_get_info(struct drm_connector *connector, * @connector: Pointer to drm connector structure * @drm_mode: Display mode set for the display * @mode_info: Out parameter. information of the mode. - * @max_mixer_width: max width supported by HW layer mixer * @display: Pointer to private display structure + * @avail_res: Pointer with curr available resources * Returns: zero on success */ int sde_wb_get_mode_info(struct drm_connector *connector, const struct drm_display_mode *drm_mode, - struct msm_mode_info *mode_info, u32 max_mixer_width, - void *display); + struct msm_mode_info *mode_info, + void *display, const struct msm_resource_caps_info *avail_res); /** * sde_wb_connector_get_wb - retrieve writeback device of the given connector @@ -301,7 +303,8 @@ sde_wb_connector_detect(struct drm_connector *connector, return connector_status_disconnected; } static inline -int sde_wb_connector_get_modes(struct drm_connector *connector, void *display) +int sde_wb_connector_get_modes(struct drm_connector *connector, void *display, + const struct msm_resource_caps_info *avail_res) { return -EINVAL; }