aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c88
1 files changed, 15 insertions, 73 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index aada26f63dec..7740dd26f007 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; 306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
307#endif 307#endif
308 308
309static void drm_fb_helper_on(struct fb_info *info) 309static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
310{ 310{
311 struct drm_fb_helper *fb_helper = info->par; 311 struct drm_fb_helper *fb_helper = info->par;
312 struct drm_device *dev = fb_helper->dev; 312 struct drm_device *dev = fb_helper->dev;
313 struct drm_crtc *crtc; 313 struct drm_crtc *crtc;
314 struct drm_crtc_helper_funcs *crtc_funcs;
315 struct drm_connector *connector;
316 struct drm_encoder *encoder;
317 int i, j;
318
319 /*
320 * For each CRTC in this fb, turn the crtc on then,
321 * find all associated encoders and turn them on.
322 */
323 mutex_lock(&dev->mode_config.mutex);
324 for (i = 0; i < fb_helper->crtc_count; i++) {
325 crtc = fb_helper->crtc_info[i].mode_set.crtc;
326 crtc_funcs = crtc->helper_private;
327
328 if (!crtc->enabled)
329 continue;
330
331 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
332
333 /* Walk the connectors & encoders on this fb turning them on */
334 for (j = 0; j < fb_helper->connector_count; j++) {
335 connector = fb_helper->connector_info[j]->connector;
336 connector->dpms = DRM_MODE_DPMS_ON;
337 drm_connector_property_set_value(connector,
338 dev->mode_config.dpms_property,
339 DRM_MODE_DPMS_ON);
340 }
341 /* Found a CRTC on this fb, now find encoders */
342 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
343 if (encoder->crtc == crtc) {
344 struct drm_encoder_helper_funcs *encoder_funcs;
345
346 encoder_funcs = encoder->helper_private;
347 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
348 }
349 }
350 }
351 mutex_unlock(&dev->mode_config.mutex);
352}
353
354static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
355{
356 struct drm_fb_helper *fb_helper = info->par;
357 struct drm_device *dev = fb_helper->dev;
358 struct drm_crtc *crtc;
359 struct drm_crtc_helper_funcs *crtc_funcs;
360 struct drm_connector *connector; 314 struct drm_connector *connector;
361 struct drm_encoder *encoder;
362 int i, j; 315 int i, j;
363 316
364 /* 317 /*
365 * For each CRTC in this fb, find all associated encoders 318 * For each CRTC in this fb, turn the connectors on/off.
366 * and turn them off, then turn off the CRTC.
367 */ 319 */
368 mutex_lock(&dev->mode_config.mutex); 320 mutex_lock(&dev->mode_config.mutex);
369 for (i = 0; i < fb_helper->crtc_count; i++) { 321 for (i = 0; i < fb_helper->crtc_count; i++) {
370 crtc = fb_helper->crtc_info[i].mode_set.crtc; 322 crtc = fb_helper->crtc_info[i].mode_set.crtc;
371 crtc_funcs = crtc->helper_private;
372 323
373 if (!crtc->enabled) 324 if (!crtc->enabled)
374 continue; 325 continue;
375 326
376 /* Walk the connectors on this fb and mark them off */ 327 /* Walk the connectors & encoders on this fb turning them on/off */
377 for (j = 0; j < fb_helper->connector_count; j++) { 328 for (j = 0; j < fb_helper->connector_count; j++) {
378 connector = fb_helper->connector_info[j]->connector; 329 connector = fb_helper->connector_info[j]->connector;
379 connector->dpms = dpms_mode; 330 drm_helper_connector_dpms(connector, dpms_mode);
380 drm_connector_property_set_value(connector, 331 drm_connector_property_set_value(connector,
381 dev->mode_config.dpms_property, 332 dev->mode_config.dpms_property, dpms_mode);
382 dpms_mode);
383 }
384 /* Found a CRTC on this fb, now find encoders */
385 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
386 if (encoder->crtc == crtc) {
387 struct drm_encoder_helper_funcs *encoder_funcs;
388
389 encoder_funcs = encoder->helper_private;
390 encoder_funcs->dpms(encoder, dpms_mode);
391 }
392 } 333 }
393 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
394 } 334 }
395 mutex_unlock(&dev->mode_config.mutex); 335 mutex_unlock(&dev->mode_config.mutex);
396} 336}
@@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
400 switch (blank) { 340 switch (blank) {
401 /* Display: On; HSync: On, VSync: On */ 341 /* Display: On; HSync: On, VSync: On */
402 case FB_BLANK_UNBLANK: 342 case FB_BLANK_UNBLANK:
403 drm_fb_helper_on(info); 343 drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
404 break; 344 break;
405 /* Display: Off; HSync: On, VSync: On */ 345 /* Display: Off; HSync: On, VSync: On */
406 case FB_BLANK_NORMAL: 346 case FB_BLANK_NORMAL:
407 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 347 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
408 break; 348 break;
409 /* Display: Off; HSync: Off, VSync: On */ 349 /* Display: Off; HSync: Off, VSync: On */
410 case FB_BLANK_HSYNC_SUSPEND: 350 case FB_BLANK_HSYNC_SUSPEND:
411 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 351 drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
412 break; 352 break;
413 /* Display: Off; HSync: On, VSync: Off */ 353 /* Display: Off; HSync: On, VSync: Off */
414 case FB_BLANK_VSYNC_SUSPEND: 354 case FB_BLANK_VSYNC_SUSPEND:
415 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); 355 drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
416 break; 356 break;
417 /* Display: Off; HSync: Off, VSync: Off */ 357 /* Display: Off; HSync: Off, VSync: Off */
418 case FB_BLANK_POWERDOWN: 358 case FB_BLANK_POWERDOWN:
419 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); 359 drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
420 break; 360 break;
421 } 361 }
422 return 0; 362 return 0;
@@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
430 for (i = 0; i < helper->connector_count; i++) 370 for (i = 0; i < helper->connector_count; i++)
431 kfree(helper->connector_info[i]); 371 kfree(helper->connector_info[i]);
432 kfree(helper->connector_info); 372 kfree(helper->connector_info);
433 for (i = 0; i < helper->crtc_count; i++) 373 for (i = 0; i < helper->crtc_count; i++) {
434 kfree(helper->crtc_info[i].mode_set.connectors); 374 kfree(helper->crtc_info[i].mode_set.connectors);
375 if (helper->crtc_info[i].mode_set.mode)
376 drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
377 }
435 kfree(helper->crtc_info); 378 kfree(helper->crtc_info);
436} 379}
437 380
@@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,
474 417
475 i = 0; 418 i = 0;
476 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 419 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
477 fb_helper->crtc_info[i].crtc_id = crtc->base.id;
478 fb_helper->crtc_info[i].mode_set.crtc = crtc; 420 fb_helper->crtc_info[i].mode_set.crtc = crtc;
479 i++; 421 i++;
480 } 422 }
481 fb_helper->conn_limit = max_conn_count; 423
482 return 0; 424 return 0;
483out_free: 425out_free:
484 drm_fb_helper_crtc_free(fb_helper); 426 drm_fb_helper_crtc_free(fb_helper);