summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/rockchip/rk3288/chip.h1
-rw-r--r--src/soc/rockchip/rk3288/display.c54
-rw-r--r--src/soc/rockchip/rk3288/include/soc/vop.h12
-rw-r--r--src/soc/rockchip/rk3288/vop.c4
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));