Poulsbo needs a physical address in the cursor base register. We allocate a stolen memory buffer and copy the cursor image provided by userspace into it. When/If we get our own userspace driver we can map this stolen memory directly. The patch also adds a mark in chip ops so we can identify devices that has this requirement. Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
		
			
				
	
	
		
			551 lines
		
	
	
	
		
			14 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			551 lines
		
	
	
	
		
			14 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/**************************************************************************
 | 
						|
 * Copyright (c) 2011, Intel Corporation.
 | 
						|
 * All Rights Reserved.
 | 
						|
 *
 | 
						|
 * 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 "psb_drv.h"
 | 
						|
#include "mid_bios.h"
 | 
						|
#include "mdfld_output.h"
 | 
						|
#include "mdfld_dsi_output.h"
 | 
						|
#include "tc35876x-dsi-lvds.h"
 | 
						|
 | 
						|
#include <asm/intel_scu_ipc.h>
 | 
						|
 | 
						|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 | 
						|
 | 
						|
#define MRST_BLC_MAX_PWM_REG_FREQ	    0xFFFF
 | 
						|
#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
 | 
						|
#define BLC_PWM_FREQ_CALC_CONSTANT 32
 | 
						|
#define MHz 1000000
 | 
						|
#define BRIGHTNESS_MIN_LEVEL 1
 | 
						|
#define BRIGHTNESS_MAX_LEVEL 100
 | 
						|
#define BRIGHTNESS_MASK	0xFF
 | 
						|
#define BLC_POLARITY_NORMAL 0
 | 
						|
#define BLC_POLARITY_INVERSE 1
 | 
						|
#define BLC_ADJUSTMENT_MAX 100
 | 
						|
 | 
						|
#define MDFLD_BLC_PWM_PRECISION_FACTOR    10
 | 
						|
#define MDFLD_BLC_MAX_PWM_REG_FREQ        0xFFFE
 | 
						|
#define MDFLD_BLC_MIN_PWM_REG_FREQ        0x2
 | 
						|
 | 
						|
#define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
 | 
						|
#define MDFLD_BACKLIGHT_PWM_CTL_SHIFT	(16)
 | 
						|
 | 
						|
static struct backlight_device *mdfld_backlight_device;
 | 
						|
 | 
						|
int mdfld_set_brightness(struct backlight_device *bd)
 | 
						|
{
 | 
						|
	struct drm_device *dev =
 | 
						|
		(struct drm_device *)bl_get_data(mdfld_backlight_device);
 | 
						|
	struct drm_psb_private *dev_priv = dev->dev_private;
 | 
						|
	int level = bd->props.brightness;
 | 
						|
 | 
						|
	DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
 | 
						|
 | 
						|
	/* Perform value bounds checking */
 | 
						|
	if (level < BRIGHTNESS_MIN_LEVEL)
 | 
						|
		level = BRIGHTNESS_MIN_LEVEL;
 | 
						|
 | 
						|
	if (gma_power_begin(dev, false)) {
 | 
						|
		u32 adjusted_level = 0;
 | 
						|
 | 
						|
		/*
 | 
						|
		 * Adjust the backlight level with the percent in
 | 
						|
		 * dev_priv->blc_adj2
 | 
						|
		 */
 | 
						|
		adjusted_level = level * dev_priv->blc_adj2;
 | 
						|
		adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX;
 | 
						|
		dev_priv->brightness_adjusted = adjusted_level;
 | 
						|
 | 
						|
		if (mdfld_get_panel_type(dev, 0) == TC35876X) {
 | 
						|
			if (dev_priv->dpi_panel_on[0] ||
 | 
						|
					dev_priv->dpi_panel_on[2])
 | 
						|
				tc35876x_brightness_control(dev,
 | 
						|
						dev_priv->brightness_adjusted);
 | 
						|
		} else {
 | 
						|
			if (dev_priv->dpi_panel_on[0])
 | 
						|
				mdfld_dsi_brightness_control(dev, 0,
 | 
						|
						dev_priv->brightness_adjusted);
 | 
						|
		}
 | 
						|
 | 
						|
		if (dev_priv->dpi_panel_on[2])
 | 
						|
			mdfld_dsi_brightness_control(dev, 2,
 | 
						|
					dev_priv->brightness_adjusted);
 | 
						|
		gma_power_end(dev);
 | 
						|
	}
 | 
						|
 | 
						|
	/* cache the brightness for later use */
 | 
						|
	dev_priv->brightness = level;
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_get_brightness(struct backlight_device *bd)
 | 
						|
{
 | 
						|
	struct drm_device *dev =
 | 
						|
		(struct drm_device *)bl_get_data(mdfld_backlight_device);
 | 
						|
	struct drm_psb_private *dev_priv = dev->dev_private;
 | 
						|
 | 
						|
	DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness);
 | 
						|
 | 
						|
	/* return locally cached var instead of HW read (due to DPST etc.) */
 | 
						|
	return dev_priv->brightness;
 | 
						|
}
 | 
						|
 | 
						|
