/*
 * Copyright 2003 NVIDIA, Corporation
 * Copyright 2006 Dave Airlie
 * Copyright 2007 Maarten Maathuis
 * Copyright 2007-2009 Stuart Bennett
 *
 * 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.
 */

#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 "nvreg.h"

#define FP_TG_CONTROL_ON  (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |	\
			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS |		\
			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE |	\
			   NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE |	\
			   NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)

static inline bool is_fpc_off(uint32_t fpc)
{
	return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) ==
			FP_TG_CONTROL_OFF);
}

int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent)
{
	/* special case of nv_read_tmds to find crtc associated with an output.
	 * this does not give a correct answer for off-chip dvi, but there's no
	 * use for such an answer anyway
	 */
	int ramdac = (dcbent->or & OUTPUT_C) >> 2;

	NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
	NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
	return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac;
}

void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
			int head, bool dl)
{
	/* The BIOS scripts don't do this for us, sadly
	 * Luckily we do know the values ;-)
	 *
	 * head < 0 indicates we wish to force a setting with the overrideval
	 * (for VT restore etc.)
	 */

	int ramdac = (dcbent->or & OUTPUT_C) >> 2;
	uint8_t tmds04 = 0x80;

	if (head != ramdac)
		tmds04 = 0x88;

	if (dcbent->type == OUTPUT_LVDS)
		tmds04 |= 0x01;

	nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04);

	if (dl)	/* dual link */
		nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08);
}

void nv04_dfp_disable(struct drm_device *dev, int head)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;

	if (NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL) &
	    FP_TG_CONTROL_ON) {
		/* digital remnants must be cleaned before new crtc
		 * values programmed.  delay is time for the vga stuff
		 * to realise it's in control again
		 */
		NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL,
			      FP_TG_CONTROL_OFF);
		msleep(50);
	}
	/* don't inadvertently turn it on when state written later */
	crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
}

void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc;
	struct nouveau_crtc *nv_crtc;
	uint32_t *fpc;

	if (mode == DRM_MODE_DPMS_ON) {
		nv_crtc = nouveau_crtc(encoder->crtc);
		fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;

		if (is_fpc_off(*fpc)) {
			/* using saved value is ok, as (is_digital && dpms_on &&
			 * fp_control==OFF) is (at present) *only* true when
			 * fpc's most recent change was by below "off" code
			 */
			*fpc = nv_crtc->dpms_saved_fp_control;
		}

		nv_crtc->fp_users |= 1 << nouveau_encoder(encoder)->dcb->index;
		NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
	} else {
		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
			nv_crtc = nouveau_crtc(crtc);
			fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;

			nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index);
			if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
				nv_crtc->dpms_saved_fp_control = *fpc;
				/* cut the FP output */
				*fpc &= ~FP_TG_CONTROL_ON;
				*fpc |= FP_TG_CONTROL_OFF;
				NVWriteRAMDAC(dev, nv_crtc->index,
					      NV_PRAMDAC_FP_TG_CONTROL, *fpc);
			}
		}
	}
}

static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);

	/* For internal panels and gpu scaling on DVI we need the native mode */
	if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
		if (!nv_connector->native_mode)
			return false;
		nv_encoder->mode = *nv_connector->native_mode;
		adjusted_mode->clock = nv_connector->native_mode->clock;
	} else {
		nv_encoder->mode = *adjusted_mode;
	}

	return true;
}

