/*
 * Copyright © 2009 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/i2c.h>
#include <linux/pm_runtime.h>

#include <drm/drmP.h>
#include "framebuffer.h"
#include "psb_drv.h"
#include "psb_intel_drv.h"
#include "psb_intel_reg.h"
#include "gma_display.h"
#include "power.h"

#define MRST_LIMIT_LVDS_100L	0
#define MRST_LIMIT_LVDS_83	1
#define MRST_LIMIT_LVDS_100	2
#define MRST_LIMIT_SDVO		3

#define MRST_DOT_MIN		  19750
#define MRST_DOT_MAX		  120000
#define MRST_M_MIN_100L		    20
#define MRST_M_MIN_100		    10
#define MRST_M_MIN_83		    12
#define MRST_M_MAX_100L		    34
#define MRST_M_MAX_100		    17
#define MRST_M_MAX_83		    20
#define MRST_P1_MIN		    2
#define MRST_P1_MAX_0		    7
#define MRST_P1_MAX_1		    8

static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
				    struct drm_crtc *crtc, int target,
				    int refclk, struct gma_clock_t *best_clock);

static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
				    struct drm_crtc *crtc, int target,
				    int refclk, struct gma_clock_t *best_clock);

static const struct gma_limit_t mrst_limits[] = {
	{			/* MRST_LIMIT_LVDS_100L */
	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
	 .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
	 .find_pll = mrst_lvds_find_best_pll,
	 },
	{			/* MRST_LIMIT_LVDS_83L */
	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
	 .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
	 .find_pll = mrst_lvds_find_best_pll,
	 },
	{			/* MRST_LIMIT_LVDS_100 */
	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
	 .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
	 .find_pll = mrst_lvds_find_best_pll,
	 },
	{			/* MRST_LIMIT_SDVO */
	 .vco = {.min = 1400000, .max = 2800000},
	 .n = {.min = 3, .max = 7},
	 .m = {.min = 80, .max = 137},
	 .p1 = {.min = 1, .max = 2},
	 .p2 = {.dot_limit = 200000, .p2_slow = 10, .p2_fast = 10},
	 .find_pll = mrst_sdvo_find_best_pll,
	 },
};

#define MRST_M_MIN	    10
static const u32 oaktrail_m_converts[] = {
	0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
	0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
	0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
};

static const struct gma_limit_t *mrst_limit(struct drm_crtc *crtc,
					    int refclk)
{
	const struct gma_limit_t *limit = NULL;
	struct drm_device *dev = crtc->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	if (gma_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
	    || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
		switch (dev_priv->core_freq) {
		case 100:
			limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
			break;
		case 166:
			limit = &mrst_limits[MRST_LIMIT_LVDS_83];
			break;
		case 200:
			limit = &mrst_limits[MRST_LIMIT_LVDS_100];
			break;
		}
	} else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
		limit = &mrst_limits[MRST_LIMIT_SDVO];
	} else {
		limit = NULL;
		dev_err(dev->dev, "mrst_limit Wrong display type.\n");
	}

	return limit;
}

/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
static void mrst_lvds_clock(int refclk, struct gma_clock_t *clock)
{
	clock->dot = (refclk * clock->m) / (14 * clock->p1);
}

static void mrst_print_pll(struct gma_clock_t *clock)
{
	DRM_DEBUG_DRIVER("dotclock=%d,  m=%d, m1=%d, m2=%d, n=%d, p1=%d, p2=%d\n",
			 clock->dot, clock->m, clock->m1, clock->m2, clock->n,
			 clock->p1, clock->p2);
}

