Skip to content

Commit 8db5fe8

Browse files
authored
Merge pull request torvalds#257 from Radxa-Alvin/linux-5.10-gen-rkr4.1
Changes: * drm/bridge: synopsys: dw-hdmi: HDMI prioritize panel preferred resolution Signed-off-by: Stephen Chen <[email protected]>
2 parents 6667094 + 706bca8 commit 8db5fe8

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

drivers/gpu/drm/bridge/synopsys/dw-hdmi.c

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
31073107
void *data = hdmi->plat_data->phy_data;
31083108
int i, ret = 0;
31093109
struct drm_display_mode *preferred_mode = NULL;
3110+
struct drm_display_mode *default_mode = NULL;
31103111

31113112
memset(metedata, 0, sizeof(*metedata));
31123113
edid = dw_hdmi_get_edid(hdmi, connector);
@@ -3160,24 +3161,58 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
31603161
dw_hdmi_check_output_type_changed(hdmi);
31613162

31623163
if ((hdmi->preset_max_hdisplay) && (hdmi->preset_max_vdisplay)) {
3164+
#ifdef DEBUG
3165+
#define MODE_DBG(x) (dev_err(hdmi->dev, "hdisplay: %d vdisplay: %d flags: %x refresh: %d\n", x->hdisplay, x->vdisplay, x->flags, drm_mode_vrefresh(x)))
3166+
#define MODE_MSG(x) (dev_err(hdmi->dev, x))
3167+
#else
3168+
#define MODE_DBG(x) {}
3169+
#define MODE_MSG(x) {}
3170+
#endif
3171+
#define IS_PREFERRED(x) (x->flags & DRM_MODE_TYPE_PREFERRED)
3172+
#define PIXEL_COUNT(x) (x->hdisplay * x->vdisplay)
3173+
#define IS_BETTER(x, y) ((PIXEL_COUNT(x) <= hdmi->preset_max_hdisplay * hdmi->preset_max_vdisplay && !(x->flags & DRM_MODE_FLAG_INTERLACE) && drm_mode_vrefresh(x) <= 60) && \
3174+
(PIXEL_COUNT(x) > PIXEL_COUNT(y) || (PIXEL_COUNT(x) == PIXEL_COUNT(y) && drm_mode_vrefresh(x) >= drm_mode_vrefresh(y)) || PIXEL_COUNT(y) > hdmi->preset_max_hdisplay * hdmi->preset_max_vdisplay || drm_mode_vrefresh(y) > 60))
3175+
3176+
// Find default mode
31633177
list_for_each_entry(mode, &connector->probed_modes, head) {
3164-
mode->type &= ~DRM_MODE_TYPE_PREFERRED;
3165-
if (mode->hdisplay == hdmi->preset_max_hdisplay &&
3166-
mode->vdisplay == hdmi->preset_max_vdisplay) {
3167-
preferred_mode?:(preferred_mode = mode);
3168-
if(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
3169-
if((preferred_mode->flags & DRM_MODE_FLAG_INTERLACE) || (
3170-
drm_mode_vrefresh(mode) >
3171-
drm_mode_vrefresh(preferred_mode) &&
3172-
drm_mode_vrefresh(mode) <= 60)) {
3173-
preferred_mode = mode;
3174-
}
3175-
}
3178+
if (IS_PREFERRED(mode)) {
3179+
default_mode = mode;
3180+
MODE_MSG("found default_mode\n");
3181+
MODE_DBG(default_mode);
3182+
break;
31763183
}
31773184
}
31783185

3179-
if (preferred_mode)
3186+
// Provide a sane initial mode for later comparision
3187+
if (default_mode) {
3188+
preferred_mode = default_mode;
3189+
MODE_MSG("preferred_mode = default_mode\n");
3190+
}
3191+
else {
3192+
preferred_mode = list_entry(&connector->probed_modes, struct drm_display_mode, head);
3193+
MODE_MSG("preferred_mode = connector->probed_modes[0]\n");
3194+
MODE_DBG(preferred_mode);
3195+
}
3196+
3197+
// Searching for better mode within our criteria
3198+
list_for_each_entry(mode, &connector->probed_modes, head) {
3199+
if (IS_BETTER(mode, preferred_mode)) {
3200+
preferred_mode = mode;
3201+
MODE_MSG("preferred_mode updated\n");
3202+
MODE_DBG(preferred_mode);
3203+
}
3204+
}
3205+
3206+
// Update preferred mode
3207+
if (!default_mode) {
31803208
preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
3209+
MODE_MSG("missing default_mode, preferred_mode used as default_mode\n");
3210+
}
3211+
else if (PIXEL_COUNT(default_mode) > hdmi->preset_max_hdisplay * hdmi->preset_max_vdisplay) {
3212+
default_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
3213+
preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
3214+
MODE_MSG("default_mode resolution is above limit\n");
3215+
}
31813216
}
31823217

31833218
return ret;

0 commit comments

Comments
 (0)