static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
				     struct nouveau_encoder *nv_encoder, int head)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nv04_mode_state *state = &dev_priv->mode_reg;
	uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;

	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
		return;

	/* SEL_CLK is only used on the primary ramdac
	 * It toggles spread spectrum PLL output and sets the bindings of PLLs
	 * to heads on digital outputs
	 */
	if (head)
		state->sel_clk |= bits1618;
	else
		state->sel_clk &= ~bits1618;

	/* nv30:
	 *	bit 0		NVClk spread spectrum on/off
	 *	bit 2		MemClk spread spectrum on/off
	 * 	bit 4		PixClk1 spread spectrum on/off toggle
	 * 	bit 6		PixClk2 spread spectrum on/off toggle
	 *
	 * nv40 (observations from bios behaviour and mmio traces):
	 * 	bits 4&6	as for nv30
	 * 	bits 5&7	head dependent as for bits 4&6, but do not appear with 4&6;
	 * 			maybe a different spread mode
	 * 	bits 8&10	seen on dual-link dvi outputs, purpose unknown (set by POST scripts)
	 * 	The logic behind turning spread spectrum on/off in the first place,
	 * 	and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
	 * 	entry has the necessary info)
	 */
	if (nv_encoder->dcb->type == OUTPUT_LVDS && dev_priv->saved_reg.sel_clk & 0xf0) {
		int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1;

		state->sel_clk &= ~0xf0;
		state->sel_clk |= (head ? 0x40 : 0x10) << shift;
	}
}

static void nv04_dfp_prepare(struct drm_encoder *encoder)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
	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 *crtcstate = dev_priv->mode_reg.crtc_reg;
	uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
	uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];

	helper->dpms(encoder, DRM_MODE_DPMS_OFF);

	nv04_dfp_prepare_sel_clk(dev, nv_encoder, head);

	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
	 * at LCD__INDEX which we don't alter
	 */
	if (!(*cr_lcd & 0x44)) {
		*cr_lcd = 0x3;

		if (nv_two_heads(dev)) {
			if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP)
				*cr_lcd |= head ? 0x0 : 0x8;
			else {
				*cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
				if (nv_encoder->dcb->type == OUTPUT_LVDS)
					*cr_lcd |= 0x30;
				if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
					/* avoid being connected to both crtcs */
					*cr_lcd_oth &= ~0x30;
					NVWriteVgaCrtc(dev, head ^ 1,
						       NV_CIO_CRE_LCD__INDEX,
						       *cr_lcd_oth);
				}
			}
		}
	}
}


