// SPDX-License-Identifier: MIT
/*
 * Copyright © 2024 Intel Corporation
 */

#include <drm/drm_print.h>

#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_core.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_lvds_regs.h"
#include "intel_pfit.h"
#include "intel_pfit_regs.h"

static int intel_pch_pfit_check_dst_window(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->hw.adjusted_mode;
	const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
	int width = drm_rect_width(dst);
	int height = drm_rect_height(dst);
	int x = dst->x1;
	int y = dst->y1;

	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE &&
	    (y & 1 || height & 1)) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") misaligned for interlaced output\n",
			    crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
		return -EINVAL;
	}

	/*
	 * "Restriction : When pipe scaling is enabled, the scaled
	 *  output must equal the pipe active area, so Pipe active
	 *  size = (2 * PF window position) + PF window size."
	 *
	 * The vertical direction seems more forgiving than the
	 * horizontal direction, but still has some issues so
	 * let's follow the same hard rule for both.
	 */
	if (adjusted_mode->crtc_hdisplay != 2 * x + width ||
	    adjusted_mode->crtc_vdisplay != 2 * y + height) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") not centered\n",
			    crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
		return -EINVAL;
	}

	/*
	 * "Restriction : The X position must not be programmed
	 *  to be 1 (28:16=0 0000 0000 0001b)."
	 */
	if (x == 1) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") badly positioned\n",
			    crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
		return -EINVAL;
	}

	return 0;
}

static int intel_pch_pfit_check_src_size(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
	int max_src_w, max_src_h;

	if (DISPLAY_VER(display) >= 8) {
		max_src_w = 4096;
		max_src_h = 4096;
	} else if (DISPLAY_VER(display) >= 7) {
		/*
		 * PF0 7x5 capable
		 * PF1 3x3 capable (could be switched to 7x5
		 *                  mode on HSW when PF2 unused)
		 * PF2 3x3 capable
		 *
		 * This assumes we use a 1:1 mapping between pipe and PF.
		 */
		max_src_w = crtc->pipe == PIPE_A ? 4096 : 2048;
		max_src_h = 4096;
	} else {
		max_src_w = 4096;
		max_src_h = 4096;
	}

	if (pipe_src_w > max_src_w || pipe_src_h > max_src_h) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] source size (%dx%d) exceeds pfit max (%dx%d)\n",
			    crtc->base.base.id, crtc->base.name,
			    pipe_src_w, pipe_src_h, max_src_w, max_src_h);
		return -EINVAL;
	}

	return 0;
}

static int intel_pch_pfit_check_scaling(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
	int hscale, vscale, max_scale = 0x12000; /* 1.125 */
	struct drm_rect src;

	drm_rect_init(&src, 0, 0, pipe_src_w << 16, pipe_src_h << 16);

	hscale = drm_rect_calc_hscale(&src, dst, 0, max_scale);
	if (hscale < 0) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) exceeds max (0x%x)\n",
			    crtc->base.base.id, crtc->base.name,
			    pipe_src_w, drm_rect_width(dst),
			    max_scale);
		return hscale;
	}

	vscale = drm_rect_calc_vscale(&src, dst, 0, max_scale);
	if (vscale < 0) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit vertical downscaling (%d->%d) exceeds max (0x%x)\n",
			    crtc->base.base.id, crtc->base.name,
			    pipe_src_h, drm_rect_height(dst),
			    max_scale);
		return vscale;
	}

	return 0;
}

static int intel_pch_pfit_check_timings(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->hw.adjusted_mode;

	if (adjusted_mode->crtc_vdisplay < 7) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] vertical active (%d) below minimum (%d) for pfit\n",
			    crtc->base.base.id, crtc->base.name,
			    adjusted_mode->crtc_vdisplay, 7);
		return -EINVAL;
	}

	return 0;
}

