/*
 * 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(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_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index);

	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(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;
}
