/*
 * Copyright (C) 2009 Francisco Jerez.
 * All Rights Reserved.
 *
 * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
 *
 */

#include "drmP.h"
#include "drm_crtc_helper.h"
#include "nouveau_drv.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
#include "nv17_tv.h"

static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
	uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
	uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
		fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
	uint32_t sample = 0;
	int head;

#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
	testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
	if (dev_priv->vbios.tvdactestval)
		testval = dev_priv->vbios.tvdactestval;

	dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
	head = (dacclk & 0x100) >> 8;

	/* Save the previous state. */
	gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
	gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
	fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL);
	fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START);
	fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END);
	fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
	test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
	ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c);
	ctv_14 = NVReadRAMDAC(dev, head, 0x680c14);
	ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c);

	/* Prepare the DAC for load detection.  */
	gpio->set(dev, DCB_GPIO_TVDAC1, true);
	gpio->set(dev, DCB_GPIO_TVDAC0, true);

	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
		      NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
		      NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 |
		      NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
		      NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |
		      NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS);

	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0);

	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
		      (dacclk & ~0xff) | 0x22);
	msleep(1);
	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset,
		      (dacclk & ~0xff) | 0x21);

	NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20);
	NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16);

	/* Sample pin 0x4 (usually S-video luma). */
	NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff);
	msleep(20);
	sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
		& 0x4 << 28;

	/* Sample the remaining pins. */
	NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff);
	msleep(20);
	sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset)
		& 0xa << 28;

	/* Restore the previous state. */
	NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c);
	NVWriteRAMDAC(dev, head, 0x680c14, ctv_14);
	NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c);
	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk);
	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start);
	NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal);
	gpio->set(dev, DCB_GPIO_TVDAC1, gpio1);
	gpio->set(dev, DCB_GPIO_TVDAC0, gpio0);

	return sample;
}

static bool
get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
{
	/* Zotac FX5200 */
	if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) ||
	    nv_match_device(dev, 0x0322, 0x19da, 0x2035)) {
		*pin_mask = 0xc;
		return false;
	}

	/* MSI nForce2 IGP */
	if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) {
		*pin_mask = 0xc;
		return false;
	}

	return true;
}

static enum drm_connector_status
nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_mode_config *conf = &dev->mode_config;
	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
	struct dcb_entry *dcb = tv_enc->base.dcb;
	bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask);

	if (nv04_dac_in_use(encoder))
		return connector_status_disconnected;

	if (reliable) {
		if (dev_priv->chipset == 0x42 ||
		    dev_priv->chipset == 0x43)
			tv_enc->pin_mask =
				nv42_tv_sample_load(encoder) >> 28 & 0xe;
		else
			tv_enc->pin_mask =
				nv17_dac_sample_load(encoder) >> 28 & 0xe;
	}

	switch (tv_enc->pin_mask) {
	case 0x2:
	case 0x4:
		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite;
		break;
	case 0xc:
		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO;
		break;
	case 0xe:
		if (dcb->tvconf.has_component_output)
			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component;
		else
			tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART;
		break;
	default:
		tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
		break;
	}

	drm_connector_property_set_value(connector,
					 conf->tv_subconnector_property,
					 tv_enc->subconnector);

	if (!reliable) {
		return connector_status_unknown;
	} else if (tv_enc->subconnector) {
		NV_INFO(dev, "Load detected on output %c\n",
			'@' + ffs(dcb->or));
		return connector_status_connected;
	} else {
		return connector_status_disconnected;
	}
}

static const struct {
	int hdisplay;
	int vdisplay;
} modes[] = {
	{ 640, 400 },
	{ 640, 480 },
	{ 720, 480 },
	{ 720, 576 },
	{ 800, 600 },
	{ 1024, 768 },
	{ 1280, 720 },
	{ 1280, 1024 },
	{ 1920, 1080 }
};

static int nv17_tv_get_modes(struct drm_encoder *encoder,
			     struct drm_connector *connector)
{
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
	struct drm_display_mode *mode;
	struct drm_display_mode *output_mode;
	int n = 0;
	int i;