static int intel_pch_pfit_check_cloning(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);

	/*
	 * The panel fitter is in the pipe and thus would affect every
	 * cloned output. The relevant properties (scaling mode, TV
	 * margins) are per-connector so we'd have to make sure each
	 * output sets them up identically. Seems like a very niche use
	 * case so let's just reject cloning entirely when pfit is used.
	 */
	if (crtc_state->uapi.encoder_mask &&
	    !is_power_of_2(crtc_state->uapi.encoder_mask)) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] no pfit when cloning\n",
			    crtc->base.base.id, crtc->base.name);
		return -EINVAL;
	}

	return 0;
}

/* adjusted_mode has been preset to be the panel's fixed mode */
static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
			     const struct drm_connector_state *conn_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->hw.adjusted_mode;
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
	int ret, x, y, width, height;

	/* Native modes don't need fitting */
	if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
	    adjusted_mode->crtc_vdisplay == pipe_src_h &&
	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
		return 0;

	switch (conn_state->scaling_mode) {
	case DRM_MODE_SCALE_CENTER:
		width = pipe_src_w;
		height = pipe_src_h;
		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
		break;

	case DRM_MODE_SCALE_ASPECT:
		/* Scale but preserve the aspect ratio */
		{
			u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
			u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;

			if (scaled_width > scaled_height) { /* pillar */
				width = scaled_height / pipe_src_h;
				if (width & 1)
					width++;
				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
				y = 0;
				height = adjusted_mode->crtc_vdisplay;
			} else if (scaled_width < scaled_height) { /* letter */
				height = scaled_width / pipe_src_w;
				if (height & 1)
					height++;
				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
				x = 0;
				width = adjusted_mode->crtc_hdisplay;
			} else {
				x = y = 0;
				width = adjusted_mode->crtc_hdisplay;
				height = adjusted_mode->crtc_vdisplay;
			}
		}
		break;

	case DRM_MODE_SCALE_NONE:
		WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
		WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
		fallthrough;
	case DRM_MODE_SCALE_FULLSCREEN:
		x = y = 0;
		width = adjusted_mode->crtc_hdisplay;
		height = adjusted_mode->crtc_vdisplay;
		break;

	default:
		MISSING_CASE(conn_state->scaling_mode);
		return -EINVAL;
	}

	drm_rect_init(&crtc_state->pch_pfit.dst,
		      x, y, width, height);
	crtc_state->pch_pfit.enabled = true;

	/*
	 * SKL+ have unified scalers for pipes/planes so the
	 * checks are done in a single place for all scalers.
	 */
	if (DISPLAY_VER(display) >= 9)
		return 0;

	ret = intel_pch_pfit_check_dst_window(crtc_state);
	if (ret)
		return ret;

	ret = intel_pch_pfit_check_src_size(crtc_state);
	if (ret)
		return ret;

	ret = intel_pch_pfit_check_scaling(crtc_state);
	if (ret)
		return ret;

	ret = intel_pch_pfit_check_timings(crtc_state);
	if (ret)
		return ret;

	ret = intel_pch_pfit_check_cloning(crtc_state);
	if (ret)
		return ret;

	return 0;
}

static void
centre_horizontally(struct drm_display_mode *adjusted_mode,
		    int width)
{
	u32 border, sync_pos, blank_width, sync_width;

	/* keep the hsync and hblank widths constant */
	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
	sync_pos = (blank_width - sync_width + 1) / 2;

	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
	border += border & 1; /* make the border even */

	adjusted_mode->crtc_hdisplay = width;
	adjusted_mode->crtc_hblank_start = width + border;
	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;

	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
}

static void
centre_vertically(struct drm_display_mode *adjusted_mode,
		  int height)
{
	u32 border, sync_pos, blank_width, sync_width;

	/* keep the vsync and vblank widths constant */
	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
	sync_pos = (blank_width - sync_width + 1) / 2;

	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;

	adjusted_mode->crtc_vdisplay = height;
	adjusted_mode->crtc_vblank_start = height + border;
	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;

	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
}

static u32 panel_fitter_scaling(u32 source, u32 target)
{
	/*
	 * Floating point operation is not supported. So the FACTOR
	 * is defined, which can avoid the floating point computation
	 * when calculating the panel ratio.
	 */
#define ACCURACY 12
#define FACTOR (1 << ACCURACY)
	u32 ratio = source * FACTOR / target;
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
}

