aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i2c/adv7511.c101
1 files changed, 53 insertions, 48 deletions
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index 828b60185016..b728523e194f 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -27,7 +27,7 @@ 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
@@ -358,6 +358,48 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
358 adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; 358 adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
359} 359}
360 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
361/* ----------------------------------------------------------------------------- 403/* -----------------------------------------------------------------------------
362 * Interrupt and hotplug detection 404 * Interrupt and hotplug detection
363 */ 405 */
@@ -524,7 +566,7 @@ static int adv7511_get_modes(struct drm_encoder *encoder,
524 unsigned int count; 566 unsigned int count;
525 567
526 /* Reading the EDID only works if the device is powered */ 568 /* Reading the EDID only works if the device is powered */
527 if (adv7511->dpms_mode != DRM_MODE_DPMS_ON) { 569 if (!adv7511->powered) {
528 regmap_write(adv7511->regmap, ADV7511_REG_INT(0), 570 regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
529 ADV7511_INT0_EDID_READY); 571 ADV7511_INT0_EDID_READY);
530 regmap_write(adv7511->regmap, ADV7511_REG_INT(1), 572 regmap_write(adv7511->regmap, ADV7511_REG_INT(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,43 +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);
567 regmap_write(adv7511->regmap, ADV7511_REG_INT(1),
568 ADV7511_INT1_DDC_ERROR);
569 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
570 ADV7511_POWER_POWER_DOWN, 0);
571 /*
572 * Per spec it is allowed to pulse the HDP signal to indicate
573 * that the EDID information has changed. Some monitors do this
574 * when they wakeup from standby or are enabled. When the HDP
575 * goes low the adv7511 is reset and the outputs are disabled
576 * which might cause the monitor to go to standby again. To
577 * avoid this we ignore the HDP pin for the first few seconds
578 * after enabling the output.
579 */
580 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
581 ADV7511_REG_POWER2_HDP_SRC_MASK,
582 ADV7511_REG_POWER2_HDP_SRC_NONE);
583 /* Most of the registers are reset during power down or
584 * when HPD is low
585 */
586 regcache_sync(adv7511->regmap);
587 break;
588 default:
589 /* TODO: setup additional power down modes */
590 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
591 ADV7511_POWER_POWER_DOWN,
592 ADV7511_POWER_POWER_DOWN);
593 regcache_mark_dirty(adv7511->regmap);
594 break;
595 }
596
597 adv7511->dpms_mode = mode;
598} 607}
599 608
600static enum drm_connector_status 609static enum drm_connector_status
@@ -622,10 +631,9 @@ adv7511_encoder_detect(struct drm_encoder *encoder,
622 * 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
623 * at least one transition from disconnected to connected and the chip 632 * at least one transition from disconnected to connected and the chip
624 * has to be reinitialized. */ 633 * has to be reinitialized. */
625 if (status == connector_status_connected && hpd && 634 if (status == connector_status_connected && hpd && adv7511->powered) {
626 adv7511->dpms_mode == DRM_MODE_DPMS_ON) {
627 regcache_mark_dirty(adv7511->regmap); 635 regcache_mark_dirty(adv7511->regmap);
628 adv7511_encoder_dpms(encoder, adv7511->dpms_mode); 636 adv7511_power_on(adv7511);
629 adv7511_get_modes(encoder, connector); 637 adv7511_get_modes(encoder, connector);
630 if (adv7511->status == connector_status_connected) 638 if (adv7511->status == connector_status_connected)
631 status = connector_status_disconnected; 639 status = connector_status_disconnected;
@@ -860,7 +868,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
860 if (!adv7511) 868 if (!adv7511)
861 return -ENOMEM; 869 return -ENOMEM;
862 870
863 adv7511->dpms_mode = DRM_MODE_DPMS_OFF; 871 adv7511->powered = false;
864 adv7511->status = connector_status_disconnected; 872 adv7511->status = connector_status_disconnected;
865 873
866 ret = adv7511_parse_dt(dev->of_node, &link_config); 874 ret = adv7511_parse_dt(dev->of_node, &link_config);
@@ -920,10 +928,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
920 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 928 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
921 ADV7511_CEC_CTRL_POWER_DOWN); 929 ADV7511_CEC_CTRL_POWER_DOWN);
922 930
923 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, 931 adv7511_power_off(adv7511);
924 ADV7511_POWER_POWER_DOWN, ADV7511_POWER_POWER_DOWN);
925
926 adv7511->current_edid_segment = -1;
927 932
928 i2c_set_clientdata(i2c, adv7511); 933 i2c_set_clientdata(i2c, adv7511);
929 934