aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-03-22 19:34:08 -0400
committerDave Airlie <airlied@redhat.com>2015-03-22 19:34:08 -0400
commite8b6fe6990643daac9bccbe957a253a7e6bf947d (patch)
tree8a83f2b138db3d9c59aa04c7a9362afc9abd2106
parentb3ede177c8ba8c001c65aec1511445363642ecd0 (diff)
parentc6169e49bd37c9556efd7564bcbbf7067cd7efa8 (diff)
Merge branch 'drm/next/adv7511' of git://linuxtv.org/pinchartl/fbdev into drm-next
adv7511 fixes. * 'drm/next/adv7511' of git://linuxtv.org/pinchartl/fbdev: drm: adv7511: Refactor power management drm: adv7511: Fix nested sleep when reading EDID drm: adv7511: Fix DDC error interrupt handling
-rw-r--r--drivers/gpu/drm/i2c/adv7511.c197
1 files changed, 102 insertions, 95 deletions
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index 61aa824d45d2..b728523e194f 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -27,12 +27,13 @@ struct adv7511 {
27 struct regmap *regmap; 27 struct regmap *regmap;
28 struct regmap *packet_memory_regmap; 28 struct regmap *packet_memory_regmap;
29 enum drm_connector_status status; 29 enum drm_connector_status status;
30 int dpms_mode; 30 bool powered;
31 31
32 unsigned int f_tmds; 32 unsigned int f_tmds;
33 33
34 unsigned int current_edid_segment; 34 unsigned int current_edid_segment;
35 uint8_t edid_buf[256]; 35 uint8_t edid_buf[256];
36 bool edid_read;
36 37
37 wait_queue_head_t wq; 38 wait_queue_head_t wq;
38 struct drm_encoder *encoder; 39 struct drm_encoder *encoder;
@@ -357,6 +358,48 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
357 adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; 358 adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
358} 359}
359 360
361static void adv7511_power_on(struct adv7511 *adv7511)
362{
363 adv7511->current_edid_segment = -1;
364
365 regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
366 ADV7511_INT0_EDID_READY);
367 regmap_write(adv7511->regmap, ADV7511_REG_INT(1),
368 ADV7511_INT1_DDC_ERROR);
369 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
370 ADV7511_POWER_POWER_DOWN, 0);
371
372 /*
373 * Per spec it is allowed to pulse the HDP signal to indicate that the
374 * EDID information has changed. Some monitors do this when they wakeup
375 * from standby or are enabled. When the HDP goes low the adv7511 is
376 * reset and the outputs are disabled which might cause the monitor to
377 * go to standby again. To avoid this we ignore the HDP pin for the
378 * first few seconds after enabling the output.
379 */
380 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
381 ADV7511_REG_POWER2_HDP_SRC_MASK,
382 ADV7511_REG_POWER2_HDP_SRC_NONE);
383
384 /*
385 * Most of the registers are reset during power down or when HPD is low.
386 */
387 regcache_sync(adv7511->regmap);
388
389 adv7511->powered = true;
390}
391
392static void adv7511_power_off(struct adv7511 *adv7511)
393{
394 /* TODO: setup additional power down modes */
395 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
396 ADV7511_POWER_POWER_DOWN,
397 ADV7511_POWER_POWER_DOWN);
398 regcache_mark_dirty(adv7511->regmap);
399
400 adv7511->powered = false;
401}
402
360/* ----------------------------------------------------------------------------- 403/* -----------------------------------------------------------------------------
361 * Interrupt and hotplug detection 404 * Interrupt and hotplug detection
362 */ 405 */
@@ -379,69 +422,71 @@ static bool adv7511_hpd(struct adv7511 *adv7511)
379 return false; 422 return false;
380} 423}
381 424
382static irqreturn_t adv7511_irq_handler(int irq, void *devid) 425static int adv7511_irq_process(struct adv7511 *adv7511)
383{
384 struct adv7511 *adv7511 = devid;
385
386 if (adv7511_hpd(adv7511))
387 drm_helper_hpd_irq_event(adv7511->encoder->dev);
388
389 wake_up_all(&adv7511->wq);
390
391 return IRQ_HANDLED;
392}
393
394static unsigned int adv7511_is_interrupt_pending(struct adv7511 *adv7511,
395 unsigned int irq)
396{ 426{
397 unsigned int irq0, irq1; 427 unsigned int irq0, irq1;
398 unsigned int pending;
399 int ret; 428 int ret;
400 429
401 ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0); 430 ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);
402 if (ret < 0) 431 if (ret < 0)
403 return 0; 432 return ret;
433
404 ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1); 434 ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(1), &irq1);
405 if (ret < 0) 435 if (ret < 0)
406 return 0; 436 return ret;
407 437
408 pending = (irq1 << 8) | irq0; 438 regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
439 regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
409 440
410 return pending & irq; 441 if (irq0 & ADV7511_INT0_HDP)
442 drm_helper_hpd_irq_event(adv7511->encoder->dev);
443
444 if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
445 adv7511->edid_read = true;
446
447 if (adv7511->i2c_main->irq)
448 wake_up_all(&adv7511->wq);
449 }
450
451 return 0;
411} 452}
412 453
413static int adv7511_wait_for_interrupt(struct adv7511 *adv7511, int irq, 454static irqreturn_t adv7511_irq_handler(int irq, void *devid)
414 int timeout) 455{
456 struct adv7511 *adv7511 = devid;
457 int ret;
458
459 ret = adv7511_irq_process(adv7511);
460 return ret < 0 ? IRQ_NONE : IRQ_HANDLED;
461}
462
463/* -----------------------------------------------------------------------------
464 * EDID retrieval
465 */
466
467static int adv7511_wait_for_edid(struct adv7511 *adv7511, int timeout)
415{ 468{
416 unsigned int pending;
417 int ret; 469 int ret;
418 470
419 if (adv7511->i2c_main->irq) { 471 if (adv7511->i2c_main->irq) {
420 ret = wait_event_interruptible_timeout(adv7511->wq, 472 ret = wait_event_interruptible_timeout(adv7511->wq,
421 adv7511_is_interrupt_pending(adv7511, irq), 473 adv7511->edid_read, msecs_to_jiffies(timeout));
422 msecs_to_jiffies(timeout));
423 if (ret <= 0)
424 return 0;
425 pending = adv7511_is_interrupt_pending(adv7511, irq);
426 } else { 474 } else {
427 if (timeout < 25) 475 for (; timeout > 0; timeout -= 25) {
428 timeout = 25; 476 ret = adv7511_irq_process(adv7511);
429 do { 477 if (ret < 0)
430 pending = adv7511_is_interrupt_pending(adv7511, irq);
431 if (pending)
432 break; 478 break;
479
480 if (adv7511->edid_read)
481 break;
482
433 msleep(25); 483 msleep(25);
434 timeout -= 25; 484 }
435 } while (timeout >= 25);
436 } 485 }
437 486
438 return pending; 487 return adv7511->edid_read ? 0 : -EIO;
439} 488}
440 489
441/* -----------------------------------------------------------------------------
442 * EDID retrieval
443 */
444
445static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, 490static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
446 size_t len) 491 size_t len)
447{ 492{
@@ -463,19 +508,14 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
463 return ret; 508 return ret;
464 509
465 if (status != 2) { 510 if (status != 2) {
511 adv7511->edid_read = false;
466 regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT, 512 regmap_write(adv7511->regmap, ADV7511_REG_EDID_SEGMENT,
467 block); 513 block);
468 ret = adv7511_wait_for_interrupt(adv7511, 514 ret = adv7511_wait_for_edid(adv7511, 200);
469 ADV7511_INT0_EDID_READY | 515 if (ret < 0)
470 ADV7511_INT1_DDC_ERROR, 200); 516 return ret;
471
472 if (!(ret & ADV7511_INT0_EDID_READY))
473 return -EIO;
474 } 517 }
475 518
476 regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
477 ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR);
478
479 /* Break this apart, hopefully more I2C controllers will 519 /* Break this apart, hopefully more I2C controllers will
480 * support 64 byte transfers than 256 byte transfers 520 * support 64 byte transfers than 256 byte transfers
481 */ 521 */
@@ -526,9 +566,11 @@ static int adv7511_get_modes(struct drm_encoder *encoder,
526 unsigned int count; 566 unsigned int count;
527 567
528 /* Reading the EDID only works if the device is powered */ 568 /* Reading the EDID only works if the device is powered */
529 if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) { 569 if (!adv7511->powered) {
530 regmap_write(adv7511->regmap, ADV7511_REG_INT(0), 570 regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
531 ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR); 571 ADV7511_INT0_EDID_READY);
572 regmap_write(adv7511->regmap, ADV7511_REG_INT(1),
573 ADV7511_INT1_DDC_ERROR);
532 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, 574 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
533 ADV7511_POWER_POWER_DOWN, 0); 575 ADV7511_POWER_POWER_DOWN, 0);
534 adv7511->current_edid_segment = -1; 576 adv7511->current_edid_segment = -1;
@@ -536,7 +578,7 @@ static int adv7511_get_modes(struct drm_encoder *encoder,
536 578
537 edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511); 579 edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
538 580
539 if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) 581 if (!adv7511->powered)
540 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, 582 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
541 ADV7511_POWER_POWER_DOWN, 583 ADV7511_POWER_POWER_DOWN,
542 ADV7511_POWER_POWER_DOWN); 584 ADV7511_POWER_POWER_DOWN);
@@ -558,41 +600,10 @@ static void adv7511_encoder_dpms(struct drm_encoder *encoder, int mode)
558{ 600{
559 struct adv7511 *adv7511 = encoder_to_adv7511(encoder); 601 struct adv7511 *adv7511 = encoder_to_adv7511(encoder);
560 602
561 switch (mode) { 603 if (mode == DRM_MODE_DPMS_ON)
562 case DRM_MODE_DPMS_ON: 604 adv7511_power_on(adv7511);
563 adv7511->current_edid_segment = -1; 605 else
564 606 adv7511_power_off(adv7511);
565 regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
566 ADV7511_INT0_EDID_READY | ADV7511_INT1_DDC_ERROR);
567 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
568 ADV7511_POWER_POWER_DOWN, 0);
569 /*
570 * Per spec it is allowed to pulse the HDP signal to indicate
571 * that the EDID information has changed. Some monitors do this
572 * when they wakeup from standby or are enabled. When the HDP
573 * goes low the adv7511 is reset and the outputs are disabled
574 * which might cause the monitor to go to standby again. To
575 * avoid this we ignore the HDP pin for the first few seconds
576 * after enabling the output.
577 */
578 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
579 ADV7511_REG_POWER2_HDP_SRC_MASK,
580 ADV7511_REG_POWER2_HDP_SRC_NONE);
581 /* Most of the registers are reset during power down or
582 * when HPD is low
583 */
584 regcache_sync(adv7511->regmap);
585 break;
586 default:
587 /* TODO: setup additional power down modes */
588 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
589 ADV7511_POWER_POWER_DOWN,
590 ADV7511_POWER_POWER_DOWN);
591 regcache_mark_dirty(adv7511->regmap);
592 break;
593 }
594
595 adv7511->dpms_mode = mode;
596} 607}
597 608
598static enum drm_connector_status 609static enum drm_connector_status
@@ -620,10 +631,9 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
620 * there is a pending HPD interrupt and the cable is connected there was 631 * there is a pending HPD interrupt and the cable is connected there was
621 * at least one transition from disconnected to connected and the chip 632 * at least one transition from disconnected to connected and the chip
622 * has to be reinitialized. */ 633 * has to be reinitialized. */
623 if (status == connector_status_connected && hpd && 634 if (status == connector_status_connected && hpd && adv7511->powered) {
624 adv7511->dpms_mode == DRM_MODE_DPMS_ON) {
625 regcache_mark_dirty(adv7511->regmap); 635 regcache_mark_dirty(adv7511->regmap);
626 adv7511_encoder_dpms(encoder, adv7511->dpms_mode); 636 adv7511_power_on(adv7511);
627 adv7511_get_modes(encoder, connector); 637 adv7511_get_modes(encoder, connector);
628 if (adv7511->status == connector_status_connected) 638 if (adv7511->status == connector_status_connected)
629 status = connector_status_disconnected; 639 status = connector_status_disconnected;
@@ -858,7 +868,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
858 if (!adv7511) 868 if (!adv7511)
859 return -ENOMEM; 869 return -ENOMEM;
860 870
861 adv7511->dpms_mode = DRM_MODE_DPMS_OFF; 871 adv7511->powered = false;
862 adv7511->status = connector_status_disconnected; 872 adv7511->status = connector_status_disconnected;
863 873
864 ret = adv7511_parse_dt(dev->of_node, &link_config); 874 ret = adv7511_parse_dt(dev->of_node, &link_config);
@@ -918,10 +928,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
918 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 928 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
919 ADV7511_CEC_CTRL_POWER_DOWN); 929 ADV7511_CEC_CTRL_POWER_DOWN);
920 930
921 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, 931 adv7511_power_off(adv7511);
922 ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN);
923
924 adv7511->current_edid_segment = -1;
925 932
926 i2c_set_clientdata(i2c, adv7511); 933 i2c_set_clientdata(i2c, adv7511);
927 934