Sat Jul 25 15:50:42 2015 UTC ()
Add HDMI audio support


(jmcneill)
diff -r1.23 -r1.24 src/sys/arch/arm/nvidia/tegra_car.c
diff -r1.19 -r1.20 src/sys/arch/arm/nvidia/tegra_carreg.h
diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_hdmi.c
diff -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_hdmireg.h

cvs diff -r1.23 -r1.24 src/sys/arch/arm/nvidia/Attic/tegra_car.c (expand / switch to context diff)
--- src/sys/arch/arm/nvidia/Attic/tegra_car.c 2015/07/23 18:22:05 1.23
+++ src/sys/arch/arm/nvidia/Attic/tegra_car.c 2015/07/25 15:50:42 1.24
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_car.c,v 1.23 2015/07/23 18:22:05 jmcneill Exp $ */
+/* $NetBSD: tegra_car.c,v 1.24 2015/07/25 15:50:42 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.23 2015/07/23 18:22:05 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.24 2015/07/25 15:50:42 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -535,24 +535,27 @@
 
 	tegra_car_get_bs(&bst, &bsh);
 
-	/* HDA */
 	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_SET_REG, CAR_DEV_V_HDA);
 	bus_space_write_4(bst, bsh, CAR_CLK_ENB_V_SET_REG, CAR_DEV_V_HDA);
-	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_CLR_REG, CAR_DEV_V_HDA);
-
-	/* HDA2CODEC_2X */
 	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_SET_REG,
 	    CAR_DEV_V_HDA2CODEC_2X);
 	bus_space_write_4(bst, bsh, CAR_CLK_ENB_V_SET_REG,
 	    CAR_DEV_V_HDA2CODEC_2X);
-	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_CLR_REG,
-	    CAR_DEV_V_HDA2CODEC_2X);
-
-	/* HDA2HDMICODEC */
 	bus_space_write_4(bst, bsh, CAR_RST_DEV_W_SET_REG,
 	    CAR_DEV_W_HDA2HDMICODEC);
 	bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG,
 	    CAR_DEV_W_HDA2HDMICODEC);
+
+	/* configure HDA2CODEC_2X for 48 MHz */
+	const u_int div = howmany(tegra_car_pllp0_rate() * 2, 48000000) - 2;
+	bus_space_write_4(bst, bsh, CAR_CLKSRC_HDA2CODEC_2X_REG,
+	    __SHIFTIN(CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLP_OUT0,
+		      CAR_CLKSRC_HDA2CODEC_2X_SRC) |
+	    __SHIFTIN(div, CAR_CLKSRC_HDA2CODEC_2X_DIV));
+
+	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_CLR_REG, CAR_DEV_V_HDA);
+	bus_space_write_4(bst, bsh, CAR_RST_DEV_V_CLR_REG,
+	    CAR_DEV_V_HDA2CODEC_2X);
 	bus_space_write_4(bst, bsh, CAR_RST_DEV_W_CLR_REG,
 	    CAR_DEV_W_HDA2HDMICODEC);
 }

cvs diff -r1.19 -r1.20 src/sys/arch/arm/nvidia/Attic/tegra_carreg.h (expand / switch to context diff)
--- src/sys/arch/arm/nvidia/Attic/tegra_carreg.h 2015/07/23 15:07:31 1.19
+++ src/sys/arch/arm/nvidia/Attic/tegra_carreg.h 2015/07/25 15:50:42 1.20
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_carreg.h,v 1.19 2015/07/23 15:07:31 skrll Exp $ */
+/* $NetBSD: tegra_carreg.h,v 1.20 2015/07/25 15:50:42 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -390,6 +390,16 @@
 #define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM		0
 #define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ	8
 
+#define CAR_CLKSRC_HDA2CODEC_2X_REG	0x3e4
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC	__BITS(31,29)
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLP_OUT0	0
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC2_OUT0	1
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC_OUT0	2
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC3_OUT0	3
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLM_OUT0	4
+#define CAR_CLKSRC_HDA2CODEC_2X_SRC_CLKM	6
+#define CAR_CLKSRC_HDA2CODEC_2X_DIV	__BITS(7,0)
+
 #define CAR_CLKSRC_SATA_OOB_REG		0x420
 #define CAR_CLKSRC_SATA_OOB_SRC		__BITS(31,29)
 #define CAR_CLKSRC_SATA_OOB_SRC_PLLP_OUT0	0
@@ -461,5 +471,13 @@
 #define CAR_SATA_PLL_CFG1_PADPLL_IDDQ2LANE_SLUMBER_DLY __BITS(23,16)
 #define CAR_SATA_PLL_CFG1_PADPLL_PU_POST_DLY	__BITS(15,8)
 #define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_IDDQ_DLY __BITS(7,0)
+
+#define CAR_CLKSRC_HDMI_AUDIO_REG	0x668
+#define CAR_CLKSRC_HDMI_AUDIO_SRC	__BITS(31,29)
+#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLP_OUT0	0
+#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLC_OUT0	1
+#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLC2_OUT0	2
+#define CAR_CLKSRC_HDMI_AUDIO_SRC_CLKM		3
+#define CAR_CLKSRC_HDMI_AUDIO_DIV	__BITS(7,0)
 
 #endif /* _ARM_TEGRA_CARREG_H */

