- sunxi display DDC probe fallback

- support 24bpp BMP files on 16bpp displays
 -----BEGIN PGP SIGNATURE-----
 
 iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCXGiRSQ4cYWd1c3RAZGVu
 eC5kZQAKCRBM6ATMmsalXBhGAJ0Z1jc7lDzxlldLsnz32J22uCPsigCdHaefxWKX
 r4K/oQsvMOHPJCDVm7Y=
 =4PiI
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Tom Rini 2019-02-16 18:10:53 -05:00
commit 500ad54e35
2 changed files with 45 additions and 20 deletions

View File

@ -113,6 +113,13 @@ static int sunxi_hdmi_hpd_detect(int hpd_delay)
writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl); writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl);
writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0); 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) { while (timer_get_us() < tmo) {
if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT) if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT)
return 1; return 1;
@ -203,7 +210,8 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
return r; 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 edid1_info edid1;
struct edid_cea861_info cea681[4]; 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; (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int i, r, ext_blocks = 0; 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 */ /* Reset i2c controller */
setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE);
writel(SUNXI_HMDI_DDC_CTRL_ENABLE | 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) { if (r == 0) {
r = edid_check_info(&edid1); r = edid_check_info(&edid1);
if (r) { if (r) {
printf("EDID: invalid EDID data\n"); if (verbose_mode)
printf("EDID: invalid EDID data\n");
r = -EINVAL; r = -EINVAL;
} }
} }
@ -1082,7 +1084,8 @@ void *video_hw_init(void)
struct ctfb_res_modes custom; struct ctfb_res_modes custom;
const char *options; const char *options;
#ifdef CONFIG_VIDEO_HDMI #ifdef CONFIG_VIDEO_HDMI
int ret, hpd, hpd_delay, edid; int hpd, hpd_delay, edid;
bool hdmi_present;
#endif #endif
int i, overscan_offset, overscan_x, overscan_y; int i, overscan_offset, overscan_x, overscan_y;
unsigned int fb_dma_addr; unsigned int fb_dma_addr;
@ -1118,12 +1121,23 @@ void *video_hw_init(void)
if (sunxi_display.monitor == sunxi_monitor_dvi || if (sunxi_display.monitor == sunxi_monitor_dvi ||
sunxi_display.monitor == sunxi_monitor_hdmi) { sunxi_display.monitor == sunxi_monitor_hdmi) {
/* Always call hdp_detect, as it also enables clocks, etc. */ /* Always call hdp_detect, as it also enables clocks, etc. */
ret = sunxi_hdmi_hpd_detect(hpd_delay); hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1);
if (ret) { if (hdmi_present && edid) {
printf("HDMI connected: "); printf("HDMI connected: ");
if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) if (sunxi_hdmi_edid_get_mode(&custom, true) == 0)
mode = &custom; 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_hdmi_shutdown();
sunxi_display.monitor = sunxi_get_default_mon(false); sunxi_display.monitor = sunxi_get_default_mon(false);
} /* else continue with hdmi/dvi without a cable connected */ } /* else continue with hdmi/dvi without a cable connected */

View File

@ -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 * and displaying 24bpp BMPs on 32bpp LCDs
* */ */
if (bpix != bmp_bpix && if (bpix != bmp_bpix &&
!(bmp_bpix == 8 && bpix == 16) && !(bmp_bpix == 8 && bpix == 16) &&
!(bmp_bpix == 24 && bpix == 16) &&
!(bmp_bpix == 24 && bpix == 32)) { !(bmp_bpix == 24 && bpix == 32)) {
printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, get_unaligned_le16(&bmp->header.bit_count)); 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: case 24:
for (i = 0; i < height; ++i) { for (i = 0; i < height; ++i) {
for (j = 0; j < width; j++) { for (j = 0; j < width; j++) {
*(fb++) = *(bmap++); if (bpix == 16) {
*(fb++) = *(bmap++); /* 16bit 555RGB format */
*(fb++) = *(bmap++); *(u16 *)fb = ((bmap[2] >> 3) << 10) |
*(fb++) = 0; ((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); fb -= priv->line_length + width * (bpix / 8);
bmap += (padded_width - width) * 3;
} }
break; break;
#endif /* CONFIG_BMP_24BPP */ #endif /* CONFIG_BMP_24BPP */