/[pkgs]/rpms/kernel/F-10/drm-connector-dpms-fix.patch
ViewVC logotype

Contents of /rpms/kernel/F-10/drm-connector-dpms-fix.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Mon Jul 6 22:57:28 2009 UTC (4 months, 2 weeks ago) by cebbert
Branch: MAIN
CVS Tags: kernel-2_6_29_6-97_fc10, kernel-2_6_29_6-99_fc10, kernel-2_6_29_6-93_fc10, HEAD
File MIME type: text/x-patch
From F-11 Jun 15 DRM fixes:
    drm-connector-dpms-fix.patch
    drm-radeon-cs-oops-fix.patch
    drm-radeon-fix-ring-commit.patch
1 commit c9fb15f60eb517c958dec64dca9357bf62bf2201
2 Author: Keith Packard <keithp@keithp.com>
3 Date: Sat May 30 20:42:28 2009 -0700
4
5 drm: Hook up DPMS property handling in drm_crtc.c. Add drm_helper_connector_dpms.
6
7 Making the drm_crtc.c code recognize the DPMS property and invoke the
8 connector->dpms function doesn't remove any capability from the driver while
9 reducing code duplication.
10
11 That just highlighted the problem with the existing DPMS functions which
12 could turn off the connector, but failed to turn off any relevant crtcs. The
13 new drm_helper_connector_dpms function manages all of that, using the
14 drm_helper-specific crtc and encoder dpms functions, automatically computing
15 the appropriate DPMS level for each object in the system.
16
17 This fixes the current troubles in the i915 driver which left PLLs, pipes
18 and planes running while in DPMS_OFF mode or even while they were unused.
19
20 Signed-off-by: Keith Packard <keithp@keithp.com>
21 Signed-off-by: Dave Airlie <airlied@redhat.com>
22
23 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
24 index 94a7688..8fab789 100644
25 --- a/drivers/gpu/drm/drm_crtc.c
26 +++ b/drivers/gpu/drm/drm_crtc.c
27 @@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
28 }
29 }
30
31 - if (connector->funcs->set_property)
32 + /* Do DPMS ourselves */
33 + if (property == connector->dev->mode_config.dpms_property) {
34 + if (connector->funcs->dpms)
35 + (*connector->funcs->dpms)(connector, (int) out_resp->value);
36 + ret = 0;
37 + } else if (connector->funcs->set_property)
38 ret = connector->funcs->set_property(connector, property, out_resp->value);
39
40 /* store the property value if succesful */
41 diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
42 index 4589044..a6f73f1 100644
43 --- a/drivers/gpu/drm/drm_crtc_helper.c
44 +++ b/drivers/gpu/drm/drm_crtc_helper.c
45 @@ -199,6 +199,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev,
46 }
47
48 /**
49 + * drm_helper_encoder_in_use - check if a given encoder is in use
50 + * @encoder: encoder to check
51 + *
52 + * LOCKING:
53 + * Caller must hold mode config lock.
54 + *
55 + * Walk @encoders's DRM device's mode_config and see if it's in use.
56 + *
57 + * RETURNS:
58 + * True if @encoder is part of the mode_config, false otherwise.
59 + */
60 +bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
61 +{
62 + struct drm_connector *connector;
63 + struct drm_device *dev = encoder->dev;
64 + list_for_each_entry(connector, &dev->mode_config.connector_list, head)
65 + if (connector->encoder == encoder)
66 + return true;
67 + return false;
68 +}
69 +EXPORT_SYMBOL(drm_helper_encoder_in_use);
70 +
71 +/**
72 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
73 * @crtc: CRTC to check
74 *
75 @@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
76 struct drm_device *dev = crtc->dev;
77 /* FIXME: Locking around list access? */
78 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
79 - if (encoder->crtc == crtc)
80 + if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
81 return true;
82 return false;
83 }
84 @@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
85
86 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
87 encoder_funcs = encoder->helper_private;
88 - if (!encoder->crtc)
89 + if (!drm_helper_encoder_in_use(encoder))
90 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
91 }
92
93 @@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev)
94 }
95 EXPORT_SYMBOL(drm_helper_initial_config);
96
97 +static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
98 +{
99 + int dpms = DRM_MODE_DPMS_OFF;
100 + struct drm_connector *connector;
101 + struct drm_device *dev = encoder->dev;
102 +
103 + list_for_each_entry(connector, &dev->mode_config.connector_list, head)
104 + if (connector->encoder == encoder)
105 + if (connector->dpms < dpms)
106 + dpms = connector->dpms;
107 + return dpms;
108 +}
109 +
110 +static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
111 +{
112 + int dpms = DRM_MODE_DPMS_OFF;
113 + struct drm_connector *connector;
114 + struct drm_device *dev = crtc->dev;
115 +
116 + list_for_each_entry(connector, &dev->mode_config.connector_list, head)
117 + if (connector->encoder && connector->encoder->crtc == crtc)
118 + if (connector->dpms < dpms)
119 + dpms = connector->dpms;
120 + return dpms;
121 +}
122 +
123 +/**
124 + * drm_helper_connector_dpms
125 + * @connector affected connector
126 + * @mode DPMS mode
127 + *
128 + * Calls the low-level connector DPMS function, then
129 + * calls appropriate encoder and crtc DPMS functions as well
130 + */
131 +void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
132 +{
133 + struct drm_encoder *encoder = connector->encoder;
134 + struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
135 + int old_dpms;
136 +
137 + if (mode == connector->dpms)
138 + return;
139 +
140 + old_dpms = connector->dpms;
141 + connector->dpms = mode;
142 +
143 + /* from off to on, do crtc then encoder */
144 + if (mode < old_dpms) {
145 + if (crtc) {
146 + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
147 + if (crtc_funcs->dpms)
148 + (*crtc_funcs->dpms) (crtc,
149 + drm_helper_choose_crtc_dpms(crtc));
150 + }
151 + if (encoder) {
152 + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
153 + if (encoder_funcs->dpms)
154 + (*encoder_funcs->dpms) (encoder,
155 + drm_helper_choose_encoder_dpms(encoder));
156 + }
157 + }
158 +
159 + /* from on to off, do encoder then crtc */
160 + if (mode > old_dpms) {
161 + if (encoder) {
162 + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
163 + if (encoder_funcs->dpms)
164 + (*encoder_funcs->dpms) (encoder,
165 + drm_helper_choose_encoder_dpms(encoder));
166 + }
167 + if (crtc) {
168 + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
169 + if (crtc_funcs->dpms)
170 + (*crtc_funcs->dpms) (crtc,
171 + drm_helper_choose_crtc_dpms(crtc));
172 + }
173 + }
174 +
175 + return;
176 +}
177 +EXPORT_SYMBOL(drm_helper_connector_dpms);
178 +
179 /**
180 * drm_hotplug_stage_two
181 * @dev DRM device
182 diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
183 index 640f515..79acc4f 100644
184 --- a/drivers/gpu/drm/i915/intel_crt.c
185 +++ b/drivers/gpu/drm/i915/intel_crt.c
186 @@ -381,11 +381,6 @@ static int intel_crt_set_property(struct drm_connector *connector,
187 struct drm_property *property,
188 uint64_t value)
189 {
190 - struct drm_device *dev = connector->dev;
191 -
192 - if (property == dev->mode_config.dpms_property && connector->encoder)
193 - intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));
194 -
195 return 0;
196 }
197
198 @@ -402,6 +397,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
199 };
200
201 static const struct drm_connector_funcs intel_crt_connector_funcs = {
202 + .dpms = drm_helper_connector_dpms,
203 .detect = intel_crt_detect,
204 .fill_modes = drm_helper_probe_single_connector_modes,
205 .destroy = intel_crt_destroy,
206 diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
207 index 8b8d6e6..1ee3007 100644
208 --- a/drivers/gpu/drm/i915/intel_dvo.c
209 +++ b/drivers/gpu/drm/i915/intel_dvo.c
210 @@ -316,6 +316,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
211 };
212
213 static const struct drm_connector_funcs intel_dvo_connector_funcs = {
214 + .dpms = drm_helper_connector_dpms,
215 .save = intel_dvo_save,
216 .restore = intel_dvo_restore,
217 .detect = intel_dvo_detect,
218 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
219 index d0983bb..7d6bdd7 100644
220 --- a/drivers/gpu/drm/i915/intel_hdmi.c
221 +++ b/drivers/gpu/drm/i915/intel_hdmi.c
222 @@ -219,6 +219,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
223 };
224
225 static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
226 + .dpms = drm_helper_connector_dpms,
227 .save = intel_hdmi_save,
228 .restore = intel_hdmi_restore,
229 .detect = intel_hdmi_detect,
230 diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
231 index 53731f0..c92a64a 100644
232 --- a/drivers/gpu/drm/i915/intel_lvds.c
233 +++ b/drivers/gpu/drm/i915/intel_lvds.c
234 @@ -343,11 +343,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
235 struct drm_property *property,
236 uint64_t value)
237 {
238 - struct drm_device *dev = connector->dev;
239 -
240 - if (property == dev->mode_config.dpms_property && connector->encoder)
241 - intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
242 -
243 return 0;
244 }
245
246 @@ -366,6 +361,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
247 };
248
249 static const struct drm_connector_funcs intel_lvds_connector_funcs = {
250 + .dpms = drm_helper_connector_dpms,
251 .save = intel_lvds_save,
252 .restore = intel_lvds_restore,
253 .detect = intel_lvds_detect,
254 diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
255 index f3ef6bf..3093b4d 100644
256 --- a/drivers/gpu/drm/i915/intel_sdvo.c
257 +++ b/drivers/gpu/drm/i915/intel_sdvo.c
258 @@ -1616,6 +1616,7 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
259 };
260
261 static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
262 + .dpms = drm_helper_connector_dpms,
263 .save = intel_sdvo_save,
264 .restore = intel_sdvo_restore,
265 .detect = intel_sdvo_detect,
266 diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
267 index d2c3298..98ac054 100644
268 --- a/drivers/gpu/drm/i915/intel_tv.c
269 +++ b/drivers/gpu/drm/i915/intel_tv.c
270 @@ -1626,6 +1626,7 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
271 };
272
273 static const struct drm_connector_funcs intel_tv_connector_funcs = {
274 + .dpms = drm_helper_connector_dpms,
275 .save = intel_tv_save,
276 .restore = intel_tv_restore,
277 .detect = intel_tv_detect,
278 diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
279 index 3c1924c..7300fb8 100644
280 --- a/include/drm/drm_crtc.h
281 +++ b/include/drm/drm_crtc.h
282 @@ -471,6 +471,9 @@ struct drm_connector {
283 u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
284 uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
285
286 + /* requested DPMS state */
287 + int dpms;
288 +
289 void *helper_private;
290
291 uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
292 diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
293 index ec073d8..6769ff6 100644
294 --- a/include/drm/drm_crtc_helper.h
295 +++ b/include/drm/drm_crtc_helper.h
296 @@ -99,6 +99,8 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
297 struct drm_framebuffer *old_fb);
298 extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
299
300 +extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
301 +
302 extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
303 struct drm_mode_fb_cmd *mode_cmd);
304

admin@fedoraproject.org
ViewVC Help
Powered by ViewVC 1.1.2