	if (tv_norm->kind != CTV_ENC_MODE) {
		struct drm_display_mode *tv_mode;

		for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) {
			mode = drm_mode_duplicate(encoder->dev, tv_mode);

			mode->clock = tv_norm->tv_enc_mode.vrefresh *
						mode->htotal / 1000 *
						mode->vtotal / 1000;

			if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
				mode->clock *= 2;

			if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay &&
			    mode->vdisplay == tv_norm->tv_enc_mode.vdisplay)
				mode->type |= DRM_MODE_TYPE_PREFERRED;

			drm_mode_probed_add(connector, mode);
			n++;
		}
		return n;
	}

	/* tv_norm->kind == CTV_ENC_MODE */
	output_mode = &tv_norm->ctv_enc_mode.mode;
	for (i = 0; i < ARRAY_SIZE(modes); i++) {
		if (modes[i].hdisplay > output_mode->hdisplay ||
		    modes[i].vdisplay > output_mode->vdisplay)
			continue;

		if (modes[i].hdisplay == output_mode->hdisplay &&
		    modes[i].vdisplay == output_mode->vdisplay) {
			mode = drm_mode_duplicate(encoder->dev, output_mode);
			mode->type |= DRM_MODE_TYPE_PREFERRED;
		} else {
			mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay,
				modes[i].vdisplay, 60, false,
				output_mode->flags & DRM_MODE_FLAG_INTERLACE,
				false);
		}

		/* CVT modes are sometimes unsuitable... */
		if (output_mode->hdisplay <= 720
		    || output_mode->hdisplay >= 1920) {
			mode->htotal = output_mode->htotal;
			mode->hsync_start = (mode->hdisplay + (mode->htotal
					     - mode->hdisplay) * 9 / 10) & ~7;
			mode->hsync_end = mode->hsync_start + 8;
		}
		if (output_mode->vdisplay >= 1024) {
			mode->vtotal = output_mode->vtotal;
			mode->vsync_start = output_mode->vsync_start;
			mode->vsync_end = output_mode->vsync_end;
		}

		mode->type |= DRM_MODE_TYPE_DRIVER;
		drm_mode_probed_add(connector, mode);
		n++;
	}
	return n;
}

static int nv17_tv_mode_valid(struct drm_encoder *encoder,
			      struct drm_display_mode *mode)
{
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);

	if (tv_norm->kind == CTV_ENC_MODE) {
		struct drm_display_mode *output_mode =
						&tv_norm->ctv_enc_mode.mode;

		if (mode->clock > 400000)
			return MODE_CLOCK_HIGH;

		if (mode->hdisplay > output_mode->hdisplay ||
		    mode->vdisplay > output_mode->vdisplay)
			return MODE_BAD;

		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) !=
		    (output_mode->flags & DRM_MODE_FLAG_INTERLACE))
			return MODE_NO_INTERLACE;

		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
			return MODE_NO_DBLESCAN;

	} else {
		const int vsync_tolerance = 600;

		if (mode->clock > 70000)
			return MODE_CLOCK_HIGH;

		if (abs(drm_mode_vrefresh(mode) * 1000 -
			tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance)
			return MODE_VSYNC;

		/* The encoder takes care of the actual interlacing */
		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
			return MODE_NO_INTERLACE;
	}

	return MODE_OK;
}

static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
			       struct drm_display_mode *mode,
			       struct drm_display_mode *adjusted_mode)
{
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);

	if (nv04_dac_in_use(encoder))
		return false;

	if (tv_norm->kind == CTV_ENC_MODE)
		adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
	else
		adjusted_mode->clock = 90000;

	return true;
}

static void  nv17_tv_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
	struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);

	if (nouveau_encoder(encoder)->last_dpms == mode)
		return;
	nouveau_encoder(encoder)->last_dpms = mode;

	NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
		 mode, nouveau_encoder(encoder)->dcb->index);

	regs->ptv_200 &= ~1;

	if (tv_norm->kind == CTV_ENC_MODE) {
		nv04_dfp_update_fp_control(encoder, mode);

	} else {
		nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF);

		if (mode == DRM_MODE_DPMS_ON)
			regs->ptv_200 |= 1;
	}

	nv_load_ptv(dev, regs, 200);

	gpio->set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
	gpio->set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);

	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
}

