diff options
author | David Hendricks <dhendrix@chromium.org> | 2015-06-17 13:47:28 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-07-06 09:40:14 +0200 |
commit | af42f069ea1bd8651a3e830323da27aee54290e5 (patch) | |
tree | 0dac302f33cb8bd31184dd445de217c0fe814f3a | |
parent | aa33609d289c4ee07ec10e4825bc055492fa107c (diff) |
rk3288: Auto-detect display.
We currently select either HDMI or EDP (default). This patch
allows us to use HDMI as a fallback for devices that may have
a display connected on either interface. It also renames the
enums to sound a little more sensible in other contexts (more
on that in the follow-up patches).
VOP_MODE_AUTO is added to the mode enum which will make it explicit
that a board can support either. In AUTO_MODE we will try EDP first
and then fallback to HDMI. Other modes can be set to force a certain
behavior such as HDMI-only on Mickey where it doesn't make sense to
try EDP.
A follow-up patch will add logic for when we explicitly don't want
to probe for any display (headless devices).
BUG=none
BRANCH=none
TEST=On veyron_danger, connected EDP and HDMI displays and saw dev
mode screen appear on EDP display. Unplugged EDP and then dev mode
screen showed up on HDMI.
Change-Id: I22b38031c4ab3d79fbb182f7a906da1197f35543
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 3f57ed3758c4e516d9fd226ad9499b102b81b423
Original-Change-Id: I352dcde16f7f3ebbf5796852b685685e541eb794
Original-Signed-off-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/281076
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: http://review.coreboot.org/10775
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r-- | src/soc/rockchip/rk3288/chip.h | 1 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/display.c | 54 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/include/soc/vop.h | 12 | ||||
-rw-r--r-- | src/soc/rockchip/rk3288/vop.c | 4 |
4 files changed, 47 insertions, 24 deletions
diff --git a/src/soc/rockchip/rk3288/chip.h b/src/soc/rockchip/rk3288/chip.h index 3a6b14d213..2c4390a515 100644 --- a/src/soc/rockchip/rk3288/chip.h +++ b/src/soc/rockchip/rk3288/chip.h @@ -21,6 +21,7 @@ #define __SOC_ROCKCHIP_RK3288_CHIP_H__ #include <soc/gpio.h> +#include <soc/vop.h> /* for vop_modes enum used in devicetree.cb */ struct soc_rockchip_rk3288_config { u32 vop_id; diff --git a/src/soc/rockchip/rk3288/display.c b/src/soc/rockchip/rk3288/display.c index 192580b534..ab297a21d1 100644 --- a/src/soc/rockchip/rk3288/display.c +++ b/src/soc/rockchip/rk3288/display.c @@ -46,6 +46,7 @@ void rk_display_init(device_t dev, u32 lcdbase, struct soc_rockchip_rk3288_config *conf = dev->chip_info; uint32_t lower = ALIGN_DOWN(lcdbase, MiB); uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB); + enum vop_modes detected_mode = VOP_MODE_UNKNOWN; printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase)); memset((void *)lcdbase, 0, fb_size); /* clear the framebuffer */ @@ -53,26 +54,41 @@ void rk_display_init(device_t dev, u32 lcdbase, mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF); switch (conf->vop_mode) { - case HDMI_MODE: + case VOP_MODE_AUTO_DETECT: + /* try EDP first, then HDMI */ + case VOP_MODE_EDP: + printk(BIOS_DEBUG, "Attempting to setup EDP display.\n"); + rkclk_configure_edp(); + rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz); + rk_edp_init(conf->vop_id); + + if (rk_edp_get_edid(&edid) == 0) { + detected_mode = VOP_MODE_EDP; + break; + } else { + printk(BIOS_WARNING, "Cannot get EDID from EDP.\n"); + if (conf->vop_mode == VOP_MODE_EDP) + return; + } + /* fall thru */ + case VOP_MODE_HDMI: + printk(BIOS_DEBUG, "Attempting to setup HDMI display.\n"); rkclk_configure_hdmi(); rkclk_configure_vop_aclk(conf->vop_id, 384 * MHz); rk_hdmi_init(conf->vop_id); - if (rk_hdmi_get_edid(&edid)) { - printk(BIOS_WARNING, "can not get edid\n"); - return; - } - break; - case EDP_MODE: - default: - rkclk_configure_edp(); - rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz); - rk_edp_init(conf->vop_id); - if (rk_edp_get_edid(&edid)) { - printk(BIOS_WARNING, "can not get edid\n"); - return; + if (rk_hdmi_get_edid(&edid) == 0) { + detected_mode = VOP_MODE_HDMI; + break; + } else { + printk(BIOS_WARNING, "Cannot get EDID from HDMI.\n"); + if (conf->vop_mode == VOP_MODE_HDMI) + return; } - break; + /* fall thru */ + default: + printk(BIOS_WARNING, "Cannot read any edid info, aborting.\n"); + return; } if (rkclk_configure_vop_dclk(conf->vop_id, edid.pixel_clock * KHz)) { @@ -84,12 +100,12 @@ void rk_display_init(device_t dev, u32 lcdbase, edid.bytes_per_line = edid.ha * conf->framebuffer_bits_per_pixel / 8; edid.x_resolution = edid.ha; edid.y_resolution = edid.va; - rkvop_mode_set(conf->vop_id, &edid, conf->vop_mode); + rkvop_mode_set(conf->vop_id, &edid, detected_mode); rkvop_enable(conf->vop_id, lcdbase, &edid); - switch (conf->vop_mode) { - case HDMI_MODE: + switch (detected_mode) { + case VOP_MODE_HDMI: if (rk_hdmi_enable(&edid)) { printk(BIOS_WARNING, "hdmi enable err\n"); return; @@ -103,7 +119,7 @@ void rk_display_init(device_t dev, u32 lcdbase, mdelay(2000); break; - case EDP_MODE: + case VOP_MODE_EDP: default: if (rk_edp_enable()) { printk(BIOS_WARNING, "edp enable err\n"); diff --git a/src/soc/rockchip/rk3288/include/soc/vop.h b/src/soc/rockchip/rk3288/include/soc/vop.h index 6cb883a635..2690726b07 100644 --- a/src/soc/rockchip/rk3288/include/soc/vop.h +++ b/src/soc/rockchip/rk3288/include/soc/vop.h @@ -100,9 +100,15 @@ enum { LB_RGB_1280X8 = 0x5 }; -enum { - EDP_MODE, - HDMI_MODE, +enum vop_modes { + /* EDP == 0 is used for early RK3288 products and is the most likely + * use case, so keep it as the default. Other desired modes should + * be set explicitly in the board's devicetree.cb. + */ + VOP_MODE_EDP = 0, + VOP_MODE_HDMI, + VOP_MODE_AUTO_DETECT, + VOP_MODE_UNKNOWN, }; /* VOP_VERSION_INFO */ diff --git a/src/soc/rockchip/rk3288/vop.c b/src/soc/rockchip/rk3288/vop.c index 03338e85a4..8c69321477 100644 --- a/src/soc/rockchip/rk3288/vop.c +++ b/src/soc/rockchip/rk3288/vop.c @@ -110,12 +110,12 @@ void rkvop_mode_set(u32 vop_id, const struct edid *edid, u32 mode) switch (mode) { - case HDMI_MODE: + case VOP_MODE_HDMI: clrsetbits_le32(&preg->sys_ctrl, M_ALL_OUT_EN, V_HDMI_OUT_EN(1)); break; - case EDP_MODE: + case VOP_MODE_EDP: default: clrsetbits_le32(&preg->sys_ctrl, M_ALL_OUT_EN, V_EDP_OUT_EN(1)); |