static void i965_scale_aspect(struct intel_crtc_state *crtc_state,
			      u32 *pfit_control)
{
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->hw.adjusted_mode;
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
	u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
	u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;

	/* 965+ is easy, it does everything in hw */
	if (scaled_width > scaled_height)
		*pfit_control |= PFIT_ENABLE |
			PFIT_SCALING_PILLAR;
	else if (scaled_width < scaled_height)
		*pfit_control |= PFIT_ENABLE |
			PFIT_SCALING_LETTER;
	else if (adjusted_mode->crtc_hdisplay != pipe_src_w)
		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
}

static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state,
			      u32 *pfit_control, u32 *pfit_pgm_ratios,
			      u32 *border)
{
	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
	u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
	u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
	u32 bits;

	/*
	 * For earlier chips we have to calculate the scaling
	 * ratio by hand and program it into the
	 * PFIT_PGM_RATIO register
	 */
	if (scaled_width > scaled_height) { /* pillar */
		centre_horizontally(adjusted_mode,
				    scaled_height / pipe_src_h);

		*border = LVDS_BORDER_ENABLE;
		if (pipe_src_h != adjusted_mode->crtc_vdisplay) {
			bits = panel_fitter_scaling(pipe_src_h,
						    adjusted_mode->crtc_vdisplay);

			*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
					     PFIT_VERT_SCALE(bits));
			*pfit_control |= (PFIT_ENABLE |
					  PFIT_VERT_INTERP_BILINEAR |
					  PFIT_HORIZ_INTERP_BILINEAR);
		}
	} else if (scaled_width < scaled_height) { /* letter */
		centre_vertically(adjusted_mode,
				  scaled_width / pipe_src_w);

		*border = LVDS_BORDER_ENABLE;
		if (pipe_src_w != adjusted_mode->crtc_hdisplay) {
			bits = panel_fitter_scaling(pipe_src_w,
						    adjusted_mode->crtc_hdisplay);

			*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
					     PFIT_VERT_SCALE(bits));
			*pfit_control |= (PFIT_ENABLE |
					  PFIT_VERT_INTERP_BILINEAR |
					  PFIT_HORIZ_INTERP_BILINEAR);
		}
	} else {
		/* Aspects match, Let hw scale both directions */
		*pfit_control |= (PFIT_ENABLE |
				  PFIT_VERT_AUTO_SCALE |
				  PFIT_HORIZ_AUTO_SCALE |
				  PFIT_VERT_INTERP_BILINEAR |
				  PFIT_HORIZ_INTERP_BILINEAR);
	}
}

static int intel_gmch_pfit_check_timings(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->hw.adjusted_mode;
	int min;

	if (DISPLAY_VER(display) >= 4)
		min = 3;
	else
		min = 2;

	if (adjusted_mode->crtc_hdisplay < min) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] horizontal active (%d) below minimum (%d) for pfit\n",
			    crtc->base.base.id, crtc->base.name,
			    adjusted_mode->crtc_hdisplay, min);
		return -EINVAL;
	}

	if (adjusted_mode->crtc_vdisplay < min) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] vertical active (%d) below minimum (%d) for pfit\n",
			    crtc->base.base.id, crtc->base.name,
			    adjusted_mode->crtc_vdisplay, min);
		return -EINVAL;
	}

	return 0;
}

