mainboard/google/fizz: Check HDMI HPD and DisplayPort HPD

Some type-c monitors do not immediately assert HPD. If we continue
to boot without HPD asserted, Depthcharge fails to show pictures
on a monitor even if HPD is asserted later.

Also, if an HDMI monitor is connected, no wait is needed. If only
an HDMI monitor is connected, currently the API always loops until
the stopwatch expires.

This patch will make the AP skip DisplayPort wait loop if it detects
an HDMI monitor. And if an HDMI monitor is not detected, the AP will
wait for DisplayPort mode (like before) but also its HPD signal.

This patch also extends the wait loop time-out to 3 seconds.

BUG=b:72387533
BRANCH=none
TEST=Verify firmware screen is displayed even when a type-c monitor
does not immediately assert HPD. Verify if HDMI monitor is connected,
AP does not wait (and firmware screen is displayed on HDMI monitor).

Change-Id: I0e1afdffbebf4caf35bbb792e7f4637fae89fa49
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://review.coreboot.org/23816
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Daisuke Nojiri 2018-02-16 17:50:06 -08:00 committed by Patrick Georgi
parent 50f06a14cd
commit d182b63347
3 changed files with 56 additions and 11 deletions

View File

@ -986,25 +986,32 @@ int google_chromeec_pd_get_amode(uint16_t svid)
return 0;
}
const static long wait_for_display_timeout_ms = 2000;
#define USB_SID_DISPLAYPORT 0xff01
void google_chromeec_wait_for_display(void)
/**
* Wait for DisplayPort to be ready
*
* @param timeout Wait aborts after <timeout> ms.
* @return 1: Success or 0: Timeout.
*/
int google_chromeec_wait_for_displayport(long timeout)
{
struct stopwatch sw;
printk(BIOS_INFO, "Waiting for display\n");
stopwatch_init_msecs_expire(&sw, wait_for_display_timeout_ms);
printk(BIOS_INFO, "Waiting for DisplayPort\n");
stopwatch_init_msecs_expire(&sw, timeout);
while (google_chromeec_pd_get_amode(USB_SID_DISPLAYPORT) != 1) {
if (stopwatch_expired(&sw)) {
printk(BIOS_WARNING,
"Display not ready after %ldms. Abort.\n",
wait_for_display_timeout_ms);
return;
"DisplayPort not ready after %ldms. Abort.\n",
timeout);
return 0;
}
mdelay(200);
}
printk(BIOS_INFO, "Display ready after %lu ms\n",
printk(BIOS_INFO, "DisplayPort ready after %lu ms\n",
stopwatch_duration_msecs(&sw));
return 1;
}

View File

@ -37,7 +37,7 @@ bool google_chromeec_is_uhepi_supported(void);
int google_ec_running_ro(void);
void google_chromeec_init(void);
int google_chromeec_pd_get_amode(uint16_t svid);
void google_chromeec_wait_for_display(void);
int google_chromeec_wait_for_displayport(long timeout);
/* Device events */
uint64_t google_chromeec_get_device_enabled_events(void);

View File

@ -14,15 +14,53 @@
*/
#include <bootmode.h>
#include <console/console.h>
#include <delay.h>
#include <ec/google/chromeec/ec.h>
#include <gpio.h>
#include <mainboard/google/fizz/gpio.h>
#include <soc/gpio.h>
#include <soc/ramstage.h>
#include <timer.h>
#include "gpio.h"
#define GPIO_HDMI_HPD GPP_E13
#define GPIO_DP_HPD GPP_E14
/* TODO: This can be moved to common directory */
static void wait_for_hpd(gpio_t gpio, long timeout)
{
struct stopwatch sw;
printk(BIOS_INFO, "Waiting for HPD\n");
gpio_input(gpio);
stopwatch_init_msecs_expire(&sw, timeout);
while (!gpio_get(gpio)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_WARNING,
"HPD not ready after %ldms. Abort.\n", timeout);
return;
}
mdelay(200);
}
printk(BIOS_INFO, "HPD ready after %lu ms\n",
stopwatch_duration_msecs(&sw));
}
void mainboard_silicon_init_params(FSP_SIL_UPD *params)
{
if (display_init_required())
static const long display_timeout_ms = 3000;
/* This is reconfigured back to whatever FSP-S expects by
gpio_configure_pads. */
gpio_input(GPIO_HDMI_HPD);
if (display_init_required() && !gpio_get(GPIO_HDMI_HPD)) {
/* This has to be done before FSP-S runs. */
google_chromeec_wait_for_display();
if (google_chromeec_wait_for_displayport(display_timeout_ms))
wait_for_hpd(GPIO_DP_HPD, display_timeout_ms);
}
gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
}