static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
				    struct drm_crtc *crtc, int target,
				    int refclk, struct gma_clock_t *best_clock)
{
	struct gma_clock_t clock;
	u32 target_vco, actual_freq;
	s32 freq_error, min_error = 100000;

	memset(best_clock, 0, sizeof(*best_clock));

	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
		for (clock.n = limit->n.min; clock.n <= limit->n.max;
		     clock.n++) {
			for (clock.p1 = limit->p1.min;
			     clock.p1 <= limit->p1.max; clock.p1++) {
				/* p2 value always stored in p2_slow on SDVO */
				clock.p = clock.p1 * limit->p2.p2_slow;
				target_vco = target * clock.p;

				/* VCO will increase at this point so break */
				if (target_vco > limit->vco.max)
					break;

				if (target_vco < limit->vco.min)
					continue;

				actual_freq = (refclk * clock.m) /
					      (clock.n * clock.p);
				freq_error = 10000 -
					     ((target * 10000) / actual_freq);

				if (freq_error < -min_error) {
					/* freq_error will start to decrease at
					   this point so break */
					break;
				}

				if (freq_error < 0)
					freq_error = -freq_error;

				if (freq_error < min_error) {
					min_error = freq_error;
					*best_clock = clock;
				}
			}
		}
		if (min_error == 0)
			break;
	}

	return min_error == 0;
}

/**
 * Returns a set of divisors for the desired target clock with the given refclk,
 * or FALSE.  Divisor values are the actual divisors for
 */
static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
				    struct drm_crtc *crtc, int target,
				    int refclk, struct gma_clock_t *best_clock)
{
	struct gma_clock_t clock;
	int err = target;

	memset(best_clock, 0, sizeof(*best_clock));

	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
		for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
		     clock.p1++) {
			int this_err;

			mrst_lvds_clock(refclk, &clock);

			this_err = abs(clock.dot - target);
			if (this_err < err) {
				*best_clock = clock;
				err = this_err;
			}
		}
	}
	return err != target;
}

/**
 * Sets the power management mode of the pipe and plane.
 *
 * This code should probably grow support for turning the cursor off and back
 * on appropriately at the same time as we're turning the pipe off/on.
 */
static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct drm_device *dev = crtc->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
	int pipe = gma_crtc->pipe;
	const struct psb_offset *map = &dev_priv->regmap[pipe];
	u32 temp;
	int i;
	int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;

	if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
		oaktrail_crtc_hdmi_dpms(crtc, mode);
		return;
	}

	if (!gma_power_begin(dev, true))
		return;

	/* XXX: When our outputs are all unaware of DPMS modes other than off
	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
	 */
	switch (mode) {
	case DRM_MODE_DPMS_ON:
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
		for (i = 0; i <= need_aux; i++) {
			/* Enable the DPLL */
			temp = REG_READ_WITH_AUX(map->dpll, i);
			if ((temp & DPLL_VCO_ENABLE) == 0) {
				REG_WRITE_WITH_AUX(map->dpll, temp, i);
				REG_READ_WITH_AUX(map->dpll, i);
				/* Wait for the clocks to stabilize. */
				udelay(150);
				REG_WRITE_WITH_AUX(map->dpll,
						   temp | DPLL_VCO_ENABLE, i);
				REG_READ_WITH_AUX(map->dpll, i);
				/* Wait for the clocks to stabilize. */
				udelay(150);
				REG_WRITE_WITH_AUX(map->dpll,
						   temp | DPLL_VCO_ENABLE, i);
				REG_READ_WITH_AUX(map->dpll, i);
				/* Wait for the clocks to stabilize. */
				udelay(150);
			}

			/* Enable the pipe */
			temp = REG_READ_WITH_AUX(map->conf, i);
			if ((temp & PIPEACONF_ENABLE) == 0) {
				REG_WRITE_WITH_AUX(map->conf,
						   temp | PIPEACONF_ENABLE, i);
			}

			/* Enable the plane */
			temp = REG_READ_WITH_AUX(map->cntr, i);
			if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
				REG_WRITE_WITH_AUX(map->cntr,
						   temp | DISPLAY_PLANE_ENABLE,
						   i);
				/* Flush the plane changes */
				REG_WRITE_WITH_AUX(map->base,
					REG_READ_WITH_AUX(map->base, i), i);
			}

		}
		gma_crtc_load_lut(crtc);

		/* Give the overlay scaler a chance to enable
		   if it's on this pipe */
		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
		break;
	case DRM_MODE_DPMS_OFF:
		/* Give the overlay scaler a chance to disable
		 * if it's on this pipe */
		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */

		for (i = 0; i <= need_aux; i++) {
			/* Disable the VGA plane that we never use */
			REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
			/* Disable display plane */
			temp = REG_READ_WITH_AUX(map->cntr, i);
			if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
				REG_WRITE_WITH_AUX(map->cntr,
					temp & ~DISPLAY_PLANE_ENABLE, i);
				/* Flush the plane changes */
				REG_WRITE_WITH_AUX(map->base,
						   REG_READ(map->base), i);
				REG_READ_WITH_AUX(map->base, i);
			}

			/* Next, disable display pipes */
			temp = REG_READ_WITH_AUX(map->conf, i);
			if ((temp & PIPEACONF_ENABLE) != 0) {
				REG_WRITE_WITH_AUX(map->conf,
						   temp & ~PIPEACONF_ENABLE, i);
				REG_READ_WITH_AUX(map->conf, i);
			}
			/* Wait for for the pipe disable to take effect. */
			gma_wait_for_vblank(dev);

			temp = REG_READ_WITH_AUX(map->dpll, i);
			if ((temp & DPLL_VCO_ENABLE) != 0) {
				REG_WRITE_WITH_AUX(map->dpll,
						   temp & ~DPLL_VCO_ENABLE, i);
				REG_READ_WITH_AUX(map->dpll, i);
			}

			/* Wait for the clocks to turn off. */
			udelay(150);
		}
		break;
	}

	/* Set FIFO Watermarks (values taken from EMGD) */
	REG_WRITE(DSPARB, 0x3f80);
	REG_WRITE(DSPFW1, 0x3f8f0404);
	REG_WRITE(DSPFW2, 0x04040f04);
	REG_WRITE(DSPFW3, 0x0);
	REG_WRITE(DSPFW4, 0x04040404);
	REG_WRITE(DSPFW5, 0x04040404);
	REG_WRITE(DSPFW6, 0x78);
	REG_WRITE(DSPCHICKENBIT, REG_READ(DSPCHICKENBIT) | 0xc040);

	gma_power_end(dev);
}

