2 * This file is part of the coreboot project.
4 * Copyright 2014 Rockchip Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/cache.h>
18 #include <console/console.h>
19 #include <device/device.h>
26 #include <soc/addressmap.h>
27 #include <soc/clock.h>
28 #include <soc/display.h>
38 void rk_display_init(device_t dev
, u32 lcdbase
,
39 unsigned long fb_size
)
42 struct soc_rockchip_rk3288_config
*conf
= dev
->chip_info
;
43 uint32_t lower
= ALIGN_DOWN(lcdbase
, MiB
);
44 uint32_t upper
= ALIGN_UP(lcdbase
+ fb_size
, MiB
);
45 enum vop_modes detected_mode
= VOP_MODE_UNKNOWN
;
47 printk(BIOS_SPEW
, "LCD framebuffer @%p\n", (void *)(lcdbase
));
48 memset((void *)lcdbase
, 0, fb_size
); /* clear the framebuffer */
49 dcache_clean_invalidate_by_mva((void *)lower
, upper
- lower
);
50 mmu_config_range(lower
/ MiB
, (upper
- lower
) / MiB
, DCACHE_OFF
);
52 switch (conf
->vop_mode
) {
55 case VOP_MODE_AUTO_DETECT
:
56 /* try EDP first, then HDMI */
58 printk(BIOS_DEBUG
, "Attempting to setup EDP display.\n");
59 rkclk_configure_edp();
60 rkclk_configure_vop_aclk(conf
->vop_id
, 192 * MHz
);
61 rk_edp_init(conf
->vop_id
);
63 if (rk_edp_get_edid(&edid
) == 0) {
64 detected_mode
= VOP_MODE_EDP
;
67 printk(BIOS_WARNING
, "Cannot get EDID from EDP.\n");
68 if (conf
->vop_mode
== VOP_MODE_EDP
)
73 printk(BIOS_DEBUG
, "Attempting to setup HDMI display.\n");
74 rkclk_configure_hdmi();
75 rkclk_configure_vop_aclk(conf
->vop_id
, 384 * MHz
);
76 rk_hdmi_init(conf
->vop_id
);
78 if (rk_hdmi_get_edid(&edid
) == 0) {
79 detected_mode
= VOP_MODE_HDMI
;
82 printk(BIOS_WARNING
, "Cannot get EDID from HDMI.\n");
83 if (conf
->vop_mode
== VOP_MODE_HDMI
)
88 printk(BIOS_WARNING
, "Cannot read any edid info, aborting.\n");
92 if (rkclk_configure_vop_dclk(conf
->vop_id
, edid
.mode
.pixel_clock
* KHz
)) {
93 printk(BIOS_WARNING
, "config vop err\n");
97 edid
.framebuffer_bits_per_pixel
= conf
->framebuffer_bits_per_pixel
;
98 edid
.bytes_per_line
= edid
.mode
.ha
* conf
->framebuffer_bits_per_pixel
/ 8;
99 edid
.x_resolution
= edid
.mode
.ha
;
100 edid
.y_resolution
= edid
.mode
.va
;
101 rkvop_mode_set(conf
->vop_id
, &edid
, detected_mode
);
103 rkvop_enable(conf
->vop_id
, lcdbase
, &edid
);
105 switch (detected_mode
) {
107 if (rk_hdmi_enable(&edid
)) {
108 printk(BIOS_WARNING
, "hdmi enable err\n");
113 * HACK: if we do remove this delay, HDMI TV may not show
114 * anythings. So we make an delay here, ensure TV have
115 * enough time to respond.
122 if (rk_edp_enable()) {
123 printk(BIOS_WARNING
, "edp enable err\n");
126 mainboard_power_on_backlight();
130 set_vbe_mode_info_valid(&edid
, (uintptr_t)lcdbase
);