video: tegra: add HDMI support
authorErik Gilling <konkers@android.com>
Fri, 3 Sep 2010 22:32:42 +0000 (15:32 -0700)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:28:27 +0000 (16:28 -0700)
Previous implementation was DVI only

Change-Id: I6e7defb0cf73a1cf094e330715a2a302fd273589
Signed-off-by: Erik Gilling <konkers@android.com>
drivers/video/tegra/dc/hdmi.c
drivers/video/tegra/dc/hdmi.h [new file with mode: 0644]
drivers/video/tegra/dc/hdmi_reg.h

index d5816ba30d396de41f7cc9e6d4c2170ef791ed66..1906d086d666ff3d3aad3eab81152f57d4eda89e 100644 (file)
 #include "dc_reg.h"
 #include "dc_priv.h"
 #include "hdmi_reg.h"
+#include "hdmi.h"
 #include "edid.h"
 
+/* datasheet claims this will always be 216MHz */
+#define HDMI_AUDIOCLK_FREQ             216000000
+
+#define HDMI_REKEY_DEFAULT             56
+
 struct tegra_dc_hdmi_data {
        struct tegra_dc                 *dc;
        struct tegra_edid               *edid;
@@ -122,6 +128,71 @@ const struct fb_videomode tegra_dc_hdmi_supported_modes[] = {
        },
 };
 
+struct tegra_hdmi_audio_config {
+       unsigned pix_clock;
+       unsigned n;
+       unsigned cts;
+};
+
+const struct tegra_hdmi_audio_config tegra_hdmi_audio_32k[] = {
+       {25200000,      4096,   25250},
+       {27000000,      4096,   27000},
+       {54000000,      4096,   54000},
+       {74250000,      4096,   74250},
+       {148500000,     4096,   148500},
+       {0,             0,      0},
+};
+
+const struct tegra_hdmi_audio_config tegra_hdmi_audio_44_1k[] = {
+       {25200000,      14112,  63125},
+       {27000000,      6272,   30000},
+       {54000000,      6272,   60000},
+       {74250000,      6272,   82500},
+       {148500000,     6272,   165000},
+       {0,             0,      0},
+};
+
+const struct tegra_hdmi_audio_config tegra_hdmi_audio_48k[] = {
+       {25200000,      6144,   25250},
+       {27000000,      6144,   27000},
+       {54000000,      6144,   54000},
+       {74250000,      6144,   74250},
+       {148500000,     6144,   148500},
+       {0,             0,      0},
+};
+
+static const struct tegra_hdmi_audio_config
+*tegra_hdmi_get_audio_config(unsigned audio_freq, unsigned pix_clock)
+{
+       const struct tegra_hdmi_audio_config *table;
+
+       switch (audio_freq) {
+       case 32000:
+               table = tegra_hdmi_audio_32k;
+               break;
+
+       case 44100:
+               table = tegra_hdmi_audio_44_1k;
+               break;
+
+       case 48000:
+               table = tegra_hdmi_audio_48k;
+               break;
+
+       default:
+               return NULL;
+       }
+
+       while (table->pix_clock) {
+               if (table->pix_clock == pix_clock)
+                       return table;
+               table++;
+       }
+
+       return NULL;
+}
+
+
 static inline unsigned long tegra_hdmi_readl(struct tegra_dc_hdmi_data *hdmi,
                                             unsigned long reg)
 {
@@ -279,13 +350,13 @@ static void hdmi_dumpregs(struct tegra_dc_hdmi_data *hdmi)
        DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG0);
        DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG1);
        DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG2);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS1);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS2);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS3);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS4);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS5);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS6);
-       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS7);
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(0));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(1));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(2));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(3));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(4));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(5));
+       DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(6));
        DUMP_REG(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH);
        DUMP_REG(HDMI_NV_PDISP_AUDIO_THRESHOLD);
        DUMP_REG(HDMI_NV_PDISP_AUDIO_CNTRL0);
@@ -495,6 +566,217 @@ static void tegra_dc_hdmi_destroy(struct tegra_dc *dc)
 
 }
 
