[go: nahoru, domu]

189c78134cc54dff016c83367912eb055637fa50cAlan Cox/**************************************************************************
289c78134cc54dff016c83367912eb055637fa50cAlan Cox * Copyright (c) 2011, Intel Corporation.
389c78134cc54dff016c83367912eb055637fa50cAlan Cox * All Rights Reserved.
489c78134cc54dff016c83367912eb055637fa50cAlan Cox *
589c78134cc54dff016c83367912eb055637fa50cAlan Cox * This program is free software; you can redistribute it and/or modify it
689c78134cc54dff016c83367912eb055637fa50cAlan Cox * under the terms and conditions of the GNU General Public License,
789c78134cc54dff016c83367912eb055637fa50cAlan Cox * version 2, as published by the Free Software Foundation.
889c78134cc54dff016c83367912eb055637fa50cAlan Cox *
989c78134cc54dff016c83367912eb055637fa50cAlan Cox * This program is distributed in the hope it will be useful, but WITHOUT
1089c78134cc54dff016c83367912eb055637fa50cAlan Cox * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1189c78134cc54dff016c83367912eb055637fa50cAlan Cox * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1289c78134cc54dff016c83367912eb055637fa50cAlan Cox * more details.
1389c78134cc54dff016c83367912eb055637fa50cAlan Cox *
1489c78134cc54dff016c83367912eb055637fa50cAlan Cox * You should have received a copy of the GNU General Public License along with
1589c78134cc54dff016c83367912eb055637fa50cAlan Cox * this program; if not, write to the Free Software Foundation, Inc.,
1689c78134cc54dff016c83367912eb055637fa50cAlan Cox * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1789c78134cc54dff016c83367912eb055637fa50cAlan Cox *
1889c78134cc54dff016c83367912eb055637fa50cAlan Cox **************************************************************************/
1989c78134cc54dff016c83367912eb055637fa50cAlan Cox
2089c78134cc54dff016c83367912eb055637fa50cAlan Cox#include <linux/backlight.h>
2189c78134cc54dff016c83367912eb055637fa50cAlan Cox#include <drm/drmP.h>
2289c78134cc54dff016c83367912eb055637fa50cAlan Cox#include <drm/drm.h>
23760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/gma_drm.h>
2489c78134cc54dff016c83367912eb055637fa50cAlan Cox#include "psb_drv.h"
2589c78134cc54dff016c83367912eb055637fa50cAlan Cox#include "psb_reg.h"
2689c78134cc54dff016c83367912eb055637fa50cAlan Cox#include "psb_intel_reg.h"
2789c78134cc54dff016c83367912eb055637fa50cAlan Cox#include "intel_bios.h"
287f67c06721641df12ed68249218d1c2118517f78Patrik Jakobsson#include "psb_device.h"
29f35257a3fe267c4280bb2f69453ca1dd3bf48956Patrik Jakobsson#include "gma_device.h"
3089c78134cc54dff016c83367912eb055637fa50cAlan Cox
3189c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_output_init(struct drm_device *dev)
3289c78134cc54dff016c83367912eb055637fa50cAlan Cox{
3389c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
3489c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_intel_lvds_init(dev, &dev_priv->mode_dev);
3589c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_intel_sdvo_init(dev, SDVOB);
3689c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
3789c78134cc54dff016c83367912eb055637fa50cAlan Cox}
3889c78134cc54dff016c83367912eb055637fa50cAlan Cox
3989c78134cc54dff016c83367912eb055637fa50cAlan Cox#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
4089c78134cc54dff016c83367912eb055637fa50cAlan Cox
4189c78134cc54dff016c83367912eb055637fa50cAlan Cox/*
4289c78134cc54dff016c83367912eb055637fa50cAlan Cox *	Poulsbo Backlight Interfaces
4389c78134cc54dff016c83367912eb055637fa50cAlan Cox */
4489c78134cc54dff016c83367912eb055637fa50cAlan Cox
4589c78134cc54dff016c83367912eb055637fa50cAlan Cox#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
4689c78134cc54dff016c83367912eb055637fa50cAlan Cox#define BLC_PWM_FREQ_CALC_CONSTANT 32
4789c78134cc54dff016c83367912eb055637fa50cAlan Cox#define MHz 1000000
4889c78134cc54dff016c83367912eb055637fa50cAlan Cox
4989c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_PWM_PRECISION_FACTOR    10
5089c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
5189c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
5289c78134cc54dff016c83367912eb055637fa50cAlan Cox
5389c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
5489c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
5589c78134cc54dff016c83367912eb055637fa50cAlan Cox
5689c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_brightness;
5789c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic struct backlight_device *psb_backlight_device;
5889c78134cc54dff016c83367912eb055637fa50cAlan Cox
5989c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_get_brightness(struct backlight_device *bd)
6089c78134cc54dff016c83367912eb055637fa50cAlan Cox{
6189c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* return locally cached var instead of HW read (due to DPST etc.) */
6289c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* FIXME: ideally return actual value in case firmware fiddled with
6389c78134cc54dff016c83367912eb055637fa50cAlan Cox	   it */
6489c78134cc54dff016c83367912eb055637fa50cAlan Cox	return psb_brightness;
6589c78134cc54dff016c83367912eb055637fa50cAlan Cox}
6689c78134cc54dff016c83367912eb055637fa50cAlan Cox
6789c78134cc54dff016c83367912eb055637fa50cAlan Cox
6889c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_backlight_setup(struct drm_device *dev)
6989c78134cc54dff016c83367912eb055637fa50cAlan Cox{
7089c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
7189c78134cc54dff016c83367912eb055637fa50cAlan Cox	unsigned long core_clock;
7289c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* u32 bl_max_freq; */
7389c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* unsigned long value; */
7489c78134cc54dff016c83367912eb055637fa50cAlan Cox	u16 bl_max_freq;
7589c78134cc54dff016c83367912eb055637fa50cAlan Cox	uint32_t value;
7689c78134cc54dff016c83367912eb055637fa50cAlan Cox	uint32_t blc_pwm_precision_factor;
7789c78134cc54dff016c83367912eb055637fa50cAlan Cox
7889c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* get bl_max_freq and pol from dev_priv*/
7989c78134cc54dff016c83367912eb055637fa50cAlan Cox	if (!dev_priv->lvds_bl) {
8089c78134cc54dff016c83367912eb055637fa50cAlan Cox		dev_err(dev->dev, "Has no valid LVDS backlight info\n");
8189c78134cc54dff016c83367912eb055637fa50cAlan Cox		return -ENOENT;
8289c78134cc54dff016c83367912eb055637fa50cAlan Cox	}
8389c78134cc54dff016c83367912eb055637fa50cAlan Cox	bl_max_freq = dev_priv->lvds_bl->freq;
8489c78134cc54dff016c83367912eb055637fa50cAlan Cox	blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
8589c78134cc54dff016c83367912eb055637fa50cAlan Cox
8689c78134cc54dff016c83367912eb055637fa50cAlan Cox	core_clock = dev_priv->core_freq;
8789c78134cc54dff016c83367912eb055637fa50cAlan Cox
8889c78134cc54dff016c83367912eb055637fa50cAlan Cox	value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
8989c78134cc54dff016c83367912eb055637fa50cAlan Cox	value *= blc_pwm_precision_factor;
9089c78134cc54dff016c83367912eb055637fa50cAlan Cox	value /= bl_max_freq;
9189c78134cc54dff016c83367912eb055637fa50cAlan Cox	value /= blc_pwm_precision_factor;
9289c78134cc54dff016c83367912eb055637fa50cAlan Cox
9389c78134cc54dff016c83367912eb055637fa50cAlan Cox	if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
9489c78134cc54dff016c83367912eb055637fa50cAlan Cox		 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
9589c78134cc54dff016c83367912eb055637fa50cAlan Cox				return -ERANGE;
9689c78134cc54dff016c83367912eb055637fa50cAlan Cox	else {
9789c78134cc54dff016c83367912eb055637fa50cAlan Cox		value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
9889c78134cc54dff016c83367912eb055637fa50cAlan Cox		REG_WRITE(BLC_PWM_CTL,
9989c78134cc54dff016c83367912eb055637fa50cAlan Cox			(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
10089c78134cc54dff016c83367912eb055637fa50cAlan Cox	}
10189c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
10289c78134cc54dff016c83367912eb055637fa50cAlan Cox}
10389c78134cc54dff016c83367912eb055637fa50cAlan Cox
10489c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_set_brightness(struct backlight_device *bd)
10589c78134cc54dff016c83367912eb055637fa50cAlan Cox{
10689c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_device *dev = bl_get_data(psb_backlight_device);
10789c78134cc54dff016c83367912eb055637fa50cAlan Cox	int level = bd->props.brightness;
10889c78134cc54dff016c83367912eb055637fa50cAlan Cox
10989c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* Percentage 1-100% being valid */
11089c78134cc54dff016c83367912eb055637fa50cAlan Cox	if (level < 1)
11189c78134cc54dff016c83367912eb055637fa50cAlan Cox		level = 1;
11289c78134cc54dff016c83367912eb055637fa50cAlan Cox
11389c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_intel_lvds_set_brightness(dev, level);
11489c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_brightness = level;
11589c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
11689c78134cc54dff016c83367912eb055637fa50cAlan Cox}
11789c78134cc54dff016c83367912eb055637fa50cAlan Cox
11889c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic const struct backlight_ops psb_ops = {
11989c78134cc54dff016c83367912eb055637fa50cAlan Cox	.get_brightness = psb_get_brightness,
12089c78134cc54dff016c83367912eb055637fa50cAlan Cox	.update_status  = psb_set_brightness,
12189c78134cc54dff016c83367912eb055637fa50cAlan Cox};
12289c78134cc54dff016c83367912eb055637fa50cAlan Cox
12389c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_backlight_init(struct drm_device *dev)
12489c78134cc54dff016c83367912eb055637fa50cAlan Cox{
12589c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
12689c78134cc54dff016c83367912eb055637fa50cAlan Cox	int ret;
12789c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct backlight_properties props;
12889c78134cc54dff016c83367912eb055637fa50cAlan Cox
12989c78134cc54dff016c83367912eb055637fa50cAlan Cox	memset(&props, 0, sizeof(struct backlight_properties));
13089c78134cc54dff016c83367912eb055637fa50cAlan Cox	props.max_brightness = 100;
13189c78134cc54dff016c83367912eb055637fa50cAlan Cox	props.type = BACKLIGHT_PLATFORM;
13289c78134cc54dff016c83367912eb055637fa50cAlan Cox
13389c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_backlight_device = backlight_device_register("psb-bl",
13489c78134cc54dff016c83367912eb055637fa50cAlan Cox					NULL, (void *)dev, &psb_ops, &props);
13589c78134cc54dff016c83367912eb055637fa50cAlan Cox	if (IS_ERR(psb_backlight_device))
13689c78134cc54dff016c83367912eb055637fa50cAlan Cox		return PTR_ERR(psb_backlight_device);
13789c78134cc54dff016c83367912eb055637fa50cAlan Cox
13889c78134cc54dff016c83367912eb055637fa50cAlan Cox	ret = psb_backlight_setup(dev);
13989c78134cc54dff016c83367912eb055637fa50cAlan Cox	if (ret < 0) {
14089c78134cc54dff016c83367912eb055637fa50cAlan Cox		backlight_device_unregister(psb_backlight_device);
14189c78134cc54dff016c83367912eb055637fa50cAlan Cox		psb_backlight_device = NULL;
14289c78134cc54dff016c83367912eb055637fa50cAlan Cox		return ret;
14389c78134cc54dff016c83367912eb055637fa50cAlan Cox	}
14489c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_backlight_device->props.brightness = 100;
14589c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_backlight_device->props.max_brightness = 100;
14689c78134cc54dff016c83367912eb055637fa50cAlan Cox	backlight_update_status(psb_backlight_device);
14789c78134cc54dff016c83367912eb055637fa50cAlan Cox	dev_priv->backlight_device = psb_backlight_device;
148f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox
149f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox	/* This must occur after the backlight is properly initialised */
150f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox	psb_lid_timer_init(dev_priv);
151f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox
15289c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
15389c78134cc54dff016c83367912eb055637fa50cAlan Cox}
15489c78134cc54dff016c83367912eb055637fa50cAlan Cox
15589c78134cc54dff016c83367912eb055637fa50cAlan Cox#endif
15689c78134cc54dff016c83367912eb055637fa50cAlan Cox
15789c78134cc54dff016c83367912eb055637fa50cAlan Cox/*
15889c78134cc54dff016c83367912eb055637fa50cAlan Cox *	Provide the Poulsbo specific chip logic and low level methods
15989c78134cc54dff016c83367912eb055637fa50cAlan Cox *	for power management
16089c78134cc54dff016c83367912eb055637fa50cAlan Cox */
16189c78134cc54dff016c83367912eb055637fa50cAlan Cox
16289c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic void psb_init_pm(struct drm_device *dev)
16389c78134cc54dff016c83367912eb055637fa50cAlan Cox{
16489c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
16589c78134cc54dff016c83367912eb055637fa50cAlan Cox
16689c78134cc54dff016c83367912eb055637fa50cAlan Cox	u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
16789c78134cc54dff016c83367912eb055637fa50cAlan Cox	gating &= ~3;	/* Disable 2D clock gating */
16889c78134cc54dff016c83367912eb055637fa50cAlan Cox	gating |= 1;
16989c78134cc54dff016c83367912eb055637fa50cAlan Cox	PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
17089c78134cc54dff016c83367912eb055637fa50cAlan Cox	PSB_RSGX32(PSB_CR_CLKGATECTL);
17189c78134cc54dff016c83367912eb055637fa50cAlan Cox}
17289c78134cc54dff016c83367912eb055637fa50cAlan Cox
17389c78134cc54dff016c83367912eb055637fa50cAlan Cox/**
17489c78134cc54dff016c83367912eb055637fa50cAlan Cox *	psb_save_display_registers	-	save registers lost on suspend
17589c78134cc54dff016c83367912eb055637fa50cAlan Cox *	@dev: our DRM device
17689c78134cc54dff016c83367912eb055637fa50cAlan Cox *
17789c78134cc54dff016c83367912eb055637fa50cAlan Cox *	Save the state we need in order to be able to restore the interface
17889c78134cc54dff016c83367912eb055637fa50cAlan Cox *	upon resume from suspend
17989c78134cc54dff016c83367912eb055637fa50cAlan Cox */
18089c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_save_display_registers(struct drm_device *dev)
18189c78134cc54dff016c83367912eb055637fa50cAlan Cox{
18289c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
18389c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_crtc *crtc;
18489c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_connector *connector;
185c6265ff593467d472814aa9f16f89f6c1dc90a5dAlan Cox	struct psb_state *regs = &dev_priv->regs.psb;
18689c78134cc54dff016c83367912eb055637fa50cAlan Cox
18789c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* Display arbitration control + watermarks */
188648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPARB = PSB_RVDC32(DSPARB);
189648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW1 = PSB_RVDC32(DSPFW1);
190648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW2 = PSB_RVDC32(DSPFW2);
191648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW3 = PSB_RVDC32(DSPFW3);
192648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW4 = PSB_RVDC32(DSPFW4);
193648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW5 = PSB_RVDC32(DSPFW5);
194648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveDSPFW6 = PSB_RVDC32(DSPFW6);
195648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
19689c78134cc54dff016c83367912eb055637fa50cAlan Cox
19789c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* Save crtc and output state */
1980a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter	drm_modeset_lock_all(dev);
19989c78134cc54dff016c83367912eb055637fa50cAlan Cox	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
20089c78134cc54dff016c83367912eb055637fa50cAlan Cox		if (drm_helper_crtc_in_use(crtc))
20189c78134cc54dff016c83367912eb055637fa50cAlan Cox			crtc->funcs->save(crtc);
20289c78134cc54dff016c83367912eb055637fa50cAlan Cox	}
20389c78134cc54dff016c83367912eb055637fa50cAlan Cox
20489c78134cc54dff016c83367912eb055637fa50cAlan Cox	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
2057beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox		if (connector->funcs->save)
2067beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox			connector->funcs->save(connector);
20789c78134cc54dff016c83367912eb055637fa50cAlan Cox
2080a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter	drm_modeset_unlock_all(dev);
20989c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
21089c78134cc54dff016c83367912eb055637fa50cAlan Cox}
21189c78134cc54dff016c83367912eb055637fa50cAlan Cox
21289c78134cc54dff016c83367912eb055637fa50cAlan Cox/**
21389c78134cc54dff016c83367912eb055637fa50cAlan Cox *	psb_restore_display_registers	-	restore lost register state
21489c78134cc54dff016c83367912eb055637fa50cAlan Cox *	@dev: our DRM device
21589c78134cc54dff016c83367912eb055637fa50cAlan Cox *
21689c78134cc54dff016c83367912eb055637fa50cAlan Cox *	Restore register state that was lost during suspend and resume.
21789c78134cc54dff016c83367912eb055637fa50cAlan Cox */
21889c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_restore_display_registers(struct drm_device *dev)
21989c78134cc54dff016c83367912eb055637fa50cAlan Cox{
22089c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
22189c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_crtc *crtc;
22289c78134cc54dff016c83367912eb055637fa50cAlan Cox	struct drm_connector *connector;
223c6265ff593467d472814aa9f16f89f6c1dc90a5dAlan Cox	struct psb_state *regs = &dev_priv->regs.psb;
22489c78134cc54dff016c83367912eb055637fa50cAlan Cox
22589c78134cc54dff016c83367912eb055637fa50cAlan Cox	/* Display arbitration + watermarks */
226648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPARB, DSPARB);
227648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW1, DSPFW1);
228648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW2, DSPFW2);
229648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW3, DSPFW3);
230648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW4, DSPFW4);
231648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW5, DSPFW5);
232648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveDSPFW6, DSPFW6);
233648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox	PSB_WVDC32(regs->saveCHICKENBIT, DSPCHICKENBIT);
23489c78134cc54dff016c83367912eb055637fa50cAlan Cox
23589c78134cc54dff016c83367912eb055637fa50cAlan Cox	/*make sure VGA plane is off. it initializes to on after reset!*/
23689c78134cc54dff016c83367912eb055637fa50cAlan Cox	PSB_WVDC32(0x80000000, VGACNTRL);
23789c78134cc54dff016c83367912eb055637fa50cAlan Cox
2380a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter	drm_modeset_lock_all(dev);
23989c78134cc54dff016c83367912eb055637fa50cAlan Cox	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
24089c78134cc54dff016c83367912eb055637fa50cAlan Cox		if (drm_helper_crtc_in_use(crtc))
24189c78134cc54dff016c83367912eb055637fa50cAlan Cox			crtc->funcs->restore(crtc);
24289c78134cc54dff016c83367912eb055637fa50cAlan Cox
24389c78134cc54dff016c83367912eb055637fa50cAlan Cox	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
2447beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox		if (connector->funcs->restore)
2457beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox			connector->funcs->restore(connector);
24689c78134cc54dff016c83367912eb055637fa50cAlan Cox
2470a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter	drm_modeset_unlock_all(dev);
24889c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
24989c78134cc54dff016c83367912eb055637fa50cAlan Cox}
25089c78134cc54dff016c83367912eb055637fa50cAlan Cox
25189c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_power_down(struct drm_device *dev)
25289c78134cc54dff016c83367912eb055637fa50cAlan Cox{
25389c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
25489c78134cc54dff016c83367912eb055637fa50cAlan Cox}
25589c78134cc54dff016c83367912eb055637fa50cAlan Cox
25689c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_power_up(struct drm_device *dev)
25789c78134cc54dff016c83367912eb055637fa50cAlan Cox{
25889c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
25989c78134cc54dff016c83367912eb055637fa50cAlan Cox}
26089c78134cc54dff016c83367912eb055637fa50cAlan Cox
2618512e0748729a49d9af6693f920c1b432796fa8dAlan Cox/* Poulsbo */
2628512e0748729a49d9af6693f920c1b432796fa8dAlan Coxstatic const struct psb_offset psb_regmap[2] = {
2638512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	{
2648512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.fp0 = FPA0,
2658512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.fp1 = FPA1,
2668512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.cntr = DSPACNTR,
2678512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.conf = PIPEACONF,
2688512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.src = PIPEASRC,
2698512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.dpll = DPLL_A,
2708512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.htotal = HTOTAL_A,
2718512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.hblank = HBLANK_A,
2728512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.hsync = HSYNC_A,
2738512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vtotal = VTOTAL_A,
2748512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vblank = VBLANK_A,
2758512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vsync = VSYNC_A,
2768512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.stride = DSPASTRIDE,
2778512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.size = DSPASIZE,
2788512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.pos = DSPAPOS,
2798512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.base = DSPABASE,
2808512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.surf = DSPASURF,
2818512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.addr = DSPABASE,
2828512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.status = PIPEASTAT,
2838512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.linoff = DSPALINOFF,
2848512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.tileoff = DSPATILEOFF,
2858512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.palette = PALETTE_A,
2868512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	},
2878512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	{
2888512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.fp0 = FPB0,
2898512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.fp1 = FPB1,
2908512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.cntr = DSPBCNTR,
2918512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.conf = PIPEBCONF,
2928512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.src = PIPEBSRC,
2938512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.dpll = DPLL_B,
2948512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.htotal = HTOTAL_B,
2958512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.hblank = HBLANK_B,
2968512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.hsync = HSYNC_B,
2978512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vtotal = VTOTAL_B,
2988512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vblank = VBLANK_B,
2998512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.vsync = VSYNC_B,
3008512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.stride = DSPBSTRIDE,
3018512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.size = DSPBSIZE,
3028512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.pos = DSPBPOS,
3038512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.base = DSPBBASE,
3048512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.surf = DSPBSURF,
3058512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.addr = DSPBBASE,
3068512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.status = PIPEBSTAT,
3078512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.linoff = DSPBLINOFF,
3088512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.tileoff = DSPBTILEOFF,
3098512e0748729a49d9af6693f920c1b432796fa8dAlan Cox		.palette = PALETTE_B,
3108512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	}
3118512e0748729a49d9af6693f920c1b432796fa8dAlan Cox};
3128512e0748729a49d9af6693f920c1b432796fa8dAlan Cox
31389c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_chip_setup(struct drm_device *dev)
31489c78134cc54dff016c83367912eb055637fa50cAlan Cox{
3158512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
3168512e0748729a49d9af6693f920c1b432796fa8dAlan Cox	dev_priv->regmap = psb_regmap;
317f35257a3fe267c4280bb2f69453ca1dd3bf48956Patrik Jakobsson	gma_get_core_freq(dev);
3185c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson	gma_intel_setup_gmbus(dev);
319d839ede47a56ff5f316c88391818488f8e5913afAlan Cox	psb_intel_opregion_init(dev);
32089c78134cc54dff016c83367912eb055637fa50cAlan Cox	psb_intel_init_bios(dev);
32189c78134cc54dff016c83367912eb055637fa50cAlan Cox	return 0;
32289c78134cc54dff016c83367912eb055637fa50cAlan Cox}
32389c78134cc54dff016c83367912eb055637fa50cAlan Cox
3245c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobssonstatic void psb_chip_teardown(struct drm_device *dev)
3255c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson{
3266607e024014e4920e8d3e43bcfeec0436d43d980Alan Cox	struct drm_psb_private *dev_priv = dev->dev_private;
3276607e024014e4920e8d3e43bcfeec0436d43d980Alan Cox	psb_lid_timer_takedown(dev_priv);
3285c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson	gma_intel_teardown_gmbus(dev);
3295c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson}
3305c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson
33189c78134cc54dff016c83367912eb055637fa50cAlan Coxconst struct psb_ops psb_chip_ops = {
33289c78134cc54dff016c83367912eb055637fa50cAlan Cox	.name = "Poulsbo",
33389c78134cc54dff016c83367912eb055637fa50cAlan Cox	.accel_2d = 1,
33489c78134cc54dff016c83367912eb055637fa50cAlan Cox	.pipes = 2,
33589c78134cc54dff016c83367912eb055637fa50cAlan Cox	.crtcs = 2,
336d235e64a4367ad3ff204309490c4325b4f89b25bAlan Cox	.hdmi_mask = (1 << 0),
337d235e64a4367ad3ff204309490c4325b4f89b25bAlan Cox	.lvds_mask = (1 << 1),
338cf8efd3afeff02fed2e2937ab3006618919bf65aPatrik Jakobsson	.sdvo_mask = (1 << 0),
339bc794829141f28e14fe7d0e07e35870bd9aee78cPatrik Jakobsson	.cursor_needs_phys = 1,
34089c78134cc54dff016c83367912eb055637fa50cAlan Cox	.sgx_offset = PSB_SGX_OFFSET,
34189c78134cc54dff016c83367912eb055637fa50cAlan Cox	.chip_setup = psb_chip_setup,
3425c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson	.chip_teardown = psb_chip_teardown,
34389c78134cc54dff016c83367912eb055637fa50cAlan Cox
34489c78134cc54dff016c83367912eb055637fa50cAlan Cox	.crtc_helper = &psb_intel_helper_funcs,
34589c78134cc54dff016c83367912eb055637fa50cAlan Cox	.crtc_funcs = &psb_intel_crtc_funcs,
3467f67c06721641df12ed68249218d1c2118517f78Patrik Jakobsson	.clock_funcs = &psb_clock_funcs,
34789c78134cc54dff016c83367912eb055637fa50cAlan Cox
34889c78134cc54dff016c83367912eb055637fa50cAlan Cox	.output_init = psb_output_init,
34989c78134cc54dff016c83367912eb055637fa50cAlan Cox
35089c78134cc54dff016c83367912eb055637fa50cAlan Cox#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
35189c78134cc54dff016c83367912eb055637fa50cAlan Cox	.backlight_init = psb_backlight_init,
35289c78134cc54dff016c83367912eb055637fa50cAlan Cox#endif
35389c78134cc54dff016c83367912eb055637fa50cAlan Cox
35489c78134cc54dff016c83367912eb055637fa50cAlan Cox	.init_pm = psb_init_pm,
35589c78134cc54dff016c83367912eb055637fa50cAlan Cox	.save_regs = psb_save_display_registers,
35689c78134cc54dff016c83367912eb055637fa50cAlan Cox	.restore_regs = psb_restore_display_registers,
35789c78134cc54dff016c83367912eb055637fa50cAlan Cox	.power_down = psb_power_down,
35889c78134cc54dff016c83367912eb055637fa50cAlan Cox	.power_up = psb_power_up,
35989c78134cc54dff016c83367912eb055637fa50cAlan Cox};
36089c78134cc54dff016c83367912eb055637fa50cAlan Cox
361