summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-02-17 02:10:53 +0300
committerTom Rini <trini@konsulko.com>2019-02-17 02:10:53 +0300
commit500ad54e35c636b0a05170753da58fcd8c8de6f2 (patch)
tree53d3ebd906ca676fdea82f98f0b5d78089496573 /drivers
parent7a2ab3778c0acae27edc01009c6ad9950a90634e (diff)
parente25710305da0f087a374ad41d5fa1f244469f6f2 (diff)
downloadu-boot-500ad54e35c636b0a05170753da58fcd8c8de6f2.tar.xz
Merge tag 'video-for-2019.04-rc2' of git://git.denx.de/u-boot-video
- sunxi display DDC probe fallback - support 24bpp BMP files on 16bpp displays
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/sunxi/sunxi_display.c42
-rw-r--r--drivers/video/video_bmp.c23
2 files changed, 45 insertions, 20 deletions
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index 6dd9bec351..46436b88c5 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -113,6 +113,13 @@ static int sunxi_hdmi_hpd_detect(int hpd_delay)
writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl);
writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0);
+ /* Enable PLLs for eventual DDC */
+ writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE,
+ &hdmi->pad_ctrl1);
+ writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15),
+ &hdmi->pll_ctrl);
+ writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
+
while (timer_get_us() < tmo) {
if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT)
return 1;
@@ -203,7 +210,8 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
return r;
}
-static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
+static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
+ bool verbose_mode)
{
struct edid1_info edid1;
struct edid_cea861_info cea681[4];
@@ -215,13 +223,6 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int i, r, ext_blocks = 0;
- /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */
- writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE,
- &hdmi->pad_ctrl1);
- writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15),
- &hdmi->pll_ctrl);
- writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0);
-
/* Reset i2c controller */
setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
writel(SUNXI_HMDI_DDC_CTRL_ENABLE |
@@ -241,7 +242,8 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode)
if (r == 0) {
r = edid_check_info(&edid1);
if (r) {
- printf("EDID: invalid EDID data\n");
+ if (verbose_mode)
+ printf("EDID: invalid EDID data\n");
r = -EINVAL;
}
}
@@ -1082,7 +1084,8 @@ void *video_hw_init(void)
struct ctfb_res_modes custom;
const char *options;
#ifdef CONFIG_VIDEO_HDMI
- int ret, hpd, hpd_delay, edid;
+ int hpd, hpd_delay, edid;
+ bool hdmi_present;
#endif
int i, overscan_offset, overscan_x, overscan_y;
unsigned int fb_dma_addr;
@@ -1118,12 +1121,23 @@ void *video_hw_init(void)
if (sunxi_display.monitor == sunxi_monitor_dvi ||
sunxi_display.monitor == sunxi_monitor_hdmi) {
/* Always call hdp_detect, as it also enables clocks, etc. */
- ret = sunxi_hdmi_hpd_detect(hpd_delay);
- if (ret) {
+ hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1);
+ if (hdmi_present && edid) {
printf("HDMI connected: ");
- if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0)
+ if (sunxi_hdmi_edid_get_mode(&custom, true) == 0)
mode = &custom;
- } else if (hpd) {
+ else
+ hdmi_present = false;
+ }
+ /* Fall back to EDID in case HPD failed */
+ if (edid && !hdmi_present) {
+ if (sunxi_hdmi_edid_get_mode(&custom, false) == 0) {
+ mode = &custom;
+ hdmi_present = true;
+ }
+ }
+ /* Shut down when display was not found */
+ if ((hpd || edid) && !hdmi_present) {
sunxi_hdmi_shutdown();
sunxi_display.monitor = sunxi_get_default_mon(false);
} /* else continue with hdmi/dvi without a cable connected */
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 2898b0b55d..193f37d275 100644
--- a/drivers/video/video_bmp.c
+++ b/drivers/video/video_bmp.c
@@ -229,11 +229,12 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
}
/*
- * We support displaying 8bpp BMPs on 16bpp LCDs
+ * We support displaying 8bpp and 24bpp BMPs on 16bpp LCDs
* and displaying 24bpp BMPs on 32bpp LCDs
- * */
+ */
if (bpix != bmp_bpix &&
!(bmp_bpix == 8 && bpix == 16) &&
+ !(bmp_bpix == 24 && bpix == 16) &&
!(bmp_bpix == 24 && bpix == 32)) {
printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, get_unaligned_le16(&bmp->header.bit_count));
@@ -318,12 +319,22 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
case 24:
for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) {
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = 0;
+ if (bpix == 16) {
+ /* 16bit 555RGB format */
+ *(u16 *)fb = ((bmap[2] >> 3) << 10) |
+ ((bmap[1] >> 3) << 5) |
+ (bmap[0] >> 3);
+ bmap += 3;
+ fb += 2;
+ } else {
+ *(fb++) = *(bmap++);
+ *(fb++) = *(bmap++);
+ *(fb++) = *(bmap++);
+ *(fb++) = 0;
+ }
}
fb -= priv->line_length + width * (bpix / 8);
+ bmap += (padded_width - width) * 3;
}
break;
#endif /* CONFIG_BMP_24BPP */