Commit 345b7c4b authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Convert fixed_mode/downclock_mode into a list

Store the fixed_mode and downclock_mode as a real list,
in preparation for exposing other supported modes as well.

v2: Init the list in intel_sdvo_connector_alloc() too
v3: Use list_first_entry_or_null() (Jani)
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220314152737.9125-1-ville.syrjala@linux.intel.com
parent c5ee2343
...@@ -54,6 +54,8 @@ int intel_connector_init(struct intel_connector *connector) ...@@ -54,6 +54,8 @@ int intel_connector_init(struct intel_connector *connector)
__drm_atomic_helper_connector_reset(&connector->base, __drm_atomic_helper_connector_reset(&connector->base,
&conn_state->base); &conn_state->base);
INIT_LIST_HEAD(&connector->panel.fixed_modes);
return 0; return 0;
} }
......
...@@ -548,12 +548,15 @@ static void intel_encoder_info(struct seq_file *m, ...@@ -548,12 +548,15 @@ static void intel_encoder_info(struct seq_file *m,
static void intel_panel_info(struct seq_file *m, static void intel_panel_info(struct seq_file *m,
struct intel_connector *connector) struct intel_connector *connector)
{ {
const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode; const struct drm_display_mode *fixed_mode;
if (!fixed_mode) if (list_empty(&connector->panel.fixed_modes))
return; return;
seq_printf(m, "\tfixed mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(fixed_mode)); seq_puts(m, "\tfixed modes:\n");
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head)
intel_seq_print_mode(m, 2, fixed_mode);
} }
static void intel_hdcp_info(struct seq_file *m, static void intel_hdcp_info(struct seq_file *m,
......
...@@ -280,8 +280,7 @@ struct intel_panel_bl_funcs { ...@@ -280,8 +280,7 @@ struct intel_panel_bl_funcs {
}; };
struct intel_panel { struct intel_panel {
struct drm_display_mode *fixed_mode; struct list_head fixed_modes;
struct drm_display_mode *downclock_mode;
/* backlight */ /* backlight */
struct { struct {
......
...@@ -48,59 +48,55 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915) ...@@ -48,59 +48,55 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915)
const struct drm_display_mode * const struct drm_display_mode *
intel_panel_preferred_fixed_mode(struct intel_connector *connector) intel_panel_preferred_fixed_mode(struct intel_connector *connector)
{ {
return connector->panel.fixed_mode; return list_first_entry_or_null(&connector->panel.fixed_modes,
struct drm_display_mode, head);
} }
const struct drm_display_mode * const struct drm_display_mode *
intel_panel_fixed_mode(struct intel_connector *connector, intel_panel_fixed_mode(struct intel_connector *connector,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode; const struct drm_display_mode *fixed_mode, *best_mode = NULL;
const struct drm_display_mode *downclock_mode = connector->panel.downclock_mode; int vrefresh = drm_mode_vrefresh(mode);
/* pick the one that is closer in terms of vrefresh */ /* pick the fixed_mode that is closest in terms of vrefresh */
/* FIXME make this a a list of modes so we can have more than two */ list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
if (fixed_mode && downclock_mode && if (!best_mode ||
abs(drm_mode_vrefresh(downclock_mode) - drm_mode_vrefresh(mode)) < abs(drm_mode_vrefresh(fixed_mode) - vrefresh) <
abs(drm_mode_vrefresh(fixed_mode) - drm_mode_vrefresh(mode))) abs(drm_mode_vrefresh(best_mode) - vrefresh))
return downclock_mode; best_mode = fixed_mode;
else }
return fixed_mode;
return best_mode;
} }
const struct drm_display_mode * const struct drm_display_mode *
intel_panel_downclock_mode(struct intel_connector *connector, intel_panel_downclock_mode(struct intel_connector *connector,
const struct drm_display_mode *adjusted_mode) const struct drm_display_mode *adjusted_mode)
{ {
const struct drm_display_mode *downclock_mode = connector->panel.downclock_mode; const struct drm_display_mode *fixed_mode, *best_mode = NULL;
int vrefresh = drm_mode_vrefresh(adjusted_mode);
/* pick the fixed_mode with the lowest refresh rate */
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
if (drm_mode_vrefresh(fixed_mode) < vrefresh) {
vrefresh = drm_mode_vrefresh(fixed_mode);
best_mode = fixed_mode;
}
}
if (downclock_mode && return best_mode;
drm_mode_vrefresh(downclock_mode) < drm_mode_vrefresh(adjusted_mode))
return downclock_mode;
else
return NULL;
} }
int intel_panel_get_modes(struct intel_connector *connector) int intel_panel_get_modes(struct intel_connector *connector)
{ {
const struct drm_display_mode *fixed_mode;
int num_modes = 0; int num_modes = 0;
if (connector->panel.fixed_mode) { list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(connector->base.dev,
connector->panel.fixed_mode);
if (mode) {
drm_mode_probed_add(&connector->base, mode);
num_modes++;
}
}
if (connector->panel.downclock_mode) {
struct drm_display_mode *mode; struct drm_display_mode *mode;
mode = drm_mode_duplicate(connector->base.dev, mode = drm_mode_duplicate(connector->base.dev, fixed_mode);
connector->panel.downclock_mode);
if (mode) { if (mode) {
drm_mode_probed_add(&connector->base, mode); drm_mode_probed_add(&connector->base, mode);
num_modes++; num_modes++;
...@@ -114,7 +110,8 @@ enum drrs_type intel_panel_drrs_type(struct intel_connector *connector) ...@@ -114,7 +110,8 @@ enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
{ {
struct drm_i915_private *i915 = to_i915(connector->base.dev); struct drm_i915_private *i915 = to_i915(connector->base.dev);
if (!connector->panel.downclock_mode) if (list_empty(&connector->panel.fixed_modes) ||
list_is_singular(&connector->panel.fixed_modes))
return DRRS_TYPE_NONE; return DRRS_TYPE_NONE;
return i915->vbt.drrs_type; return i915->vbt.drrs_type;
...@@ -608,8 +605,10 @@ int intel_panel_init(struct intel_panel *panel, ...@@ -608,8 +605,10 @@ int intel_panel_init(struct intel_panel *panel,
{ {
intel_backlight_init_funcs(panel); intel_backlight_init_funcs(panel);
panel->fixed_mode = fixed_mode; if (fixed_mode)
panel->downclock_mode = downclock_mode; list_add_tail(&fixed_mode->head, &panel->fixed_modes);
if (downclock_mode)
list_add_tail(&downclock_mode->head, &panel->fixed_modes);
return 0; return 0;
} }
...@@ -618,13 +617,12 @@ void intel_panel_fini(struct intel_panel *panel) ...@@ -618,13 +617,12 @@ void intel_panel_fini(struct intel_panel *panel)
{ {
struct intel_connector *intel_connector = struct intel_connector *intel_connector =
container_of(panel, struct intel_connector, panel); container_of(panel, struct intel_connector, panel);
struct drm_display_mode *fixed_mode, *next;
intel_backlight_destroy(panel); intel_backlight_destroy(panel);
if (panel->fixed_mode) list_for_each_entry_safe(fixed_mode, next, &panel->fixed_modes, head) {
drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); list_del(&fixed_mode->head);
drm_mode_destroy(intel_connector->base.dev, fixed_mode);
if (panel->downclock_mode) }
drm_mode_destroy(intel_connector->base.dev,
panel->downclock_mode);
} }
...@@ -2747,6 +2747,8 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) ...@@ -2747,6 +2747,8 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
__drm_atomic_helper_connector_reset(&sdvo_connector->base.base, __drm_atomic_helper_connector_reset(&sdvo_connector->base.base,
&conn_state->base.base); &conn_state->base.base);
INIT_LIST_HEAD(&sdvo_connector->base.panel.fixed_modes);
return sdvo_connector; return sdvo_connector;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment