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