linux/drivers/gpu/drm/i915/display/intel_tv.c

/*
 * Copyright © 2006-2008 Intel Corporation
 *   Jesse Barnes <[email protected]>
 *
 * 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 <[email protected]>
 *
 */

/** @file
 * Integrated TV-out support for the 915GM and 945GM.
 */

#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>

#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_dpll.h"
#include "intel_hotplug.h"
#include "intel_load_detect.h"
#include "intel_tv.h"
#include "intel_tv_regs.h"

enum tv_margin {};

struct intel_tv {};

struct video_levels {};

struct color_conversion {};

static const u32 filter_table[] =;

/*
 * 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 =;

static const struct video_levels ntsc_m_levels_composite =;

static const struct color_conversion ntsc_m_csc_svideo =;

static const struct video_levels ntsc_m_levels_svideo =;

static const struct color_conversion ntsc_j_csc_composite =;

static const struct video_levels ntsc_j_levels_composite =;

static const struct color_conversion ntsc_j_csc_svideo =;

static const struct video_levels ntsc_j_levels_svideo =;

static const struct color_conversion pal_csc_composite =;

static const struct video_levels pal_levels_composite =;

static const struct color_conversion pal_csc_svideo =;

static const struct video_levels pal_levels_svideo =;

static const struct color_conversion pal_m_csc_composite =;

static const struct video_levels pal_m_levels_composite =;

static const struct color_conversion pal_m_csc_svideo =;

static const struct video_levels pal_m_levels_svideo =;

static const struct color_conversion pal_n_csc_composite =;

static const struct video_levels pal_n_levels_composite =;

static const struct color_conversion pal_n_csc_svideo =;

static const struct video_levels pal_n_levels_svideo =;

/*
 * Component connections
 */
static const struct color_conversion sdtv_csc_yprpb =;

static const struct color_conversion hdtv_csc_yprpb =;

static const struct video_levels component_levels =;


struct tv_mode {};


/*
 * 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.
 */
static const struct tv_mode tv_modes[] =;

struct intel_tv_connector_state {};

#define to_intel_tv_connector_state(conn_state)

static struct drm_connector_state *
intel_tv_connector_duplicate_state(struct drm_connector *connector)
{}

static struct intel_tv *enc_to_tv(struct intel_encoder *encoder)
{}

static struct intel_tv *intel_attached_tv(struct intel_connector *connector)
{}

static bool
intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
{}

static void
intel_enable_tv(struct intel_atomic_state *state,
		struct intel_encoder *encoder,
		const struct intel_crtc_state *pipe_config,
		const struct drm_connector_state *conn_state)
{}

static void
intel_disable_tv(struct intel_atomic_state *state,
		 struct intel_encoder *encoder,
		 const struct intel_crtc_state *old_crtc_state,
		 const struct drm_connector_state *old_conn_state)
{}

static const struct tv_mode *intel_tv_mode_find(const struct drm_connector_state *conn_state)
{}

static enum drm_mode_status
intel_tv_mode_valid(struct drm_connector *connector,
		    struct drm_display_mode *mode)
{}

static int
intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
{}

static void
intel_tv_mode_to_mode(struct drm_display_mode *mode,
		      const struct tv_mode *tv_mode,
		      int clock)
{}

static void intel_tv_scale_mode_horiz(struct drm_display_mode *mode,
				      int hdisplay, int left_margin,
				      int right_margin)
{}

static void intel_tv_scale_mode_vert(struct drm_display_mode *mode,
				     int vdisplay, int top_margin,
				     int bottom_margin)
{}

static void
intel_tv_get_config(struct intel_encoder *encoder,
		    struct intel_crtc_state *pipe_config)
{}

static bool intel_tv_source_too_wide(struct intel_display *display,
				     int hdisplay)
{}

static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
				  const struct drm_connector_state *conn_state,
				  int vdisplay)
{}

static int
intel_tv_compute_config(struct intel_encoder *encoder,
			struct intel_crtc_state *pipe_config,
			struct drm_connector_state *conn_state)
{}

static void
set_tv_mode_timings(struct intel_display *display,
		    const struct tv_mode *tv_mode,
		    bool burst_ena)
{}

static void set_color_conversion(struct intel_display *display,
				 const struct color_conversion *color_conversion)
{}

static void intel_tv_pre_enable(struct intel_atomic_state *state,
				struct intel_encoder *encoder,
				const struct intel_crtc_state *pipe_config,
				const struct drm_connector_state *conn_state)
{}

static int
intel_tv_detect_type(struct intel_tv *intel_tv,
		      struct drm_connector *connector)
{}

/*
 * Here we set accurate tv format according to connector type
 * i.e Component TV should not be assigned by NTSC or PAL
 */
static void intel_tv_find_better_format(struct drm_connector *connector)
{}

static int
intel_tv_detect(struct drm_connector *connector,
		struct drm_modeset_acquire_ctx *ctx,
		bool force)
{}

static const struct input_res {} input_res_table[] =;

/* Choose preferred mode according to line number of TV format */
static bool
intel_tv_is_preferred_mode(const struct drm_display_mode *mode,
			   const struct tv_mode *tv_mode)
{}

static void
intel_tv_set_mode_type(struct drm_display_mode *mode,
		       const struct tv_mode *tv_mode)
{}

static int
intel_tv_get_modes(struct drm_connector *connector)
{}

static const struct drm_connector_funcs intel_tv_connector_funcs =;

static int intel_tv_atomic_check(struct drm_connector *connector,
				 struct drm_atomic_state *state)
{}

static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs =;

static const struct drm_encoder_funcs intel_tv_enc_funcs =;

static void intel_tv_add_properties(struct drm_connector *connector)
{}

void
intel_tv_init(struct intel_display *display)
{}