On Sat, Aug 06, 2016 at 04:26:27AM -0400, Ian Sutton wrote:
> Interestingly, the am335x SoC does not have a HDMI/DP/etc transmitter on
> silicon -- the BBB has its LCDC pins wired to a TDA19988 HDMI
> transmitter which is additionally backwired to one of the am335x's i2c
> ports:
>
> "nxp,tda998x" at iic0 addr 0x70 not configured
>
> Without a TDA19988 driver we are unable to probe for an attached
> display's EDID bits thus unable to tailor timing/videomode parameters
> on a per-display basis.
The following patch adds the nxptda(4) i2c driver:
nxptda0 at iic0 addr 0x70: rev 0x0301
It correctly ascertains the EDID bits of displays connected to the
beaglebone black:
nxptda0 at iic0 addr 0x70
nxptda0: set page to 0x00
nxptda0: read 0x31 from 0x00 on page 0x00, result: 0
nxptda0: read 0x03 from 0x02 on page 0x00, result: 0
nxptda0: rev 0x0301
nxptda0: read 0x00 from 0x0a on page 0x00, result: 0
nxptda0: wrote 0x03 to 0x0a on page 0x00, result: 0
nxptda0: read 0x03 from 0x0a on page 0x00, result: 0
nxptda0: wrote 0x00 to 0x0a on page 0x00, result: 0
<snip>
nxptda0: read 0x02 from 0x11 on page 0x00, result: 0
nxptda0: EDID-ready IRQ fired
nxptda0: set page to 0x09
nxptda0: ------------- EDID -------------
nxptda0: 00ffffffffffff0022f05b2801010101
nxptda0: 1b15010380261e8ceef6b0a3554c9b25
nxptda0: 115054a1080081808140010101010101
nxptda0: 010101010101302a009851002a403070
nxptda0: 13007c2c1100001e000000fd00324c18
nxptda0: 530e000a202020202020000000fc004c
nxptda0: 41313935310a202020202020000000ff
nxptda0: 00434e43313237504c56420a20200022
nxptda0: --------------------------------
^--matches EDID bits from `xrandr --verbose`
This will be important for upcoming display support on armv7 (see
amdisplay(4) threads on this list[1]). The following code is
review-ready to some degree, however, I imagine further register
fiddling will be needed to communicate the intended timings perhaps
implicating more externally callable functions.
Speaking of which:
I am apprehensive of nxptda(4)'s current external interface model. I
currently have the lone nxptda_refresh_edid() function declared in
nxptdavar.h header in sys/dev/i2c/, meant to be included by other drivers
which need the EDID information it provides. No other such foo_var.h
headers appear in that directory which makes me think I am doing
something wrong. nxptda(4) is an i2c driver and must attach to the MI
iic(4) driver precluding a direct attachment interface. Is there a
better way of doing this?
Thanks
Ian
Index: share/man/man4/nxptda.4
===================================================================
RCS file: share/man/man4/nxptda.4
diff -N share/man/man4/nxptda.4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ share/man/man4/nxptda.4 18 Aug 2016 19:19:17 -0000
@@ -0,0 +1,47 @@
+.\"
+.\" Copyright (c) 2016 joshua stein <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: August 18 2016 $
+.Dt NXPTDA 4
+.Os
+.Sh NAME
+.Nm nxptda
+.Nd TDA19988 I2C HDMI transmitter support
+.Sh SYNOPSIS
+.Cd "nxptda* at iic? addr 0x70"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for TDA19988 I2C HDMI transmitter. Currently,
+.Nm
+only provides the EDID bits from connected displays via the following
externally
+callable function:
+.Bl -tag -width Ds
+.It Ft int
+.Fn nxptda_refresh_edid "void *buf" "size_t len"
+.El
+.Sh FILES
+.Pa /usr/src/sys/dev/i2c/nxptdavar.h
+.Sh SEE ALSO
+.Xr iic 4
+.Sh HISTORY
+The
+.Nm
+device driver does not appear in OpenBSD currently.
+.Sh AUTHORS
+The
+.Nm
+driver was written by
+.An Ian Sutton Aq Mt [email protected] .
Index: sys/arch/armv7/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/armv7/conf/GENERIC,v
retrieving revision 1.45
diff -u -p -r1.45 GENERIC
--- sys/arch/armv7/conf/GENERIC 11 Aug 2016 04:33:06 -0000 1.45
+++ sys/arch/armv7/conf/GENERIC 18 Aug 2016 19:19:18 -0000
@@ -70,6 +70,7 @@ omgpio* at fdt? # user-visible
GPIO p
gpio* at omgpio?
tiiic* at fdt?
iic* at tiiic?
+nxptda* at iic? # TDA 19988 HDMI transmitter
gptimer* at omap? # general purpose timers
dmtimer* at omap? # am335x dual mode timers
omusbtll* at omap?
Index: sys/dev/i2c/files.i2c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/files.i2c,v
retrieving revision 1.56
diff -u -p -r1.56 files.i2c
--- sys/dev/i2c/files.i2c 20 Jun 2016 13:42:42 -0000 1.56
+++ sys/dev/i2c/files.i2c 18 Aug 2016 19:19:19 -0000
@@ -84,6 +84,11 @@ device maxds
attach maxds at i2c
file dev/i2c/ds1631.c maxds
+# NXP TDA19988
+device nxptda
+attach nxptda at i2c
+file dev/i2c/nxptda.c nxptda
+
# Apple FCU
device fcu
attach fcu at i2c
Index: sys/dev/i2c/nxptda.c
===================================================================
RCS file: sys/dev/i2c/nxptda.c
diff -N sys/dev/i2c/nxptda.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/i2c/nxptda.c 18 Aug 2016 20:06:34 -0000
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2016 Ian Sutton <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/nxptdavar.h>
+
+#define DEVNAME(s) ((s)->sc_dev.dv_xname)
+#ifdef I2CDEBUG
+int nxptda_debug = 20;
+#define DPRINTF(n,s) do { if ((n) <= nxptda_debug) printf s; } while
(0)
+#else
+#define DPRINTF(n,s) do {} while (0)
+#endif
+
+/* NXP TDA19988 addresses */
+#define NXPTDA_HDMI_CORE 0x70
+#define NXPTDA_CEC_CORE 0x34
+
+/* NXP TDA19988 memory pages */
+#define NXPTDA_PAGE_CTRL 0x00
+#define NXPTDA_PAGE_PPL 0x02
+#define NXPTDA_PAGE_EDID 0x09
+#define NXPTDA_PAGE_INFO 0x10
+#define NXPTDA_PAGE_AUDIO 0x11
+#define NXPTDA_PAGE_HDCP 0x12
+#define NXPTDA_PAGE_GAMUT 0x13
+
+/* NXP TDA19988 registers & masks */
+#define NXPTDA_CEC_ENADDR 0xff
+#define NXPTDA_CEC_EN 0x87
+#define NXPTDA_CEC_STATUS 0xfe
+#define NXPTDA_CTRL_CNTRL0 0x01
+#define NXPTDA_CTRL_CNTRL0_SR 0x01
+#define NXPTDA_CTRL_REV_LO 0x00
+#define NXPTDA_CTRL_REV_HI 0x02
+#define NXPTDA_CTRL_RESETADDR 0x0a
+#define NXPTDA_CTRL_RESET 0x03
+#define NXPTDA_CTRL_DDCADDR 0x0b
+#define NXPTDA_CTRL_DDC 0x00
+#define NXPTDA_CTRL_DDCCLKADDR 0x0c
+#define NXPTDA_CTRL_DDCCLK 0x01
+#define NXPTDA_PAGE_SELECT 0xff
+#define NXPTDA_EDID_DATA 0x00
+#define NXPTDA_EDID_DEVADDR 0xfb
+#define NXPTDA_EDID_DEV 0xa0
+#define NXPTDA_EDID_OFFSETADDR 0xfc
+#define NXPTDA_EDID_OFFSET 0x00
+#define NXPTDA_EDID_SEGPTRADDR 0xfc
+#define NXPTDA_EDID_SEGPTR 0x00
+#define NXPTDA_EDID_SEGADDR 0xfe
+#define NXPTDA_EDID_SEG 0x00
+#define NXPTDA_EDID_RREQ 0xfa
+#define NXPTDA_EDID_RREQ_ACK 0x01
+#define NXPTDA_HDCP_DDCCLKADDR 0x9a
+#define NXPTDA_HDCP_DDCCLK 0x27
+
+/* NXP TDA19988 irq */
+#define NXPTDA_CTRL_INT_CTL 0x0f
+#define NXPTDA_CTRL_INT_EN 0x04
+#define NXPTDA_CTRL_INT 0x11
+#define NXPTDA_CTRL_INT_EDID 0x02
+
+/* NXP TDA19988 magic */
+#define NXPTDA_HDCP_MREG 0x9b
+#define NXPTDA_HDCP_MASK 0x02
+
+#define EDID_LENGTH 0x80
+
+struct nxptda_softc {
+ struct device sc_dev;
+ i2c_tag_t sc_tag;
+ i2c_addr_t sc_addr;
+
+ uint8_t sc_curpage;
+ uint8_t sc_edid[EDID_LENGTH];
+};
+
+int nxptda_match(struct device *, void *, void *);
+void nxptda_attach(struct device *, struct device *, void *);
+
+int nxptda_read(struct nxptda_softc *, uint8_t, uint8_t, uint8_t *);
+int nxptda_write(struct nxptda_softc *, uint8_t, uint8_t, uint8_t);
+int nxptda_set(struct nxptda_softc *, uint8_t, uint8_t, uint8_t);
+int nxptda_clear(struct nxptda_softc *, uint8_t, uint8_t, uint8_t);
+int nxptda_set_page(struct nxptda_softc *, uint8_t);
+int nxptda_read_edid(struct nxptda_softc *);
+int nxptda_reset(struct nxptda_softc *);
+
+struct cfattach nxptda_ca = {
+ sizeof(struct nxptda_softc), nxptda_match, nxptda_attach
+};
+
+struct cfdriver nxptda_cd = {
+ NULL, "nxptda", DV_DULL
+};
+
+int
+nxptda_match(struct device *parent, void *match, void *aux)
+{
+ struct i2c_attach_args *ia = aux;
+
+ if (strcmp(ia->ia_name, "nxp,tda998x") == 0)
+ return 1;
+
+ return 0;
+}
+
+void
+nxptda_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct nxptda_softc *sc = (struct nxptda_softc *)self;
+ struct i2c_attach_args *ia = aux;
+ uint8_t reg, cmd[2];
+ uint16_t rev = 0;
+ int res;
+
+ sc->sc_tag = ia->ia_tag;
+ sc->sc_addr = ia->ia_addr;
+ sc->sc_curpage = 0xff;
+
+ DPRINTF(3,("\n"));
+
+ iic_acquire_bus(sc->sc_tag, 0);
+
+ /* enable HDMI core via CEC */
+ cmd[1] = NXPTDA_CEC_EN;
+ cmd[0] = NXPTDA_CEC_ENADDR;
+ res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, NXPTDA_CEC_CORE,
&cmd, 2,
+ NULL, 0, 0);
+ delay(1000);
+
+ res = nxptda_read(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_REV_LO, ®);
+ rev |= reg;
+ res = nxptda_read(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_REV_HI, ®);
+ rev |= (reg << 8);
+ rev &= ~0x30; /* clear feature bits */
+
+ DPRINTF(3,("%s", DEVNAME(sc)));
+ printf(": rev 0x%04x\n", rev);
+
+ nxptda_reset(sc);
+
+ /* enable DDC clocks */
+ nxptda_write(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_DDCADDR,
NXPTDA_CTRL_DDC);
+ nxptda_write(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_DDCCLKADDR,
+ NXPTDA_CTRL_DDCCLK);
+ nxptda_write(sc, NXPTDA_PAGE_HDCP, NXPTDA_HDCP_DDCCLKADDR,
+ NXPTDA_HDCP_DDCCLK);
+
+ iic_release_bus(sc->sc_tag, 0);
+
+ nxptda_read_edid(sc);
+}
+
+int
+nxptda_set_page(struct nxptda_softc *sc, uint8_t page)
+{
+ int ret = 0;
+ uint8_t sendbuf[] = {NXPTDA_PAGE_SELECT, page};
+
+ if (sc->sc_curpage == page)
+ return ret;
+
+ if ((ret = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
NXPTDA_HDMI_CORE,
+ &sendbuf, sizeof(sendbuf), NULL, 0, 0))) {
+ DPRINTF(3,("%s: failed to set memory page 0x%02x, errno %d\n",
DEVNAME(sc),
+ page, ret));
+ return ret;
+ }
+
+ DPRINTF(3,("%s: set page to 0x%02x\n", DEVNAME(sc), page));
+ sc->sc_curpage = page;
+
+ return ret;
+}
+
+int
+nxptda_read(struct nxptda_softc *sc, uint8_t page, uint8_t reg, uint8_t *buf)
+{
+ int ret;
+
+ nxptda_set_page(sc, page);
+
+ if ((ret = iic_smbus_read_byte(sc->sc_tag, NXPTDA_HDMI_CORE, reg, buf,
0))) {
+ DPRINTF(3,("%s: failed to read addr 0x%02x on page 0x%02x, errno
%d\n",
+ DEVNAME(sc), reg, page, ret));
+ return ret;
+ }
+
+ DPRINTF(3,("%s: read 0x%02x from 0x%02x on page 0x%02x, result: %d\n",
+ DEVNAME(sc), *buf, reg, page, ret));
+ return ret;
+}
+
+int
+nxptda_write(struct nxptda_softc *sc, uint8_t page, uint8_t reg, uint8_t buf)
+{
+ int ret;
+ uint8_t sendbuf[] = {reg, buf};
+
+ nxptda_set_page(sc, page);
+
+ if ((ret = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
NXPTDA_HDMI_CORE,
+ &sendbuf, 2, NULL, 0, 0))) {
+ DPRINTF(3,("%s: failed to write 0x%02x to 0x%02x on page
0x%02x, errno %d\n",
+ DEVNAME(sc), buf, reg, page, ret));
+ return ret;
+ }
+
+ DPRINTF(3,("%s: wrote 0x%02x to 0x%02x on page 0x%02x, result: %d\n",
+ DEVNAME(sc), buf, reg, page, ret));
+
+ return ret;
+}
+
+int
+nxptda_set(struct nxptda_softc *sc, uint8_t page, uint8_t reg, uint8_t bits)
+{
+ int ret = 0;
+ uint8_t buf;
+
+ if ((ret = nxptda_read(sc, page, reg, &buf)))
+ return ret;
+ buf |= bits;
+ ret = nxptda_write(sc, page, reg, buf);
+
+ return ret;
+}
+
+int
+nxptda_clear(struct nxptda_softc *sc, uint8_t page, uint8_t reg, uint8_t bits)
+{
+ int ret = 0;
+ uint8_t buf;
+
+ if ((ret = nxptda_read(sc, page, reg, &buf)))
+ return ret;
+ buf &= ~bits;
+ ret = nxptda_write(sc, page, reg, buf);
+
+ return ret;
+}
+
+int
+nxptda_read_edid(struct nxptda_softc *sc)
+{
+ int i, success = 0, ret = 0;
+ uint8_t reg;
+
+ iic_acquire_bus(sc->sc_tag, 0);
+
+ /* clear magic HDCP bits */
+ ret = nxptda_clear(sc, NXPTDA_PAGE_HDCP, NXPTDA_HDCP_MREG,
NXPTDA_HDCP_MASK);
+
+ /* enable edid read intr. */
+ ret |= nxptda_set(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_INT,
NXPTDA_CTRL_INT_EDID);
+
+ /* enable intrs. */
+ ret |= nxptda_set(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_INT_CTL,
+ NXPTDA_CTRL_INT_EN);
+
+ /* set dev addr */
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_DEVADDR,
+ NXPTDA_EDID_DEV);
+
+ /* set offset */
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_OFFSETADDR,
+ NXPTDA_EDID_OFFSET);
+
+ /* set segment ptr/segment address */
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_SEGPTRADDR,
+ NXPTDA_EDID_SEGPTR);
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_SEGADDR,
+ NXPTDA_EDID_SEG);
+
+ /* strobe read request bits */
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_RREQ,
+ NXPTDA_EDID_RREQ_ACK);
+ ret |= nxptda_write(sc, NXPTDA_PAGE_EDID, NXPTDA_EDID_RREQ, 0);
+
+ /* poll for irq */
+ for (i = 0; i < 100; i++) {
+ nxptda_read(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_INT, ®);
+ if (reg & NXPTDA_CTRL_INT_EDID) {
+ DPRINTF(3,("%s: EDID-ready IRQ fired\n", DEVNAME(sc)));
+ success = 1;
+ break;
+ }
+ }
+
+ if (!(success)) {
+ printf("%s: no display detected\n", DEVNAME(sc));
+ ret = ENXIO;
+ iic_release_bus(sc->sc_tag, 0);
+ return ret;
+ }
+
+ /* read edid block */
+ reg = NXPTDA_EDID_SEG;
+ nxptda_set_page(sc, NXPTDA_PAGE_EDID);
+
+ DPRINTF(3,("%s: ------------- EDID -------------", DEVNAME(sc)));
+ for (i = 0; i < EDID_LENGTH; i++) {
+ iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, NXPTDA_HDMI_CORE, ®,
1,
+ &sc->sc_edid[i], 1, 0);
+ if (!(i % 16))
+ DPRINTF(3,("\n%s: ", DEVNAME(sc)));
+ DPRINTF(3,("%02x", sc->sc_edid[i]));
+ reg++;
+ }
+ DPRINTF(3,("\n%s: --------------------------------\n", DEVNAME(sc)));
+
+ nxptda_clear(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_INT,
NXPTDA_CTRL_INT_EDID);
+ iic_release_bus(sc->sc_tag, 0);
+
+ return ret;
+}
+
+int
+nxptda_reset(struct nxptda_softc *sc)
+{
+ int err = 0;
+
+ err |= nxptda_set(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_RESETADDR,
+ NXPTDA_CTRL_RESET);
+ delay(1000);
+ err |= nxptda_clear(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_RESETADDR,
+ NXPTDA_CTRL_RESET);
+ delay(1000);
+
+ err |= nxptda_set(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_CNTRL0,
+ NXPTDA_CTRL_CNTRL0_SR);
+ delay(100);
+ err |= nxptda_clear(sc, NXPTDA_PAGE_CTRL, NXPTDA_CTRL_CNTRL0,
+ NXPTDA_CTRL_CNTRL0_SR);
+ delay(100);
+
+ return err;
+}
+
+int
+nxptda_refresh_edid(void *buf, size_t len)
+{
+ struct nxptda_softc *sc = nxptda_cd.cd_devs[0];
+ int ret = 0;
+
+ if (len < EDID_LENGTH)
+ return EINVAL;
+
+ if ((ret = nxptda_read_edid(sc)))
+ return ret;
+
+ memcpy(buf, sc->sc_edid, EDID_LENGTH);
+ return ret;
+}
Index: sys/dev/i2c/nxptdavar.h
===================================================================
RCS file: sys/dev/i2c/nxptdavar.h
diff -N sys/dev/i2c/nxptdavar.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/i2c/nxptdavar.h 18 Aug 2016 19:19:19 -0000
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016 Ian Sutton <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+int nxptda_refresh_edid(void *, size_t);