/**
 * Return the pipe currently connected to the panel fitter,
 * or -1 if the panel fitter is not present or not in use
 */
static int oaktrail_panel_fitter_pipe(struct drm_device *dev)
{
	u32 pfit_control;

	pfit_control = REG_READ(PFIT_CONTROL);

	/* See if the panel fitter is in use */
	if ((pfit_control & PFIT_ENABLE) == 0)
		return -1;
	return (pfit_control >> 29) & 3;
}

static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
			      struct drm_display_mode *mode,
			      struct drm_display_mode *adjusted_mode,
			      int x, int y,
			      struct drm_framebuffer *old_fb)
{
	struct drm_device *dev = crtc->dev;
	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
	struct drm_psb_private *dev_priv = dev->dev_private;
	int pipe = gma_crtc->pipe;
	const struct psb_offset *map = &dev_priv->regmap[pipe];
	int refclk = 0;
	struct gma_clock_t clock;
	const struct gma_limit_t *limit;
	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
	bool ok, is_sdvo = false;
	bool is_lvds = false;
	bool is_mipi = false;
	struct drm_mode_config *mode_config = &dev->mode_config;
	struct gma_encoder *gma_encoder = NULL;
	uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
	struct drm_connector *connector;
	int i;
	int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;

	if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
		return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb);

	if (!gma_power_begin(dev, true))
		return 0;

	memcpy(&gma_crtc->saved_mode,
		mode,
		sizeof(struct drm_display_mode));
	memcpy(&gma_crtc->saved_adjusted_mode,
		adjusted_mode,
		sizeof(struct drm_display_mode));

	list_for_each_entry(connector, &mode_config->connector_list, head) {
		if (!connector->encoder || connector->encoder->crtc != crtc)
			continue;

		gma_encoder = gma_attached_encoder(connector);

		switch (gma_encoder->type) {
		case INTEL_OUTPUT_LVDS:
			is_lvds = true;
			break;
		case INTEL_OUTPUT_SDVO:
			is_sdvo = true;
			break;
		case INTEL_OUTPUT_MIPI:
			is_mipi = true;
			break;
		}
	}

	/* Disable the VGA plane that we never use */
	for (i = 0; i <= need_aux; i++)
		REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);

	/* Disable the panel fitter if it was on our pipe */
	if (oaktrail_panel_fitter_pipe(dev) == pipe)
		REG_WRITE(PFIT_CONTROL, 0);

	for (i = 0; i <= need_aux; i++) {
		REG_WRITE_WITH_AUX(map->src, ((mode->crtc_hdisplay - 1) << 16) |
					     (mode->crtc_vdisplay - 1), i);
	}

	if (gma_encoder)
		drm_object_property_get_value(&connector->base,
			dev->mode_config.scaling_mode_property, &scalingType);

	if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
		/* Moorestown doesn't have register support for centering so
		 * we need to mess with the h/vblank and h/vsync start and
		 * ends to get centering */
		int offsetX = 0, offsetY = 0;

		offsetX = (adjusted_mode->crtc_hdisplay -
			   mode->crtc_hdisplay) / 2;
		offsetY = (adjusted_mode->crtc_vdisplay -
			   mode->crtc_vdisplay) / 2;

		for (i = 0; i <= need_aux; i++) {
			REG_WRITE_WITH_AUX(map->htotal, (mode->crtc_hdisplay - 1) |
				((adjusted_mode->crtc_htotal - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vtotal, (mode->crtc_vdisplay - 1) |
				((adjusted_mode->crtc_vtotal - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->hblank,
				(adjusted_mode->crtc_hblank_start - offsetX - 1) |
				((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->hsync,
				(adjusted_mode->crtc_hsync_start - offsetX - 1) |
				((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vblank,
				(adjusted_mode->crtc_vblank_start - offsetY - 1) |
				((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vsync,
				(adjusted_mode->crtc_vsync_start - offsetY - 1) |
				((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16), i);
		}
	} else {
		for (i = 0; i <= need_aux; i++) {
			REG_WRITE_WITH_AUX(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
				((adjusted_mode->crtc_htotal - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
				((adjusted_mode->crtc_vtotal - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
				((adjusted_mode->crtc_hblank_end - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
				((adjusted_mode->crtc_hsync_end - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
				((adjusted_mode->crtc_vblank_end - 1) << 16), i);
			REG_WRITE_WITH_AUX(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
				((adjusted_mode->crtc_vsync_end - 1) << 16), i);
		}
	}

	/* Flush the plane changes */
	{
		const struct drm_crtc_helper_funcs *crtc_funcs =
		    crtc->helper_private;
		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
	}

	/* setup pipeconf */
	pipeconf = REG_READ(map->conf);

	/* Set up the display plane register */
	dspcntr = REG_READ(map->cntr);
	dspcntr |= DISPPLANE_GAMMA_ENABLE;

	if (pipe == 0)
		dspcntr |= DISPPLANE_SEL_PIPE_A;
	else
		dspcntr |= DISPPLANE_SEL_PIPE_B;

	if (is_mipi)
		goto oaktrail_crtc_mode_set_exit;


	dpll = 0;		/*BIT16 = 0 for 100MHz reference */

	refclk = is_sdvo ? 96000 : dev_priv->core_freq * 1000;
	limit = mrst_limit(crtc, refclk);
	ok = limit->find_pll(limit, crtc, adjusted_mode->clock,
			     refclk, &clock);

	if (is_sdvo) {
		/* Convert calculated values to register values */
		clock.p1 = (1L << (clock.p1 - 1));
		clock.m -= 2;
		clock.n = (1L << (clock.n - 1));
	}

	if (!ok)
		DRM_ERROR("Failed to find proper PLL settings");

	mrst_print_pll(&clock);

	if (is_sdvo)
		fp = clock.n << 16 | clock.m;
	else
		fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8;

	dpll |= DPLL_VGA_MODE_DIS;


	dpll |= DPLL_VCO_ENABLE;

	if (is_lvds)
		dpll |= DPLLA_MODE_LVDS;
	else
		dpll |= DPLLB_MODE_DAC_SERIAL;

	if (is_sdvo) {
		int sdvo_pixel_multiply =
		    adjusted_mode->clock / mode->clock;

		dpll |= DPLL_DVO_HIGH_SPEED;
		dpll |=
		    (sdvo_pixel_multiply -
		     1) << SDVO_MULTIPLIER_SHIFT_HIRES;
	}


	/* compute bitmask from p1 value */
	if (is_sdvo)
		dpll |= clock.p1 << 16; // dpll |= (1 << (clock.p1 - 1)) << 16;
	else
		dpll |= (1 << (clock.p1 - 2)) << 17;

	dpll |= DPLL_VCO_ENABLE;

	if (dpll & DPLL_VCO_ENABLE) {
		for (i = 0; i <= need_aux; i++) {
			REG_WRITE_WITH_AUX(map->fp0, fp, i);
			REG_WRITE_WITH_AUX(map->dpll, dpll & ~DPLL_VCO_ENABLE, i);
			REG_READ_WITH_AUX(map->dpll, i);
			/* Check the DPLLA lock bit PIPEACONF[29] */
			udelay(150);
		}
	}

	for (i = 0; i <= need_aux; i++) {
		REG_WRITE_WITH_AUX(map->fp0, fp, i);
		REG_WRITE_WITH_AUX(map->dpll, dpll, i);
		REG_READ_WITH_AUX(map->dpll, i);
		/* Wait for the clocks to stabilize. */
		udelay(150);

		/* write it again -- the BIOS does, after all */
		REG_WRITE_WITH_AUX(map->dpll, dpll, i);
		REG_READ_WITH_AUX(map->dpll, i);
		/* Wait for the clocks to stabilize. */
		udelay(150);

		REG_WRITE_WITH_AUX(map->conf, pipeconf, i);
		REG_READ_WITH_AUX(map->conf, i);
		gma_wait_for_vblank(dev);

		REG_WRITE_WITH_AUX(map->cntr, dspcntr, i);
		gma_wait_for_vblank(dev);
	}

oaktrail_crtc_mode_set_exit:
	gma_power_end(dev);
	return 0;
}

static int oaktrail_pipe_set_base(struct drm_crtc *crtc,
			    int x, int y, struct drm_framebuffer *old_fb)
{
	struct drm_device *dev = crtc->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
	struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb);
	int pipe = gma_crtc->pipe;
	const struct psb_offset *map = &dev_priv->regmap[pipe];
	unsigned long start, offset;

	u32 dspcntr;
	int ret = 0;

	/* no fb bound */
	if (!crtc->primary->fb) {
		dev_dbg(dev->dev, "No FB bound\n");
		return 0;
	}

	if (!gma_power_begin(dev, true))
		return 0;

	start = psbfb->gtt->offset;
	offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8);

	REG_WRITE(map->stride, crtc->primary->fb->pitches[0]);

	dspcntr = REG_READ(map->cntr);
	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;

	switch (crtc->primary->fb->bits_per_pixel) {
	case 8:
		dspcntr |= DISPPLANE_8BPP;
		break;
	case 16:
		if (crtc->primary->fb->depth == 15)
			dspcntr |= DISPPLANE_15_16BPP;
		else
			dspcntr |= DISPPLANE_16BPP;
		break;
	case 24:
	case 32:
		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
		break;
	default:
		dev_err(dev->dev, "Unknown color depth\n");
		ret = -EINVAL;
		goto pipe_set_base_exit;
	}
	REG_WRITE(map->cntr, dspcntr);

	REG_WRITE(map->base, offset);
	REG_READ(map->base);
	REG_WRITE(map->surf, start);
	REG_READ(map->surf);

pipe_set_base_exit:
	gma_power_end(dev);
	return ret;
}

const struct drm_crtc_helper_funcs oaktrail_helper_funcs = {
	.dpms = oaktrail_crtc_dpms,
	.mode_fixup = gma_crtc_mode_fixup,
	.mode_set = oaktrail_crtc_mode_set,
	.mode_set_base = oaktrail_pipe_set_base,
	.prepare = gma_crtc_prepare,
	.commit = gma_crtc_commit,
};

/* Not used yet */
const struct gma_clock_funcs mrst_clock_funcs = {
	.clock = mrst_lvds_clock,
	.limit = mrst_limit,
	.pll_is_valid = gma_pll_is_valid,
};