cvs diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/Attic/tegra_hdmi.c (expand / switch to context diff)
--- src/sys/arch/arm/nvidia/Attic/tegra_hdmi.c 2015/07/23 15:43:06 1.5
+++ src/sys/arch/arm/nvidia/Attic/tegra_hdmi.c 2015/07/25 15:50:42 1.6
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_hdmi.c,v 1.5 2015/07/23 15:43:06 jmcneill Exp $ */
+/* $NetBSD: tegra_hdmi.c,v 1.6 2015/07/25 15:50:42 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_hdmi.c,v 1.5 2015/07/23 15:43:06 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_hdmi.c,v 1.6 2015/07/25 15:50:42 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -87,6 +87,7 @@
 
 	bool			sc_connected;
 	const struct videomode	*sc_curmode;
+	bool			sc_hdmimode;
 };
 
 static void	tegra_hdmi_hpd(struct tegra_hdmi_softc *);
@@ -94,6 +95,10 @@
 static void	tegra_hdmi_disconnect(struct tegra_hdmi_softc *);
 static void	tegra_hdmi_enable(struct tegra_hdmi_softc *, const uint8_t *);
 static int	tegra_hdmi_sor_start(struct tegra_hdmi_softc *);
+static bool	tegra_hdmi_is_hdmi(struct tegra_hdmi_softc *,
+				   const struct edid_info *);
+static void	tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi_softc *);
+static uint8_t	tegra_hdmi_infoframe_csum(const uint8_t *, size_t);
 
 CFATTACH_DECL_NEW(tegra_hdmi, sizeof(struct tegra_hdmi_softc),
 	tegra_hdmi_match, tegra_hdmi_attach, NULL, NULL);
@@ -230,6 +235,13 @@
 	}
 
 	sc->sc_curmode = mode;
+	sc->sc_hdmimode = tegra_hdmi_is_hdmi(sc, &ei);
+device_printf(sc->sc_dev, "connected to %s display\n", sc->sc_hdmimode ? "HDMI" : "DVI");
+	if (sc->sc_hdmimode == false) {
+		device_printf(sc->sc_dev, "forcing HDMI mode\n");
+		sc->sc_hdmimode = true;
+	}
+
 	tegra_hdmi_enable(sc, pedid);
 }
 
@@ -244,35 +256,34 @@
 	const struct tegra_hdmi_tmds_config *tmds = NULL;
 	const struct videomode *mode = sc->sc_curmode;
 	uint32_t input_ctrl;
-	u_int n;
+	u_int i;
 
 	KASSERT(sc->sc_curmode != NULL);
 	tegra_pmc_hdmi_enable();
 
 	tegra_car_hdmi_enable(mode->dot_clock * 1000);
 
-	for (n = 0; n < __arraycount(tegra_hdmi_tmds_config); n++) {
-		if (tegra_hdmi_tmds_config[n].dot_clock >= mode->dot_clock) {
+	for (i = 0; i < __arraycount(tegra_hdmi_tmds_config); i++) {
+		if (tegra_hdmi_tmds_config[i].dot_clock >= mode->dot_clock) {
 			break;
 		}
 	}
-	if (n < __arraycount(tegra_hdmi_tmds_config)) {
-		tmds = &tegra_hdmi_tmds_config[n];
+	if (i < __arraycount(tegra_hdmi_tmds_config)) {
+		tmds = &tegra_hdmi_tmds_config[i];
 	} else {
 		tmds = &tegra_hdmi_tmds_config[__arraycount(tegra_hdmi_tmds_config) - 1];
 	}
-	if (tmds != NULL) {
-		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PLL0_REG, tmds->sor_pll0);
-		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PLL1_REG, tmds->sor_pll1);
-		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT_REG,
-		    tmds->sor_lane_drive_current);
-		HDMI_WRITE(sc, HDMI_NV_PDISP_PE_CURRENT_REG, tmds->pe_current);
-		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT_REG,
-		    tmds->sor_io_peak_current);
-		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PAD_CTLS0_REG,
-		    tmds->sor_pad_ctls0);
-	}
 
+	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PLL0_REG, tmds->sor_pll0);
+	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PLL1_REG, tmds->sor_pll1);
+	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT_REG,
+	    tmds->sor_lane_drive_current);
+	HDMI_WRITE(sc, HDMI_NV_PDISP_PE_CURRENT_REG, tmds->pe_current);
+	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT_REG,
+	    tmds->sor_io_peak_current);
+	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_PAD_CTLS0_REG,
+	    tmds->sor_pad_ctls0);
+
 	tegra_dc_enable(sc->sc_displaydev, sc->sc_dev, mode, edid);
 
 	const u_int div = (mode->dot_clock / 1000) * 4;
@@ -314,18 +325,58 @@
 	uint32_t ctrl =
 	    __SHIFTIN(rekey, HDMI_NV_PDISP_HDMI_CTRL_REKEY) |
 	    __SHIFTIN(max_ac_packet, HDMI_NV_PDISP_HDMI_CTRL_MAX_AC_PACKET);
-#if notyet
-	if (HDMI mode) {
+	if (sc->sc_hdmimode) {
 		ctrl |= HDMI_NV_PDISP_HDMI_CTRL_ENABLE; /* HDMI ENABLE */
 	}
