video: tegra: add HDMI support

Previous implementation was DVI only

Change-Id: I6e7defb0cf73a1cf094e330715a2a302fd273589
Signed-off-by: Erik Gilling <konkers@android.com>
This commit is contained in:
Erik Gilling 2010-09-03 15:32:42 -07:00 committed by Colin Cross
parent e8118b168b
commit d6f0cc113a
3 changed files with 557 additions and 39 deletions

View File

@ -33,8 +33,14 @@
#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);
err = tegra_dc_hdmi_setup_audio(dc);
if (err < 0)
dvi = true;
tegra_hdmi_writel(hdmi, 0x40090038, HDMI_NV_PDISP_HDMI_CTRL);
tegra_hdmi_writel(hdmi, 0x0, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
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;

View File

@ -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

View File

@ -88,7 +88,21 @@
#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
@ -114,6 +128,17 @@
#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)
@ -136,6 +161,12 @@
#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
@ -334,17 +365,38 @@
#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)