static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
			      const struct drm_connector_state *conn_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);

	/* Native modes don't need fitting */
	if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
	    adjusted_mode->crtc_vdisplay == pipe_src_h)
		goto out;

	/*
	 * TODO: implement downscaling for i965+. Need to account
	 * for downscaling in intel_crtc_compute_pixel_rate().
	 */
	if (adjusted_mode->crtc_hdisplay < pipe_src_w) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) not supported\n",
			    crtc->base.base.id, crtc->base.name,
			    pipe_src_w, adjusted_mode->crtc_hdisplay);
		return -EINVAL;
	}
	if (adjusted_mode->crtc_vdisplay < pipe_src_h) {
		drm_dbg_kms(display->drm,
			    "[CRTC:%d:%s] pfit vertical downscaling (%d->%d) not supported\n",
			    crtc->base.base.id, crtc->base.name,
			    pipe_src_h, adjusted_mode->crtc_vdisplay);
		return -EINVAL;
	}

	switch (conn_state->scaling_mode) {
	case DRM_MODE_SCALE_CENTER:
		/*
		 * For centered modes, we have to calculate border widths &
		 * heights and modify the values programmed into the CRTC.
		 */
		centre_horizontally(adjusted_mode, pipe_src_w);
		centre_vertically(adjusted_mode, pipe_src_h);
		border = LVDS_BORDER_ENABLE;
		break;
	case DRM_MODE_SCALE_ASPECT:
		/* Scale but preserve the aspect ratio */
		if (DISPLAY_VER(display) >= 4)
			i965_scale_aspect(crtc_state, &pfit_control);
		else
			i9xx_scale_aspect(crtc_state, &pfit_control,
					  &pfit_pgm_ratios, &border);
		break;
	case DRM_MODE_SCALE_FULLSCREEN:
		/*
		 * Full scaling, even if it changes the aspect ratio.
		 * Fortunately this is all done for us in hw.
		 */
		if (pipe_src_h != adjusted_mode->crtc_vdisplay ||
		    pipe_src_w != adjusted_mode->crtc_hdisplay) {
			pfit_control |= PFIT_ENABLE;
			if (DISPLAY_VER(display) >= 4)
				pfit_control |= PFIT_SCALING_AUTO;
			else
				pfit_control |= (PFIT_VERT_AUTO_SCALE |
						 PFIT_VERT_INTERP_BILINEAR |
						 PFIT_HORIZ_AUTO_SCALE |
						 PFIT_HORIZ_INTERP_BILINEAR);
		}
		break;
	default:
		MISSING_CASE(conn_state->scaling_mode);
		return -EINVAL;
	}

	/* 965+ wants fuzzy fitting */
	/* FIXME: handle multiple panels by failing gracefully */
	if (DISPLAY_VER(display) >= 4)
		pfit_control |= PFIT_PIPE(crtc->pipe) | PFIT_FILTER_FUZZY;

out:
	if ((pfit_control & PFIT_ENABLE) == 0) {
		pfit_control = 0;
		pfit_pgm_ratios = 0;
	}

	/* Make sure pre-965 set dither correctly for 18bpp panels. */
	if (DISPLAY_VER(display) < 4 && crtc_state->pipe_bpp == 18)
		pfit_control |= PFIT_PANEL_8TO6_DITHER_ENABLE;

	crtc_state->gmch_pfit.control = pfit_control;
	crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
	crtc_state->gmch_pfit.lvds_border_bits = border;

	if ((pfit_control & PFIT_ENABLE) == 0)
		return 0;

	return intel_gmch_pfit_check_timings(crtc_state);
}

int intel_pfit_compute_config(struct intel_crtc_state *crtc_state,
			      const struct drm_connector_state *conn_state)
{
	struct intel_display *display = to_intel_display(crtc_state);

	if (HAS_GMCH(display))
		return gmch_panel_fitting(crtc_state, conn_state);
	else
		return pch_panel_fitting(crtc_state, conn_state);
}

void ilk_pfit_enable(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
	enum pipe pipe = crtc->pipe;
	int width = drm_rect_width(dst);
	int height = drm_rect_height(dst);
	int x = dst->x1;
	int y = dst->y1;

	if (!crtc_state->pch_pfit.enabled)
		return;

	/*
	 * Force use of hard-coded filter coefficients as some pre-programmed
	 * values are broken, e.g. x201.
	 */
	if (display->platform.ivybridge || display->platform.haswell)
		intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE |
				  PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe));
	else
		intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE |
				  PF_FILTER_MED_3x3);
	intel_de_write_fw(display, PF_WIN_POS(pipe),
			  PF_WIN_XPOS(x) | PF_WIN_YPOS(y));
	intel_de_write_fw(display, PF_WIN_SZ(pipe),
			  PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height));
}