-#endif
 	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_CTRL_REG, ctrl);
 
-	/* XXX DVI */
-	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL_REG, 0);
-	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_REG, 0);
-	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_REG, 0);
+	if (sc->sc_hdmimode) {
+		const u_int n = 6144;	/* 48 kHz */
+		const u_int cts = ((mode->dot_clock * 10) * (n / 128)) / 480;
 
+		HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_REG,
+		    __SHIFTIN(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT_AUTO,
+			      HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT) |
+		    HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_INJECT_NULLSMPL);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_AUDIO_N_REG,
+		    HDMI_NV_PDISP_AUDIO_N_RESETF |
+		    HDMI_NV_PDISP_AUDIO_N_GENERATE |
+		    __SHIFTIN(n - 1, HDMI_NV_PDISP_AUDIO_N_VALUE));
+
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_SPARE_REG,
+		    HDMI_NV_PDISP_HDMI_SPARE_HW_CTS |
+		    HDMI_NV_PDISP_HDMI_SPARE_FORCE_SW_CTS |
+		    __SHIFTIN(1, HDMI_NV_PDISP_HDMI_SPARE_CTS_RESET_VAL));
+
+		/*
+		 * When HW_CTS=1 and FORCE_SW_CTS=1, the CTS is programmed by
+		 * software in the 44.1 kHz register regardless of chosen rate.
+		 */
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW_REG,
+		    cts << 8);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH_REG,
+		    0x80000000 | n);
+
+		HDMI_SET_CLEAR(sc, HDMI_NV_PDISP_AUDIO_N_REG, 0,
+		    HDMI_NV_PDISP_AUDIO_N_RESETF);
+
+		HDMI_WRITE(sc, 24000, HDMI_NV_PDISP_SOR_AUDIO_AVAL_0480_REG);
+
+		tegra_hdmi_setup_audio_infoframe(sc);
+
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL_REG,
+		    HDMI_NV_PDISP_HDMI_GENERIC_CTRL_AUDIO);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_REG, 0);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_REG,
+		    HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_ENABLE);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_ACR_CTRL_REG, 0);
+	} else {
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_GENERIC_CTRL_REG, 0);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_REG, 0);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_REG, 0);
+		HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_ACR_CTRL_REG, 0);
+	}
+
 	/* Start HDMI output */
 	tegra_dc_hdmi_start(sc->sc_displaydev);
 }
