@@ -48,59 +48,55 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915)
48
48
const struct drm_display_mode *
49
49
intel_panel_preferred_fixed_mode (struct intel_connector * connector )
50
50
{
51
- return connector -> panel .fixed_mode ;
51
+ return list_first_entry_or_null (& connector -> panel .fixed_modes ,
52
+ struct drm_display_mode , head );
52
53
}
53
54
54
55
const struct drm_display_mode *
55
56
intel_panel_fixed_mode (struct intel_connector * connector ,
56
57
const struct drm_display_mode * mode )
57
58
{
58
- const struct drm_display_mode * fixed_mode = connector -> panel .fixed_mode ;
59
- const struct drm_display_mode * downclock_mode = connector -> panel .downclock_mode ;
60
-
61
- /* pick the one that is closer in terms of vrefresh */
62
- /* FIXME make this a a list of modes so we can have more than two */
63
- if (fixed_mode && downclock_mode &&
64
- abs (drm_mode_vrefresh (downclock_mode ) - drm_mode_vrefresh (mode )) <
65
- abs (drm_mode_vrefresh (fixed_mode ) - drm_mode_vrefresh (mode )))
66
- return downclock_mode ;
67
- else
68
- return fixed_mode ;
59
+ const struct drm_display_mode * fixed_mode , * best_mode = NULL ;
60
+ int vrefresh = drm_mode_vrefresh (mode );
61
+
62
+ /* pick the fixed_mode that is closest in terms of vrefresh */
63
+ list_for_each_entry (fixed_mode , & connector -> panel .fixed_modes , head ) {
64
+ if (!best_mode ||
65
+ abs (drm_mode_vrefresh (fixed_mode ) - vrefresh ) <
66
+ abs (drm_mode_vrefresh (best_mode ) - vrefresh ))
67
+ best_mode = fixed_mode ;
68
+ }
69
+
70
+ return best_mode ;
69
71
}
70
72
71
73
const struct drm_display_mode *
72
74
intel_panel_downclock_mode (struct intel_connector * connector ,
73
75
const struct drm_display_mode * adjusted_mode )
74
76
{
75
- const struct drm_display_mode * downclock_mode = connector -> panel .downclock_mode ;
77
+ const struct drm_display_mode * fixed_mode , * best_mode = NULL ;
78
+ int vrefresh = drm_mode_vrefresh (adjusted_mode );
79
+
80
+ /* pick the fixed_mode with the lowest refresh rate */
81
+ list_for_each_entry (fixed_mode , & connector -> panel .fixed_modes , head ) {
82
+ if (drm_mode_vrefresh (fixed_mode ) < vrefresh ) {
83
+ vrefresh = drm_mode_vrefresh (fixed_mode );
84
+ best_mode = fixed_mode ;
85
+ }
86
+ }
76
87
77
- if (downclock_mode &&
78
- drm_mode_vrefresh (downclock_mode ) < drm_mode_vrefresh (adjusted_mode ))
79
- return downclock_mode ;
80
- else
81
- return NULL ;
88
+ return best_mode ;
82
89
}
83
90
84
91
int intel_panel_get_modes (struct intel_connector * connector )
85
92
{
93
+ const struct drm_display_mode * fixed_mode ;
86
94
int num_modes = 0 ;
87
95
88
- if (connector -> panel .fixed_mode ) {
89
- struct drm_display_mode * mode ;
90
-
91
- mode = drm_mode_duplicate (connector -> base .dev ,
92
- connector -> panel .fixed_mode );
93
- if (mode ) {
94
- drm_mode_probed_add (& connector -> base , mode );
95
- num_modes ++ ;
96
- }
97
- }
98
-
99
- if (connector -> panel .downclock_mode ) {
96
+ list_for_each_entry (fixed_mode , & connector -> panel .fixed_modes , head ) {
100
97
struct drm_display_mode * mode ;
101
98
102
- mode = drm_mode_duplicate (connector -> base .dev ,
103
- connector -> panel .downclock_mode );
99
+ mode = drm_mode_duplicate (connector -> base .dev , fixed_mode );
104
100
if (mode ) {
105
101
drm_mode_probed_add (& connector -> base , mode );
106
102
num_modes ++ ;
@@ -114,7 +110,8 @@ enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
114
110
{
115
111
struct drm_i915_private * i915 = to_i915 (connector -> base .dev );
116
112
117
- if (!connector -> panel .downclock_mode )
113
+ if (list_empty (& connector -> panel .fixed_modes ) ||
114
+ list_is_singular (& connector -> panel .fixed_modes ))
118
115
return DRRS_TYPE_NONE ;
119
116
120
117
return i915 -> vbt .drrs_type ;
@@ -608,8 +605,10 @@ int intel_panel_init(struct intel_panel *panel,
608
605
{
609
606
intel_backlight_init_funcs (panel );
610
607
611
- panel -> fixed_mode = fixed_mode ;
612
- panel -> downclock_mode = downclock_mode ;
608
+ if (fixed_mode )
609
+ list_add_tail (& fixed_mode -> head , & panel -> fixed_modes );
610
+ if (downclock_mode )
611
+ list_add_tail (& downclock_mode -> head , & panel -> fixed_modes );
613
612
614
613
return 0 ;
615
614
}
@@ -618,13 +617,12 @@ void intel_panel_fini(struct intel_panel *panel)
618
617
{
619
618
struct intel_connector * intel_connector =
620
619
container_of (panel , struct intel_connector , panel );
620
+ struct drm_display_mode * fixed_mode , * next ;
621
621
622
622
intel_backlight_destroy (panel );
623
623
624
- if (panel -> fixed_mode )
625
- drm_mode_destroy (intel_connector -> base .dev , panel -> fixed_mode );
626
-
627
- if (panel -> downclock_mode )
628
- drm_mode_destroy (intel_connector -> base .dev ,
629
- panel -> downclock_mode );
624
+ list_for_each_entry_safe (fixed_mode , next , & panel -> fixed_modes , head ) {
625
+ list_del (& fixed_mode -> head );
626
+ drm_mode_destroy (intel_connector -> base .dev , fixed_mode );
627
+ }
630
628
}
0 commit comments