+static void tegra_dc_hdmi_setup_audio_fs_tables(struct tegra_dc *dc)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       int i;
+       unsigned freqs[] = {
+               32000,
+               44100,
+               48000,
+               88200,
+               96000,
+               176400,
+               192000,
+        };
+
+       for (i = 0; i < ARRAY_SIZE(freqs); i++) {
+               unsigned f = freqs[i];
+               unsigned eight_half;
+               unsigned delta;;
+
+               if (f > 96000)
+                       delta = 2;
+               else if (f > 48000)
+                       delta = 6;
+               else
+                       delta = 9;
+
+               eight_half = (8 * HDMI_AUDIOCLK_FREQ) / (f * 128);
+               tegra_hdmi_writel(hdmi, AUDIO_FS_LOW(eight_half - delta) |
+                                 AUDIO_FS_HIGH(eight_half + delta),
+                                 HDMI_NV_PDISP_AUDIO_FS(i));
+       }
+}
+
+static int tegra_dc_hdmi_setup_audio(struct tegra_dc *dc)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       const struct tegra_hdmi_audio_config *config;
+       unsigned long audio_n;
+       unsigned audio_freq = 44100; /* TODO: find some way of configuring this */
+
+       tegra_hdmi_writel(hdmi,
+                         AUDIO_CNTRL0_ERROR_TOLERANCE(9) |
+                         AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0) |
+                         AUDIO_CNTRL0_SOURCE_SELECT_AUTO,
+                         HDMI_NV_PDISP_AUDIO_CNTRL0);
+
+       config = tegra_hdmi_get_audio_config(audio_freq, dc->mode.pclk);
+       if (!config) {
+               dev_err(&dc->ndev->dev,
+                       "hdmi: can't set audio to %d at %d pix_clock",
+                       audio_freq, dc->mode.pclk);
+               return -EINVAL;
+       }
+
+       tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_HDMI_ACR_CTRL);
+
+       audio_n = AUDIO_N_RESETF | AUDIO_N_GENERATE_ALTERNALTE |
+               AUDIO_N_VALUE(config->n);
+       tegra_hdmi_writel(hdmi, audio_n, HDMI_NV_PDISP_AUDIO_N);
+
+       tegra_hdmi_writel(hdmi, ACR_SUBPACK_N(config->n) | ACR_ENABLE,
+                         HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
+       tegra_hdmi_writel(hdmi, ACR_SUBPACK_CTS(config->n),
+                         HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
+
+       tegra_hdmi_writel(hdmi, SPARE_HW_CTS | SPARE_FORCE_SW_CTS |
+                         SPARE_CTS_RESET_VAL(1),
+                         HDMI_NV_PDISP_HDMI_SPARE);
+
+       audio_n &= ~AUDIO_N_RESETF;
+       tegra_hdmi_writel(hdmi, audio_n, HDMI_NV_PDISP_AUDIO_N);
+
+       tegra_dc_hdmi_setup_audio_fs_tables(dc);
+
+       return 0;
+}
+
+static void tegra_dc_hdmi_write_infopack(struct tegra_dc *dc, int header_reg,
+                                        u8 type, u8 version, void *data, int len)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       u32 subpack[2];  /* extra byte for zero padding of subpack */
+       int i;
+       u8 csum;
+
+       /* first byte of data is the checksum */
+       csum = type + version + len - 1;
+       for (i = 1; i < len; i++)
+               csum +=((u8 *)data)[i];
+       ((u8 *)data)[0] = 0x100 - csum;
+
+       tegra_hdmi_writel(hdmi, INFOFRAME_HEADER_TYPE(type) |
+                         INFOFRAME_HEADER_VERSION(version) |
+                         INFOFRAME_HEADER_LEN(len - 1),
+                         header_reg);
+
+       /* The audio inforame only has one set of subpack registers.  The hdmi
+        * block pads the rest of the data as per the spec so we have to fixup
+        * the length before filling in the subpacks.
+        */
+       if (header_reg == HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER)
+               len = 6;
+
+       /* each subpack 7 bytes devided into:
+        *   subpack_low - bytes 0 - 3
+        *   subpack_high - bytes 4 - 6 (with byte 7 padded to 0x00)
+        */
+       for (i = 0; i < len; i++) {
+               int subpack_idx = i % 7;
+
+               if (subpack_idx == 0)
+                       memset(subpack, 0x0, sizeof(subpack));
+
+               ((u8 *)subpack)[subpack_idx] = ((u8 *)data)[i];
+
+               if (subpack_idx == 6 || (i + 1 == len)) {
+                       int reg = header_reg + 1 + (i / 7) * 2;
+
+                       tegra_hdmi_writel(hdmi, subpack[0], reg);
+                       tegra_hdmi_writel(hdmi, subpack[1], reg + 1);
+               }
+       }
+}
+
+static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       struct hdmi_avi_infoframe avi;
+
+       if (dvi) {
+               tegra_hdmi_writel(hdmi, 0x0,
+                                 HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
+               return;
+       }
+
+       memset(&avi, 0x0, sizeof(avi));
+
+       avi.r = HDMI_AVI_R_SAME;
+
+       if (dc->mode.v_active == 480) {
+               if (dc->mode.h_active == 640) {
+                       avi.m = HDMI_AVI_M_4_3;
+                       avi.vic = 1;
+               } else {
+                       avi.m = HDMI_AVI_M_16_9;
+                       avi.vic = 3;
+               }
+       } else if (dc->mode.v_active == 576) {
+               /* CEC modes 17 and 18 differ only by the pysical size of the
+                * screen so we have to calculation the physical aspect
+                * ratio.  4 * 10 / 3  is 13
+                */
+               if ((dc->out->h_size * 10) / dc->out->v_size > 14) {
+                       avi.m = HDMI_AVI_M_16_9;
+                       avi.vic = 18;
+               } else {
+                       avi.m = HDMI_AVI_M_16_9;
+                       avi.vic = 17;
+               }
+       } else if (dc->mode.v_active == 720) {
+               avi.m = HDMI_AVI_M_16_9;
+               if (dc->mode.h_front_porch == 110)
+                       avi.vic = 4; /* 60 Hz */
+               else
+                       avi.vic = 19; /* 50 Hz */
+       } else if (dc->mode.v_active == 720) {
+               avi.m = HDMI_AVI_M_16_9;
+               if (dc->mode.h_front_porch == 88)
+                       avi.vic = 16; /* 60 Hz */
+               else if (dc->mode.h_front_porch == 528)
+                       avi.vic = 31; /* 50 Hz */
+               else
+                       avi.vic = 32; /* 24 Hz */
+       } else {
+               avi.m = HDMI_AVI_M_16_9;
+               avi.vic = 0;
+       }
+
+
+       tegra_dc_hdmi_write_infopack(dc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER,
+                                    HDMI_INFOFRAME_TYPE_AVI,
+                                    HDMI_AVI_VERSION,
+                                    &avi, sizeof(avi));
+
+       tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
+                         HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
+}
+
+static void tegra_dc_hdmi_setup_audio_infoframe(struct tegra_dc *dc, bool dvi)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       struct hdmi_audio_infoframe audio;
+
+       if (dvi) {
+               tegra_hdmi_writel(hdmi, 0x0,
+                                 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
+               return;
+       }
+
+       memset(&audio, 0x0, sizeof(audio));
+
+       audio.cc = HDMI_AUDIO_CC_2;
+       tegra_dc_hdmi_write_infopack(dc, HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER,
+                                    HDMI_INFOFRAME_TYPE_AUDIO,
+                                    HDMI_AUDIO_VERSION,
+                                    &audio, sizeof(audio));
+
+       tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
+                         HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
+}
+
 static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
 {
        struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
@@ -504,7 +786,10 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
        int pll1;
        int ds;
        int retries;
+       int rekey;
+       int err;
        unsigned long val;
+       bool dvi = false;
 
        /* enbale power, clocks, resets, etc. */
        tegra_dc_setup_clk(dc, hdmi->clk);
@@ -544,8 +829,6 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
                          VSYNC_WINDOW_ENABLE,
                          HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
 
-       /* TODO: scale output to 16-235 */
-
        tegra_hdmi_writel(hdmi,
                          (dc->ndev->id ? HDMI_SRC_DISPLAYB : HDMI_SRC_DISPLAYA) |
                          ARM_VIDEO_RANGE_LIMITED,
@@ -559,30 +842,30 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
 
        /* TODO: setup audio */
 
-       /* values from harmony board.  Will be replaced when
-        * audio and avi are supported */
-       tegra_hdmi_writel(hdmi, 0x00000001, 0x1e);
-       tegra_hdmi_writel(hdmi, 0x00000000, 0x20);
-       tegra_hdmi_writel(hdmi, 0x000000aa, 0x21);
-       tegra_hdmi_writel(hdmi, 0x00000001, 0x23);
-       tegra_hdmi_writel(hdmi, 0x00000001, 0x24);
-       tegra_hdmi_writel(hdmi, 0x00000000, 0x25);
-       tegra_hdmi_writel(hdmi, 0x000445eb, 0x26);
-       tegra_hdmi_writel(hdmi, 0x00000004, 0x27);
-       tegra_hdmi_writel(hdmi, 0x00002710, 0x2a);
-       tegra_hdmi_writel(hdmi, 0x00000000, 0x35);
-       tegra_hdmi_writel(hdmi, 0x0015bc10, 0x38);
-       tegra_hdmi_writel(hdmi, 0x04c4bb58, 0x39);
-       tegra_hdmi_writel(hdmi, 0x0263b9b6, 0x44);
-       tegra_hdmi_writel(hdmi, 0x00002713, 0x4f);
-       tegra_hdmi_writel(hdmi, 0x01e85426, 0x57);
-       tegra_hdmi_writel(hdmi, 0x001136c2, 0x89);
-       tegra_hdmi_writel(hdmi, 0x00000730, 0x8a);
-       tegra_hdmi_writel(hdmi, 0x0001875b, 0x8c);
-       tegra_hdmi_writel(hdmi, 0x00000000, 0x9d);
-
-       tegra_hdmi_writel(hdmi, 0x40090038, HDMI_NV_PDISP_HDMI_CTRL);
-       tegra_hdmi_writel(hdmi, 0x0, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       err = tegra_dc_hdmi_setup_audio(dc);
+       if (err < 0)
+               dvi = true;
+
+       rekey = HDMI_REKEY_DEFAULT;
+       val = HDMI_CTRL_REKEY(rekey);
+       val |= HDMI_CTRL_MAX_AC_PACKET((dc->mode.h_sync_width +
+                                       dc->mode.h_back_porch +
+                                       dc->mode.h_front_porch -
+                                       rekey - 18) / 32);
+       if (!dvi)
+               val |= HDMI_CTRL_ENABLE;
+       tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_CTRL);
+
+       if (dvi)
+               tegra_hdmi_writel(hdmi, 0x0,
+                                 HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       else
+               tegra_hdmi_writel(hdmi, GENERIC_CTRL_AUDIO,
+                                 HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+
+
+       tegra_dc_hdmi_setup_avi_infoframe(dc, dvi);
+       tegra_dc_hdmi_setup_audio_infoframe(dc, dvi);
 
        /* TMDS CONFIG */
        pll0 = 0x200033f;
diff --git a/drivers/video/tegra/dc/hdmi.h b/drivers/video/tegra/dc/hdmi.h
new file mode 100644 (file)
index 0000000..0189f08
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * drivers/video/tegra/dc/hdmi.h
+ *
+ * non-tegra specific HDMI declarations
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling <konkers@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_VIDEO_TEGRA_DC_HDMI_H
+#define __DRIVERS_VIDEO_TEGRA_DC_HDMI_H
+
+#define HDMI_INFOFRAME_TYPE_VENDOR     0x81
+#define HDMI_INFOFRAME_TYPE_AVI                0x82
+#define HDMI_INFOFRAME_TYPE_SPD                0x83
+#define HDMI_INFOFRAME_TYPE_AUDIO      0x84
+#define HDMI_INFOFRAME_TYPE_MPEG_SRC   0x85
+#define HDMI_INFOFRAME_TYPE_NTSC_VBI   0x86
+
+/* all fields little endian */
+struct hdmi_avi_infoframe {
+       /* PB0 */
+       u8              csum;
+
+       /* PB1 */
+       unsigned        s:2;    /* scan information */
+       unsigned        b:2;    /* bar info data valid */
+       unsigned        a:1;    /* active info present */
+       unsigned        y:2;    /* RGB or YCbCr */
+       unsigned        res1:1;
+
+       /* PB2 */
+       unsigned        r:4;    /* active format aspect ratio */
+       unsigned        m:2;    /* picture aspect ratio */
+       unsigned        c:2;    /* colorimetry */
+
+       /* PB3 */
+       unsigned        sc:2;   /* scan information */
+       unsigned        q:2;    /* quantization range */
+       unsigned        ec:3;   /* extended colorimetry */
+       unsigned        itc:1;  /* it content */
+
+       /* PB4 */
+       unsigned        vic:7;  /* video format id code */
+       unsigned        res4:1;
+
+       /* PB5 */
+       unsigned        pr:4;   /* pixel repetition factor */
+       unsigned        cn:2;   /* it content type*/
+       unsigned        yq:2;   /* ycc quantization range */
+
+       /* PB6-7 */
+       u16             top_bar_end_line;
+
+       /* PB8-9 */
+       u16             bot_bar_start_line;
+
+       /* PB10-11 */
+       u16             left_bar_end_pixel;
+
+       /* PB12-13 */
+       u16             right_bar_start_pixel;
+} __attribute__((packed));
+
+#define HDMI_AVI_VERSION               0x02
+
+#define HDMI_AVI_Y_RGB                 0x0
+#define HDMI_AVI_Y_YCBCR_422           0x1
+#define HDMI_AVI_Y_YCBCR_444           0x2
+
+#define HDMI_AVI_B_VERT                        0x1
+#define HDMI_AVI_B_HORIZ               0x2
+
+#define HDMI_AVI_S_NONE                        0x0
+#define HDMI_AVI_S_OVERSCAN            0x1
+#define HDMI_AVI_S_UNDERSCAN           0x2
+
+#define HDMI_AVI_C_NONE                        0x0
+#define HDMI_AVI_C_SMPTE               0x1
+#define HDMI_AVI_C_ITU_R               0x2
+#define HDMI_AVI_C_EXTENDED            0x4
+
+#define HDMI_AVI_M_4_3                 0x1
+#define HDMI_AVI_M_16_9                        0x2
+
+#define HDMI_AVI_R_SAME                        0x8
+#define HDMI_AVI_R_4_3_CENTER          0x9
+#define HDMI_AVI_R_16_9_CENTER         0xa
+#define HDMI_AVI_R_14_9_CENTER         0xb
+
+/* all fields little endian */
+struct hdmi_audio_infoframe {
+       /* PB0 */
+       u8              csum;
+
+       /* PB1 */
+       unsigned        cc:3;           /* channel count */
+       unsigned        res1:1;
+       unsigned        ct:4;           /* coding type */
+
+       /* PB2 */
+       unsigned        ss:2;           /* sample size */
+       unsigned        sf:3;           /* sample frequency */
+       unsigned        res2:3;
+
+       /* PB3 */
+       unsigned        cxt:5;          /* coding extention type */
+       unsigned        res3:3;
+
+       /* PB4 */
+       u8              ca;             /* channel/speaker allocation */
+
+       /* PB5 */
+       unsigned        res5:3;
+       unsigned        lsv:4;          /* level shift value */
+       unsigned        dm_inh:1;       /* downmix inhibit */
+
+       /* PB6-10 reserved */
+       u8              res6;
+       u8              res7;
+       u8              res8;
+       u8              res9;
+       u8              res10;
+} __attribute__((packed));
+
+#define HDMI_AUDIO_VERSION             0x01
+
+#define HDMI_AUDIO_CC_STREAM           0x0 /* specified by audio stream */
+#define HDMI_AUDIO_CC_2                        0x1
+#define HDMI_AUDIO_CC_3                        0x2
+#define HDMI_AUDIO_CC_4                        0x3
+#define HDMI_AUDIO_CC_5                        0x4
+#define HDMI_AUDIO_CC_6                        0x5
+#define HDMI_AUDIO_CC_7                        0x6
+#define HDMI_AUDIO_CC_8                        0x7
+
+#define HDMI_AUDIO_CT_STREAM           0x0 /* specified by audio stream */
+#define HDMI_AUDIO_CT_PCM              0x1
+#define HDMI_AUDIO_CT_AC3              0x2
+#define HDMI_AUDIO_CT_MPEG1            0x3
+#define HDMI_AUDIO_CT_MP3              0x4
+#define HDMI_AUDIO_CT_MPEG2            0x5
+#define HDMI_AUDIO_CT_AAC_LC           0x6
+#define HDMI_AUDIO_CT_DTS              0x7
+#define HDMI_AUDIO_CT_ATRAC            0x8
+#define HDMI_AUDIO_CT_DSD              0x9
+#define HDMI_AUDIO_CT_E_AC3            0xa
+#define HDMI_AUDIO_CT_DTS_HD           0xb
+#define HDMI_AUDIO_CT_MLP              0xc
+#define HDMI_AUDIO_CT_DST              0xd
+#define HDMI_AUDIO_CT_WMA_PRO          0xe
+#define HDMI_AUDIO_CT_CXT              0xf
+
+#define HDMI_AUDIO_SF_STREAM           0x0 /* specified by audio stream */
+#define HDMI_AUIDO_SF_32K              0x1
+#define HDMI_AUDIO_SF_44_1K            0x2
+#define HDMI_AUDIO_SF_48K              0x3
+#define HDMI_AUDIO_SF_88_2K            0x4
+#define HDMI_AUDIO_SF_96K              0x5
+#define HDMI_AUDIO_SF_176_4K           0x6
+#define HDMI_AUDIO_SF_192K             0x7
+
+#define HDMI_AUDIO_SS_STREAM           0x0 /* specified by audio stream */
+#define HDMI_AUDIO_SS_16BIT            0x1
+#define HDMI_AUDIO_SS_20BIT            0x2
+#define HDMI_AUDIO_SS_24BIT            0x3
+
+#define HDMI_AUDIO_CXT_CT              0x0 /* refer to coding in CT */
+#define HDMI_AUDIO_CXT_HE_AAC          0x1
+#define HDMI_AUDIO_CXT_HE_AAC_V2       0x2
+#define HDMI_AUDIO_CXT_MPEG_SURROUND   0x3
+
+#endif
index 862f8d62646750aa571bc2b343aca9166015105d..67d2b23a3d81198f0b6a1fb6661f6741d67bc392 100644 (file)
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH         0x27
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW          0x28
 #define HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH         0x29
+#define  INFOFRAME_CTRL_ENABLE                 (1 << 0)
+#define  INFOFRAME_CTRL_OTHER                  (1 << 4)
+#define  INFOFRAME_CTRL_SINGLE                 (1 << 8)
+
+#define INFOFRAME_HEADER_TYPE(x)               ((x) & 0xff)
+#define INFOFRAME_HEADER_VERSION(x)            (((x) & 0xff) << 8)
+#define INFOFRAME_HEADER_LEN(x)                        (((x) & 0xf) << 16)
+
 #define HDMI_NV_PDISP_HDMI_GENERIC_CTRL                                0x2a
+#define  GENERIC_CTRL_ENABLE                   (1 << 0)
+#define  GENERIC_CTRL_OTHER                    (1 << 4)
+#define  GENERIC_CTRL_SINGLE                   (1 << 8)
+#define  GENERIC_CTRL_HBLANK                   (1 << 12)
+#define  GENERIC_CTRL_AUDIO                    (1 << 16)
+
 #define HDMI_NV_PDISP_HDMI_GENERIC_STATUS                      0x2b
 #define HDMI_NV_PDISP_HDMI_GENERIC_HEADER                      0x2c
 #define HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW                        0x2d
 #define HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH               0x41
 #define HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW                        0x42
 #define HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH               0x43
+#define  ACR_SB3(x)                            (((x) & 0xff) << 8)
+#define  ACR_SB2(x)                            (((x) & 0xff) << 16)
+#define  ACR_SB1(x)                            (((x) & 0xff) << 24)
+#define  ACR_SUBPACK_CTS(x)                    (((x) & 0xffffff) << 8)
+
+#define  ACR_SB6(x)                            (((x) & 0xff) << 0)
+#define  ACR_SB5(x)                            (((x) & 0xff) << 8)
+#define  ACR_SB4(x)                            (((x) & 0xff) << 16)
+#define  ACR_ENABLE                            (1 << 31)
+#define  ACR_SUBPACK_N(x)                      ((x) & 0xffffff)
+
 #define HDMI_NV_PDISP_HDMI_CTRL                                        0x44
 #define  HDMI_CTRL_REKEY(x)                    (((x) & 0x7f) << 0)
 #define  HDMI_CTRL_AUDIO_LAYOUT                        (1 << 8)
 #define HDMI_NV_PDISP_HDMI_EMU1                                        0x4d
 #define HDMI_NV_PDISP_HDMI_EMU1_RDATA                          0x4e
 #define HDMI_NV_PDISP_HDMI_SPARE                               0x4f
+#define  SPARE_HW_CTS                          (1 << 0)
+#define  SPARE_FORCE_SW_CTS                    (1 << 1)
+#define  SPARE_CTS_RESET_VAL(x)                        (((x) & 0x7) << 16)
+#define  SPARE_ACR_PRIORITY_HIGH               (0 << 31)
+#define  SPARE_ACR_PRIORITY_LOW                        (1 << 31)
+
 #define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1                   0x50
 #define HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2                   0x51
 #define HDMI_NV_PDISP_HDCPRIF_ROM_CTRL                         0x53
 #define HDMI_NV_PDISP_AUDIO_DEBUG0                             0x7f
 #define HDMI_NV_PDISP_AUDIO_DEBUG1                             0x80
 #define HDMI_NV_PDISP_AUDIO_DEBUG2                             0x81
-#define HDMI_NV_PDISP_AUDIO_FS1                                        0x82
-#define HDMI_NV_PDISP_AUDIO_FS2                                        0x83
-#define HDMI_NV_PDISP_AUDIO_FS3                                        0x84
-#define HDMI_NV_PDISP_AUDIO_FS4                                        0x85
-#define HDMI_NV_PDISP_AUDIO_FS5                                        0x86
-#define HDMI_NV_PDISP_AUDIO_FS6                                        0x87
-#define HDMI_NV_PDISP_AUDIO_FS7                                        0x88
+/* note: datasheet defines FS1..FS7.  we have FS(0)..FS(6) */
+#define HDMI_NV_PDISP_AUDIO_FS(x)                              (0x82 + (x))
+#define  AUDIO_FS_LOW(x)                       (((x) & 0xfff) << 0)
+#define  AUDIO_FS_HIGH(x)                      (((x) & 0xfff) << 16)
+
+
 #define HDMI_NV_PDISP_AUDIO_PULSE_WIDTH                                0x89
 #define HDMI_NV_PDISP_AUDIO_THRESHOLD                          0x8a
 #define HDMI_NV_PDISP_AUDIO_CNTRL0                             0x8b
+#define  AUDIO_CNTRL0_ERROR_TOLERANCE(x)       (((x) & 0xff) << 0)
+#define  AUDIO_CNTRL0_SOFT_RESET               (1 << 8)
+#define  AUDIO_CNTRL0_SOFT_RESET_ALL           (1 << 12)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_UNKNOWN    (1 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_32K                (2 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_44_1K      (0 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_48K                (2 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_88_2K      (8 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_96K                (10 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_176_4K     (12 << 16)
+#define  AUDIO_CNTRL0_SAMPLING_FREQ_192K       (14 << 16)
+#define  AUDIO_CNTRL0_SOURCE_SELECT_AUTO       (0 << 20)
+#define  AUDIO_CNTRL0_SOURCE_SELECT_SPDIF      (1 << 20)
+#define  AUDIO_CNTRL0_SOURCE_SELECT_HDAL       (2 << 20)
+#define  AUDIO_CNTRL0_FRAMES_PER_BLOCK(x)      (((x) & 0xff) << 24)
+
 #define HDMI_NV_PDISP_AUDIO_N                                  0x8c
+#define  AUDIO_N_VALUE(x)                      (((x) & 0xfffff) << 0)
+#define  AUDIO_N_RESETF                                (1 << 20)
+#define  AUDIO_N_GENERATE_NORMAL               (0 << 24)
+#define  AUDIO_N_GENERATE_ALTERNALTE           (1 << 24)
+#define  AUDIO_N_LOOKUP_ENABLE                 (1 << 28)
+
 #define HDMI_NV_PDISP_HDCPRIF_ROM_TIMING                       0x94
 #define HDMI_NV_PDISP_SOR_REFCLK                               0x95
 #define  SOR_REFCLK_DIV_INT(x)                 (((x) & 0xff) << 8)