@@ -390,4 +441,100 @@
 	HDMI_WRITE(sc, HDMI_NV_PDISP_SOR_STATE0_REG, 0);
 
 	return 0;
+}
+
+static bool
+tegra_hdmi_is_hdmi(struct tegra_hdmi_softc *sc, const struct edid_info *ei)
+{
+	char edid[128];
+	bool found_hdmi = false;
+	unsigned int n, p;
+
+	/*
+	 * Scan through extension blocks, looking for a CEA-861-D v3
+	 * block. If an HDMI Vendor-Specific Data Block (HDMI VSDB) is
+	 * found in that, assume HDMI mode.
+	 */
+	for (n = 1; n <= MIN(ei->edid_ext_block_count, 4); n++) {
+		if (ddc_dev_read_edid_block(sc->sc_ddcdev, edid,
+		    sizeof(edid), n)) {
+			break;
+		}
+
+		const uint8_t tag = edid[0];
+		const uint8_t rev = edid[1];
+		const uint8_t off = edid[2];
+
+		/* We are looking for a CEA-861-D tag (02h) with revision 3 */
+		if (tag != 0x02 || rev != 3)
+			continue;
+		/*
+		 * CEA data block collection starts at byte 4, so the
+		 * DTD blocks must start after it.
+		 */
+		if (off <= 4)
+			continue;
+
+		/* Parse the CEA data blocks */
+		for (p = 4; p < off;) {
+			const uint8_t btag = (edid[p] >> 5) & 0x7;
+			const uint8_t blen = edid[p] & 0x1f;
+
+			/* Make sure the length is sane */
+			if (p + blen + 1 > off)
+				break;
+			/* Looking for a VSDB tag */
+			if (btag != 3)
+				goto next_block;
+			/* HDMI VSDB is at least 5 bytes long */
+			if (blen < 5)
+				goto next_block;
+
+			/* HDMI 24-bit IEEE registration ID is 0x000C03 */
+			if (memcmp(&edid[p + 1], "\x03\x0c\x00", 3) == 0)
+				found_hdmi = true;
+
+next_block:
+			p += (1 + blen);
+		}
+	}
+
+	return found_hdmi;
+}
+
+static void
+tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi_softc *sc)
+{
+	uint8_t data[10] = {
+		0x84, 0x01, 0x10,
+		0x00,	/* PB0 (checksum) */
+		0x01,	/* CT=0, CC=2ch */
+		0xc0,	/* SS=0, SF=48kHz */
+		0x00,	/* CA=FR/FL */
+		0x00,	/* LSV=0dB, DM_INH=permitted */
+		0x00, 0x00
+	};
+
+	data[3] = tegra_hdmi_infoframe_csum(data, sizeof(data));
+
+	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER_REG,
+	    data[0] | (data[1] << 8) | (data[2] << 16));
+	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW_REG,
+	    data[3] | (data[4] << 8) | (data[5] << 16) | (data[6] << 24));
+	HDMI_WRITE(sc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH_REG,
+	    data[7] | (data[8] << 8) | (data[9] << 16));
+}
+
+static uint8_t
+tegra_hdmi_infoframe_csum(const uint8_t *data, size_t len)
+{
+	uint8_t csum = 0;
+	u_int n;
+
+	for (n = 0; n < len; n++)
+		csum += data[n];
+	if (csum)
+		csum = 0x100 - csum;
+
+	return csum;
 }

