mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 15:42:19 +02:00
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:
parent
e8118b168b
commit
d6f0cc113a
|
|
@ -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;
|
||||
|
|
|
|||
183
drivers/video/tegra/dc/hdmi.h
Normal file
183
drivers/video/tegra/dc/hdmi.h
Normal 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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user