soc/intel/cmn/gfx: Detect dual display (eDP + HDMI)

This patch adds support for detecting dual displays (eDP and HDMI) on
Intel platforms. This information is useful for setting the
`lb_framebuffer.has_external_display` variable, which is used to
determine whether depthchage should avoid shutting down when an
extended display is present.

TEST= Able to build and boot google/rex, where depthchage now
successfully avoids shutting down when both eDP and HDMI displays
are attached.

w/o this patch:
  with eDP and HDMI attached: .has_external_display=0
  with eDP attached: .has_external_display=0
  with HDMI attached: .has_external_display=1

w/ this patch:
  with eDP and HDMI attached: .has_external_display = 1
  with eDP attached: .has_external_display=0
  with HDMI attached: .has_external_display=1

Change-Id: Ie39d48da75a21e3508a1fbcf09da31caedaa1c0a
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78383
Reviewed-by: Eric Lai <ericllai@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2023-10-15 17:33:59 +05:30
parent 045251e451
commit 8da57ba0e7
1 changed files with 25 additions and 6 deletions

View File

@ -31,6 +31,14 @@ intel_igd_get_controller_info(const struct device *device)
return NULL; return NULL;
} }
static uint32_t graphics_get_ddi_func_ctrl(unsigned long reg)
{
uint32_t ddi_func_ctrl = graphics_gtt_read(reg);
ddi_func_ctrl &= TRANS_DDI_PORT_MASK;
return ddi_func_ctrl;
}
/* /*
* Transcoders contain the timing generators for eDP, DP, and HDMI interfaces. * Transcoders contain the timing generators for eDP, DP, and HDMI interfaces.
* Intel transcoders are based on Quick Sync Video, which offloads video * Intel transcoders are based on Quick Sync Video, which offloads video
@ -58,21 +66,32 @@ intel_igd_get_controller_info(const struct device *device)
*/ */
static int get_external_display_status(void) static int get_external_display_status(void)
{ {
uint32_t ddi_func_ctrl = graphics_gtt_read(TRANS_DDI_FUNC_CTL_A); /* Read the transcoder register for DDI-A (eDP) */
ddi_func_ctrl &= TRANS_DDI_PORT_MASK; uint32_t ddi_a_func_ctrl = graphics_get_ddi_func_ctrl(TRANS_DDI_FUNC_CTL_A);
/* Read the transcoder register for DDI-B (HDMI) */
uint32_t ddi_b_func_ctrl = graphics_get_ddi_func_ctrl(TRANS_DDI_FUNC_CTL_B);
/* /*
* Check if transcoder is none or connected to DDI-A port (aka eDP). * Check if transcoder is none or connected to DDI-A port (aka eDP).
* Report no external display in both cases. * Report no external display in both cases.
*/ */
if (ddi_func_ctrl == TRANS_DDI_PORT_NONE) { if (ddi_a_func_ctrl == TRANS_DDI_PORT_NONE) {
return 0; return 0;
} else { } else {
if (ddi_func_ctrl == TRANS_DDI_SELECT_PORT(PORT_A)) if ((ddi_a_func_ctrl == TRANS_DDI_SELECT_PORT(PORT_A)) &&
(ddi_b_func_ctrl == TRANS_DDI_SELECT_PORT(PORT_B))) {
/*
* Dual display detected: both DDI-A(eDP) and
* DDI-B(HDMI) pipes are active
*/
return 1;
} else {
if (ddi_a_func_ctrl == TRANS_DDI_SELECT_PORT(PORT_A))
return 0; return 0;
else else
return 1; return 1;
} }
}
} }
/* Check and report if an external display is attached */ /* Check and report if an external display is attached */