mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
Improve HDMI display detection by searching the CEA-861 extension block for
an HDMI vendor-specific data block (VSDB) containing the HDMI 24-bit IEEE registration ID (0x000C03). Approved by: gonzo (mentor)
This commit is contained in:
parent
e881d8757c
commit
bfba653b0e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=297514
@ -195,6 +195,15 @@ __FBSDID("$FreeBSD$");
|
||||
#define CEA_TAG_ID 0x02
|
||||
#define CEA_DTD 0x03
|
||||
#define DTD_BASIC_AUDIO (1 << 6)
|
||||
#define CEA_REV 0x02
|
||||
#define CEA_DATA_OFF 0x03
|
||||
#define CEA_DATA_START 4
|
||||
#define BLOCK_TAG(x) (((x) >> 5) & 0x7)
|
||||
#define BLOCK_TAG_VSDB 3
|
||||
#define BLOCK_LEN(x) ((x) & 0x1f)
|
||||
#define HDMI_VSDB_MINLEN 5
|
||||
#define HDMI_OUI "\x03\x0c\x00"
|
||||
#define HDMI_OUI_LEN 3
|
||||
|
||||
struct a10hdmi_softc {
|
||||
struct resource *res;
|
||||
@ -372,6 +381,41 @@ a10hdmi_ddc_read(struct a10hdmi_softc *sc, int block, uint8_t *edid)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a10hdmi_detect_hdmi_vsdb(uint8_t *edid)
|
||||
{
|
||||
int off, p, btag, blen;
|
||||
|
||||
if (edid[EXT_TAG] != CEA_TAG_ID)
|
||||
return (0);
|
||||
|
||||
off = edid[CEA_DATA_OFF];
|
||||
|
||||
/* CEA data block collection starts at byte 4 */
|
||||
if (off <= CEA_DATA_START)
|
||||
return (0);
|
||||
|
||||
/* Parse the CEA data blocks */
|
||||
for (p = CEA_DATA_START; p < off;) {
|
||||
btag = BLOCK_TAG(edid[p]);
|
||||
blen = BLOCK_LEN(edid[p]);
|
||||
|
||||
/* Make sure the length is sane */
|
||||
if (p + blen + 1 > off)
|
||||
break;
|
||||
|
||||
/* Look for a VSDB with the HDMI 24-bit IEEE registration ID */
|
||||
if (btag == BLOCK_TAG_VSDB && blen >= HDMI_VSDB_MINLEN &&
|
||||
memcmp(&edid[p + 1], HDMI_OUI, HDMI_OUI_LEN) == 0)
|
||||
return (1);
|
||||
|
||||
/* Next data block */
|
||||
p += (1 + blen);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
a10hdmi_detect_hdmi(struct a10hdmi_softc *sc, int *phdmi, int *paudio)
|
||||
{
|
||||
@ -389,7 +433,7 @@ a10hdmi_detect_hdmi(struct a10hdmi_softc *sc, int *phdmi, int *paudio)
|
||||
if (a10hdmi_ddc_read(sc, block, edid) != 0)
|
||||
return;
|
||||
|
||||
if (edid[EXT_TAG] == CEA_TAG_ID) {
|
||||
if (a10hdmi_detect_hdmi_vsdb(edid) != 0) {
|
||||
*phdmi = 1;
|
||||
*paudio = ((edid[CEA_DTD] & DTD_BASIC_AUDIO) != 0);
|
||||
return;
|
||||
@ -518,6 +562,9 @@ a10hdmi_set_videomode(device_t dev, const struct videomode *mode)
|
||||
PLLCTRL0_VCO_S);
|
||||
|
||||
/* Setup display settings */
|
||||
if (bootverbose)
|
||||
device_printf(dev, "HDMI: %s, Audio: %s\n",
|
||||
sc->has_hdmi ? "yes" : "no", sc->has_audio ? "yes" : "no");
|
||||
val = 0;
|
||||
if (sc->has_hdmi)
|
||||
val |= VID_CTRL_HDMI_MODE;
|
||||
|
Loading…
Reference in New Issue
Block a user