static const struct backlight_ops mdfld_ops = {
 | 
						|
	.get_brightness = mdfld_get_brightness,
 | 
						|
	.update_status  = mdfld_set_brightness,
 | 
						|
};
 | 
						|
 | 
						|
static int device_backlight_init(struct drm_device *dev)
 | 
						|
{
 | 
						|
	struct drm_psb_private *dev_priv = (struct drm_psb_private *)
 | 
						|
		dev->dev_private;
 | 
						|
 | 
						|
	dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
 | 
						|
	dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_backlight_init(struct drm_device *dev)
 | 
						|
{
 | 
						|
	struct backlight_properties props;
 | 
						|
	int ret = 0;
 | 
						|
 | 
						|
	memset(&props, 0, sizeof(struct backlight_properties));
 | 
						|
	props.max_brightness = BRIGHTNESS_MAX_LEVEL;
 | 
						|
	props.type = BACKLIGHT_PLATFORM;
 | 
						|
	mdfld_backlight_device = backlight_device_register("mdfld-bl",
 | 
						|
				NULL, (void *)dev, &mdfld_ops, &props);
 | 
						|
 | 
						|
	if (IS_ERR(mdfld_backlight_device))
 | 
						|
		return PTR_ERR(mdfld_backlight_device);
 | 
						|
 | 
						|
	ret = device_backlight_init(dev);
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL;
 | 
						|
	mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL;
 | 
						|
	backlight_update_status(mdfld_backlight_device);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
struct backlight_device *mdfld_get_backlight_device(void)
 | 
						|
{
 | 
						|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 | 
						|
	return mdfld_backlight_device;
 | 
						|
#else
 | 
						|
	return NULL;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * mdfld_save_display_registers
 | 
						|
 *
 | 
						|
 * Description: We are going to suspend so save current display
 | 
						|
 * register state.
 | 
						|
 *
 | 
						|
 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
 | 
						|
 */
 | 
						|
static int mdfld_save_display_registers(struct drm_device *dev, int pipenum)
 | 
						|
{
 | 
						|
	struct drm_psb_private *dev_priv = dev->dev_private;
 | 
						|
	struct medfield_state *regs = &dev_priv->regs.mdfld;
 | 
						|
	struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
 | 
						|
	const struct psb_offset *map = &dev_priv->regmap[pipenum];
 | 
						|
	int i;
 | 
						|
	u32 *mipi_val;
 | 
						|
 | 
						|
	/* register */
 | 
						|
	u32 mipi_reg = MIPI;
 | 
						|
 | 
						|
	switch (pipenum) {
 | 
						|
	case 0:
 | 
						|
		mipi_val = ®s->saveMIPI;
 | 
						|
		break;
 | 
						|
	case 1:
 | 
						|
		mipi_val = ®s->saveMIPI;
 | 
						|
		break;
 | 
						|
	case 2:
 | 
						|
		/* register */
 | 
						|
		mipi_reg = MIPI_C;
 | 
						|
		/* pointer to values */
 | 
						|
		mipi_val = ®s->saveMIPI_C;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
 | 
						|
		return -EINVAL;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Pipe & plane A info */
 | 
						|
	pipe->dpll = PSB_RVDC32(map->dpll);
 | 
						|
	pipe->fp0 = PSB_RVDC32(map->fp0);
 | 
						|
	pipe->conf = PSB_RVDC32(map->conf);
 | 
						|
	pipe->htotal = PSB_RVDC32(map->htotal);
 | 
						|
	pipe->hblank = PSB_RVDC32(map->hblank);
 | 
						|
	pipe->hsync = PSB_RVDC32(map->hsync);
 | 
						|
	pipe->vtotal = PSB_RVDC32(map->vtotal);
 | 
						|
	pipe->vblank = PSB_RVDC32(map->vblank);
 | 
						|
	pipe->vsync = PSB_RVDC32(map->vsync);
 | 
						|
	pipe->src = PSB_RVDC32(map->src);
 | 
						|
	pipe->stride = PSB_RVDC32(map->stride);
 | 
						|
	pipe->linoff = PSB_RVDC32(map->linoff);
 | 
						|
	pipe->tileoff = PSB_RVDC32(map->tileoff);
 | 
						|
	pipe->size = PSB_RVDC32(map->size);
 | 
						|
	pipe->pos = PSB_RVDC32(map->pos);
 | 
						|
	pipe->surf = PSB_RVDC32(map->surf);
 | 
						|
	pipe->cntr = PSB_RVDC32(map->cntr);
 | 
						|
	pipe->status = PSB_RVDC32(map->status);
 | 
						|
 | 
						|
	/*save palette (gamma) */
 | 
						|
	for (i = 0; i < 256; i++)
 | 
						|
		pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2));
 | 
						|
 | 
						|
	if (pipenum == 1) {
 | 
						|
		regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
 | 
						|
		regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
 | 
						|
 | 
						|
		regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
 | 
						|
		regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	*mipi_val = PSB_RVDC32(mipi_reg);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * mdfld_restore_display_registers
 | 
						|
 *
 | 
						|
 * Description: We are going to resume so restore display register state.
 | 
						|
 *
 | 
						|
 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
 | 
						|
 */
 | 
						|
static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum)
 | 
						|
{
 | 
						|
	/* To get  panel out of ULPS mode. */
 | 
						|
	u32 temp = 0;
 | 
						|
	u32 device_ready_reg = DEVICE_READY_REG;
 | 
						|
	struct drm_psb_private *dev_priv = dev->dev_private;
 | 
						|
	struct mdfld_dsi_config *dsi_config = NULL;
 | 
						|
	struct medfield_state *regs = &dev_priv->regs.mdfld;
 | 
						|
	struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
 | 
						|
	const struct psb_offset *map = &dev_priv->regmap[pipenum];
 | 
						|
	u32 i;
 | 
						|
	u32 dpll;
 | 
						|
	u32 timeout = 0;
 | 
						|
 | 
						|
	/* register */
 | 
						|
	u32 mipi_reg = MIPI;
 | 
						|
 | 
						|
	/* values */
 | 
						|
	u32 dpll_val = pipe->dpll;
 | 
						|
	u32 mipi_val = regs->saveMIPI;
 | 
						|
 | 
						|
	switch (pipenum) {
 | 
						|
	case 0:
 | 
						|
		dpll_val &= ~DPLL_VCO_ENABLE;
 | 
						|
		dsi_config = dev_priv->dsi_configs[0];
 | 
						|
		break;
 | 
						|
	case 1:
 | 
						|
		dpll_val &= ~DPLL_VCO_ENABLE;
 | 
						|
		break;
 | 
						|
	case 2:
 | 
						|
		mipi_reg = MIPI_C;
 | 
						|
		mipi_val = regs->saveMIPI_C;
 | 
						|
		dsi_config = dev_priv->dsi_configs[1];
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
 | 
						|
		return -EINVAL;
 | 
						|
	}
 | 
						|
 | 
						|
	/*make sure VGA plane is off. it initializes to on after reset!*/
 | 
						|
	PSB_WVDC32(0x80000000, VGACNTRL);
 | 
						|
 | 
						|
	if (pipenum == 1) {
 | 
						|
		PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll);
 | 
						|
		PSB_RVDC32(map->dpll);
 | 
						|
 | 
						|
		PSB_WVDC32(pipe->fp0, map->fp0);
 | 
						|
	} else {
 | 
						|
 | 
						|
		dpll = PSB_RVDC32(map->dpll);
 | 
						|
 | 
						|
		if (!(dpll & DPLL_VCO_ENABLE)) {
 | 
						|
 | 
						|
			/* When ungating power of DPLL, needs to wait 0.5us
 | 
						|
			   before enable the VCO */
 | 
						|
			if (dpll & MDFLD_PWR_GATE_EN) {
 | 
						|
				dpll &= ~MDFLD_PWR_GATE_EN;
 | 
						|
				PSB_WVDC32(dpll, map->dpll);
 | 
						|
				/* FIXME_MDFLD PO - change 500 to 1 after PO */
 | 
						|
				udelay(500);
 | 
						|
			}
 | 
						|
 | 
						|
			PSB_WVDC32(pipe->fp0, map->fp0);
 | 
						|
			PSB_WVDC32(dpll_val, map->dpll);
 | 
						|
			/* FIXME_MDFLD PO - change 500 to 1 after PO */
 | 
						|
			udelay(500);
 | 
						|
 | 
						|
			dpll_val |= DPLL_VCO_ENABLE;
 | 
						|
			PSB_WVDC32(dpll_val, map->dpll);
 | 
						|
			PSB_RVDC32(map->dpll);
 | 
						|
 | 
						|
			/* wait for DSI PLL to lock */
 | 
						|
			while (timeout < 20000 &&
 | 
						|
			  !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) {
 | 
						|
				udelay(150);
 | 
						|
				timeout++;
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 20000) {
 | 
						|
				DRM_ERROR("%s, can't lock DSIPLL.\n",
 | 
						|
								__func__);
 | 
						|
				return -EINVAL;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/* Restore mode */
 | 
						|
	PSB_WVDC32(pipe->htotal, map->htotal);
 | 
						|
	PSB_WVDC32(pipe->hblank, map->hblank);
 | 
						|
	PSB_WVDC32(pipe->hsync, map->hsync);
 | 
						|
	PSB_WVDC32(pipe->vtotal, map->vtotal);
 | 
						|
	PSB_WVDC32(pipe->vblank, map->vblank);
 | 
						|
	PSB_WVDC32(pipe->vsync, map->vsync);
 | 
						|
	PSB_WVDC32(pipe->src, map->src);
 | 
						|
	PSB_WVDC32(pipe->status, map->status);
 | 
						|
 | 
						|
	/*set up the plane*/
 | 
						|
	PSB_WVDC32(pipe->stride, map->stride);
 | 
						|
	PSB_WVDC32(pipe->linoff, map->linoff);
 | 
						|
	PSB_WVDC32(pipe->tileoff, map->tileoff);
 | 
						|
	PSB_WVDC32(pipe->size, map->size);
 | 
						|
	PSB_WVDC32(pipe->pos, map->pos);
 | 
						|
	PSB_WVDC32(pipe->surf, map->surf);
 | 
						|
 | 
						|
	if (pipenum == 1) {
 | 
						|
		/* restore palette (gamma) */
 | 
						|
		/*DRM_UDELAY(50000); */
 | 
						|
		for (i = 0; i < 256; i++)
 | 
						|
			PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));
 | 
						|
 | 
						|
		PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL);
 | 
						|
		PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
 | 
						|
 | 
						|
		/*TODO: resume HDMI port */
 | 
						|
 | 
						|
		/*TODO: resume pipe*/
 | 
						|
 | 
						|
		/*enable the plane*/
 | 
						|
		PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr);
 | 
						|
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	/*set up pipe related registers*/
 | 
						|
	PSB_WVDC32(mipi_val, mipi_reg);
 | 
						|
 | 
						|
	/*setup MIPI adapter + MIPI IP registers*/
 | 
						|
	if (dsi_config)
 | 
						|
		mdfld_dsi_controller_init(dsi_config, pipenum);
 | 
						|
 | 
						|
	if (in_atomic() || in_interrupt())
 | 
						|
		mdelay(20);
 | 
						|
	else
 | 
						|
		msleep(20);
 | 
						|
 | 
						|
	/*enable the plane*/
 | 
						|
	PSB_WVDC32(pipe->cntr, map->cntr);
 | 
						|
 | 
						|
	if (in_atomic() || in_interrupt())
 | 
						|
		mdelay(20);
 | 
						|
	else
 | 
						|
		msleep(20);
 | 
						|
 | 
						|
	/* LP Hold Release */
 | 
						|
	temp = REG_READ(mipi_reg);
 | 
						|
	temp |= LP_OUTPUT_HOLD_RELEASE;
 | 
						|
	REG_WRITE(mipi_reg, temp);
 | 
						|
	mdelay(1);
 | 
						|
 | 
						|
 | 
						|
	/* Set DSI host to exit from Utra Low Power State */
 | 
						|
	temp = REG_READ(device_ready_reg);
 | 
						|
	temp &= ~ULPS_MASK;
 | 
						|
	temp |= 0x3;
 | 
						|
	temp |= EXIT_ULPS_DEV_READY;
 | 
						|
	REG_WRITE(device_ready_reg, temp);
 | 
						|
	mdelay(1);
 | 
						|
 | 
						|
	temp = REG_READ(device_ready_reg);
 | 
						|
	temp &= ~ULPS_MASK;
 | 
						|
	temp |= EXITING_ULPS;
 | 
						|
	REG_WRITE(device_ready_reg, temp);
 | 
						|
	mdelay(1);
 | 
						|
 | 
						|
	/*enable the pipe*/
 | 
						|
	PSB_WVDC32(pipe->conf, map->conf);
 | 
						|
 | 
						|
	/* restore palette (gamma) */
 | 
						|
	/*DRM_UDELAY(50000); */
 | 
						|
	for (i = 0; i < 256; i++)
 | 
						|
		PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_save_registers(struct drm_device *dev)
 | 
						|
{
 | 
						|
	/* mdfld_save_cursor_overlay_registers(dev); */
 | 
						|
	mdfld_save_display_registers(dev, 0);
 | 
						|
	mdfld_save_display_registers(dev, 2);
 | 
						|
	mdfld_disable_crtc(dev, 0);
 | 
						|
	mdfld_disable_crtc(dev, 2);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_restore_registers(struct drm_device *dev)
 | 
						|
{
 | 
						|
	mdfld_restore_display_registers(dev, 2);
 | 
						|
	mdfld_restore_display_registers(dev, 0);
 | 
						|
	/* mdfld_restore_cursor_overlay_registers(dev); */
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_power_down(struct drm_device *dev)
 | 
						|
{
 | 
						|
	/* FIXME */
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int mdfld_power_up(struct drm_device *dev)
 | 
						|
{
 | 
						|
	/* FIXME */
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/* Medfield  */
 | 
						|
static const struct psb_offset mdfld_regmap[3] = {
 | 
						|
	{
 | 
						|
		.fp0 = MRST_FPA0,
 | 
						|
		.fp1 = MRST_FPA1,
 | 
						|
		.cntr = DSPACNTR,
 | 
						|
		.conf = PIPEACONF,
 | 
						|
		.src = PIPEASRC,
 | 
						|
		.dpll = MRST_DPLL_A,
 | 
						|
		.htotal = HTOTAL_A,
 | 
						|
		.hblank = HBLANK_A,
 | 
						|
		.hsync = HSYNC_A,
 | 
						|
		.vtotal = VTOTAL_A,
 | 
						|
		.vblank = VBLANK_A,
 | 
						|
		.vsync = VSYNC_A,
 | 
						|
		.stride = DSPASTRIDE,
 | 
						|
		.size = DSPASIZE,
 | 
						|
		.pos = DSPAPOS,
 | 
						|
		.surf = DSPASURF,
 | 
						|
		.addr = MRST_DSPABASE,
 | 
						|
		.status = PIPEASTAT,
 | 
						|
		.linoff = DSPALINOFF,
 | 
						|
		.tileoff = DSPATILEOFF,
 | 
						|
		.palette = PALETTE_A,
 | 
						|
	},
 | 
						|
	{
 | 
						|
		.fp0 = MDFLD_DPLL_DIV0,
 | 
						|
		.cntr = DSPBCNTR,
 | 
						|
		.conf = PIPEBCONF,
 | 
						|
		.src = PIPEBSRC,
 | 
						|
		.dpll = MDFLD_DPLL_B,
 | 
						|
		.htotal = HTOTAL_B,
 | 
						|
		.hblank = HBLANK_B,
 | 
						|
		.hsync = HSYNC_B,
 | 
						|
		.vtotal = VTOTAL_B,
 | 
						|
		.vblank = VBLANK_B,
 | 
						|
		.vsync = VSYNC_B,
 | 
						|
		.stride = DSPBSTRIDE,
 | 
						|
		.size = DSPBSIZE,
 | 
						|
		.pos = DSPBPOS,
 | 
						|
		.surf = DSPBSURF,
 | 
						|
		.addr = MRST_DSPBBASE,
 | 
						|
		.status = PIPEBSTAT,
 | 
						|
		.linoff = DSPBLINOFF,
 | 
						|
		.tileoff = DSPBTILEOFF,
 | 
						|
		.palette = PALETTE_B,
 | 
						|
	},
 | 
						|
	{
 | 
						|
		.fp0 = MRST_FPA0,	/* This is what the old code did ?? */
 | 
						|
		.cntr = DSPCCNTR,
 | 
						|
		.conf = PIPECCONF,
 | 
						|
		.src = PIPECSRC,
 | 
						|
		/* No DPLL_C */
 | 
						|
		.dpll = MRST_DPLL_A,
 | 
						|
		.htotal = HTOTAL_C,
 | 
						|
		.hblank = HBLANK_C,
 | 
						|
		.hsync = HSYNC_C,
 | 
						|
		.vtotal = VTOTAL_C,
 | 
						|
		.vblank = VBLANK_C,
 | 
						|
		.vsync = VSYNC_C,
 | 
						|
		.stride = DSPCSTRIDE,
 | 
						|
		.size = DSPBSIZE,
 | 
						|
		.pos = DSPCPOS,
 | 
						|
		.surf = DSPCSURF,
 | 
						|
		.addr = MDFLD_DSPCBASE,
 | 
						|
		.status = PIPECSTAT,
 | 
						|
		.linoff = DSPCLINOFF,
 | 
						|
		.tileoff = DSPCTILEOFF,
 | 
						|
		.palette = PALETTE_C,
 | 
						|
	},
 | 
						|
};
 | 
						|
 | 
						|
static int mdfld_chip_setup(struct drm_device *dev)
 | 
						|
{
 | 
						|
	struct drm_psb_private *dev_priv = dev->dev_private;
 | 
						|
	if (pci_enable_msi(dev->pdev))
 | 
						|
		dev_warn(dev->dev, "Enabling MSI failed!\n");
 | 
						|
	dev_priv->regmap = mdfld_regmap;
 | 
						|
	return mid_chip_setup(dev);
 | 
						|
}
 | 
						|
 | 
						|
const struct psb_ops mdfld_chip_ops = {
 | 
						|
	.name = "mdfld",
 | 
						|
	.accel_2d = 0,
 | 
						|
	.pipes = 3,
 | 
						|
	.crtcs = 3,
 | 
						|
	.lvds_mask = (1 << 1),
 | 
						|
	.hdmi_mask = (1 << 1),
 | 
						|
	.cursor_needs_phys = 0,
 | 
						|
	.sgx_offset = MRST_SGX_OFFSET,
 | 
						|
 | 
						|
	.chip_setup = mdfld_chip_setup,
 | 
						|
	.crtc_helper = &mdfld_helper_funcs,
 | 
						|
	.crtc_funcs = &psb_intel_crtc_funcs,
 | 
						|
 | 
						|
	.output_init = mdfld_output_init,
 | 
						|
 | 
						|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 | 
						|
	.backlight_init = mdfld_backlight_init,
 | 
						|
#endif
 | 
						|
 | 
						|
	.save_regs = mdfld_save_registers,
 | 
						|
	.restore_regs = mdfld_restore_registers,
 | 
						|
	.power_down = mdfld_power_down,
 | 
						|
	.power_up = mdfld_power_up,
 | 
						|
};
 |