static void nv04_dfp_mode_set(struct drm_encoder *encoder,
			      struct drm_display_mode *mode,
			      struct drm_display_mode *adjusted_mode)
{
	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 nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
	struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
	struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc);
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct drm_display_mode *output_mode = &nv_encoder->mode;
	uint32_t mode_ratio, panel_ratio;

	NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
	drm_mode_debug_printmodeline(output_mode);

	/* Initialize the FP registers in this CRTC. */
	regp->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1;
	regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
	if (!nv_gf4_disp_arch(dev) ||
	    (output_mode->hsync_start - output_mode->hdisplay) >=
					dev_priv->vbios.digital_min_front_porch)
		regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
	else
		regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1;
	regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
	regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
	regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
	regp->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - 1;

	regp->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1;
	regp->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1;
	regp->fp_vert_regs[FP_CRTC] = output_mode->vtotal - 5 - 1;
	regp->fp_vert_regs[FP_SYNC_START] = output_mode->vsync_start - 1;
	regp->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1;
	regp->fp_vert_regs[FP_VALID_START] = 0;
	regp->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - 1;

	/* bit26: a bit seen on some g7x, no as yet discernable purpose */
	regp->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
			   (savep->fp_control & (1 << 26 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG));
	/* Deal with vsync/hsync polarity */
	/* LVDS screens do set this, but modes with +ve syncs are very rare */
	if (output_mode->flags & DRM_MODE_FLAG_PVSYNC)
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
	if (output_mode->flags & DRM_MODE_FLAG_PHSYNC)
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
	/* panel scaling first, as native would get set otherwise */
	if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
	    nv_connector->scaling_mode == DRM_MODE_SCALE_CENTER)	/* panel handles it */
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER;
	else if (adjusted_mode->hdisplay == output_mode->hdisplay &&
		 adjusted_mode->vdisplay == output_mode->vdisplay) /* native mode */
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE;
	else /* gpu needs to scale */
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE;
	if (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
		regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
	if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP &&
	    output_mode->clock > 165000)
		regp->fp_control |= (2 << 24);
	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
		bool duallink, dummy;

		nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode->
					      clock, &duallink, &dummy);
		if (duallink)
			regp->fp_control |= (8 << 28);
	} else
	if (output_mode->clock > 165000)
		regp->fp_control |= (8 << 28);

	regp->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;

	/* We want automatic scaling */
	regp->fp_debug_1 = 0;
	/* This can override HTOTAL and VTOTAL */
	regp->fp_debug_2 = 0;

	/* Use 20.12 fixed point format to avoid floats */
	mode_ratio = (1 << 12) * adjusted_mode->hdisplay / adjusted_mode->vdisplay;
	panel_ratio = (1 << 12) * output_mode->hdisplay / output_mode->vdisplay;
	/* if ratios are equal, SCALE_ASPECT will automatically (and correctly)
	 * get treated the same as SCALE_FULLSCREEN */
	if (nv_connector->scaling_mode == DRM_MODE_SCALE_ASPECT &&
	    mode_ratio != panel_ratio) {
		uint32_t diff, scale;
		bool divide_by_2 = nv_gf4_disp_arch(dev);

		if (mode_ratio < panel_ratio) {
			/* vertical needs to expand to glass size (automatic)
			 * horizontal needs to be scaled at vertical scale factor
			 * to maintain aspect */

			scale = (1 << 12) * adjusted_mode->vdisplay / output_mode->vdisplay;
			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);

			/* restrict area of screen used, horizontally */
			diff = output_mode->hdisplay -
			       output_mode->vdisplay * mode_ratio / (1 << 12);
			regp->fp_horiz_regs[FP_VALID_START] += diff / 2;
			regp->fp_horiz_regs[FP_VALID_END] -= diff / 2;
		}

		if (mode_ratio > panel_ratio) {
			/* horizontal needs to expand to glass size (automatic)
			 * vertical needs to be scaled at horizontal scale factor
			 * to maintain aspect */

			scale = (1 << 12) * adjusted_mode->hdisplay / output_mode->hdisplay;
			regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
					   XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE);

			/* restrict area of screen used, vertically */
			diff = output_mode->vdisplay -
			       (1 << 12) * output_mode->hdisplay / mode_ratio;
			regp->fp_vert_regs[FP_VALID_START] += diff / 2;
			regp->fp_vert_regs[FP_VALID_END] -= diff / 2;
		}
	}

	/* Output property. */
	if (nv_connector->use_dithering) {
		if (dev_priv->chipset == 0x11)
			regp->dither = savep->dither | 0x00010000;
		else {
			int i;
			regp->dither = savep->dither | 0x00000001;
			for (i = 0; i < 3; i++) {
				regp->dither_regs[i] = 0xe4e4e4e4;
				regp->dither_regs[i + 3] = 0x44444444;
			}
		}
	} else {
		if (dev_priv->chipset != 0x11) {
			/* reset them */
			int i;
			for (i = 0; i < 3; i++) {
				regp->dither_regs[i] = savep->dither_regs[i];
				regp->dither_regs[i + 3] = savep->dither_regs[i + 3];
			}
		}
		regp->dither = savep->dither;
	}

	regp->fp_margin_color = 0;
}

static void nv04_dfp_commit(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 nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct dcb_entry *dcbe = nv_encoder->dcb;
	int head = nouveau_crtc(encoder->crtc)->index;

	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));

	if (dcbe->type == OUTPUT_TMDS)
		run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
	else if (dcbe->type == OUTPUT_LVDS)
		call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock);

	/* update fp_control state for any changes made by scripts,
	 * so correct value is written at DPMS on */
	dev_priv->mode_reg.crtc_reg[head].fp_control =
		NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);

	/* This could use refinement for flatpanels, but it should work this way */
	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 inline bool is_powersaving_dpms(int mode)
{
	return (mode != DRM_MODE_DPMS_ON);
}

