From 2b1c9cd696049d23845870329d2b61a5873f7b13 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 15 Feb 2008 16:13:21 -0800 Subject: i915: initial (and untested) TV out support Ported from xf86-video-intel. Still need to tie in TV modes somehow, though preferably w/o using the properties mechanism. --- linux-core/intel_tv.c | 1763 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1763 insertions(+) create mode 100644 linux-core/intel_tv.c (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c new file mode 100644 index 00000000..0edbdbac --- /dev/null +++ b/linux-core/intel_tv.c @@ -0,0 +1,1763 @@ +/* + * Copyright © 2006 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/** @file + * Integrated TV-out support for the 915GM and 945GM. + */ + +#include "drmP.h" +#include "drm.h" +#include "drm_crtc.h" +#include "drm_edid.h" +#include "intel_drv.h" +#include "i915_drm.h" +#include "i915_drv.h" + +enum tv_type { + TV_TYPE_NONE, + TV_TYPE_UNKNOWN, + TV_TYPE_COMPOSITE, + TV_TYPE_SVIDEO, + TV_TYPE_COMPONENT +}; + +enum tv_margin { + TV_MARGIN_LEFT, TV_MARGIN_TOP, + TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM +}; + +/** Private structure for the integrated TV support */ +struct intel_tv_priv { + int type; + char *tv_format; + int margin[4]; + u32 save_TV_H_CTL_1; + u32 save_TV_H_CTL_2; + u32 save_TV_H_CTL_3; + u32 save_TV_V_CTL_1; + u32 save_TV_V_CTL_2; + u32 save_TV_V_CTL_3; + u32 save_TV_V_CTL_4; + u32 save_TV_V_CTL_5; + u32 save_TV_V_CTL_6; + u32 save_TV_V_CTL_7; + u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3; + + u32 save_TV_CSC_Y; + u32 save_TV_CSC_Y2; + u32 save_TV_CSC_U; + u32 save_TV_CSC_U2; + u32 save_TV_CSC_V; + u32 save_TV_CSC_V2; + u32 save_TV_CLR_KNOBS; + u32 save_TV_CLR_LEVEL; + u32 save_TV_WIN_POS; + u32 save_TV_WIN_SIZE; + u32 save_TV_FILTER_CTL_1; + u32 save_TV_FILTER_CTL_2; + u32 save_TV_FILTER_CTL_3; + + u32 save_TV_H_LUMA[60]; + u32 save_TV_H_CHROMA[60]; + u32 save_TV_V_LUMA[43]; + u32 save_TV_V_CHROMA[43]; + + u32 save_TV_DAC; + u32 save_TV_CTL; +}; + +struct video_levels { + int blank, black, burst; +}; + +struct color_conversion { + u16 ry, gy, by, ay; + u16 ru, gu, bu, au; + u16 rv, gv, bv, av; +}; + +static const u32 filter_table[] = { + 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, + 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, + 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, + 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, + 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, + 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, + 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, + 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, + 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, + 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, + 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, + 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, + 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, + 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, + 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, + 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, + 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, + 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, + 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, + 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, + 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, + 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, + 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, + 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, + 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, + 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, + 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, + 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, + 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, + 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, + 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0, + 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, + 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, + 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, + 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, + 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, + 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, + 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, + 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, + 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, + 0x28003100, 0x28002F00, 0x00003100, 0x36403000, + 0x2D002CC0, 0x30003640, 0x2D0036C0, + 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, + 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, + 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, + 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, + 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, + 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, + 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, + 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, + 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, + 0x28003100, 0x28002F00, 0x00003100, +}; + +/* + * Color conversion values have 3 separate fixed point formats: + * + * 10 bit fields (ay, au) + * 1.9 fixed point (b.bbbbbbbbb) + * 11 bit fields (ry, by, ru, gu, gv) + * exp.mantissa (ee.mmmmmmmmm) + * ee = 00 = 10^-1 (0.mmmmmmmmm) + * ee = 01 = 10^-2 (0.0mmmmmmmmm) + * ee = 10 = 10^-3 (0.00mmmmmmmmm) + * ee = 11 = 10^-4 (0.000mmmmmmmmm) + * 12 bit fields (gy, rv, bu) + * exp.mantissa (eee.mmmmmmmmm) + * eee = 000 = 10^-1 (0.mmmmmmmmm) + * eee = 001 = 10^-2 (0.0mmmmmmmmm) + * eee = 010 = 10^-3 (0.00mmmmmmmmm) + * eee = 011 = 10^-4 (0.000mmmmmmmmm) + * eee = 100 = reserved + * eee = 101 = reserved + * eee = 110 = reserved + * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation) + * + * Saturation and contrast are 8 bits, with their own representation: + * 8 bit field (saturation, contrast) + * exp.mantissa (ee.mmmmmm) + * ee = 00 = 10^-1 (0.mmmmmm) + * ee = 01 = 10^0 (m.mmmmm) + * ee = 10 = 10^1 (mm.mmmm) + * ee = 11 = 10^2 (mmm.mmm) + * + * Simple conversion function: + * + * static u32 + * float_to_csc_11(float f) + * { + * u32 exp; + * u32 mant; + * u32 ret; + * + * if (f < 0) + * f = -f; + * + * if (f >= 1) { + * exp = 0x7; + * mant = 1 << 8; + * } else { + * for (exp = 0; exp < 3 && f < 0.5; exp++) + * f *= 2.0; + * mant = (f * (1 << 9) + 0.5); + * if (mant >= (1 << 9)) + * mant = (1 << 9) - 1; + * } + * ret = (exp << 9) | mant; + * return ret; + * } + */ + +/* + * Behold, magic numbers! If we plant them they might grow a big + * s-video cable to the sky... or something. + * + * Pre-converted to appropriate hex value. + */ + +/* + * PAL & NTSC values for composite & s-video connections + */ +static const struct color_conversion ntsc_m_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, + .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, + .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, +}; + +static const struct video_levels ntsc_m_levels_composite = { + .blank = 225, .black = 267, .burst = 113, +}; + +static const struct color_conversion ntsc_m_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, + .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, + .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, +}; + +static const struct video_levels ntsc_m_levels_svideo = { + .blank = 266, .black = 316, .burst = 133, +}; + +static const struct color_conversion ntsc_j_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119, + .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0f00, + .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0f00, +}; + +static const struct video_levels ntsc_j_levels_composite = { + .blank = 225, .black = 225, .burst = 113, +}; + +static const struct color_conversion ntsc_j_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c, + .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0f00, + .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0f00, +}; + +static const struct video_levels ntsc_j_levels_svideo = { + .blank = 266, .black = 266, .burst = 133, +}; + +static const struct color_conversion pal_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113, + .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0f00, + .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0f00, +}; + +static const struct video_levels pal_levels_composite = { + .blank = 237, .black = 237, .burst = 118, +}; + +static const struct color_conversion pal_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, + .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0f00, + .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0f00, +}; + +static const struct video_levels pal_levels_svideo = { + .blank = 280, .black = 280, .burst = 139, +}; + +static const struct color_conversion pal_m_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, + .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, + .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, +}; + +static const struct video_levels pal_m_levels_composite = { + .blank = 225, .black = 267, .burst = 113, +}; + +static const struct color_conversion pal_m_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, + .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, + .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, +}; + +static const struct video_levels pal_m_levels_svideo = { + .blank = 266, .black = 316, .burst = 133, +}; + +static const struct color_conversion pal_n_csc_composite = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, + .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00, + .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00, +}; + +static const struct video_levels pal_n_levels_composite = { + .blank = 225, .black = 267, .burst = 118, +}; + +static const struct color_conversion pal_n_csc_svideo = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134, + .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00, + .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00, +}; + +static const struct video_levels pal_n_levels_svideo = { + .blank = 266, .black = 316, .burst = 139, +}; + +/* + * Component connections + */ +static const struct color_conversion sdtv_csc_yprpb = { + .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0146, + .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0f00, + .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0f00, +}; + +static const struct color_conversion sdtv_csc_rgb = { + .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, + .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, + .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, +}; + +static const struct color_conversion hdtv_csc_yprpb = { + .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0146, + .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0f00, + .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0f00, +}; + +static const struct color_conversion hdtv_csc_rgb = { + .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, + .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, + .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, +}; + +static const struct video_levels component_levels = { + .blank = 279, .black = 279, .burst = 0, +}; + + +struct tv_mode { + char *name; + int clock; + int refresh; /* in millihertz (for precision) */ + u32 oversample; + int hsync_end, hblank_start, hblank_end, htotal; + bool progressive, trilevel_sync, component_only; + int vsync_start_f1, vsync_start_f2, vsync_len; + bool veq_ena; + int veq_start_f1, veq_start_f2, veq_len; + int vi_end_f1, vi_end_f2, nbr_end; + bool burst_ena; + int hburst_start, hburst_len; + int vburst_start_f1, vburst_end_f1; + int vburst_start_f2, vburst_end_f2; + int vburst_start_f3, vburst_end_f3; + int vburst_start_f4, vburst_end_f4; + /* + * subcarrier programming + */ + int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc; + u32 sc_reset; + bool pal_burst; + /* + * blank/black levels + */ + const struct video_levels *composite_levels, *svideo_levels; + const struct color_conversion *composite_color, *svideo_color; + const u32 *filter_table; + int max_srcw; +}; + + +/* + * Sub carrier DDA + * + * I think this works as follows: + * + * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096 + * + * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value + * + * So, + * dda1_ideal = subcarrier/pixel * 4096 + * dda1_inc = floor (dda1_ideal) + * dda2 = dda1_ideal - dda1_inc + * + * then pick a ratio for dda2 that gives the closest approximation. If + * you can't get close enough, you can play with dda3 as well. This + * seems likely to happen when dda2 is small as the jumps would be larger + * + * To invert this, + * + * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size) + * + * The constants below were all computed using a 107.520MHz clock + */ + +/** + * Register programming values for TV modes. + * + * These values account for -1s required. + */ + +const static struct tv_mode tv_modes[] = { + { + .name = "NTSC-M", + .clock = 107520, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ + + .hsync_end = 64, .hblank_end = 124, + .hblank_start = 836, .htotal = 857, + + .progressive = FALSE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 6, .vsync_start_f2 = 7, + .vsync_len = 6, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 18, + + .vi_end_f1 = 20, .vi_end_f2 = 21, + .nbr_end = 240, + + .burst_ena = TRUE, + .hburst_start = 72, .hburst_len = 34, + .vburst_start_f1 = 9, .vburst_end_f1 = 240, + .vburst_start_f2 = 10, .vburst_end_f2 = 240, + .vburst_start_f3 = 9, .vburst_end_f3 = 240, + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ + .dda1_inc = 136, + .dda2_inc = 7624, .dda2_size = 20013, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_4, + .pal_burst = FALSE, + + .composite_levels = &ntsc_m_levels_composite, + .composite_color = &ntsc_m_csc_composite, + .svideo_levels = &ntsc_m_levels_svideo, + .svideo_color = &ntsc_m_csc_svideo, + + .filter_table = filter_table, + }, + { + .name = "NTSC-443", + .clock = 107520, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ + .hsync_end = 64, .hblank_end = 124, + .hblank_start = 836, .htotal = 857, + + .progressive = FALSE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 6, .vsync_start_f2 = 7, + .vsync_len = 6, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 18, + + .vi_end_f1 = 20, .vi_end_f2 = 21, + .nbr_end = 240, + + .burst_ena = 8, + .hburst_start = 72, .hburst_len = 34, + .vburst_start_f1 = 9, .vburst_end_f1 = 240, + .vburst_start_f2 = 10, .vburst_end_f2 = 240, + .vburst_start_f3 = 9, .vburst_end_f3 = 240, + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ + .dda1_inc = 168, + .dda2_inc = 18557, .dda2_size = 20625, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_8, + .pal_burst = TRUE, + + .composite_levels = &ntsc_m_levels_composite, + .composite_color = &ntsc_m_csc_composite, + .svideo_levels = &ntsc_m_levels_svideo, + .svideo_color = &ntsc_m_csc_svideo, + + .filter_table = filter_table, + }, + { + .name = "NTSC-J", + .clock = 107520, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + + /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ + .hsync_end = 64, .hblank_end = 124, + .hblank_start = 836, .htotal = 857, + + .progressive = FALSE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 6, .vsync_start_f2 = 7, + .vsync_len = 6, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 18, + + .vi_end_f1 = 20, .vi_end_f2 = 21, + .nbr_end = 240, + + .burst_ena = TRUE, + .hburst_start = 72, .hburst_len = 34, + .vburst_start_f1 = 9, .vburst_end_f1 = 240, + .vburst_start_f2 = 10, .vburst_end_f2 = 240, + .vburst_start_f3 = 9, .vburst_end_f3 = 240, + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ + .dda1_inc = 136, + .dda2_inc = 7624, .dda2_size = 20013, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_4, + .pal_burst = FALSE, + + .composite_levels = &ntsc_j_levels_composite, + .composite_color = &ntsc_j_csc_composite, + .svideo_levels = &ntsc_j_levels_svideo, + .svideo_color = &ntsc_j_csc_svideo, + + .filter_table = filter_table, + }, + { + .name = "PAL-M", + .clock = 107520, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + + /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ + .hsync_end = 64, .hblank_end = 124, + .hblank_start = 836, .htotal = 857, + + .progressive = FALSE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 6, .vsync_start_f2 = 7, + .vsync_len = 6, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 18, + + .vi_end_f1 = 20, .vi_end_f2 = 21, + .nbr_end = 240, + + .burst_ena = TRUE, + .hburst_start = 72, .hburst_len = 34, + .vburst_start_f1 = 9, .vburst_end_f1 = 240, + .vburst_start_f2 = 10, .vburst_end_f2 = 240, + .vburst_start_f3 = 9, .vburst_end_f3 = 240, + .vburst_start_f4 = 10, .vburst_end_f4 = 240, + + /* desired 3.5800000 actual 3.5800000 clock 107.52 */ + .dda1_inc = 136, + .dda2_inc = 7624, .dda2_size = 20013, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_4, + .pal_burst = FALSE, + + .composite_levels = &pal_m_levels_composite, + .composite_color = &pal_m_csc_composite, + .svideo_levels = &pal_m_levels_svideo, + .svideo_color = &pal_m_csc_svideo, + + .filter_table = filter_table, + }, + { + /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ + .name = "PAL-N", + .clock = 107520, + .refresh = 25000, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + + .hsync_end = 64, .hblank_end = 128, + .hblank_start = 844, .htotal = 863, + + .progressive = FALSE, .trilevel_sync = FALSE, + + + .vsync_start_f1 = 6, .vsync_start_f2 = 7, + .vsync_len = 6, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 18, + + .vi_end_f1 = 24, .vi_end_f2 = 25, + .nbr_end = 286, + + .burst_ena = TRUE, + .hburst_start = 73, .hburst_len = 34, + .vburst_start_f1 = 8, .vburst_end_f1 = 285, + .vburst_start_f2 = 8, .vburst_end_f2 = 286, + .vburst_start_f3 = 9, .vburst_end_f3 = 286, + .vburst_start_f4 = 9, .vburst_end_f4 = 285, + + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ + .dda1_inc = 168, + .dda2_inc = 18557, .dda2_size = 20625, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_8, + .pal_burst = TRUE, + + .composite_levels = &pal_n_levels_composite, + .composite_color = &pal_n_csc_composite, + .svideo_levels = &pal_n_levels_svideo, + .svideo_color = &pal_n_csc_svideo, + + .filter_table = filter_table, + }, + { + /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ + .name = "PAL", + .clock = 107520, + .refresh = 25000, + .oversample = TV_OVERSAMPLE_8X, + .component_only = 0, + + .hsync_end = 64, .hblank_end = 128, + .hblank_start = 844, .htotal = 863, + + .progressive = FALSE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 5, .vsync_start_f2 = 6, + .vsync_len = 5, + + .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_start_f2 = 1, .veq_len = 15, + + .vi_end_f1 = 24, .vi_end_f2 = 25, + .nbr_end = 286, + + .burst_ena = TRUE, + .hburst_start = 73, .hburst_len = 32, + .vburst_start_f1 = 8, .vburst_end_f1 = 285, + .vburst_start_f2 = 8, .vburst_end_f2 = 286, + .vburst_start_f3 = 9, .vburst_end_f3 = 286, + .vburst_start_f4 = 9, .vburst_end_f4 = 285, + + /* desired 4.4336180 actual 4.4336180 clock 107.52 */ + .dda1_inc = 168, + .dda2_inc = 18557, .dda2_size = 20625, + .dda3_inc = 0, .dda3_size = 0, + .sc_reset = TV_SC_RESET_EVERY_8, + .pal_burst = TRUE, + + .composite_levels = &pal_levels_composite, + .composite_color = &pal_csc_composite, + .svideo_levels = &pal_levels_svideo, + .svideo_color = &pal_csc_svideo, + + .filter_table = filter_table, + }, + { + .name = "480p@59.94Hz", + .clock = 107520, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 857, + + .progressive = TRUE,.trilevel_sync = FALSE, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = FALSE, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 496, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "480p@60Hz", + .clock = 107520, + .refresh = 60000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 856, + + .progressive = TRUE,.trilevel_sync = FALSE, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = FALSE, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 496, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "576p", + .clock = 107520, + .refresh = 50000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 139, + .hblank_start = 859, .htotal = 863, + + .progressive = TRUE, .trilevel_sync = FALSE, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = FALSE, + + .vi_end_f1 = 48, .vi_end_f2 = 48, + .nbr_end = 575, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "720p@60Hz", + .clock = 148800, + .refresh = 60000, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 80, .hblank_end = 300, + .hblank_start = 1580, .htotal = 1649, + + .progressive = TRUE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = FALSE, + + .vi_end_f1 = 29, .vi_end_f2 = 29, + .nbr_end = 719, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "720p@59.94Hz", + .clock = 148800, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 80, .hblank_end = 300, + .hblank_start = 1580, .htotal = 1651, + + .progressive = TRUE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = FALSE, + + .vi_end_f1 = 29, .vi_end_f2 = 29, + .nbr_end = 719, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "720p@50Hz", + .clock = 148800, + .refresh = 50000, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 80, .hblank_end = 300, + .hblank_start = 1580, .htotal = 1979, + + .progressive = TRUE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = FALSE, + + .vi_end_f1 = 29, .vi_end_f2 = 29, + .nbr_end = 719, + + .burst_ena = FALSE, + + .filter_table = filter_table, + .max_srcw = 800 + }, + { + .name = "1080i@50Hz", + .clock = 148800, + .refresh = 25000, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2639, + + .progressive = FALSE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 4, .vsync_start_f2 = 5, + .vsync_len = 10, + + .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_start_f2 = 4, .veq_len = 10, + + + .vi_end_f1 = 21, .vi_end_f2 = 22, + .nbr_end = 539, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "1080i@60Hz", + .clock = 148800, + .refresh = 30000, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2199, + + .progressive = FALSE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 4, .vsync_start_f2 = 5, + .vsync_len = 10, + + .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_start_f2 = 4, .veq_len = 10, + + + .vi_end_f1 = 21, .vi_end_f2 = 22, + .nbr_end = 539, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, + { + .name = "1080i@59.94Hz", + .clock = 148800, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2200, + + .progressive = FALSE, .trilevel_sync = TRUE, + + .vsync_start_f1 = 4, .vsync_start_f2 = 5, + .vsync_len = 10, + + .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_start_f2 = 4, .veq_len = 10, + + + .vi_end_f1 = 21, .vi_end_f2 = 22, + .nbr_end = 539, + + .burst_ena = FALSE, + + .filter_table = filter_table, + }, +}; + +#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) + +static void +intel_tv_dpms(struct drm_output *output, int mode) +{ + struct drm_device *dev = output->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + switch(mode) { + case DPMSModeOn: + I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); + break; + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); + break; + } +} + +static void +intel_tv_save(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + int i; + + tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); + tv_priv->save_TV_H_CTL_2 = I915_READ(TV_H_CTL_2); + tv_priv->save_TV_H_CTL_3 = I915_READ(TV_H_CTL_3); + tv_priv->save_TV_V_CTL_1 = I915_READ(TV_V_CTL_1); + tv_priv->save_TV_V_CTL_2 = I915_READ(TV_V_CTL_2); + tv_priv->save_TV_V_CTL_3 = I915_READ(TV_V_CTL_3); + tv_priv->save_TV_V_CTL_4 = I915_READ(TV_V_CTL_4); + tv_priv->save_TV_V_CTL_5 = I915_READ(TV_V_CTL_5); + tv_priv->save_TV_V_CTL_6 = I915_READ(TV_V_CTL_6); + tv_priv->save_TV_V_CTL_7 = I915_READ(TV_V_CTL_7); + tv_priv->save_TV_SC_CTL_1 = I915_READ(TV_SC_CTL_1); + tv_priv->save_TV_SC_CTL_2 = I915_READ(TV_SC_CTL_2); + tv_priv->save_TV_SC_CTL_3 = I915_READ(TV_SC_CTL_3); + + tv_priv->save_TV_CSC_Y = I915_READ(TV_CSC_Y); + tv_priv->save_TV_CSC_Y2 = I915_READ(TV_CSC_Y2); + tv_priv->save_TV_CSC_U = I915_READ(TV_CSC_U); + tv_priv->save_TV_CSC_U2 = I915_READ(TV_CSC_U2); + tv_priv->save_TV_CSC_V = I915_READ(TV_CSC_V); + tv_priv->save_TV_CSC_V2 = I915_READ(TV_CSC_V2); + tv_priv->save_TV_CLR_KNOBS = I915_READ(TV_CLR_KNOBS); + tv_priv->save_TV_CLR_LEVEL = I915_READ(TV_CLR_LEVEL); + tv_priv->save_TV_WIN_POS = I915_READ(TV_WIN_POS); + tv_priv->save_TV_WIN_SIZE = I915_READ(TV_WIN_SIZE); + tv_priv->save_TV_FILTER_CTL_1 = I915_READ(TV_FILTER_CTL_1); + tv_priv->save_TV_FILTER_CTL_2 = I915_READ(TV_FILTER_CTL_2); + tv_priv->save_TV_FILTER_CTL_3 = I915_READ(TV_FILTER_CTL_3); + + for (i = 0; i < 60; i++) + tv_priv->save_TV_H_LUMA[i] = I915_READ(TV_H_LUMA_0 + (i <<2)); + for (i = 0; i < 60; i++) + tv_priv->save_TV_H_CHROMA[i] = I915_READ(TV_H_CHROMA_0 + (i <<2)); + for (i = 0; i < 43; i++) + tv_priv->save_TV_V_LUMA[i] = I915_READ(TV_V_LUMA_0 + (i <<2)); + for (i = 0; i < 43; i++) + tv_priv->save_TV_V_CHROMA[i] = I915_READ(TV_V_CHROMA_0 + (i <<2)); + + tv_priv->save_TV_DAC = I915_READ(TV_DAC); + tv_priv->save_TV_CTL = I915_READ(TV_CTL); +} + +static void +intel_tv_restore(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct drm_crtc *crtc = output->crtc; + struct intel_crtc *intel_crtc; + int i; + + /* FIXME: No CRTC? */ + if (!crtc) + return; + + intel_crtc = crtc->driver_private; + I915_WRITE(TV_H_CTL_1, tv_priv->save_TV_H_CTL_1); + I915_WRITE(TV_H_CTL_2, tv_priv->save_TV_H_CTL_2); + I915_WRITE(TV_H_CTL_3, tv_priv->save_TV_H_CTL_3); + I915_WRITE(TV_V_CTL_1, tv_priv->save_TV_V_CTL_1); + I915_WRITE(TV_V_CTL_2, tv_priv->save_TV_V_CTL_2); + I915_WRITE(TV_V_CTL_3, tv_priv->save_TV_V_CTL_3); + I915_WRITE(TV_V_CTL_4, tv_priv->save_TV_V_CTL_4); + I915_WRITE(TV_V_CTL_5, tv_priv->save_TV_V_CTL_5); + I915_WRITE(TV_V_CTL_6, tv_priv->save_TV_V_CTL_6); + I915_WRITE(TV_V_CTL_7, tv_priv->save_TV_V_CTL_7); + I915_WRITE(TV_SC_CTL_1, tv_priv->save_TV_SC_CTL_1); + I915_WRITE(TV_SC_CTL_2, tv_priv->save_TV_SC_CTL_2); + I915_WRITE(TV_SC_CTL_3, tv_priv->save_TV_SC_CTL_3); + + I915_WRITE(TV_CSC_Y, tv_priv->save_TV_CSC_Y); + I915_WRITE(TV_CSC_Y2, tv_priv->save_TV_CSC_Y2); + I915_WRITE(TV_CSC_U, tv_priv->save_TV_CSC_U); + I915_WRITE(TV_CSC_U2, tv_priv->save_TV_CSC_U2); + I915_WRITE(TV_CSC_V, tv_priv->save_TV_CSC_V); + I915_WRITE(TV_CSC_V2, tv_priv->save_TV_CSC_V2); + I915_WRITE(TV_CLR_KNOBS, tv_priv->save_TV_CLR_KNOBS); + I915_WRITE(TV_CLR_LEVEL, tv_priv->save_TV_CLR_LEVEL); + + { + int pipeconf_reg = (intel_crtc->pipe == 0) ? + PIPEACONF : PIPEBCONF; + int dspcntr_reg = (intel_crtc->plane == 0) ? + DSPACNTR : DSPBCNTR; + int pipeconf = I915_READ(pipeconf_reg); + int dspcntr = I915_READ(dspcntr_reg); + int dspbase_reg = (intel_crtc->plane == 0) ? + DSPABASE : DSPBBASE; + /* Pipe must be off here */ + I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); + + if (!IS_I9XX(dev)) { + /* Wait for vblank for the disable to take effect */ + intel_wait_for_vblank(dev); + } + + I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); + /* Wait for vblank for the disable to take effect. */ + intel_wait_for_vblank(dev); + + /* Filter ctl must be set before TV_WIN_SIZE */ + I915_WRITE(TV_FILTER_CTL_1, tv_priv->save_TV_FILTER_CTL_1); + I915_WRITE(TV_FILTER_CTL_2, tv_priv->save_TV_FILTER_CTL_2); + I915_WRITE(TV_FILTER_CTL_3, tv_priv->save_TV_FILTER_CTL_3); + I915_WRITE(TV_WIN_POS, tv_priv->save_TV_WIN_POS); + I915_WRITE(TV_WIN_SIZE, tv_priv->save_TV_WIN_SIZE); + I915_WRITE(pipeconf_reg, pipeconf); + I915_WRITE(dspcntr_reg, dspcntr); + /* Flush the plane changes */ + I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); + } + + for (i = 0; i < 60; i++) + I915_WRITE(TV_H_LUMA_0 + (i <<2), tv_priv->save_TV_H_LUMA[i]); + for (i = 0; i < 60; i++) + I915_WRITE(TV_H_CHROMA_0 + (i <<2), tv_priv->save_TV_H_CHROMA[i]); + for (i = 0; i < 43; i++) + I915_WRITE(TV_V_LUMA_0 + (i <<2), tv_priv->save_TV_V_LUMA[i]); + for (i = 0; i < 43; i++) + I915_WRITE(TV_V_CHROMA_0 + (i <<2), tv_priv->save_TV_V_CHROMA[i]); + + I915_WRITE(TV_DAC, tv_priv->save_TV_DAC); + I915_WRITE(TV_CTL, tv_priv->save_TV_CTL); +} + +static const struct tv_mode * +intel_tv_mode_lookup (char *tv_format) +{ + int i; + + for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) { + const struct tv_mode *tv_mode = &tv_modes[i]; + + if (!strcmp(tv_format, tv_mode->name)) + return tv_mode; + } + return NULL; +} + +static const struct tv_mode * +intel_tv_mode_find (struct drm_output *output) +{ + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + + return intel_tv_mode_lookup(tv_priv->tv_format); +} + +static enum drm_mode_status +intel_tv_mode_valid(struct drm_output *output, struct drm_display_mode *mode) +{ + const struct tv_mode *tv_mode = intel_tv_mode_find(output); + + /* Ensure TV refresh is close to desired refresh */ + if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1) + return MODE_OK; + return MODE_CLOCK_RANGE; +} + + +static bool +intel_tv_mode_fixup(struct drm_output *output, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = output->dev; + struct drm_mode_config *drm_config = &dev->mode_config; + const struct tv_mode *tv_mode = intel_tv_mode_find (output); + struct drm_output *other_output; + + if (!tv_mode) + return FALSE; + + /* FIXME: lock output list */ + list_for_each_entry(other_output, &drm_config->output_list, head) { + if (other_output != output && + other_output->crtc == output->crtc) + return FALSE; + } + + adjusted_mode->clock = tv_mode->clock; + return TRUE; +} + +static void +intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = output->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = output->crtc; + struct intel_crtc *intel_crtc = crtc->driver_private; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + const struct tv_mode *tv_mode = intel_tv_mode_find(output); + u32 tv_ctl; + u32 hctl1, hctl2, hctl3; + u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; + u32 scctl1, scctl2, scctl3; + int i, j; + const struct video_levels *video_levels; + const struct color_conversion *color_conversion; + bool burst_ena; + + if (!tv_mode) + return; /* can't happen (mode_prepare prevents this) */ + + tv_ctl = 0; + + switch (tv_priv->type) { + default: + case TV_TYPE_UNKNOWN: + case TV_TYPE_COMPOSITE: + tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; + video_levels = tv_mode->composite_levels; + color_conversion = tv_mode->composite_color; + burst_ena = tv_mode->burst_ena; + break; + case TV_TYPE_COMPONENT: + tv_ctl |= TV_ENC_OUTPUT_COMPONENT; + video_levels = &component_levels; + if (tv_mode->burst_ena) + color_conversion = &sdtv_csc_yprpb; + else + color_conversion = &hdtv_csc_yprpb; + burst_ena = FALSE; + break; + case TV_TYPE_SVIDEO: + tv_ctl |= TV_ENC_OUTPUT_SVIDEO; + video_levels = tv_mode->svideo_levels; + color_conversion = tv_mode->svideo_color; + burst_ena = tv_mode->burst_ena; + break; + } + hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) | + (tv_mode->htotal << TV_HTOTAL_SHIFT); + + hctl2 = (tv_mode->hburst_start << 16) | + (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT); + + if (burst_ena) + hctl2 |= TV_BURST_ENA; + + hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) | + (tv_mode->hblank_end << TV_HBLANK_END_SHIFT); + + vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) | + (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) | + (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT); + + vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) | + (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) | + (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT); + + vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) | + (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) | + (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT); + + if (tv_mode->veq_ena) + vctl3 |= TV_EQUAL_ENA; + + vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) | + (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT); + + vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) | + (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT); + + vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) | + (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT); + + vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) | + (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT); + + if (intel_crtc->pipe == 1) + tv_ctl |= TV_ENC_PIPEB_SELECT; + tv_ctl |= tv_mode->oversample; + + if (tv_mode->progressive) + tv_ctl |= TV_PROGRESSIVE; + if (tv_mode->trilevel_sync) + tv_ctl |= TV_TRILEVEL_SYNC; + if (tv_mode->pal_burst) + tv_ctl |= TV_PAL_BURST; + scctl1 = 0; + if (tv_mode->dda1_inc) + scctl1 |= TV_SC_DDA1_EN; + + if (tv_mode->dda2_inc) + scctl1 |= TV_SC_DDA2_EN; + + if (tv_mode->dda3_inc) + scctl1 |= TV_SC_DDA3_EN; + + scctl1 |= tv_mode->sc_reset; + scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; + + scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | + tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT; + + scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT | + tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT; + + /* Enable two fixes for the chips that need them. */ + if (dev->pci_device < 0x2772) + tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX; + + I915_WRITE(TV_H_CTL_1, hctl1); + I915_WRITE(TV_H_CTL_2, hctl2); + I915_WRITE(TV_H_CTL_3, hctl3); + I915_WRITE(TV_V_CTL_1, vctl1); + I915_WRITE(TV_V_CTL_2, vctl2); + I915_WRITE(TV_V_CTL_3, vctl3); + I915_WRITE(TV_V_CTL_4, vctl4); + I915_WRITE(TV_V_CTL_5, vctl5); + I915_WRITE(TV_V_CTL_6, vctl6); + I915_WRITE(TV_V_CTL_7, vctl7); + I915_WRITE(TV_SC_CTL_1, scctl1); + I915_WRITE(TV_SC_CTL_2, scctl2); + I915_WRITE(TV_SC_CTL_3, scctl3); + + I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | + color_conversion->gy); + I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) | + color_conversion->ay); + I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | + color_conversion->gu); + I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | + color_conversion->au); + I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | + color_conversion->gv); + I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | + color_conversion->av); + + I915_WRITE(TV_CLR_KNOBS, 0x00606000); + I915_WRITE(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | + (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); + { + int pipeconf_reg = (intel_crtc->pipe == 0) ? + PIPEACONF : PIPEBCONF; + int dspcntr_reg = (intel_crtc->plane == 0) ? + DSPACNTR : DSPBCNTR; + int pipeconf = I915_READ(pipeconf_reg); + int dspcntr = I915_READ(dspcntr_reg); + int dspbase_reg = (intel_crtc->plane == 0) ? + DSPABASE : DSPBBASE; + int xpos = 0x0, ypos = 0x0; + unsigned int xsize, ysize; + /* Pipe must be off here */ + I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); + + /* Wait for vblank for the disable to take effect */ + if (!IS_I9XX(dev)) + intel_wait_for_vblank(dev); + + I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); + /* Wait for vblank for the disable to take effect. */ + intel_wait_for_vblank(dev); + + /* Filter ctl must be set before TV_WIN_SIZE */ + I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); + xsize = tv_mode->hblank_start - tv_mode->hblank_end; + if (tv_mode->progressive) + ysize = tv_mode->nbr_end + 1; + else + ysize = 2*tv_mode->nbr_end + 1; + + xpos += tv_priv->margin[TV_MARGIN_LEFT]; + ypos += tv_priv->margin[TV_MARGIN_TOP]; + xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + + tv_priv->margin[TV_MARGIN_RIGHT]); + ysize -= (tv_priv->margin[TV_MARGIN_TOP] + + tv_priv->margin[TV_MARGIN_BOTTOM]); + I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); + I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); + + I915_WRITE(pipeconf_reg, pipeconf); + I915_WRITE(dspcntr_reg, dspcntr); + /* Flush the plane changes */ + I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); + } + + j = 0; + for (i = 0; i < 60; i++) + I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); + for (i = 0; i < 60; i++) + I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); + for (i = 0; i < 43; i++) + I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); + for (i = 0; i < 43; i++) + I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); + I915_WRITE(TV_DAC, 0); + I915_WRITE(TV_CTL, tv_ctl); +} + +static const struct drm_display_mode reported_modes[] = { + { + .name = "NTSC 480i", + .clock = 107520, + .hdisplay = 1280, + .hsync_start = 1368, + .hsync_end = 1496, + .htotal = 1712, + + .vdisplay = 1024, + .vsync_start = 1027, + .vsync_end = 1034, + .vtotal = 1104, + .type = DRM_MODE_TYPE_DRIVER, + }, +}; + +/** + * Detects TV presence by checking for load. + * + * Requires that the current pipe's DPLL is active. + + * \return TRUE if TV is connected. + * \return FALSE if TV is disconnected. + */ +static int +intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) +{ + struct drm_device *dev = output->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_output *intel_output = output->driver_private; + u32 tv_ctl, save_tv_ctl; + u32 tv_dac, save_tv_dac; + int type = TV_TYPE_UNKNOWN; + + tv_dac = I915_READ(TV_DAC); + /* + * Detect TV by polling) + */ + if (intel_output->load_detect_temp) { + /* TV not currently running, prod it with destructive detect */ + save_tv_dac = tv_dac; + tv_ctl = I915_READ(TV_CTL); + save_tv_ctl = tv_ctl; + tv_ctl &= ~TV_ENC_ENABLE; + tv_ctl &= ~TV_TEST_MODE_MASK; + tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; + tv_dac &= ~TVDAC_SENSE_MASK; + tv_dac |= (TVDAC_STATE_CHG_EN | + TVDAC_A_SENSE_CTL | + TVDAC_B_SENSE_CTL | + TVDAC_C_SENSE_CTL | + DAC_CTL_OVERRIDE | + DAC_A_0_7_V | + DAC_B_0_7_V | + DAC_C_0_7_V); + I915_WRITE(TV_CTL, tv_ctl); + I915_WRITE(TV_DAC, tv_dac); + intel_wait_for_vblank(dev); + tv_dac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, save_tv_dac); + I915_WRITE(TV_CTL, save_tv_ctl); + } + /* + * A B C + * 0 1 1 Composite + * 1 0 X svideo + * 0 0 0 Component + */ + if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { + DRM_DEBUG("Detected Composite TV connection\n"); + type = TV_TYPE_COMPOSITE; + } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { + DRM_DEBUG("Detected S-Video TV connection\n"); + type = TV_TYPE_SVIDEO; + } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { + DRM_DEBUG("Detected Component TV connection\n"); + type = TV_TYPE_COMPONENT; + } else { + DRM_DEBUG("No TV connection detected\n"); + type = TV_TYPE_NONE; + } + + return type; +} + +static int +intel_tv_format_configure_property (struct drm_output *output); + +/** + * Detect the TV connection. + * + * Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure + * we have a pipe programmed in order to probe the TV. + */ +static enum drm_output_status +intel_tv_detect(struct drm_output *output) +{ + struct drm_crtc *crtc; + struct drm_display_mode mode; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + int dpms_mode; + int type = tv_priv->type; + + mode = reported_modes[0]; + drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); +#if 0 + /* FIXME: pipe allocation for load detection */ + crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode); + if (crtc) { + type = intel_tv_detect_type(crtc, output); + i830ReleaseLoadDetectPipe (output, dpms_mode); + } +#endif + if (type != tv_priv->type) { + tv_priv->type = type; + intel_tv_format_configure_property (output); + } + + switch (type) { + case TV_TYPE_NONE: + return output_status_disconnected; + case TV_TYPE_UNKNOWN: + return output_status_unknown; + default: + return output_status_connected; + } +} + +static struct input_res { + char *name; + int w, h; +} input_res_table[] = +{ + {"640x480", 640, 480}, + {"800x600", 800, 600}, + {"1024x768", 1024, 768}, + {"1280x1024", 1280, 1024}, + {"848x480", 848, 480}, + {"1280x720", 1280, 720}, + {"1920x1080", 1920, 1080}, +}; + +/** + * Stub get_modes function. + * + * This should probably return a set of fixed modes, unless we can figure out + * how to probe modes off of TV connections. + */ + +static int +intel_tv_get_modes(struct drm_output *output) +{ + struct drm_display_mode *mode_ptr; + const struct tv_mode *tv_mode = intel_tv_mode_find(output); + int j; + + for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]); + j++) { + struct input_res *input = &input_res_table[j]; + unsigned int hactive_s = input->w; + unsigned int vactive_s = input->h; + + if (tv_mode->max_srcw && input->w > tv_mode->max_srcw) + continue; + + if (input->w > 1024 && (!tv_mode->progressive + && !tv_mode->component_only)) + continue; + + mode_ptr = drm_calloc(1, sizeof(struct drm_display_mode), + DRM_MEM_DRIVER); + strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN); + + mode_ptr->hdisplay = hactive_s; + mode_ptr->hsync_start = hactive_s + 1; + mode_ptr->hsync_end = hactive_s + 64; + if (mode_ptr->hsync_end <= mode_ptr->hsync_start) + mode_ptr->hsync_end = mode_ptr->hsync_start + 1; + mode_ptr->htotal = hactive_s + 96; + + mode_ptr->vdisplay = vactive_s; + mode_ptr->vsync_start = vactive_s + 1; + mode_ptr->vsync_end = vactive_s + 32; + if (mode_ptr->vsync_end <= mode_ptr->vsync_start) + mode_ptr->vsync_end = mode_ptr->vsync_start + 1; + mode_ptr->vtotal = vactive_s + 33; + + mode_ptr->clock = (int) (tv_mode->refresh * + mode_ptr->vtotal * + mode_ptr->htotal / 1000) / 1000; + + mode_ptr->type = DRM_MODE_TYPE_DRIVER; + drm_mode_probed_add(output, mode_ptr); + } + + return 0; +} + +static void +intel_tv_destroy (struct drm_output *output) +{ + if (output->driver_private) + drm_free(output->driver_private, sizeof(struct intel_tv_priv), + DRM_MEM_DRIVER); +} + +static bool +intel_tv_format_set_property(struct drm_output *output, + struct drm_property *prop, uint64_t val) +{ +#if 0 + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + const struct tv_mode *tv_mode = + intel_tv_mode_lookup(tv_priv->tv_format); + int err; + + if (!tv_mode) + tv_mode = &tv_modes[0]; + err = RRChangeOutputProperty (output->randr_output, tv_format_atom, + XA_ATOM, 32, PropModeReplace, 1, + &tv_format_name_atoms[tv_mode - tv_modes], + FALSE, TRUE); + return err == Success; +#endif + return 0; +} + + +/** + * Configure the TV_FORMAT property to list only supported formats + * + * Unless the connector is component, list only the formats supported by + * svideo and composite + */ + +static int +intel_tv_format_configure_property(struct drm_output *output) +{ +#if 0 + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + Atom current_atoms[NUM_TV_MODES]; + int num_atoms = 0; + int i; + + if (!output->randr_output) + return Success; + + for (i = 0; i < NUM_TV_MODES; i++) + if (!tv_modes[i].component_only || + tv_priv->type == TV_TYPE_COMPONENT) + current_atoms[num_atoms++] = tv_format_name_atoms[i]; + + return RRConfigureOutputProperty(output->randr_output, tv_format_atom, + TRUE, FALSE, FALSE, + num_atoms, (INT32 *) current_atoms); +#endif + return 0; +} + +static void +intel_tv_create_resources(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; + int i, err; + +#if 0 + /* Set up the tv_format property, which takes effect on mode set + * and accepts strings that match exactly + */ + tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1, + TRUE); + + for (i = 0; i < NUM_TV_MODES; i++) + tv_format_name_atoms[i] = MakeAtom (tv_modes[i].name, + strlen (tv_modes[i].name), + TRUE); + + err = intel_tv_format_configure_property (output); + + if (err != 0) { + xf86DrvMsg(dev->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + + /* Set the current value of the tv_format property */ + if (!intel_tv_format_set_property (output)) + xf86DrvMsg(dev->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + + for (i = 0; i < 4; i++) + { + INT32 range[2]; + margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]), + TRUE); + + range[0] = 0; + range[1] = 100; + err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i], + TRUE, TRUE, FALSE, 2, range); + + if (err != 0) + xf86DrvMsg(dev->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + + err = RRChangeOutputProperty(output->randr_output, margin_atoms[i], + XA_INTEGER, 32, PropModeReplace, + 1, &tv_priv->margin[i], + FALSE, TRUE); + if (err != 0) + xf86DrvMsg(dev->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } +#endif +} + +static bool +intel_tv_set_property(struct drm_output *output, struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = output->dev; + int ret = 0; + + if (property == dev->mode_config.tv_left_margin_property || + property == dev->mode_config.tv_right_margin_property || + property == dev->mode_config.tv_top_margin_property || + property == dev->mode_config.tv_bottom_margin_property) { + ret = drm_output_property_set_value(output, property, val); + } else { + /* TV mode handling here */ + } + + return ret; +} + +static const struct drm_output_funcs intel_tv_output_funcs = { + .dpms = intel_tv_dpms, + .save = intel_tv_save, + .restore = intel_tv_restore, + .mode_valid = intel_tv_mode_valid, + .mode_fixup = intel_tv_mode_fixup, + .prepare = intel_output_prepare, + .mode_set = intel_tv_mode_set, + .commit = intel_output_commit, + .detect = intel_tv_detect, + .get_modes = intel_tv_get_modes, + .cleanup = intel_tv_destroy, + .set_property = intel_tv_set_property, +}; + +void +intel_tv_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_output *output; + struct intel_output *intel_output; + struct intel_tv_priv *tv_priv; + u32 tv_dac_on, tv_dac_off, save_tv_dac; + + /* FIXME: better TV detection and/or quirks */ +#if 0 + if (tv_priv->quirk_flag & QUIRK_IGNORE_TV) + return; +#endif + if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) + return; + + /* + * Sanity check the TV output by checking to see if the + * DAC register holds a value + */ + save_tv_dac = I915_READ(TV_DAC); + + I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN); + tv_dac_on = I915_READ(TV_DAC); + + I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); + tv_dac_off = I915_READ(TV_DAC); + + I915_WRITE(TV_DAC, save_tv_dac); + + /* + * If the register does not hold the state change enable + * bit, (either as a 0 or a 1), assume it doesn't really + * exist + */ + if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 || + (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) + return; + + output = drm_output_create(dev, &intel_tv_output_funcs, + DRM_MODE_OUTPUT_TVDAC); + + if (!output) + return; + + intel_output = drm_calloc(1, sizeof(struct intel_output) + + sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); + if (!intel_output) { + drm_output_destroy(output); + return; + } + + tv_priv = (struct intel_tv_priv *)(intel_output + 1); + intel_output->type = INTEL_OUTPUT_TVOUT; + output->possible_crtcs = ((1 << 0) | (1 << 1)); + output->possible_clones = (1 << INTEL_OUTPUT_TVOUT); + intel_output->dev_priv = tv_priv; + tv_priv->type = TV_TYPE_UNKNOWN; + + tv_priv->tv_format = NULL; + + /* BIOS margin values */ + tv_priv->margin[TV_MARGIN_LEFT] = 54; + tv_priv->margin[TV_MARGIN_TOP] = 36; + tv_priv->margin[TV_MARGIN_RIGHT] = 46; + tv_priv->margin[TV_MARGIN_BOTTOM] = 37; + + if (!tv_priv->tv_format) + tv_priv->tv_format = kstrdup(tv_modes[0].name, GFP_KERNEL); + + output->driver_private = intel_output; + output->interlace_allowed = FALSE; + output->doublescan_allowed = FALSE; +} -- cgit v1.2.3 From fa116081a919e716eb95fcfa421d93f10f6f0a4f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 9 Apr 2008 11:30:15 -0700 Subject: Fixup sysfs output registration Put off registering new outputs with sysfs until they're properly configured, or we may get duplicates if the type hasn't been set yet (as is the case with SDVO initialization). This also means moving de-registration into the cleanup function instead of output destroy, since the latter occurs during the normal course of setup when an output isn't found (and therefore not registered with sysfs yet. --- linux-core/intel_tv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 0edbdbac..cc50f8c1 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1760,4 +1760,6 @@ intel_tv_init(struct drm_device *dev) output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + + drm_sysfs_output_add(output); } -- cgit v1.2.3 From b3737f3fd9210aead1f7fc4187dd05eea77ed0a6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 9 Apr 2008 14:09:29 -0700 Subject: Fix TV load detection Now that we can allocate load detect pipes, we can perform TV out load detection correctly. Call the new routines and enable proper TV detection. --- linux-core/intel_tv.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index cc50f8c1..84825eb8 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1438,17 +1438,16 @@ intel_tv_detect(struct drm_output *output) mode = reported_modes[0]; drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); -#if 0 - /* FIXME: pipe allocation for load detection */ - crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode); + + crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode); if (crtc) { type = intel_tv_detect_type(crtc, output); - i830ReleaseLoadDetectPipe (output, dpms_mode); + intel_release_load_detect_pipe(output, dpms_mode); } -#endif + if (type != tv_priv->type) { tv_priv->type = type; - intel_tv_format_configure_property (output); + intel_tv_format_configure_property(output); } switch (type) { -- cgit v1.2.3 From 3b32ee36ae58f733f281a2fa569ea8a8a926bb6d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 10 Apr 2008 20:31:31 -0700 Subject: Fixup Intel TV property code Use the new TV property creation routine and fixup the set_property code to actually do a mode set call when properties change. --- linux-core/intel_tv.c | 266 ++++++++++++++++++-------------------------------- 1 file changed, 97 insertions(+), 169 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 84825eb8..89bdda1c 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -37,14 +37,6 @@ #include "i915_drm.h" #include "i915_drv.h" -enum tv_type { - TV_TYPE_NONE, - TV_TYPE_UNKNOWN, - TV_TYPE_COMPOSITE, - TV_TYPE_SVIDEO, - TV_TYPE_COMPONENT -}; - enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM @@ -1145,14 +1137,14 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, switch (tv_priv->type) { default: - case TV_TYPE_UNKNOWN: - case TV_TYPE_COMPOSITE: + case ConnectorUnknown: + case ConnectorComposite: tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; video_levels = tv_mode->composite_levels; color_conversion = tv_mode->composite_color; burst_ena = tv_mode->burst_ena; break; - case TV_TYPE_COMPONENT: + case ConnectorComponent: tv_ctl |= TV_ENC_OUTPUT_COMPONENT; video_levels = &component_levels; if (tv_mode->burst_ena) @@ -1161,7 +1153,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, color_conversion = &hdtv_csc_yprpb; burst_ena = FALSE; break; - case TV_TYPE_SVIDEO: + case ConnectorSVIDEO: tv_ctl |= TV_ENC_OUTPUT_SVIDEO; video_levels = tv_mode->svideo_levels; color_conversion = tv_mode->svideo_color; @@ -1218,8 +1210,11 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, if (tv_mode->pal_burst) tv_ctl |= TV_PAL_BURST; scctl1 = 0; - if (tv_mode->dda1_inc) + /* dda1 implies valid video levels */ + if (tv_mode->dda1_inc) { scctl1 |= TV_SC_DDA1_EN; + scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; + } if (tv_mode->dda2_inc) scctl1 |= TV_SC_DDA2_EN; @@ -1228,7 +1223,6 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, scctl1 |= TV_SC_DDA3_EN; scctl1 |= tv_mode->sc_reset; - scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | @@ -1255,22 +1249,26 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, I915_WRITE(TV_SC_CTL_2, scctl2); I915_WRITE(TV_SC_CTL_3, scctl3); - I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | - color_conversion->gy); - I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) | - color_conversion->ay); - I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | - color_conversion->gu); - I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | - color_conversion->au); - I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | - color_conversion->gv); - I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | - color_conversion->av); + if (color_conversion) { + I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | + color_conversion->gy); + I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) | + color_conversion->ay); + I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | + color_conversion->gu); + I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | + color_conversion->au); + I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | + color_conversion->gv); + I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | + color_conversion->av); + } I915_WRITE(TV_CLR_KNOBS, 0x00606000); - I915_WRITE(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | - (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); + if (video_levels) + I915_WRITE(TV_CLR_LEVEL, + ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | + (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); { int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; @@ -1364,7 +1362,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) struct intel_output *intel_output = output->driver_private; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; - int type = TV_TYPE_UNKNOWN; + int type = ConnectorUnknown; tv_dac = I915_READ(TV_DAC); /* @@ -1402,24 +1400,21 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) */ if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { DRM_DEBUG("Detected Composite TV connection\n"); - type = TV_TYPE_COMPOSITE; + type = ConnectorComposite; } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { DRM_DEBUG("Detected S-Video TV connection\n"); - type = TV_TYPE_SVIDEO; + type = ConnectorSVIDEO; } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { DRM_DEBUG("Detected Component TV connection\n"); - type = TV_TYPE_COMPONENT; + type = ConnectorComponent; } else { DRM_DEBUG("No TV connection detected\n"); - type = TV_TYPE_NONE; + type = -1; } return type; } -static int -intel_tv_format_configure_property (struct drm_output *output); - /** * Detect the TV connection. * @@ -1446,18 +1441,18 @@ intel_tv_detect(struct drm_output *output) } if (type != tv_priv->type) { + struct drm_property *connector_property = + output->dev->mode_config.connector_type_property; + tv_priv->type = type; - intel_tv_format_configure_property(output); + drm_output_property_set_value(output, connector_property, + type); } - switch (type) { - case TV_TYPE_NONE: + if (type < 0) return output_status_disconnected; - case TV_TYPE_UNKNOWN: - return output_status_unknown; - default: - return output_status_connected; - } + + return output_status_connected; } static struct input_res { @@ -1538,135 +1533,41 @@ intel_tv_destroy (struct drm_output *output) DRM_MEM_DRIVER); } -static bool -intel_tv_format_set_property(struct drm_output *output, - struct drm_property *prop, uint64_t val) -{ -#if 0 - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = - intel_tv_mode_lookup(tv_priv->tv_format); - int err; - - if (!tv_mode) - tv_mode = &tv_modes[0]; - err = RRChangeOutputProperty (output->randr_output, tv_format_atom, - XA_ATOM, 32, PropModeReplace, 1, - &tv_format_name_atoms[tv_mode - tv_modes], - FALSE, TRUE); - return err == Success; -#endif - return 0; -} - - -/** - * Configure the TV_FORMAT property to list only supported formats - * - * Unless the connector is component, list only the formats supported by - * svideo and composite - */ - -static int -intel_tv_format_configure_property(struct drm_output *output) -{ -#if 0 - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - Atom current_atoms[NUM_TV_MODES]; - int num_atoms = 0; - int i; - - if (!output->randr_output) - return Success; - - for (i = 0; i < NUM_TV_MODES; i++) - if (!tv_modes[i].component_only || - tv_priv->type == TV_TYPE_COMPONENT) - current_atoms[num_atoms++] = tv_format_name_atoms[i]; - - return RRConfigureOutputProperty(output->randr_output, tv_format_atom, - TRUE, FALSE, FALSE, - num_atoms, (INT32 *) current_atoms); -#endif - return 0; -} - -static void -intel_tv_create_resources(struct drm_output *output) -{ - struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - int i, err; - -#if 0 - /* Set up the tv_format property, which takes effect on mode set - * and accepts strings that match exactly - */ - tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1, - TRUE); - - for (i = 0; i < NUM_TV_MODES; i++) - tv_format_name_atoms[i] = MakeAtom (tv_modes[i].name, - strlen (tv_modes[i].name), - TRUE); - - err = intel_tv_format_configure_property (output); - - if (err != 0) { - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - - /* Set the current value of the tv_format property */ - if (!intel_tv_format_set_property (output)) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - - for (i = 0; i < 4; i++) - { - INT32 range[2]; - margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]), - TRUE); - - range[0] = 0; - range[1] = 100; - err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i], - TRUE, TRUE, FALSE, 2, range); - - if (err != 0) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - - err = RRChangeOutputProperty(output->randr_output, margin_atoms[i], - XA_INTEGER, 32, PropModeReplace, - 1, &tv_priv->margin[i], - FALSE, TRUE); - if (err != 0) - xf86DrvMsg(dev->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } -#endif -} - static bool intel_tv_set_property(struct drm_output *output, struct drm_property *property, uint64_t val) { struct drm_device *dev = output->dev; + struct intel_output *intel_output = output->driver_private; + struct intel_tv_priv *tv_priv = intel_output->dev_priv; int ret = 0; - - if (property == dev->mode_config.tv_left_margin_property || - property == dev->mode_config.tv_right_margin_property || - property == dev->mode_config.tv_top_margin_property || - property == dev->mode_config.tv_bottom_margin_property) { - ret = drm_output_property_set_value(output, property, val); + + ret = drm_output_property_set_value(output, property, val); + if (ret < 0) + goto out; + + if (property == dev->mode_config.tv_left_margin_property) + tv_priv->margin[TV_MARGIN_LEFT] = val; + else if (property == dev->mode_config.tv_right_margin_property) + tv_priv->margin[TV_MARGIN_RIGHT] = val; + else if (property == dev->mode_config.tv_top_margin_property) + tv_priv->margin[TV_MARGIN_TOP] = val; + else if (property == dev->mode_config.tv_bottom_margin_property) + tv_priv->margin[TV_MARGIN_BOTTOM] = val; + else if (property == dev->mode_config.tv_mode_property) { + if (val >= NUM_TV_MODES) { + ret = -EINVAL; + goto out; + } + tv_priv->tv_format = tv_modes[val].name; + intel_tv_mode_set(output, NULL, NULL); } else { - /* TV mode handling here */ + ret = -EINVAL; + goto out; } + intel_tv_mode_set(output, NULL, NULL); +out: return ret; } @@ -1693,6 +1594,8 @@ intel_tv_init(struct drm_device *dev) struct intel_output *intel_output; struct intel_tv_priv *tv_priv; u32 tv_dac_on, tv_dac_off, save_tv_dac; + char **tv_format_names; + int i, initial_mode = 0; /* FIXME: better TV detection and/or quirks */ #if 0 @@ -1743,22 +1646,47 @@ intel_tv_init(struct drm_device *dev) output->possible_crtcs = ((1 << 0) | (1 << 1)); output->possible_clones = (1 << INTEL_OUTPUT_TVOUT); intel_output->dev_priv = tv_priv; - tv_priv->type = TV_TYPE_UNKNOWN; + tv_priv->type = ConnectorUnknown; - tv_priv->tv_format = NULL; - /* BIOS margin values */ tv_priv->margin[TV_MARGIN_LEFT] = 54; tv_priv->margin[TV_MARGIN_TOP] = 36; tv_priv->margin[TV_MARGIN_RIGHT] = 46; tv_priv->margin[TV_MARGIN_BOTTOM] = 37; - if (!tv_priv->tv_format) - tv_priv->tv_format = kstrdup(tv_modes[0].name, GFP_KERNEL); + tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + drm_output_attach_property(output, + dev->mode_config.connector_type_property, + ConnectorUnknown); + + /* Create TV properties then attach current values */ + tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES, + DRM_MEM_DRIVER); + if (!tv_format_names) + goto out; + for (i = 0; i < NUM_TV_MODES; i++) + tv_format_names[i] = tv_modes[i].name; + drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + + drm_output_attach_property(output, dev->mode_config.tv_mode_property, + initial_mode); + drm_output_attach_property(output, + dev->mode_config.tv_left_margin_property, + tv_priv->margin[TV_MARGIN_LEFT]); + drm_output_attach_property(output, + dev->mode_config.tv_top_margin_property, + tv_priv->margin[TV_MARGIN_TOP]); + drm_output_attach_property(output, + dev->mode_config.tv_right_margin_property, + tv_priv->margin[TV_MARGIN_RIGHT]); + drm_output_attach_property(output, + dev->mode_config.tv_bottom_margin_property, + tv_priv->margin[TV_MARGIN_BOTTOM]); +out: drm_sysfs_output_add(output); } -- cgit v1.2.3 From 6ee0c09b0e2746022c25962cbfe655f2f1d5c53e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 9 May 2008 14:19:39 -0700 Subject: i915: use BDB TV flag for TV detection Even if the TV encoder hasn't been fused off, we may not have a TV connector on the platform. The BDB in the BIOS should give us this info in some cases. --- linux-core/intel_tv.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 89bdda1c..ba134d62 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1597,14 +1597,13 @@ intel_tv_init(struct drm_device *dev) char **tv_format_names; int i, initial_mode = 0; - /* FIXME: better TV detection and/or quirks */ -#if 0 - if (tv_priv->quirk_flag & QUIRK_IGNORE_TV) - return; -#endif if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) return; + /* Even if we have an encoder we may not have a connector */ + if (!dev_priv->bdb->int_tv_support) + return; + /* * Sanity check the TV output by checking to see if the * DAC register holds a value -- cgit v1.2.3 From d32ce7f621c0d8e42cdf88ce6f1d15638a3d34b7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 12 May 2008 15:47:19 -0700 Subject: i915: TV hotplug fixes In order to avoid recursive ->detect->interrupt->detect->interrupt->... we need to disable TV hotplug interrupts in intel_tv.c:intel_tv_detect_type. We also need to enable the TV interrupt detection and hotplug sequence properly in i915_irq.c. --- linux-core/intel_tv.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index ba134d62..865e27b9 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1360,11 +1360,21 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output = output->driver_private; + u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; int type = ConnectorUnknown; tv_dac = I915_READ(TV_DAC); + + /* Disable TV interrupts around load detect or we'll recurse */ + pipeastat = I915_READ(I915REG_PIPEASTAT); + pipeastat_save = pipeastat; + pipeastat &= ~I915_HOTPLUG_INTERRUPT_ENABLE; + pipeastat &= ~I915_HOTPLUG_TV_INTERRUPT_ENABLE; + I915_WRITE(I915REG_PIPEASTAT, pipeastat | I915_HOTPLUG_TV_CLEAR | + I915_HOTPLUG_CLEAR); + /* * Detect TV by polling) */ @@ -1412,6 +1422,10 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) type = -1; } + /* Restore interrupt config */ + I915_WRITE(I915REG_PIPEASTAT, pipeastat_save | I915_HOTPLUG_TV_CLEAR | + I915_HOTPLUG_CLEAR); + return type; } @@ -1434,10 +1448,15 @@ intel_tv_detect(struct drm_output *output) mode = reported_modes[0]; drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); - crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode); - if (crtc) { - type = intel_tv_detect_type(crtc, output); - intel_release_load_detect_pipe(output, dpms_mode); + if (output->crtc) { + type = intel_tv_detect_type(output->crtc, output); + } else { + crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode); + if (crtc) { + type = intel_tv_detect_type(crtc, output); + intel_release_load_detect_pipe(output, dpms_mode); + } else + type = -1; } if (type != tv_priv->type) { -- cgit v1.2.3 From ee631e1b8604a176b9118396998ce5bfc6475dae Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 13 May 2008 14:44:17 -0700 Subject: i915: register definition & header file cleanup It would be nice if one day the DRM driver was the canonical source for register definitions and core macros. To that end, this patch cleans things up quite a bit, removing redundant definitions (some with different names referring to the same register) and generally tidying up the header file. --- linux-core/intel_tv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 865e27b9..42f4b10b 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1012,7 +1012,7 @@ intel_tv_restore(struct drm_output *output) int pipeconf = I915_READ(pipeconf_reg); int dspcntr = I915_READ(dspcntr_reg); int dspbase_reg = (intel_crtc->plane == 0) ? - DSPABASE : DSPBBASE; + DSPAADDR : DSPBADDR; /* Pipe must be off here */ I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ @@ -1277,7 +1277,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, int pipeconf = I915_READ(pipeconf_reg); int dspcntr = I915_READ(dspcntr_reg); int dspbase_reg = (intel_crtc->plane == 0) ? - DSPABASE : DSPBBASE; + DSPAADDR : DSPBADDR; int xpos = 0x0, ypos = 0x0; unsigned int xsize, ysize; /* Pipe must be off here */ @@ -1368,12 +1368,12 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) tv_dac = I915_READ(TV_DAC); /* Disable TV interrupts around load detect or we'll recurse */ - pipeastat = I915_READ(I915REG_PIPEASTAT); + pipeastat = I915_READ(PIPEASTAT); pipeastat_save = pipeastat; - pipeastat &= ~I915_HOTPLUG_INTERRUPT_ENABLE; - pipeastat &= ~I915_HOTPLUG_TV_INTERRUPT_ENABLE; - I915_WRITE(I915REG_PIPEASTAT, pipeastat | I915_HOTPLUG_TV_CLEAR | - I915_HOTPLUG_CLEAR); + pipeastat &= ~PIPE_HOTPLUG_INTERRUPT_ENABLE; + pipeastat &= ~PIPE_HOTPLUG_TV_INTERRUPT_ENABLE; + I915_WRITE(PIPEASTAT, pipeastat | PIPE_HOTPLUG_TV_INTERRUPT_STATUS | + PIPE_HOTPLUG_INTERRUPT_STATUS); /* * Detect TV by polling) @@ -1423,8 +1423,8 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) } /* Restore interrupt config */ - I915_WRITE(I915REG_PIPEASTAT, pipeastat_save | I915_HOTPLUG_TV_CLEAR | - I915_HOTPLUG_CLEAR); + I915_WRITE(PIPEASTAT, pipeastat_save | PIPE_HOTPLUG_TV_INTERRUPT_STATUS | + PIPE_HOTPLUG_INTERRUPT_STATUS); return type; } -- cgit v1.2.3 From 9fc4ea5c00dfb91ebff893fb5092e768155cc2e2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2008 18:42:47 -0700 Subject: i915: do a better job of parsing VBIOS data Add code to get panel modes from the VBIOS if present and check whether certain outputs exist. Should make our display detection code a little more robust. --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 42f4b10b..650c46f7 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1620,7 +1620,7 @@ intel_tv_init(struct drm_device *dev) return; /* Even if we have an encoder we may not have a connector */ - if (!dev_priv->bdb->int_tv_support) + if (!dev_priv->int_tv_support) return; /* -- cgit v1.2.3 From df8cd54286fbae5903d8ede390ec4a11cb6c4b6c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 14:02:14 +1000 Subject: modesetting: reorganise code into core and helper functions. This splits a lot of the core modesetting code out into a file of helper functions, that are only called from themselves and/or the driver. The driver gets called into more often or can call these functions from itself if it is a helper using driver. I've broken framebuffer resize doing this but I didn't like the API for that in any case. --- linux-core/intel_tv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 650c46f7..18fb1f37 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1590,15 +1590,18 @@ out: return ret; } +static const struct drm_output_helper_funcs intel_tv_helper_funcs = { + .mode_fixup = intel_tv_mode_fixup, + .prepare = intel_output_prepare, + .mode_set = intel_tv_mode_set, + .commit = intel_output_commit, +}; + static const struct drm_output_funcs intel_tv_output_funcs = { .dpms = intel_tv_dpms, .save = intel_tv_save, .restore = intel_tv_restore, .mode_valid = intel_tv_mode_valid, - .mode_fixup = intel_tv_mode_fixup, - .prepare = intel_output_prepare, - .mode_set = intel_tv_mode_set, - .commit = intel_output_commit, .detect = intel_tv_detect, .get_modes = intel_tv_get_modes, .cleanup = intel_tv_destroy, @@ -1674,6 +1677,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); + drm_output_helper_add(output, &intel_tv_helper_funcs); output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; -- cgit v1.2.3 From 98c5cf7f6fc51f1a8f5f90b3895009cd38dd8f22 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 11:25:41 +1000 Subject: modesetting: reorganise out crtc/outputs are allocated. Use subclassing from the drivers to allocate the objects. This saves two objects being allocated for each crtc/output and generally makes exit paths cleaner. --- linux-core/intel_tv.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 18fb1f37..e3e78a9f 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -920,7 +920,7 @@ intel_tv_save(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int i; @@ -970,7 +970,7 @@ intel_tv_restore(struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; struct drm_crtc *crtc = output->crtc; struct intel_crtc *intel_crtc; @@ -980,7 +980,7 @@ intel_tv_restore(struct drm_output *output) if (!crtc) return; - intel_crtc = crtc->driver_private; + intel_crtc = to_intel_crtc(crtc); I915_WRITE(TV_H_CTL_1, tv_priv->save_TV_H_CTL_1); I915_WRITE(TV_H_CTL_2, tv_priv->save_TV_H_CTL_2); I915_WRITE(TV_H_CTL_3, tv_priv->save_TV_H_CTL_3); @@ -1069,7 +1069,7 @@ intel_tv_mode_lookup (char *tv_format) static const struct tv_mode * intel_tv_mode_find (struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; return intel_tv_mode_lookup(tv_priv->tv_format); @@ -1117,8 +1117,8 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = output->crtc; - struct intel_crtc *intel_crtc = crtc->driver_private; - struct intel_output *intel_output = output->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; const struct tv_mode *tv_mode = intel_tv_mode_find(output); u32 tv_ctl; @@ -1359,7 +1359,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; @@ -1440,7 +1440,7 @@ intel_tv_detect(struct drm_output *output) { struct drm_crtc *crtc; struct drm_display_mode mode; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int dpms_mode; int type = tv_priv->type; @@ -1547,17 +1547,20 @@ intel_tv_get_modes(struct drm_output *output) static void intel_tv_destroy (struct drm_output *output) { - if (output->driver_private) - drm_free(output->driver_private, sizeof(struct intel_tv_priv), - DRM_MEM_DRIVER); + struct intel_output *intel_output = to_intel_output(output); + + drm_output_cleanup(output); + drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), + DRM_MEM_DRIVER); } + static bool intel_tv_set_property(struct drm_output *output, struct drm_property *property, uint64_t val) { struct drm_device *dev = output->dev; - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int ret = 0; @@ -1604,7 +1607,7 @@ static const struct drm_output_funcs intel_tv_output_funcs = { .mode_valid = intel_tv_mode_valid, .detect = intel_tv_detect, .get_modes = intel_tv_get_modes, - .cleanup = intel_tv_destroy, + .destroy = intel_tv_destroy, .set_property = intel_tv_set_property, }; @@ -1649,18 +1652,15 @@ intel_tv_init(struct drm_device *dev) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; - output = drm_output_create(dev, &intel_tv_output_funcs, - DRM_MODE_OUTPUT_TVDAC); - - if (!output) - return; - intel_output = drm_calloc(1, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); if (!intel_output) { - drm_output_destroy(output); return; } + output = &intel_output->base; + + drm_output_init(dev, output, &intel_tv_output_funcs, + DRM_MODE_OUTPUT_TVDAC); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; @@ -1678,7 +1678,6 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); drm_output_helper_add(output, &intel_tv_helper_funcs); - output->driver_private = intel_output; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; -- cgit v1.2.3 From 9d38448ed33aaff324cc4bbe1e0878593e97d07d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:03:12 +1000 Subject: modesetting: the great renaming. Okay we have crtc, encoder and connectors. No more outputs exposed beyond driver internals I've broken intel tv connector stuff. Really for TV we should have one TV connector, with a sub property for the type of signal been driven over it --- linux-core/intel_tv.c | 173 +++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 87 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index e3e78a9f..330c204a 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -898,9 +898,9 @@ const static struct tv_mode tv_modes[] = { #define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) static void -intel_tv_dpms(struct drm_output *output, int mode) +intel_tv_dpms(struct drm_connector *connector, int mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; switch(mode) { @@ -916,11 +916,11 @@ intel_tv_dpms(struct drm_output *output, int mode) } static void -intel_tv_save(struct drm_output *output) +intel_tv_save(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int i; @@ -966,13 +966,13 @@ intel_tv_save(struct drm_output *output) } static void -intel_tv_restore(struct drm_output *output) +intel_tv_restore(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_crtc *crtc = output->crtc; + struct drm_crtc *crtc = connector->crtc; struct intel_crtc *intel_crtc; int i; @@ -1067,18 +1067,18 @@ intel_tv_mode_lookup (char *tv_format) } static const struct tv_mode * -intel_tv_mode_find (struct drm_output *output) +intel_tv_mode_find (struct intel_output *intel_output) { - struct intel_output *intel_output = to_intel_output(output); struct intel_tv_priv *tv_priv = intel_output->dev_priv; return intel_tv_mode_lookup(tv_priv->tv_format); } static enum drm_mode_status -intel_tv_mode_valid(struct drm_output *output, struct drm_display_mode *mode) +intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - const struct tv_mode *tv_mode = intel_tv_mode_find(output); + struct intel_output *intel_output = to_intel_output(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); /* Ensure TV refresh is close to desired refresh */ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1) @@ -1088,21 +1088,22 @@ intel_tv_mode_valid(struct drm_output *output, struct drm_display_mode *mode) static bool -intel_tv_mode_fixup(struct drm_output *output, struct drm_display_mode *mode, +intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_mode_config *drm_config = &dev->mode_config; - const struct tv_mode *tv_mode = intel_tv_mode_find (output); - struct drm_output *other_output; + struct intel_output *intel_output = to_intel_output(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); + struct drm_connector *other_connector; if (!tv_mode) return FALSE; - /* FIXME: lock output list */ - list_for_each_entry(other_output, &drm_config->output_list, head) { - if (other_output != output && - other_output->crtc == output->crtc) + /* FIXME: lock connector list */ + list_for_each_entry(other_connector, &drm_config->connector_list, head) { + if (other_connector != connector && + other_connector->crtc == connector->crtc) return FALSE; } @@ -1111,16 +1112,16 @@ intel_tv_mode_fixup(struct drm_output *output, struct drm_display_mode *mode, } static void -intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, +intel_tv_mode_set(struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = output->crtc; + struct drm_crtc *crtc = connector->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = intel_tv_mode_find(output); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); u32 tv_ctl; u32 hctl1, hctl2, hctl3; u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; @@ -1137,14 +1138,14 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, switch (tv_priv->type) { default: - case ConnectorUnknown: - case ConnectorComposite: + case DRM_MODE_CONNECTOR_Unknown: + case DRM_MODE_CONNECTOR_Composite: tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; video_levels = tv_mode->composite_levels; color_conversion = tv_mode->composite_color; burst_ena = tv_mode->burst_ena; break; - case ConnectorComponent: + case DRM_MODE_CONNECTOR_Component: tv_ctl |= TV_ENC_OUTPUT_COMPONENT; video_levels = &component_levels; if (tv_mode->burst_ena) @@ -1153,7 +1154,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode, color_conversion = &hdtv_csc_yprpb; burst_ena = FALSE; break; - case ConnectorSVIDEO: + case DRM_MODE_CONNECTOR_SVIDEO: tv_ctl |= TV_ENC_OUTPUT_SVIDEO; video_levels = tv_mode->svideo_levels; color_conversion = tv_mode->svideo_color; @@ -1355,15 +1356,15 @@ static const struct drm_display_mode reported_modes[] = { * \return FALSE if TV is disconnected. */ static int -intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) +intel_tv_detect_type (struct drm_crtc *crtc, struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; - int type = ConnectorUnknown; + int type = DRM_MODE_CONNECTOR_Unknown; tv_dac = I915_READ(TV_DAC); @@ -1410,13 +1411,13 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) */ if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { DRM_DEBUG("Detected Composite TV connection\n"); - type = ConnectorComposite; + type = DRM_MODE_CONNECTOR_Composite; } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { DRM_DEBUG("Detected S-Video TV connection\n"); - type = ConnectorSVIDEO; + type = DRM_MODE_CONNECTOR_SVIDEO; } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { DRM_DEBUG("Detected Component TV connection\n"); - type = ConnectorComponent; + type = DRM_MODE_CONNECTOR_Component; } else { DRM_DEBUG("No TV connection detected\n"); type = -1; @@ -1432,15 +1433,15 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output) /** * Detect the TV connection. * - * Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure + * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure * we have a pipe programmed in order to probe the TV. */ -static enum drm_output_status -intel_tv_detect(struct drm_output *output) +static enum drm_connector_status +intel_tv_detect(struct drm_connector *connector) { struct drm_crtc *crtc; struct drm_display_mode mode; - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int dpms_mode; int type = tv_priv->type; @@ -1448,30 +1449,31 @@ intel_tv_detect(struct drm_output *output) mode = reported_modes[0]; drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); - if (output->crtc) { - type = intel_tv_detect_type(output->crtc, output); + if (connector->crtc) { + type = intel_tv_detect_type(connector->crtc, connector); } else { - crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode); + crtc = intel_get_load_detect_pipe(connector, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(crtc, output); - intel_release_load_detect_pipe(output, dpms_mode); + type = intel_tv_detect_type(crtc, connector); + intel_release_load_detect_pipe(connector, dpms_mode); } else type = -1; } +#if 0 if (type != tv_priv->type) { struct drm_property *connector_property = - output->dev->mode_config.connector_type_property; + connector->dev->mode_config.connector_type_property; tv_priv->type = type; - drm_output_property_set_value(output, connector_property, + drm_connector_property_set_value(connector, connector_property, type); } - +#endif if (type < 0) - return output_status_disconnected; + return connector_status_disconnected; - return output_status_connected; + return connector_status_connected; } static struct input_res { @@ -1496,10 +1498,11 @@ static struct input_res { */ static int -intel_tv_get_modes(struct drm_output *output) +intel_tv_get_modes(struct drm_connector *connector) { struct drm_display_mode *mode_ptr; - const struct tv_mode *tv_mode = intel_tv_mode_find(output); + struct intel_output *intel_output = to_intel_output(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); int j; for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]); @@ -1538,33 +1541,33 @@ intel_tv_get_modes(struct drm_output *output) mode_ptr->htotal / 1000) / 1000; mode_ptr->type = DRM_MODE_TYPE_DRIVER; - drm_mode_probed_add(output, mode_ptr); + drm_mode_probed_add(connector, mode_ptr); } return 0; } static void -intel_tv_destroy (struct drm_output *output) +intel_tv_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); - drm_output_cleanup(output); + drm_connector_cleanup(connector); drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); } static bool -intel_tv_set_property(struct drm_output *output, struct drm_property *property, +intel_tv_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { - struct drm_device *dev = output->dev; - struct intel_output *intel_output = to_intel_output(output); + struct drm_device *dev = connector->dev; + struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; int ret = 0; - ret = drm_output_property_set_value(output, property, val); + ret = drm_connector_property_set_value(connector, property, val); if (ret < 0) goto out; @@ -1582,25 +1585,25 @@ intel_tv_set_property(struct drm_output *output, struct drm_property *property, goto out; } tv_priv->tv_format = tv_modes[val].name; - intel_tv_mode_set(output, NULL, NULL); + intel_tv_mode_set(connector, NULL, NULL); } else { ret = -EINVAL; goto out; } - intel_tv_mode_set(output, NULL, NULL); + intel_tv_mode_set(connector, NULL, NULL); out: return ret; } -static const struct drm_output_helper_funcs intel_tv_helper_funcs = { +static const struct drm_connector_helper_funcs intel_tv_helper_funcs = { .mode_fixup = intel_tv_mode_fixup, - .prepare = intel_output_prepare, + .prepare = intel_connector_prepare, .mode_set = intel_tv_mode_set, - .commit = intel_output_commit, + .commit = intel_connector_commit, }; -static const struct drm_output_funcs intel_tv_output_funcs = { +static const struct drm_connector_funcs intel_tv_connector_funcs = { .dpms = intel_tv_dpms, .save = intel_tv_save, .restore = intel_tv_restore, @@ -1615,7 +1618,7 @@ void intel_tv_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_output *output; + struct drm_connector *connector; struct intel_output *intel_output; struct intel_tv_priv *tv_priv; u32 tv_dac_on, tv_dac_off, save_tv_dac; @@ -1657,17 +1660,17 @@ intel_tv_init(struct drm_device *dev) if (!intel_output) { return; } - output = &intel_output->base; + connector = &intel_output->base; - drm_output_init(dev, output, &intel_tv_output_funcs, - DRM_MODE_OUTPUT_TVDAC); + drm_connector_init(dev, connector, &intel_tv_connector_funcs, + DRM_MODE_CONNECTOR_Unknown); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; - output->possible_crtcs = ((1 << 0) | (1 << 1)); - output->possible_clones = (1 << INTEL_OUTPUT_TVOUT); + connector->possible_crtcs = ((1 << 0) | (1 << 1)); + connector->possible_clones = (1 << INTEL_OUTPUT_TVOUT); intel_output->dev_priv = tv_priv; - tv_priv->type = ConnectorUnknown; + tv_priv->type = DRM_MODE_CONNECTOR_Unknown; /* BIOS margin values */ tv_priv->margin[TV_MARGIN_LEFT] = 54; @@ -1677,13 +1680,9 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); - drm_output_helper_add(output, &intel_tv_helper_funcs); - output->interlace_allowed = FALSE; - output->doublescan_allowed = FALSE; - - drm_output_attach_property(output, - dev->mode_config.connector_type_property, - ConnectorUnknown); + drm_connector_helper_add(connector, &intel_tv_helper_funcs); + connector->interlace_allowed = FALSE; + connector->doublescan_allowed = FALSE; /* Create TV properties then attach current values */ tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES, @@ -1694,20 +1693,20 @@ intel_tv_init(struct drm_device *dev) tv_format_names[i] = tv_modes[i].name; drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); - drm_output_attach_property(output, dev->mode_config.tv_mode_property, + drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, initial_mode); - drm_output_attach_property(output, + drm_connector_attach_property(connector, dev->mode_config.tv_left_margin_property, tv_priv->margin[TV_MARGIN_LEFT]); - drm_output_attach_property(output, + drm_connector_attach_property(connector, dev->mode_config.tv_top_margin_property, tv_priv->margin[TV_MARGIN_TOP]); - drm_output_attach_property(output, + drm_connector_attach_property(connector, dev->mode_config.tv_right_margin_property, tv_priv->margin[TV_MARGIN_RIGHT]); - drm_output_attach_property(output, + drm_connector_attach_property(connector, dev->mode_config.tv_bottom_margin_property, tv_priv->margin[TV_MARGIN_BOTTOM]); out: - drm_sysfs_output_add(output); + drm_sysfs_connector_add(connector); } -- cgit v1.2.3 From 5d47185eb69d73dd7e6ee3ddde4d0c7642c2d5b7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:32:58 +1000 Subject: drm: switch possible crtc/clones over to encoders --- linux-core/intel_tv.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 330c204a..c2658f13 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1614,6 +1614,16 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { .set_property = intel_tv_set_property, }; +void intel_tv_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs intel_tv_enc_funcs = { + .destroy = intel_tv_enc_destroy, +}; + + void intel_tv_init(struct drm_device *dev) { @@ -1665,10 +1675,13 @@ intel_tv_init(struct drm_device *dev) drm_connector_init(dev, connector, &intel_tv_connector_funcs, DRM_MODE_CONNECTOR_Unknown); + drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, + DRM_MODE_ENCODER_TVDAC); + tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; - connector->possible_crtcs = ((1 << 0) | (1 << 1)); - connector->possible_clones = (1 << INTEL_OUTPUT_TVOUT); + intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); + intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); intel_output->dev_priv = tv_priv; tv_priv->type = DRM_MODE_CONNECTOR_Unknown; -- cgit v1.2.3 From e439e74776b215d70d8e34e8aa9cea22179dcbc6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 10:05:54 +1000 Subject: drm/modesetting: another re-org of some internals. Move dpms into the helper functions. Move crtc into the encoder. Move disable unused functions into the helper. --- linux-core/intel_tv.c | 61 ++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index c2658f13..b13b035f 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -898,9 +898,9 @@ const static struct tv_mode tv_modes[] = { #define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) static void -intel_tv_dpms(struct drm_connector *connector, int mode) +intel_tv_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; switch(mode) { @@ -972,7 +972,7 @@ intel_tv_restore(struct drm_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_crtc *crtc = connector->crtc; + struct drm_crtc *crtc = connector->encoder->crtc; struct intel_crtc *intel_crtc; int i; @@ -1088,22 +1088,22 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo static bool -intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mode, +intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_mode_config *drm_config = &dev->mode_config; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); - struct drm_connector *other_connector; + struct drm_encoder *other_encoder; if (!tv_mode) return FALSE; - /* FIXME: lock connector list */ - list_for_each_entry(other_connector, &drm_config->connector_list, head) { - if (other_connector != connector && - other_connector->crtc == connector->crtc) + /* FIXME: lock encoder list */ + list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { + if (other_encoder != encoder && + other_encoder->crtc == encoder->crtc) return FALSE; } @@ -1112,14 +1112,14 @@ intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mo } static void -intel_tv_mode_set(struct drm_connector *connector, struct drm_display_mode *mode, +intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = connector->crtc; + struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_tv_priv *tv_priv = intel_output->dev_priv; const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); u32 tv_ctl; @@ -1356,11 +1356,11 @@ static const struct drm_display_mode reported_modes[] = { * \return FALSE if TV is disconnected. */ static int -intel_tv_detect_type (struct drm_crtc *crtc, struct drm_connector *connector) +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) { - struct drm_device *dev = connector->dev; + struct drm_encoder *encoder = &intel_output->enc; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; @@ -1443,19 +1443,20 @@ intel_tv_detect(struct drm_connector *connector) struct drm_display_mode mode; struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct drm_encoder *encoder = &intel_output->enc; int dpms_mode; int type = tv_priv->type; mode = reported_modes[0]; drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); - if (connector->crtc) { - type = intel_tv_detect_type(connector->crtc, connector); + if (encoder->crtc) { + type = intel_tv_detect_type(encoder->crtc, intel_output); } else { - crtc = intel_get_load_detect_pipe(connector, &mode, &dpms_mode); + crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(crtc, connector); - intel_release_load_detect_pipe(connector, dpms_mode); + type = intel_tv_detect_type(crtc, intel_output); + intel_release_load_detect_pipe(intel_output, dpms_mode); } else type = -1; } @@ -1585,26 +1586,26 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop goto out; } tv_priv->tv_format = tv_modes[val].name; - intel_tv_mode_set(connector, NULL, NULL); + intel_tv_mode_set(&intel_output->enc, NULL, NULL); } else { ret = -EINVAL; goto out; } - intel_tv_mode_set(connector, NULL, NULL); + intel_tv_mode_set(&intel_output->enc, NULL, NULL); out: return ret; } -static const struct drm_connector_helper_funcs intel_tv_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { + .dpms = intel_tv_dpms, .mode_fixup = intel_tv_mode_fixup, - .prepare = intel_connector_prepare, + .prepare = intel_encoder_prepare, .mode_set = intel_tv_mode_set, - .commit = intel_connector_commit, + .commit = intel_encoder_commit, }; static const struct drm_connector_funcs intel_tv_connector_funcs = { - .dpms = intel_tv_dpms, .save = intel_tv_save, .restore = intel_tv_restore, .mode_valid = intel_tv_mode_valid, @@ -1693,7 +1694,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); - drm_connector_helper_add(connector, &intel_tv_helper_funcs); + drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; -- cgit v1.2.3 From 0dd000b578adec6ff101c957bce7dc9a32b76713 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 11:12:28 +1000 Subject: drm/modesetting: move some connector functions to helper. Migrated the output mode collection into the helper. --- linux-core/intel_tv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index b13b035f..c3b5c093 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1608,11 +1608,15 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { static const struct drm_connector_funcs intel_tv_connector_funcs = { .save = intel_tv_save, .restore = intel_tv_restore, - .mode_valid = intel_tv_mode_valid, .detect = intel_tv_detect, - .get_modes = intel_tv_get_modes, .destroy = intel_tv_destroy, .set_property = intel_tv_set_property, + .fill_modes = drm_helper_probe_single_connector_modes, +}; + +static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { + .mode_valid = intel_tv_mode_valid, + .get_modes = intel_tv_get_modes, }; void intel_tv_enc_destroy(struct drm_encoder *encoder) @@ -1695,6 +1699,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); + drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; -- cgit v1.2.3 From 46c78a2223802b9105a87b7125fd4872ab69c4ca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 11:44:35 +1000 Subject: drm/modesetting: add best encoder finding for modesetting This asks the driver to suggest the best encoder for the connector during the pick crtcs stage. Need to also do this during mode setting stages --- linux-core/intel_tv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index c3b5c093..e45cfa3b 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1617,6 +1617,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { .mode_valid = intel_tv_mode_valid, .get_modes = intel_tv_get_modes, + .best_encoder = intel_best_encoder, }; void intel_tv_enc_destroy(struct drm_encoder *encoder) @@ -1683,6 +1684,7 @@ intel_tv_init(struct drm_device *dev) drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, DRM_MODE_ENCODER_TVDAC); + drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); -- cgit v1.2.3 From 58aca7485a4cd9fcccc6e4044325048abcc2f9c7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Jun 2008 13:03:23 +1000 Subject: drm: remove sysfs in driver for now.. should probably be in helper --- linux-core/intel_tv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index e45cfa3b..25fb2e6b 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1553,6 +1553,7 @@ intel_tv_destroy (struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); -- cgit v1.2.3 From a8725d95bc2b51500ff56c4e6365408d15f3bc6e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Jun 2008 15:17:00 +1000 Subject: intel: report a known connector --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 25fb2e6b..39f33d6c 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1680,7 +1680,7 @@ intel_tv_init(struct drm_device *dev) connector = &intel_output->base; drm_connector_init(dev, connector, &intel_tv_connector_funcs, - DRM_MODE_CONNECTOR_Unknown); + DRM_MODE_CONNECTOR_SVIDEO); drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, DRM_MODE_ENCODER_TVDAC); -- cgit v1.2.3 From 13943fe5823c45759091c1a1f487a4abe377421e Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 26 Jun 2008 21:28:29 +0200 Subject: modesetting-101: Make dpms property optional + misc cleanup. - intel_crt seems the only one to provide it, so init it there. --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 39f33d6c..f564fa91 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1713,7 +1713,7 @@ intel_tv_init(struct drm_device *dev) goto out; for (i = 0; i < NUM_TV_MODES; i++) tv_format_names[i] = tv_modes[i].name; - drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, initial_mode); -- cgit v1.2.3 From 087e3f577d795bcd007619514bb2977eede70c16 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 26 Jun 2008 23:12:04 +0200 Subject: Revert "modesetting-101: Make dpms property optional + misc cleanup." This reverts commit 13943fe5823c45759091c1a1f487a4abe377421e. --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index f564fa91..39f33d6c 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1713,7 +1713,7 @@ intel_tv_init(struct drm_device *dev) goto out; for (i = 0; i < NUM_TV_MODES; i++) tv_format_names[i] = tv_modes[i].name; - drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, initial_mode); -- cgit v1.2.3 From b29578103f57a8d684b4a3a79f220e6cc626605e Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 4 Jul 2008 17:17:11 +0200 Subject: [modesetting-101] Add subconnector and select_subconnector properties. - These facilitate DVI-I and tv-out that can drive multiple types of signals. --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 39f33d6c..f564fa91 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1713,7 +1713,7 @@ intel_tv_init(struct drm_device *dev) goto out; for (i = 0; i < NUM_TV_MODES; i++) tv_format_names[i] = tv_modes[i].name; - drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, initial_mode); -- cgit v1.2.3 From 6738e7b00bf05529303ed690873495db6d83337c Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 6 Jul 2008 11:08:49 +0200 Subject: modesetting-101: Rename DPMS modes to avoid compatibility issues with xorg definitions. --- linux-core/intel_tv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index f564fa91..389487bb 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -904,12 +904,12 @@ intel_tv_dpms(struct drm_encoder *encoder, int mode) struct drm_i915_private *dev_priv = dev->dev_private; switch(mode) { - case DPMSModeOn: + case DRM_MODE_DPMS_ON: I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); break; - case DPMSModeStandby: - case DPMSModeSuspend: - case DPMSModeOff: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); break; } -- cgit v1.2.3 From 7fd8a5de63781f6faa053509c80e02e8f1cdbb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 7 Jul 2008 11:56:59 -0400 Subject: Use lowercase bool constants. --- linux-core/intel_tv.c | 116 +++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 39f33d6c..ba680635 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -422,18 +422,18 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 124, .hblank_start = 836, .htotal = 857, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 6, .vsync_start_f2 = 7, .vsync_len = 6, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 18, .vi_end_f1 = 20, .vi_end_f2 = 21, .nbr_end = 240, - .burst_ena = TRUE, + .burst_ena = true, .hburst_start = 72, .hburst_len = 34, .vburst_start_f1 = 9, .vburst_end_f1 = 240, .vburst_start_f2 = 10, .vburst_end_f2 = 240, @@ -445,7 +445,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 7624, .dda2_size = 20013, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = FALSE, + .pal_burst = false, .composite_levels = &ntsc_m_levels_composite, .composite_color = &ntsc_m_csc_composite, @@ -464,12 +464,12 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 124, .hblank_start = 836, .htotal = 857, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 6, .vsync_start_f2 = 7, .vsync_len = 6, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 18, .vi_end_f1 = 20, .vi_end_f2 = 21, @@ -487,7 +487,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 18557, .dda2_size = 20625, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, + .pal_burst = true, .composite_levels = &ntsc_m_levels_composite, .composite_color = &ntsc_m_csc_composite, @@ -507,18 +507,18 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 124, .hblank_start = 836, .htotal = 857, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 6, .vsync_start_f2 = 7, .vsync_len = 6, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 18, .vi_end_f1 = 20, .vi_end_f2 = 21, .nbr_end = 240, - .burst_ena = TRUE, + .burst_ena = true, .hburst_start = 72, .hburst_len = 34, .vburst_start_f1 = 9, .vburst_end_f1 = 240, .vburst_start_f2 = 10, .vburst_end_f2 = 240, @@ -530,7 +530,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 7624, .dda2_size = 20013, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = FALSE, + .pal_burst = false, .composite_levels = &ntsc_j_levels_composite, .composite_color = &ntsc_j_csc_composite, @@ -550,18 +550,18 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 124, .hblank_start = 836, .htotal = 857, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 6, .vsync_start_f2 = 7, .vsync_len = 6, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 18, .vi_end_f1 = 20, .vi_end_f2 = 21, .nbr_end = 240, - .burst_ena = TRUE, + .burst_ena = true, .hburst_start = 72, .hburst_len = 34, .vburst_start_f1 = 9, .vburst_end_f1 = 240, .vburst_start_f2 = 10, .vburst_end_f2 = 240, @@ -573,7 +573,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 7624, .dda2_size = 20013, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = FALSE, + .pal_burst = false, .composite_levels = &pal_m_levels_composite, .composite_color = &pal_m_csc_composite, @@ -593,19 +593,19 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 128, .hblank_start = 844, .htotal = 863, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 6, .vsync_start_f2 = 7, .vsync_len = 6, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 18, .vi_end_f1 = 24, .vi_end_f2 = 25, .nbr_end = 286, - .burst_ena = TRUE, + .burst_ena = true, .hburst_start = 73, .hburst_len = 34, .vburst_start_f1 = 8, .vburst_end_f1 = 285, .vburst_start_f2 = 8, .vburst_end_f2 = 286, @@ -618,7 +618,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 18557, .dda2_size = 20625, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, + .pal_burst = true, .composite_levels = &pal_n_levels_composite, .composite_color = &pal_n_csc_composite, @@ -638,18 +638,18 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 128, .hblank_start = 844, .htotal = 863, - .progressive = FALSE, .trilevel_sync = FALSE, + .progressive = false, .trilevel_sync = false, .vsync_start_f1 = 5, .vsync_start_f2 = 6, .vsync_len = 5, - .veq_ena = TRUE, .veq_start_f1 = 0, + .veq_ena = true, .veq_start_f1 = 0, .veq_start_f2 = 1, .veq_len = 15, .vi_end_f1 = 24, .vi_end_f2 = 25, .nbr_end = 286, - .burst_ena = TRUE, + .burst_ena = true, .hburst_start = 73, .hburst_len = 32, .vburst_start_f1 = 8, .vburst_end_f1 = 285, .vburst_start_f2 = 8, .vburst_end_f2 = 286, @@ -661,7 +661,7 @@ const static struct tv_mode tv_modes[] = { .dda2_inc = 18557, .dda2_size = 20625, .dda3_inc = 0, .dda3_size = 0, .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, + .pal_burst = true, .composite_levels = &pal_levels_composite, .composite_color = &pal_csc_composite, @@ -680,17 +680,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 122, .hblank_start = 842, .htotal = 857, - .progressive = TRUE,.trilevel_sync = FALSE, + .progressive = true,.trilevel_sync = false, .vsync_start_f1 = 12, .vsync_start_f2 = 12, .vsync_len = 12, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 44, .vi_end_f2 = 44, .nbr_end = 496, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -704,17 +704,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 122, .hblank_start = 842, .htotal = 856, - .progressive = TRUE,.trilevel_sync = FALSE, + .progressive = true,.trilevel_sync = false, .vsync_start_f1 = 12, .vsync_start_f2 = 12, .vsync_len = 12, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 44, .vi_end_f2 = 44, .nbr_end = 496, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -728,17 +728,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 64, .hblank_end = 139, .hblank_start = 859, .htotal = 863, - .progressive = TRUE, .trilevel_sync = FALSE, + .progressive = true, .trilevel_sync = false, .vsync_start_f1 = 10, .vsync_start_f2 = 10, .vsync_len = 10, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 48, .vi_end_f2 = 48, .nbr_end = 575, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -752,17 +752,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 80, .hblank_end = 300, .hblank_start = 1580, .htotal = 1649, - .progressive = TRUE, .trilevel_sync = TRUE, + .progressive = true, .trilevel_sync = true, .vsync_start_f1 = 10, .vsync_start_f2 = 10, .vsync_len = 10, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 29, .vi_end_f2 = 29, .nbr_end = 719, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -776,17 +776,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 80, .hblank_end = 300, .hblank_start = 1580, .htotal = 1651, - .progressive = TRUE, .trilevel_sync = TRUE, + .progressive = true, .trilevel_sync = true, .vsync_start_f1 = 10, .vsync_start_f2 = 10, .vsync_len = 10, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 29, .vi_end_f2 = 29, .nbr_end = 719, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -800,17 +800,17 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 80, .hblank_end = 300, .hblank_start = 1580, .htotal = 1979, - .progressive = TRUE, .trilevel_sync = TRUE, + .progressive = true, .trilevel_sync = true, .vsync_start_f1 = 10, .vsync_start_f2 = 10, .vsync_len = 10, - .veq_ena = FALSE, + .veq_ena = false, .vi_end_f1 = 29, .vi_end_f2 = 29, .nbr_end = 719, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, .max_srcw = 800 @@ -825,19 +825,19 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 88, .hblank_end = 235, .hblank_start = 2155, .htotal = 2639, - .progressive = FALSE, .trilevel_sync = TRUE, + .progressive = false, .trilevel_sync = true, .vsync_start_f1 = 4, .vsync_start_f2 = 5, .vsync_len = 10, - .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_ena = true, .veq_start_f1 = 4, .veq_start_f2 = 4, .veq_len = 10, .vi_end_f1 = 21, .vi_end_f2 = 22, .nbr_end = 539, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -851,19 +851,19 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 88, .hblank_end = 235, .hblank_start = 2155, .htotal = 2199, - .progressive = FALSE, .trilevel_sync = TRUE, + .progressive = false, .trilevel_sync = true, .vsync_start_f1 = 4, .vsync_start_f2 = 5, .vsync_len = 10, - .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_ena = true, .veq_start_f1 = 4, .veq_start_f2 = 4, .veq_len = 10, .vi_end_f1 = 21, .vi_end_f2 = 22, .nbr_end = 539, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -877,19 +877,19 @@ const static struct tv_mode tv_modes[] = { .hsync_end = 88, .hblank_end = 235, .hblank_start = 2155, .htotal = 2200, - .progressive = FALSE, .trilevel_sync = TRUE, + .progressive = false, .trilevel_sync = true, .vsync_start_f1 = 4, .vsync_start_f2 = 5, .vsync_len = 10, - .veq_ena = TRUE, .veq_start_f1 = 4, + .veq_ena = true, .veq_start_f1 = 4, .veq_start_f2 = 4, .veq_len = 10, .vi_end_f1 = 21, .vi_end_f2 = 22, .nbr_end = 539, - .burst_ena = FALSE, + .burst_ena = false, .filter_table = filter_table, }, @@ -1098,17 +1098,17 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_encoder *other_encoder; if (!tv_mode) - return FALSE; + return false; /* FIXME: lock encoder list */ list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { if (other_encoder != encoder && other_encoder->crtc == encoder->crtc) - return FALSE; + return false; } adjusted_mode->clock = tv_mode->clock; - return TRUE; + return true; } static void @@ -1152,7 +1152,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, color_conversion = &sdtv_csc_yprpb; else color_conversion = &hdtv_csc_yprpb; - burst_ena = FALSE; + burst_ena = false; break; case DRM_MODE_CONNECTOR_SVIDEO: tv_ctl |= TV_ENC_OUTPUT_SVIDEO; @@ -1352,8 +1352,8 @@ static const struct drm_display_mode reported_modes[] = { * * Requires that the current pipe's DPLL is active. - * \return TRUE if TV is connected. - * \return FALSE if TV is disconnected. + * \return true if TV is connected. + * \return false if TV is disconnected. */ static int intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) @@ -1703,8 +1703,8 @@ intel_tv_init(struct drm_device *dev) drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); - connector->interlace_allowed = FALSE; - connector->doublescan_allowed = FALSE; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; /* Create TV properties then attach current values */ tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES, -- cgit v1.2.3 From 3ef1d05001a9e28ed52536de7e020323d8d34d83 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 20 Jul 2008 14:51:22 +0200 Subject: modesetting-101: set_property should return an int, not a bool --- linux-core/intel_tv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_tv.c') diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index 389487bb..29cfc031 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -1560,7 +1560,7 @@ intel_tv_destroy (struct drm_connector *connector) } -static bool +static int intel_tv_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { -- cgit v1.2.3