static void nv17_tv_prepare(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
	int head = nouveau_crtc(encoder->crtc)->index;
	uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[
							NV_CIO_CRE_LCD__INDEX];
	uint32_t dacclk_off = NV_PRAMDAC_DACCLK +
					nv04_dac_output_offset(encoder);
	uint32_t dacclk;

	helper->dpms(encoder, DRM_MODE_DPMS_OFF);

	nv04_dfp_disable(dev, head);

	/* Unbind any FP encoders from this head if we need the FP
	 * stuff enabled. */
	if (tv_norm->kind == CTV_ENC_MODE) {
		struct drm_encoder *enc;

		list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
			struct dcb_entry *dcb = nouveau_encoder(enc)->dcb;

			if ((dcb->type == OUTPUT_TMDS ||
			     dcb->type == OUTPUT_LVDS) &&
			     !enc->crtc &&
			     nv04_dfp_get_bound_head(dev, dcb) == head) {
				nv04_dfp_bind_head(dev, dcb, head ^ 1,
						dev_priv->vbios.fp.dual_link);
			}
		}

	}

	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
	 * at LCD__INDEX which we don't alter
	 */
	if (!(*cr_lcd & 0x44)) {
		if (tv_norm->kind == CTV_ENC_MODE)
			*cr_lcd = 0x1 | (head ? 0x0 : 0x8);
		else
			*cr_lcd = 0;
	}

	/* Set the DACCLK register */
	dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1;

	if (dev_priv->card_type == NV_40)
		dacclk |= 0x1a << 16;

	if (tv_norm->kind == CTV_ENC_MODE) {
		dacclk |=  0x20;

		if (head)
			dacclk |= 0x100;
		else
			dacclk &= ~0x100;

	} else {
		dacclk |= 0x10;

	}

	NVWriteRAMDAC(dev, 0, dacclk_off, dacclk);
}

static void nv17_tv_mode_set(struct drm_encoder *encoder,
			     struct drm_display_mode *drm_mode,
			     struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int head = nouveau_crtc(encoder->crtc)->index;
	struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
	struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state;
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
	int i;

	regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */
	regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */
	regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */
	regs->tv_setup = 1;
	regs->ramdac_8c0 = 0x0;

	if (tv_norm->kind == TV_ENC_MODE) {
		tv_regs->ptv_200 = 0x13111100;
		if (head)
			tv_regs->ptv_200 |= 0x10;

		tv_regs->ptv_20c = 0x808010;
		tv_regs->ptv_304 = 0x2d00000;
		tv_regs->ptv_600 = 0x0;
		tv_regs->ptv_60c = 0x0;
		tv_regs->ptv_610 = 0x1e00000;

		if (tv_norm->tv_enc_mode.vdisplay == 576) {
			tv_regs->ptv_508 = 0x1200000;
			tv_regs->ptv_614 = 0x33;

		} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
			tv_regs->ptv_508 = 0xf00000;
			tv_regs->ptv_614 = 0x13;
		}

		if (dev_priv->card_type >= NV_30) {
			tv_regs->ptv_500 = 0xe8e0;
			tv_regs->ptv_504 = 0x1710;
			tv_regs->ptv_604 = 0x0;
			tv_regs->ptv_608 = 0x0;
		} else {
			if (tv_norm->tv_enc_mode.vdisplay == 576) {
				tv_regs->ptv_604 = 0x20;
				tv_regs->ptv_608 = 0x10;
				tv_regs->ptv_500 = 0x19710;
				tv_regs->ptv_504 = 0x68f0;

			} else if (tv_norm->tv_enc_mode.vdisplay == 480) {
				tv_regs->ptv_604 = 0x10;
				tv_regs->ptv_608 = 0x20;
				tv_regs->ptv_500 = 0x4b90;
				tv_regs->ptv_504 = 0x1b480;
			}
		}

		for (i = 0; i < 0x40; i++)
			tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i];

	} else {
		struct drm_display_mode *output_mode =
						&tv_norm->ctv_enc_mode.mode;

		/* The registers in PRAMDAC+0xc00 control some timings and CSC
		 * parameters for the CTV encoder (It's only used for "HD" TV
		 * modes, I don't think I have enough working to guess what
		 * they exactly mean...), it's probably connected at the
		 * output of the FP encoder, but it also needs the analog
		 * encoder in its OR enabled and routed to the head it's
		 * using. It's enabled with the DACCLK register, bits [5:4].
		 */
		for (i = 0; i < 38; i++)
			regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i];

		regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
		regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
		regs->fp_horiz_regs[FP_SYNC_START] =
						output_mode->hsync_start - 1;
		regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
		regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay +
			max((output_mode->hdisplay-600)/40 - 1, 1);

		regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
		regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
		regs->fp_vert_regs[FP_SYNC_START] =
						output_mode->vsync_start - 1;
		regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
		regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1;

		regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
			NV_PRAMDAC_FP_TG_CONTROL_READ_PROG |
			NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;

		if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
		if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
			regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;

		regs->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
			NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
			NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
			NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
			NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
			NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
			NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;

		regs->fp_debug_2 = 0;

		regs->fp_margin_color = 0x801080;

	}
}

