From d6f0cc113ab1939b1b0963fb52e0b0db577bc792 Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Fri, 3 Sep 2010 15:32:42 -0700 Subject: [PATCH] video: tegra: add HDMI support Previous implementation was DVI only Change-Id: I6e7defb0cf73a1cf094e330715a2a302fd273589 Signed-off-by: Erik Gilling --- drivers/video/tegra/dc/hdmi.c | 349 +++++++++++++++++++++++++++--- drivers/video/tegra/dc/hdmi.h | 183 ++++++++++++++++ drivers/video/tegra/dc/hdmi_reg.h | 66 +++++- 3 files changed, 558 insertions(+), 40 deletions(-) create mode 100644 drivers/video/tegra/dc/hdmi.h diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c index d5816ba30d39..1906d086d666 100644 --- a/drivers/video/tegra/dc/hdmi.c +++ b/drivers/video/tegra/dc/hdmi.c @@ -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); - - 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 index 000000000000..0189f08719fe --- /dev/null +++ b/drivers/video/tegra/dc/hdmi.h @@ -0,0 +1,183 @@ +/* + * drivers/video/tegra/dc/hdmi.h + * + * non-tegra specific HDMI declarations + * + * Copyright (C) 2010 Google, Inc. + * Author: Erik Gilling + * + * 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 diff --git a/drivers/video/tegra/dc/hdmi_reg.h b/drivers/video/tegra/dc/hdmi_reg.h index 862f8d626467..67d2b23a3d81 100644 --- a/drivers/video/tegra/dc/hdmi_reg.h +++ b/drivers/video/tegra/dc/hdmi_reg.h @@ -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) -- 2.34.1