summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_panel.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2022-03-14 17:27:37 +0200
committerVille Syrjälä <ville.syrjala@linux.intel.com>2022-03-15 00:16:58 +0200
commit345b7c4b86884cf413735be3edc8e28d0d494916 (patch)
tree9a5c7b2db22269b6deb9271793103ae189218419 /drivers/gpu/drm/i915/display/intel_panel.c
parentc5ee23437cae2cffadc1a96ebd444ae2504e0408 (diff)
downloadlinux-345b7c4b86884cf413735be3edc8e28d0d494916.tar.gz
linux-345b7c4b86884cf413735be3edc8e28d0d494916.tar.bz2
linux-345b7c4b86884cf413735be3edc8e28d0d494916.zip
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: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220314152737.9125-1-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_panel.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_panel.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 08a0612edd60..f428d0457c17 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -48,59 +48,55 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915)
const struct drm_display_mode *
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 *
intel_panel_fixed_mode(struct intel_connector *connector,
const struct drm_display_mode *mode)
{
- const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode;
- const struct drm_display_mode *downclock_mode = connector->panel.downclock_mode;
-
- /* pick the one that is closer in terms of vrefresh */
- /* FIXME make this a a list of modes so we can have more than two */
- if (fixed_mode && downclock_mode &&
- abs(drm_mode_vrefresh(downclock_mode) - drm_mode_vrefresh(mode)) <
- abs(drm_mode_vrefresh(fixed_mode) - drm_mode_vrefresh(mode)))
- return downclock_mode;
- else
- return fixed_mode;
+ const struct drm_display_mode *fixed_mode, *best_mode = NULL;
+ int vrefresh = drm_mode_vrefresh(mode);
+
+ /* pick the fixed_mode that is closest in terms of vrefresh */
+ list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
+ if (!best_mode ||
+ abs(drm_mode_vrefresh(fixed_mode) - vrefresh) <
+ abs(drm_mode_vrefresh(best_mode) - vrefresh))
+ best_mode = fixed_mode;
+ }
+
+ return best_mode;
}
const struct drm_display_mode *
intel_panel_downclock_mode(struct intel_connector *connector,
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 &&
- drm_mode_vrefresh(downclock_mode) < drm_mode_vrefresh(adjusted_mode))
- return downclock_mode;
- else
- return NULL;
+ return best_mode;
}
int intel_panel_get_modes(struct intel_connector *connector)
{
+ const struct drm_display_mode *fixed_mode;
int num_modes = 0;
- if (connector->panel.fixed_mode) {
- 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) {
+ 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.downclock_mode);
+ mode = drm_mode_duplicate(connector->base.dev, fixed_mode);
if (mode) {
drm_mode_probed_add(&connector->base, mode);
num_modes++;
@@ -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);
- if (!connector->panel.downclock_mode)
+ if (list_empty(&connector->panel.fixed_modes) ||
+ list_is_singular(&connector->panel.fixed_modes))
return DRRS_TYPE_NONE;
return i915->vbt.drrs_type;
@@ -608,8 +605,10 @@ int intel_panel_init(struct intel_panel *panel,
{
intel_backlight_init_funcs(panel);
- panel->fixed_mode = fixed_mode;
- panel->downclock_mode = downclock_mode;
+ if (fixed_mode)
+ list_add_tail(&fixed_mode->head, &panel->fixed_modes);
+ if (downclock_mode)
+ list_add_tail(&downclock_mode->head, &panel->fixed_modes);
return 0;
}
@@ -618,13 +617,12 @@ void intel_panel_fini(struct intel_panel *panel)
{
struct intel_connector *intel_connector =
container_of(panel, struct intel_connector, panel);
+ struct drm_display_mode *fixed_mode, *next;
intel_backlight_destroy(panel);
- if (panel->fixed_mode)
- drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
-
- if (panel->downclock_mode)
- drm_mode_destroy(intel_connector->base.dev,
- panel->downclock_mode);
+ list_for_each_entry_safe(fixed_mode, next, &panel->fixed_modes, head) {
+ list_del(&fixed_mode->head);
+ drm_mode_destroy(intel_connector->base.dev, fixed_mode);
+ }
}