static void nv17_tv_commit(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct drm_encoder_helper_funcs *helper = encoder->helper_private;

	if (get_tv_norm(encoder)->kind == TV_ENC_MODE) {
		nv17_tv_update_rescaler(encoder);
		nv17_tv_update_properties(encoder);
	} else {
		nv17_ctv_update_rescaler(encoder);
	}

	nv17_tv_state_load(dev, &to_tv_enc(encoder)->state);

	/* This could use refinement for flatpanels, but it should work */
	if (dev_priv->chipset < 0x44)
		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
					nv04_dac_output_offset(encoder),
					0xf0000000);
	else
		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
					nv04_dac_output_offset(encoder),
					0x00100000);

	helper->dpms(encoder, DRM_MODE_DPMS_ON);

	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
		drm_get_connector_name(
			&nouveau_encoder_connector_get(nv_encoder)->base),
		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}

static void nv17_tv_save(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);

	nouveau_encoder(encoder)->restore.output =
					NVReadRAMDAC(dev, 0,
					NV_PRAMDAC_DACCLK +
					nv04_dac_output_offset(encoder));

	nv17_tv_state_save(dev, &tv_enc->saved_state);

	tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200;
}

static void nv17_tv_restore(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;

	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
				nv04_dac_output_offset(encoder),
				nouveau_encoder(encoder)->restore.output);

	nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);

	nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED;
}

static int nv17_tv_create_resources(struct drm_encoder *encoder,
				    struct drm_connector *connector)
{
	struct drm_device *dev = encoder->dev;
	struct drm_mode_config *conf = &dev->mode_config;
	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
	int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
							NUM_LD_TV_NORMS;
	int i;

	if (nouveau_tv_norm) {
		for (i = 0; i < num_tv_norms; i++) {
			if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) {
				tv_enc->tv_norm = i;
				break;
			}
		}

		if (i == num_tv_norms)
			NV_WARN(dev, "Invalid TV norm setting \"%s\"\n",
				nouveau_tv_norm);
	}

	drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);

	drm_connector_attach_property(connector,
					conf->tv_select_subconnector_property,
					tv_enc->select_subconnector);
	drm_connector_attach_property(connector,
					conf->tv_subconnector_property,
					tv_enc->subconnector);
	drm_connector_attach_property(connector,
					conf->tv_mode_property,
					tv_enc->tv_norm);
	drm_connector_attach_property(connector,
					conf->tv_flicker_reduction_property,
					tv_enc->flicker);
	drm_connector_attach_property(connector,
					conf->tv_saturation_property,
					tv_enc->saturation);
	drm_connector_attach_property(connector,
					conf->tv_hue_property,
					tv_enc->hue);
	drm_connector_attach_property(connector,
					conf->tv_overscan_property,
					tv_enc->overscan);

	return 0;
}

