summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2012-12-11 13:02:12 -0800
committerMandar Padmawar <mpadmawar@nvidia.com>2013-01-27 23:55:13 -0800
commit715942e13fcf90ea64fe448ed2aebc687a2b5323 (patch)
tree4d315afbcb4f40ac0ca6bdf207a45e7a46c62848 /drivers/video/tegra/dc
parent9b6b5e13eff90ff25292e99a92f2a6ea4050770a (diff)
video: tegra: dc: support HDMI avi format values
Support all HDMI VIC format values using cea_modes[] list for determining the the AVI format number. Stores aspect ratio in fb_videmode and tegra_dc_mode so that ambiguous modes are resolved. Bug 1167856 Bug 1173814 Change-Id: Icf66753732076b99dd0ff0163f4a4f6a9f90ae57 Signed-off-by: Jon Mayo <jmayo@nvidia.com> Reviewed-on: http://git-master/r/170279 (cherry picked from commit e9f8abd89c1c2ac222ab0233448d391057ce3c93) Reviewed-on: http://git-master/r/193498 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Rakesh Iyer <riyer@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc')
-rw-r--r--drivers/video/tegra/dc/hdmi.c75
-rw-r--r--drivers/video/tegra/dc/mode.c20
2 files changed, 49 insertions, 46 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index 07eacd6c0d09..27f70148f5a8 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -1496,6 +1496,30 @@ static void tegra_dc_hdmi_write_infopack(struct tegra_dc *dc, int header_reg,
}
}
+static int tegra_dc_find_cea_vic(const struct tegra_dc_mode *mode)
+{
+ struct fb_videomode m;
+ unsigned i;
+
+ tegra_dc_to_fb_videomode(&m, mode);
+
+ for (i = 1; i < CEA_MODEDB_SIZE; i++) {
+ const struct fb_videomode *curr = &cea_modes[i];
+ if (fb_mode_is_equal(&m, curr)) {
+ /* if either flag is set, then match is required */
+ if (m.flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9)) {
+ if (m.flag & curr->flag & FB_FLAG_RATIO_4_3)
+ return i;
+ if (m.flag & curr->flag & FB_FLAG_RATIO_16_9)
+ return i;
+ } else {
+ return i;
+ }
+ }
+ }
+ return 0;
+}
+
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);
@@ -1516,52 +1540,9 @@ static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
else
tegra_dc_writel(dc, 0x00000000, DC_DISP_BORDER_COLOR);
- 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_4_3;
- avi.vic = 17;
- }
- } else if (dc->mode.v_active == 720 ||
- (dc->mode.v_active == 1470 && dc->mode.stereo_mode)) {
- /* VIC for both 720p and 720p 3D mode */
- 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 == 1080 ||
- (dc->mode.v_active == 2205 && dc->mode.stereo_mode)) {
- /* VIC for both 1080p and 1080p 3D mode */
- avi.m = HDMI_AVI_M_16_9;
- if (dc->mode.h_front_porch == 88) {
- if (dc->mode.pclk > 74250000)
- avi.vic = 16; /* 60 Hz */
- else
- avi.vic = 34; /* 30 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;
- }
-
+ avi.vic = tegra_dc_find_cea_vic(&dc->mode);
+ avi.m = dc->mode.avi_m;
+ dev_dbg(&dc->ndev->dev, "HDMI AVI vic=%d m=%d\n", avi.vic, avi.m);
tegra_dc_hdmi_write_infopack(dc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER,
HDMI_INFOFRAME_TYPE_AVI,
@@ -1705,6 +1686,7 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
/* program HDMI registers and SOR sequencer */
+ tegra_dc_io_start(dc);
tegra_dc_writel(dc, VSYNC_H_POSITION(1), DC_DISP_DISP_TIMING_OPTIONS);
tegra_dc_writel(dc, DITHER_CONTROL_DISABLE | BASE_COLOR_SIZE888,
DC_DISP_DISP_COLOR_CONTROL);
@@ -1878,6 +1860,7 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
tegra_nvhdcp_set_plug(hdmi->nvhdcp, 1);
+ tegra_dc_io_end(dc);
}
static void tegra_dc_hdmi_disable(struct tegra_dc *dc)
diff --git a/drivers/video/tegra/dc/mode.c b/drivers/video/tegra/dc/mode.c
index 747706ef45db..c9812f46527c 100644
--- a/drivers/video/tegra/dc/mode.c
+++ b/drivers/video/tegra/dc/mode.c
@@ -327,6 +327,11 @@ int tegra_dc_to_fb_videomode(struct fb_videomode *fbmode,
fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
if (!(mode->flags & TEGRA_DC_MODE_FLAG_NEG_V_SYNC))
fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (mode->avi_m == TEGRA_DC_MODE_AVI_M_16_9)
+ fbmode->flag |= FB_FLAG_RATIO_16_9;
+ else if (mode->avi_m == TEGRA_DC_MODE_AVI_M_4_3)
+ fbmode->flag |= FB_FLAG_RATIO_4_3;
+
if (mode->rated_pclk >= 1000)
fbmode->pixclock = KHZ2PICOS(mode->rated_pclk / 1000);
else if (mode->pclk >= 1000)
@@ -361,6 +366,21 @@ int tegra_dc_set_fb_mode(struct tegra_dc *dc,
mode.h_front_porch = fbmode->right_margin;
mode.v_front_porch = fbmode->lower_margin;
mode.stereo_mode = stereo_mode;
+ if (fbmode->flag & FB_FLAG_RATIO_16_9)
+ mode.avi_m = TEGRA_DC_MODE_AVI_M_16_9;
+ else if (fbmode->flag & FB_FLAG_RATIO_4_3)
+ mode.avi_m = TEGRA_DC_MODE_AVI_M_4_3;
+ else if (dc->out) { /* if ratio is unspecified, detect a default */
+ unsigned h_size = dc->out->h_size;
+ unsigned v_size = dc->out->v_size;
+
+ /* get aspect ratio */
+ if (h_size * 18 > v_size * 31 && h_size * 18 < v_size * 33)
+ mode.avi_m = TEGRA_DC_MODE_AVI_M_16_9;
+ if (h_size * 18 > v_size * 23 && h_size * 18 < v_size * 25)
+ mode.avi_m = TEGRA_DC_MODE_AVI_M_4_3;
+ }
+
if (dc->out->type == TEGRA_DC_OUT_HDMI) {
/* HDMI controller requires h_ref=1, v_ref=1 */
mode.h_ref_to_sync = 1;