psb_device.c revision cf8efd3afeff02fed2e2937ab3006618919bf65a
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" 2989c78134cc54dff016c83367912eb055637fa50cAlan Cox 3089c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_output_init(struct drm_device *dev) 3189c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 3289c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 3389c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_intel_lvds_init(dev, &dev_priv->mode_dev); 3489c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_intel_sdvo_init(dev, SDVOB); 3589c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 3689c78134cc54dff016c83367912eb055637fa50cAlan Cox} 3789c78134cc54dff016c83367912eb055637fa50cAlan Cox 3889c78134cc54dff016c83367912eb055637fa50cAlan Cox#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 3989c78134cc54dff016c83367912eb055637fa50cAlan Cox 4089c78134cc54dff016c83367912eb055637fa50cAlan Cox/* 4189c78134cc54dff016c83367912eb055637fa50cAlan Cox * Poulsbo Backlight Interfaces 4289c78134cc54dff016c83367912eb055637fa50cAlan Cox */ 4389c78134cc54dff016c83367912eb055637fa50cAlan Cox 4489c78134cc54dff016c83367912eb055637fa50cAlan Cox#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ 4589c78134cc54dff016c83367912eb055637fa50cAlan Cox#define BLC_PWM_FREQ_CALC_CONSTANT 32 4689c78134cc54dff016c83367912eb055637fa50cAlan Cox#define MHz 1000000 4789c78134cc54dff016c83367912eb055637fa50cAlan Cox 4889c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_PWM_PRECISION_FACTOR 10 4989c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE 5089c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 5189c78134cc54dff016c83367912eb055637fa50cAlan Cox 5289c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) 5389c78134cc54dff016c83367912eb055637fa50cAlan Cox#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) 5489c78134cc54dff016c83367912eb055637fa50cAlan Cox 5589c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_brightness; 5689c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic struct backlight_device *psb_backlight_device; 5789c78134cc54dff016c83367912eb055637fa50cAlan Cox 5889c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_get_brightness(struct backlight_device *bd) 5989c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 6089c78134cc54dff016c83367912eb055637fa50cAlan Cox /* return locally cached var instead of HW read (due to DPST etc.) */ 6189c78134cc54dff016c83367912eb055637fa50cAlan Cox /* FIXME: ideally return actual value in case firmware fiddled with 6289c78134cc54dff016c83367912eb055637fa50cAlan Cox it */ 6389c78134cc54dff016c83367912eb055637fa50cAlan Cox return psb_brightness; 6489c78134cc54dff016c83367912eb055637fa50cAlan Cox} 6589c78134cc54dff016c83367912eb055637fa50cAlan Cox 6689c78134cc54dff016c83367912eb055637fa50cAlan Cox 6789c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_backlight_setup(struct drm_device *dev) 6889c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 6989c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 7089c78134cc54dff016c83367912eb055637fa50cAlan Cox unsigned long core_clock; 7189c78134cc54dff016c83367912eb055637fa50cAlan Cox /* u32 bl_max_freq; */ 7289c78134cc54dff016c83367912eb055637fa50cAlan Cox /* unsigned long value; */ 7389c78134cc54dff016c83367912eb055637fa50cAlan Cox u16 bl_max_freq; 7489c78134cc54dff016c83367912eb055637fa50cAlan Cox uint32_t value; 7589c78134cc54dff016c83367912eb055637fa50cAlan Cox uint32_t blc_pwm_precision_factor; 7689c78134cc54dff016c83367912eb055637fa50cAlan Cox 7789c78134cc54dff016c83367912eb055637fa50cAlan Cox /* get bl_max_freq and pol from dev_priv*/ 7889c78134cc54dff016c83367912eb055637fa50cAlan Cox if (!dev_priv->lvds_bl) { 7989c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_err(dev->dev, "Has no valid LVDS backlight info\n"); 8089c78134cc54dff016c83367912eb055637fa50cAlan Cox return -ENOENT; 8189c78134cc54dff016c83367912eb055637fa50cAlan Cox } 8289c78134cc54dff016c83367912eb055637fa50cAlan Cox bl_max_freq = dev_priv->lvds_bl->freq; 8389c78134cc54dff016c83367912eb055637fa50cAlan Cox blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; 8489c78134cc54dff016c83367912eb055637fa50cAlan Cox 8589c78134cc54dff016c83367912eb055637fa50cAlan Cox core_clock = dev_priv->core_freq; 8689c78134cc54dff016c83367912eb055637fa50cAlan Cox 8789c78134cc54dff016c83367912eb055637fa50cAlan Cox value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; 8889c78134cc54dff016c83367912eb055637fa50cAlan Cox value *= blc_pwm_precision_factor; 8989c78134cc54dff016c83367912eb055637fa50cAlan Cox value /= bl_max_freq; 9089c78134cc54dff016c83367912eb055637fa50cAlan Cox value /= blc_pwm_precision_factor; 9189c78134cc54dff016c83367912eb055637fa50cAlan Cox 9289c78134cc54dff016c83367912eb055637fa50cAlan Cox if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || 9389c78134cc54dff016c83367912eb055637fa50cAlan Cox value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) 9489c78134cc54dff016c83367912eb055637fa50cAlan Cox return -ERANGE; 9589c78134cc54dff016c83367912eb055637fa50cAlan Cox else { 9689c78134cc54dff016c83367912eb055637fa50cAlan Cox value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; 9789c78134cc54dff016c83367912eb055637fa50cAlan Cox REG_WRITE(BLC_PWM_CTL, 9889c78134cc54dff016c83367912eb055637fa50cAlan Cox (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value)); 9989c78134cc54dff016c83367912eb055637fa50cAlan Cox } 10089c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 10189c78134cc54dff016c83367912eb055637fa50cAlan Cox} 10289c78134cc54dff016c83367912eb055637fa50cAlan Cox 10389c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_set_brightness(struct backlight_device *bd) 10489c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 10589c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_device *dev = bl_get_data(psb_backlight_device); 10689c78134cc54dff016c83367912eb055637fa50cAlan Cox int level = bd->props.brightness; 10789c78134cc54dff016c83367912eb055637fa50cAlan Cox 10889c78134cc54dff016c83367912eb055637fa50cAlan Cox /* Percentage 1-100% being valid */ 10989c78134cc54dff016c83367912eb055637fa50cAlan Cox if (level < 1) 11089c78134cc54dff016c83367912eb055637fa50cAlan Cox level = 1; 11189c78134cc54dff016c83367912eb055637fa50cAlan Cox 11289c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_intel_lvds_set_brightness(dev, level); 11389c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_brightness = level; 11489c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 11589c78134cc54dff016c83367912eb055637fa50cAlan Cox} 11689c78134cc54dff016c83367912eb055637fa50cAlan Cox 11789c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic const struct backlight_ops psb_ops = { 11889c78134cc54dff016c83367912eb055637fa50cAlan Cox .get_brightness = psb_get_brightness, 11989c78134cc54dff016c83367912eb055637fa50cAlan Cox .update_status = psb_set_brightness, 12089c78134cc54dff016c83367912eb055637fa50cAlan Cox}; 12189c78134cc54dff016c83367912eb055637fa50cAlan Cox 12289c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_backlight_init(struct drm_device *dev) 12389c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 12489c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 12589c78134cc54dff016c83367912eb055637fa50cAlan Cox int ret; 12689c78134cc54dff016c83367912eb055637fa50cAlan Cox struct backlight_properties props; 12789c78134cc54dff016c83367912eb055637fa50cAlan Cox 12889c78134cc54dff016c83367912eb055637fa50cAlan Cox memset(&props, 0, sizeof(struct backlight_properties)); 12989c78134cc54dff016c83367912eb055637fa50cAlan Cox props.max_brightness = 100; 13089c78134cc54dff016c83367912eb055637fa50cAlan Cox props.type = BACKLIGHT_PLATFORM; 13189c78134cc54dff016c83367912eb055637fa50cAlan Cox 13289c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_backlight_device = backlight_device_register("psb-bl", 13389c78134cc54dff016c83367912eb055637fa50cAlan Cox NULL, (void *)dev, &psb_ops, &props); 13489c78134cc54dff016c83367912eb055637fa50cAlan Cox if (IS_ERR(psb_backlight_device)) 13589c78134cc54dff016c83367912eb055637fa50cAlan Cox return PTR_ERR(psb_backlight_device); 13689c78134cc54dff016c83367912eb055637fa50cAlan Cox 13789c78134cc54dff016c83367912eb055637fa50cAlan Cox ret = psb_backlight_setup(dev); 13889c78134cc54dff016c83367912eb055637fa50cAlan Cox if (ret < 0) { 13989c78134cc54dff016c83367912eb055637fa50cAlan Cox backlight_device_unregister(psb_backlight_device); 14089c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_backlight_device = NULL; 14189c78134cc54dff016c83367912eb055637fa50cAlan Cox return ret; 14289c78134cc54dff016c83367912eb055637fa50cAlan Cox } 14389c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_backlight_device->props.brightness = 100; 14489c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_backlight_device->props.max_brightness = 100; 14589c78134cc54dff016c83367912eb055637fa50cAlan Cox backlight_update_status(psb_backlight_device); 14689c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->backlight_device = psb_backlight_device; 147f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox 148f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox /* This must occur after the backlight is properly initialised */ 149f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox psb_lid_timer_init(dev_priv); 150f507598b06ab00fb46495ccdeeb3ef9c1dc43deeAlan Cox 15189c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 15289c78134cc54dff016c83367912eb055637fa50cAlan Cox} 15389c78134cc54dff016c83367912eb055637fa50cAlan Cox 15489c78134cc54dff016c83367912eb055637fa50cAlan Cox#endif 15589c78134cc54dff016c83367912eb055637fa50cAlan Cox 15689c78134cc54dff016c83367912eb055637fa50cAlan Cox/* 15789c78134cc54dff016c83367912eb055637fa50cAlan Cox * Provide the Poulsbo specific chip logic and low level methods 15889c78134cc54dff016c83367912eb055637fa50cAlan Cox * for power management 15989c78134cc54dff016c83367912eb055637fa50cAlan Cox */ 16089c78134cc54dff016c83367912eb055637fa50cAlan Cox 16189c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic void psb_init_pm(struct drm_device *dev) 16289c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 16389c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 16489c78134cc54dff016c83367912eb055637fa50cAlan Cox 16589c78134cc54dff016c83367912eb055637fa50cAlan Cox u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); 16689c78134cc54dff016c83367912eb055637fa50cAlan Cox gating &= ~3; /* Disable 2D clock gating */ 16789c78134cc54dff016c83367912eb055637fa50cAlan Cox gating |= 1; 16889c78134cc54dff016c83367912eb055637fa50cAlan Cox PSB_WSGX32(gating, PSB_CR_CLKGATECTL); 16989c78134cc54dff016c83367912eb055637fa50cAlan Cox PSB_RSGX32(PSB_CR_CLKGATECTL); 17089c78134cc54dff016c83367912eb055637fa50cAlan Cox} 17189c78134cc54dff016c83367912eb055637fa50cAlan Cox 17289c78134cc54dff016c83367912eb055637fa50cAlan Cox/** 17389c78134cc54dff016c83367912eb055637fa50cAlan Cox * psb_save_display_registers - save registers lost on suspend 17489c78134cc54dff016c83367912eb055637fa50cAlan Cox * @dev: our DRM device 17589c78134cc54dff016c83367912eb055637fa50cAlan Cox * 17689c78134cc54dff016c83367912eb055637fa50cAlan Cox * Save the state we need in order to be able to restore the interface 17789c78134cc54dff016c83367912eb055637fa50cAlan Cox * upon resume from suspend 17889c78134cc54dff016c83367912eb055637fa50cAlan Cox */ 17989c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_save_display_registers(struct drm_device *dev) 18089c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 18189c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 18289c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_crtc *crtc; 18389c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_connector *connector; 184c6265ff593467d472814aa9f16f89f6c1dc90a5dAlan Cox struct psb_state *regs = &dev_priv->regs.psb; 18589c78134cc54dff016c83367912eb055637fa50cAlan Cox 18689c78134cc54dff016c83367912eb055637fa50cAlan Cox /* Display arbitration control + watermarks */ 187648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPARB = PSB_RVDC32(DSPARB); 188648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW1 = PSB_RVDC32(DSPFW1); 189648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW2 = PSB_RVDC32(DSPFW2); 190648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW3 = PSB_RVDC32(DSPFW3); 191648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW4 = PSB_RVDC32(DSPFW4); 192648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW5 = PSB_RVDC32(DSPFW5); 193648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveDSPFW6 = PSB_RVDC32(DSPFW6); 194648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); 19589c78134cc54dff016c83367912eb055637fa50cAlan Cox 19689c78134cc54dff016c83367912eb055637fa50cAlan Cox /* Save crtc and output state */ 1970a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter drm_modeset_lock_all(dev); 19889c78134cc54dff016c83367912eb055637fa50cAlan Cox list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 19989c78134cc54dff016c83367912eb055637fa50cAlan Cox if (drm_helper_crtc_in_use(crtc)) 20089c78134cc54dff016c83367912eb055637fa50cAlan Cox crtc->funcs->save(crtc); 20189c78134cc54dff016c83367912eb055637fa50cAlan Cox } 20289c78134cc54dff016c83367912eb055637fa50cAlan Cox 20389c78134cc54dff016c83367912eb055637fa50cAlan Cox list_for_each_entry(connector, &dev->mode_config.connector_list, head) 2047beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox if (connector->funcs->save) 2057beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox connector->funcs->save(connector); 20689c78134cc54dff016c83367912eb055637fa50cAlan Cox 2070a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter drm_modeset_unlock_all(dev); 20889c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 20989c78134cc54dff016c83367912eb055637fa50cAlan Cox} 21089c78134cc54dff016c83367912eb055637fa50cAlan Cox 21189c78134cc54dff016c83367912eb055637fa50cAlan Cox/** 21289c78134cc54dff016c83367912eb055637fa50cAlan Cox * psb_restore_display_registers - restore lost register state 21389c78134cc54dff016c83367912eb055637fa50cAlan Cox * @dev: our DRM device 21489c78134cc54dff016c83367912eb055637fa50cAlan Cox * 21589c78134cc54dff016c83367912eb055637fa50cAlan Cox * Restore register state that was lost during suspend and resume. 21689c78134cc54dff016c83367912eb055637fa50cAlan Cox */ 21789c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_restore_display_registers(struct drm_device *dev) 21889c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 21989c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 22089c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_crtc *crtc; 22189c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_connector *connector; 222c6265ff593467d472814aa9f16f89f6c1dc90a5dAlan Cox struct psb_state *regs = &dev_priv->regs.psb; 22389c78134cc54dff016c83367912eb055637fa50cAlan Cox 22489c78134cc54dff016c83367912eb055637fa50cAlan Cox /* Display arbitration + watermarks */ 225648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPARB, DSPARB); 226648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW1, DSPFW1); 227648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW2, DSPFW2); 228648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW3, DSPFW3); 229648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW4, DSPFW4); 230648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW5, DSPFW5); 231648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveDSPFW6, DSPFW6); 232648a8e342c5a754bdc62f003d3af90507c1abfdeAlan Cox PSB_WVDC32(regs->saveCHICKENBIT, DSPCHICKENBIT); 23389c78134cc54dff016c83367912eb055637fa50cAlan Cox 23489c78134cc54dff016c83367912eb055637fa50cAlan Cox /*make sure VGA plane is off. it initializes to on after reset!*/ 23589c78134cc54dff016c83367912eb055637fa50cAlan Cox PSB_WVDC32(0x80000000, VGACNTRL); 23689c78134cc54dff016c83367912eb055637fa50cAlan Cox 2370a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter drm_modeset_lock_all(dev); 23889c78134cc54dff016c83367912eb055637fa50cAlan Cox list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 23989c78134cc54dff016c83367912eb055637fa50cAlan Cox if (drm_helper_crtc_in_use(crtc)) 24089c78134cc54dff016c83367912eb055637fa50cAlan Cox crtc->funcs->restore(crtc); 24189c78134cc54dff016c83367912eb055637fa50cAlan Cox 24289c78134cc54dff016c83367912eb055637fa50cAlan Cox list_for_each_entry(connector, &dev->mode_config.connector_list, head) 2437beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox if (connector->funcs->restore) 2447beff62ee39d3ccf088bb77f61a63037f714d235Alan Cox connector->funcs->restore(connector); 24589c78134cc54dff016c83367912eb055637fa50cAlan Cox 2460a819515fc346b4e79d6e3fc01d837a660452c74Daniel Vetter drm_modeset_unlock_all(dev); 24789c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 24889c78134cc54dff016c83367912eb055637fa50cAlan Cox} 24989c78134cc54dff016c83367912eb055637fa50cAlan Cox 25089c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_power_down(struct drm_device *dev) 25189c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 25289c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 25389c78134cc54dff016c83367912eb055637fa50cAlan Cox} 25489c78134cc54dff016c83367912eb055637fa50cAlan Cox 25589c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_power_up(struct drm_device *dev) 25689c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 25789c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 25889c78134cc54dff016c83367912eb055637fa50cAlan Cox} 25989c78134cc54dff016c83367912eb055637fa50cAlan Cox 26089c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic void psb_get_core_freq(struct drm_device *dev) 26189c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 26289c78134cc54dff016c83367912eb055637fa50cAlan Cox uint32_t clock; 26389c78134cc54dff016c83367912eb055637fa50cAlan Cox struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); 26489c78134cc54dff016c83367912eb055637fa50cAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 26589c78134cc54dff016c83367912eb055637fa50cAlan Cox 26689c78134cc54dff016c83367912eb055637fa50cAlan Cox /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ 26789c78134cc54dff016c83367912eb055637fa50cAlan Cox /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ 26889c78134cc54dff016c83367912eb055637fa50cAlan Cox 26989c78134cc54dff016c83367912eb055637fa50cAlan Cox pci_write_config_dword(pci_root, 0xD0, 0xD0050300); 27089c78134cc54dff016c83367912eb055637fa50cAlan Cox pci_read_config_dword(pci_root, 0xD4, &clock); 27189c78134cc54dff016c83367912eb055637fa50cAlan Cox pci_dev_put(pci_root); 27289c78134cc54dff016c83367912eb055637fa50cAlan Cox 27389c78134cc54dff016c83367912eb055637fa50cAlan Cox switch (clock & 0x07) { 27489c78134cc54dff016c83367912eb055637fa50cAlan Cox case 0: 27589c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 100; 27689c78134cc54dff016c83367912eb055637fa50cAlan Cox break; 27789c78134cc54dff016c83367912eb055637fa50cAlan Cox case 1: 27889c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 133; 27989c78134cc54dff016c83367912eb055637fa50cAlan Cox break; 28089c78134cc54dff016c83367912eb055637fa50cAlan Cox case 2: 28189c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 150; 28289c78134cc54dff016c83367912eb055637fa50cAlan Cox break; 28389c78134cc54dff016c83367912eb055637fa50cAlan Cox case 3: 28489c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 178; 28589c78134cc54dff016c83367912eb055637fa50cAlan Cox break; 28689c78134cc54dff016c83367912eb055637fa50cAlan Cox case 4: 28789c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 200; 28889c78134cc54dff016c83367912eb055637fa50cAlan Cox break; 28989c78134cc54dff016c83367912eb055637fa50cAlan Cox case 5: 29089c78134cc54dff016c83367912eb055637fa50cAlan Cox case 6: 29189c78134cc54dff016c83367912eb055637fa50cAlan Cox case 7: 29289c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 266; 2936f314ebbaa2667d67a7206ba78f28e46cf47eda5Alan Cox break; 29489c78134cc54dff016c83367912eb055637fa50cAlan Cox default: 29589c78134cc54dff016c83367912eb055637fa50cAlan Cox dev_priv->core_freq = 0; 29689c78134cc54dff016c83367912eb055637fa50cAlan Cox } 29789c78134cc54dff016c83367912eb055637fa50cAlan Cox} 29889c78134cc54dff016c83367912eb055637fa50cAlan Cox 2998512e0748729a49d9af6693f920c1b432796fa8dAlan Cox/* Poulsbo */ 3008512e0748729a49d9af6693f920c1b432796fa8dAlan Coxstatic const struct psb_offset psb_regmap[2] = { 3018512e0748729a49d9af6693f920c1b432796fa8dAlan Cox { 3028512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .fp0 = FPA0, 3038512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .fp1 = FPA1, 3048512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .cntr = DSPACNTR, 3058512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .conf = PIPEACONF, 3068512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .src = PIPEASRC, 3078512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .dpll = DPLL_A, 3088512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .htotal = HTOTAL_A, 3098512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .hblank = HBLANK_A, 3108512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .hsync = HSYNC_A, 3118512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vtotal = VTOTAL_A, 3128512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vblank = VBLANK_A, 3138512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vsync = VSYNC_A, 3148512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .stride = DSPASTRIDE, 3158512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .size = DSPASIZE, 3168512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .pos = DSPAPOS, 3178512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .base = DSPABASE, 3188512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .surf = DSPASURF, 3198512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .addr = DSPABASE, 3208512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .status = PIPEASTAT, 3218512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .linoff = DSPALINOFF, 3228512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .tileoff = DSPATILEOFF, 3238512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .palette = PALETTE_A, 3248512e0748729a49d9af6693f920c1b432796fa8dAlan Cox }, 3258512e0748729a49d9af6693f920c1b432796fa8dAlan Cox { 3268512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .fp0 = FPB0, 3278512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .fp1 = FPB1, 3288512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .cntr = DSPBCNTR, 3298512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .conf = PIPEBCONF, 3308512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .src = PIPEBSRC, 3318512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .dpll = DPLL_B, 3328512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .htotal = HTOTAL_B, 3338512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .hblank = HBLANK_B, 3348512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .hsync = HSYNC_B, 3358512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vtotal = VTOTAL_B, 3368512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vblank = VBLANK_B, 3378512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .vsync = VSYNC_B, 3388512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .stride = DSPBSTRIDE, 3398512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .size = DSPBSIZE, 3408512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .pos = DSPBPOS, 3418512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .base = DSPBBASE, 3428512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .surf = DSPBSURF, 3438512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .addr = DSPBBASE, 3448512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .status = PIPEBSTAT, 3458512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .linoff = DSPBLINOFF, 3468512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .tileoff = DSPBTILEOFF, 3478512e0748729a49d9af6693f920c1b432796fa8dAlan Cox .palette = PALETTE_B, 3488512e0748729a49d9af6693f920c1b432796fa8dAlan Cox } 3498512e0748729a49d9af6693f920c1b432796fa8dAlan Cox}; 3508512e0748729a49d9af6693f920c1b432796fa8dAlan Cox 35189c78134cc54dff016c83367912eb055637fa50cAlan Coxstatic int psb_chip_setup(struct drm_device *dev) 35289c78134cc54dff016c83367912eb055637fa50cAlan Cox{ 3538512e0748729a49d9af6693f920c1b432796fa8dAlan Cox struct drm_psb_private *dev_priv = dev->dev_private; 3548512e0748729a49d9af6693f920c1b432796fa8dAlan Cox dev_priv->regmap = psb_regmap; 35589c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_get_core_freq(dev); 3565c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson gma_intel_setup_gmbus(dev); 357d839ede47a56ff5f316c88391818488f8e5913afAlan Cox psb_intel_opregion_init(dev); 35889c78134cc54dff016c83367912eb055637fa50cAlan Cox psb_intel_init_bios(dev); 35989c78134cc54dff016c83367912eb055637fa50cAlan Cox return 0; 36089c78134cc54dff016c83367912eb055637fa50cAlan Cox} 36189c78134cc54dff016c83367912eb055637fa50cAlan Cox 3625c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobssonstatic void psb_chip_teardown(struct drm_device *dev) 3635c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson{ 3646607e024014e4920e8d3e43bcfeec0436d43d980Alan Cox struct drm_psb_private *dev_priv = dev->dev_private; 3656607e024014e4920e8d3e43bcfeec0436d43d980Alan Cox psb_lid_timer_takedown(dev_priv); 3665c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson gma_intel_teardown_gmbus(dev); 3675c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson} 3685c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson 36989c78134cc54dff016c83367912eb055637fa50cAlan Coxconst struct psb_ops psb_chip_ops = { 37089c78134cc54dff016c83367912eb055637fa50cAlan Cox .name = "Poulsbo", 37189c78134cc54dff016c83367912eb055637fa50cAlan Cox .accel_2d = 1, 37289c78134cc54dff016c83367912eb055637fa50cAlan Cox .pipes = 2, 37389c78134cc54dff016c83367912eb055637fa50cAlan Cox .crtcs = 2, 374d235e64a4367ad3ff204309490c4325b4f89b25bAlan Cox .hdmi_mask = (1 << 0), 375d235e64a4367ad3ff204309490c4325b4f89b25bAlan Cox .lvds_mask = (1 << 1), 376cf8efd3afeff02fed2e2937ab3006618919bf65aPatrik Jakobsson .sdvo_mask = (1 << 0), 377bc794829141f28e14fe7d0e07e35870bd9aee78cPatrik Jakobsson .cursor_needs_phys = 1, 37889c78134cc54dff016c83367912eb055637fa50cAlan Cox .sgx_offset = PSB_SGX_OFFSET, 37989c78134cc54dff016c83367912eb055637fa50cAlan Cox .chip_setup = psb_chip_setup, 3805c0c1d50d7ba7a678b7d6e2c4f2ff31edafb1067Patrik Jakobsson .chip_teardown = psb_chip_teardown, 38189c78134cc54dff016c83367912eb055637fa50cAlan Cox 38289c78134cc54dff016c83367912eb055637fa50cAlan Cox .crtc_helper = &psb_intel_helper_funcs, 38389c78134cc54dff016c83367912eb055637fa50cAlan Cox .crtc_funcs = &psb_intel_crtc_funcs, 3847f67c06721641df12ed68249218d1c2118517f78Patrik Jakobsson .clock_funcs = &psb_clock_funcs, 38589c78134cc54dff016c83367912eb055637fa50cAlan Cox 38689c78134cc54dff016c83367912eb055637fa50cAlan Cox .output_init = psb_output_init, 38789c78134cc54dff016c83367912eb055637fa50cAlan Cox 38889c78134cc54dff016c83367912eb055637fa50cAlan Cox#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 38989c78134cc54dff016c83367912eb055637fa50cAlan Cox .backlight_init = psb_backlight_init, 39089c78134cc54dff016c83367912eb055637fa50cAlan Cox#endif 39189c78134cc54dff016c83367912eb055637fa50cAlan Cox 39289c78134cc54dff016c83367912eb055637fa50cAlan Cox .init_pm = psb_init_pm, 39389c78134cc54dff016c83367912eb055637fa50cAlan Cox .save_regs = psb_save_display_registers, 39489c78134cc54dff016c83367912eb055637fa50cAlan Cox .restore_regs = psb_restore_display_registers, 39589c78134cc54dff016c83367912eb055637fa50cAlan Cox .power_down = psb_power_down, 39689c78134cc54dff016c83367912eb055637fa50cAlan Cox .power_up = psb_power_up, 39789c78134cc54dff016c83367912eb055637fa50cAlan Cox}; 39889c78134cc54dff016c83367912eb055637fa50cAlan Cox 399