static int nv17_tv_set_property(struct drm_encoder *encoder,
				struct drm_connector *connector,
				struct drm_property *property,
				uint64_t val)
{
	struct drm_mode_config *conf = &encoder->dev->mode_config;
	struct drm_crtc *crtc = encoder->crtc;
	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
	bool modes_changed = false;

	if (property == conf->tv_overscan_property) {
		tv_enc->overscan = val;
		if (encoder->crtc) {
			if (tv_norm->kind == CTV_ENC_MODE)
				nv17_ctv_update_rescaler(encoder);
			else
				nv17_tv_update_rescaler(encoder);
		}

	} else if (property == conf->tv_saturation_property) {
		if (tv_norm->kind != TV_ENC_MODE)
			return -EINVAL;

		tv_enc->saturation = val;
		nv17_tv_update_properties(encoder);

	} else if (property == conf->tv_hue_property) {
		if (tv_norm->kind != TV_ENC_MODE)
			return -EINVAL;

		tv_enc->hue = val;
		nv17_tv_update_properties(encoder);

	} else if (property == conf->tv_flicker_reduction_property) {
		if (tv_norm->kind != TV_ENC_MODE)
			return -EINVAL;

		tv_enc->flicker = val;
		if (encoder->crtc)
			nv17_tv_update_rescaler(encoder);

	} else if (property == conf->tv_mode_property) {
		if (connector->dpms != DRM_MODE_DPMS_OFF)
			return -EINVAL;

		tv_enc->tv_norm = val;

		modes_changed = true;

	} else if (property == conf->tv_select_subconnector_property) {
		if (tv_norm->kind != TV_ENC_MODE)
			return -EINVAL;

		tv_enc->select_subconnector = val;
		nv17_tv_update_properties(encoder);

	} else {
		return -EINVAL;
	}

	if (modes_changed) {
		drm_helper_probe_single_connector_modes(connector, 0, 0);

		/* Disable the crtc to ensure a full modeset is
		 * performed whenever it's turned on again. */
		if (crtc) {
			struct drm_mode_set modeset = {
				.crtc = crtc,
			};

			crtc->funcs->set_config(&modeset);
		}
	}

	return 0;
}

static void nv17_tv_destroy(struct drm_encoder *encoder)
{
	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);

	NV_DEBUG_KMS(encoder->dev, "\n");

	drm_encoder_cleanup(encoder);
	kfree(tv_enc);
}

static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = {
	.dpms = nv17_tv_dpms,
	.save = nv17_tv_save,
	.restore = nv17_tv_restore,
	.mode_fixup = nv17_tv_mode_fixup,
	.prepare = nv17_tv_prepare,
	.commit = nv17_tv_commit,
	.mode_set = nv17_tv_mode_set,
	.detect = nv17_tv_detect,
};

static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = {
	.get_modes = nv17_tv_get_modes,
	.mode_valid = nv17_tv_mode_valid,
	.create_resources = nv17_tv_create_resources,
	.set_property = nv17_tv_set_property,
};

static struct drm_encoder_funcs nv17_tv_funcs = {
	.destroy = nv17_tv_destroy,
};

int
nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
{
	struct drm_device *dev = connector->dev;
	struct drm_encoder *encoder;
	struct nv17_tv_encoder *tv_enc = NULL;

	tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL);
	if (!tv_enc)
		return -ENOMEM;

	tv_enc->overscan = 50;
	tv_enc->flicker = 50;
	tv_enc->saturation = 50;
	tv_enc->hue = 0;
	tv_enc->tv_norm = TV_NORM_PAL;
	tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
	tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic;
	tv_enc->pin_mask = 0;

	encoder = to_drm_encoder(&tv_enc->base);

	tv_enc->base.dcb = entry;
	tv_enc->base.or = ffs(entry->or) - 1;

	drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC);
	drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs);
	to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs;

	encoder->possible_crtcs = entry->heads;
	encoder->possible_clones = 0;

	nv17_tv_create_resources(encoder, connector);
	drm_mode_connector_attach_encoder(connector, encoder);
	return 0;
}