void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state)
{
	struct intel_display *display = to_intel_display(old_crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
	enum pipe pipe = crtc->pipe;

	/*
	 * To avoid upsetting the power well on haswell only disable the pfit if
	 * it's in use. The hw state code will make sure we get this right.
	 */
	if (!old_crtc_state->pch_pfit.enabled)
		return;

	intel_de_write_fw(display, PF_CTL(pipe), 0);
	intel_de_write_fw(display, PF_WIN_POS(pipe), 0);
	intel_de_write_fw(display, PF_WIN_SZ(pipe), 0);
}

void ilk_pfit_get_config(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	u32 ctl, pos, size;
	enum pipe pipe;

	ctl = intel_de_read(display, PF_CTL(crtc->pipe));
	if ((ctl & PF_ENABLE) == 0)
		return;

	if (display->platform.ivybridge || display->platform.haswell)
		pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl);
	else
		pipe = crtc->pipe;

	crtc_state->pch_pfit.enabled = true;

	pos = intel_de_read(display, PF_WIN_POS(crtc->pipe));
	size = intel_de_read(display, PF_WIN_SZ(crtc->pipe));

	drm_rect_init(&crtc_state->pch_pfit.dst,
		      REG_FIELD_GET(PF_WIN_XPOS_MASK, pos),
		      REG_FIELD_GET(PF_WIN_YPOS_MASK, pos),
		      REG_FIELD_GET(PF_WIN_XSIZE_MASK, size),
		      REG_FIELD_GET(PF_WIN_YSIZE_MASK, size));

	/*
	 * We currently do not free assignments of panel fitters on
	 * ivb/hsw (since we don't use the higher upscaling modes which
	 * differentiates them) so just WARN about this case for now.
	 */
	drm_WARN_ON(display->drm, pipe != crtc->pipe);
}

void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);

	if (!crtc_state->gmch_pfit.control)
		return;

	/*
	 * The panel fitter should only be adjusted whilst the pipe is disabled,
	 * according to register description and PRM.
	 */
	drm_WARN_ON(display->drm,
		    intel_de_read(display, PFIT_CONTROL(display)) & PFIT_ENABLE);
	assert_transcoder_disabled(display, crtc_state->cpu_transcoder);

	intel_de_write(display, PFIT_PGM_RATIOS(display),
		       crtc_state->gmch_pfit.pgm_ratios);
	intel_de_write(display, PFIT_CONTROL(display),
		       crtc_state->gmch_pfit.control);

	/*
	 * Border color in case we don't scale up to the full screen. Black by
	 * default, change to something else for debugging.
	 */
	intel_de_write(display, BCLRPAT(display, crtc->pipe), 0);
}

void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
{
	struct intel_display *display = to_intel_display(old_crtc_state);

	if (!old_crtc_state->gmch_pfit.control)
		return;

	assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder);

	drm_dbg_kms(display->drm, "disabling pfit, current: 0x%08x\n",
		    intel_de_read(display, PFIT_CONTROL(display)));
	intel_de_write(display, PFIT_CONTROL(display), 0);
}

static bool i9xx_has_pfit(struct intel_display *display)
{
	if (display->platform.i830)
		return false;

	return DISPLAY_VER(display) >= 4 ||
		display->platform.pineview || display->platform.mobile;
}

void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	enum pipe pipe;
	u32 tmp;

	if (!i9xx_has_pfit(display))
		return;

	tmp = intel_de_read(display, PFIT_CONTROL(display));
	if (!(tmp & PFIT_ENABLE))
		return;

	/* Check whether the pfit is attached to our pipe. */
	if (DISPLAY_VER(display) >= 4)
		pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp);
	else
		pipe = PIPE_B;

	if (pipe != crtc->pipe)
		return;

	crtc_state->gmch_pfit.control = tmp;
	crtc_state->gmch_pfit.pgm_ratios =
		intel_de_read(display, PFIT_PGM_RATIOS(display));
}