static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_crtc *crtc = encoder->crtc;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);

	if (nv_encoder->last_dpms == mode)
		return;
	nv_encoder->last_dpms = mode;

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

	if (was_powersaving && is_powersaving_dpms(mode))
		return;

	if (nv_encoder->dcb->lvdsconf.use_power_scripts) {
		struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);

		/* when removing an output, crtc may not be set, but PANEL_OFF
		 * must still be run
		 */
		int head = crtc ? nouveau_crtc(crtc)->index :
			   nv04_dfp_get_bound_head(dev, nv_encoder->dcb);

		if (mode == DRM_MODE_DPMS_ON) {
			if (!nv_connector->native_mode) {
				NV_ERROR(dev, "Not turning on LVDS without native mode\n");
				return;
			}
			call_lvds_script(dev, nv_encoder->dcb, head,
					 LVDS_PANEL_ON, nv_connector->native_mode->clock);
		} else
			/* pxclk of 0 is fine for PANEL_OFF, and for a
			 * disconnected LVDS encoder there is no native_mode
			 */
			call_lvds_script(dev, nv_encoder->dcb, head,
					 LVDS_PANEL_OFF, 0);
	}

	nv04_dfp_update_fp_control(encoder, mode);

	if (mode == DRM_MODE_DPMS_ON)
		nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index);
	else {
		dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
		dev_priv->mode_reg.sel_clk &= ~0xf0;
	}
	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
}

static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

	if (nv_encoder->last_dpms == mode)
		return;
	nv_encoder->last_dpms = mode;

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

	nv04_dfp_update_fp_control(encoder, mode);
}

static void nv04_dfp_save(struct drm_encoder *encoder)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct drm_device *dev = encoder->dev;

	if (nv_two_heads(dev))
		nv_encoder->restore.head =
			nv04_dfp_get_bound_head(dev, nv_encoder->dcb);
}

static void nv04_dfp_restore(struct drm_encoder *encoder)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	int head = nv_encoder->restore.head;

	if (nv_encoder->dcb->type == OUTPUT_LVDS) {
		struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode;
		if (native_mode)
			call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
					 native_mode->clock);
		else
			NV_ERROR(dev, "Not restoring LVDS without native mode\n");

	} else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
		int clock = nouveau_hw_pllvals_to_clk
					(&dev_priv->saved_reg.crtc_reg[head].pllvals);

		run_tmds_table(dev, nv_encoder->dcb, head, clock);
	}

	nv_encoder->last_dpms = NV_DPMS_CLEARED;
}

static void nv04_dfp_destroy(struct drm_encoder *encoder)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

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

	drm_encoder_cleanup(encoder);
	kfree(nv_encoder);
}

static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
	.dpms = nv04_lvds_dpms,
	.save = nv04_dfp_save,
	.restore = nv04_dfp_restore,
	.mode_fixup = nv04_dfp_mode_fixup,
	.prepare = nv04_dfp_prepare,
	.commit = nv04_dfp_commit,
	.mode_set = nv04_dfp_mode_set,
	.detect = NULL,
};

static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = {
	.dpms = nv04_tmds_dpms,
	.save = nv04_dfp_save,
	.restore = nv04_dfp_restore,
	.mode_fixup = nv04_dfp_mode_fixup,
	.prepare = nv04_dfp_prepare,
	.commit = nv04_dfp_commit,
	.mode_set = nv04_dfp_mode_set,
	.detect = NULL,
};

static const struct drm_encoder_funcs nv04_dfp_funcs = {
	.destroy = nv04_dfp_destroy,
};

int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
{
	const struct drm_encoder_helper_funcs *helper;
	struct drm_encoder *encoder;
	struct nouveau_encoder *nv_encoder = NULL;
	int type;

	switch (entry->type) {
	case OUTPUT_TMDS:
		type = DRM_MODE_ENCODER_TMDS;
		helper = &nv04_tmds_helper_funcs;
		break;
	case OUTPUT_LVDS:
		type = DRM_MODE_ENCODER_LVDS;
		helper = &nv04_lvds_helper_funcs;
		break;
	default:
		return -EINVAL;
	}

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

	encoder = to_drm_encoder(nv_encoder);

	nv_encoder->dcb = entry;
	nv_encoder->or = ffs(entry->or) - 1;

	drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
	drm_encoder_helper_add(encoder, helper);

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

	return 0;
}