cvs diff -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_hdmireg.h (expand / switch to context diff)
--- src/sys/arch/arm/nvidia/tegra_hdmireg.h 2015/07/23 15:08:19 1.3
+++ src/sys/arch/arm/nvidia/tegra_hdmireg.h 2015/07/25 15:50:42 1.4
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_hdmireg.h,v 1.3 2015/07/23 15:08:19 skrll Exp $ */
+/* $NetBSD: tegra_hdmireg.h,v 1.4 2015/07/25 15:50:42 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -59,19 +59,38 @@
 #define HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0_REG			0x06c
 #define HDMI_NV_PDISP_HDMI_AUDIO_EMU1_REG			0x070
 #define HDMI_NV_PDISP_HDMI_AUDIO_EMU2_REG			0x074
+
 #define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_REG		0x078
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_CHKSUM_HW	__BIT(9)
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_SINGLE		__BIT(8)
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_OTHER		__BIT(4)
+#define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL_ENABLE		__BIT(0)
+
 #define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS_REG		0x07c
 #define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER_REG		0x080
 #define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW_REG	0x084
 #define HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH_REG	0x088
+
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_REG		0x08c
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_CHKSUM_HW	__BIT(9)
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_SINGLE		__BIT(8)
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_OTHER		__BIT(4)
+#define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL_ENABLE		__BIT(0)
+
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS_REG		0x090
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER_REG		0x094
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW_REG	0x098
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH_REG	0x09c
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW_REG	0x0a0
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH_REG	0x0a4
+
 #define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_REG			0x0a8
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_AUDIO			__BIT(16)
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_HBLANK			__BIT(12)
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_SINGLE			__BIT(8)
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_OTHER			__BIT(4)
+#define HDMI_NV_PDISP_HDMI_GENERIC_CTRL_ENABLE			__BIT(0)
+
 #define HDMI_NV_PDISP_HDMI_GENERIC_STATUS_REG			0x0ac
 #define HDMI_NV_PDISP_HDMI_GENERIC_HEADER_REG			0x0b0
 #define HDMI_NV_PDISP_HDMI_GENERIC_INFOFRAME_SUBPACK0_LOW_REG	0x0b4
@@ -121,7 +140,12 @@
 #define HDMI_NV_PDISP_HDMI_EMU0_REG				0x130
 #define HDMI_NV_PDISP_HDMI_EMU1_REG				0x134
 #define HDMI_NV_PDISP_HDMI_EMU1_RDATA_REG			0x138
+
 #define HDMI_NV_PDISP_HDMI_SPARE_REG				0x13c
+#define HDMI_NV_PDISP_HDMI_SPARE_HW_CTS				__BIT(0)
+#define HDMI_NV_PDISP_HDMI_SPARE_FORCE_SW_CTS			__BIT(1)
+#define HDMI_NV_PDISP_HDMI_SPARE_CTS_RESET_VAL			__BITS(18,16)
+
 #define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1_REG		0x140
 #define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STAUTS2_REG		0x144
 #define HDMI_NV_PDISP_CRC_CONTROL_REG				0x258
@@ -271,7 +295,30 @@
  * Audio Registers
  */
 #define HDMI_NV_PDISP_AUDIO_N_REG				0x230
+#define HDMI_NV_PDISP_AUDIO_N_LOOKUP				__BIT(28)
+#define HDMI_NV_PDISP_AUDIO_N_GENERATE				__BIT(24)
+#define HDMI_NV_PDISP_AUDIO_N_RESETF				__BIT(20)
+#define HDMI_NV_PDISP_AUDIO_N_VALUE				__BITS(19,0)
+
 #define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_REG			0x2b0
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_INPUT_MODE		__BIT(31)
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_INJECT_NULLSMPL		__BIT(29)
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT		__BITS(21,20)
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT_AUTO	0
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT_SPDIF	1
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SOURCE_SELECT_HDAL	2
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ		__BITS(19,16)
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_32_0KHZ	3
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_44_1KHZ	0
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_88_2KHZ	8
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_176_4KHZ	12
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_48_0KHZ	2
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_96_0KHZ	10
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_192_0KHZ	14
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_SAMPLING_FREQ_UNKNOWN	1
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_AFIFO_FLUSH		__BIT(12)
+#define HDMI_NV_PDISP_SOR_AUDIO_CNTRL0_PORT_CONNECTIVITY	__BIT(0)
+
 #define HDMI_NV_PDISP_SOR_AUDIO_DEBUG_REG			0x2b4
 #define HDMI_NV_PDISP_SOR_AUDIO_SPARE0_REG			0x2b8
 #define HDMI_NV_PDISP_SOR_AUDIO_NVAL_0320_REG			0x2bc