drm/linux-core/i915_pm.c

168 lines
4.4 KiB
C
Raw Normal View History

/* i915_pm.c -- Power management support for the i915 -*- linux-c -*-
*/
/**************************************************************************
*
2005-06-06 03:18:44 -06:00
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
2005-06-06 03:18:44 -06:00
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#define __NO_VERSION__
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
#include "i915_drv.h"
/**
* Set DPMS mode.
*/
static int i915_set_dpms(drm_device_t *dev, int mode)
{
drm_i915_private_t *dev_priv =
(drm_i915_private_t *)dev->dev_private;
unsigned sr01, adpa, ppcr, dvob, dvoc, lvds;
DRM_DEBUG("%s mode=%d\n", __FUNCTION__, mode);
if (!dev_priv) return 0;
I915_WRITE( SRX_INDEX, SR01 );
sr01 = I915_READ( SRX_DATA );
adpa = I915_READ( ADPA );
ppcr = I915_READ( PPCR );
dvoc = I915_READ( DVOC );
dvob = I915_READ( DVOB );
lvds = I915_READ( LVDS );
switch(mode) {
case 0:
/* On */
sr01 = dev_priv->sr01;
adpa = dev_priv->adpa;
#if 0
I915_WRITE( LVDS, lvds | LVDS_ON ); /* Power on LVDS */
#endif
I915_WRITE( PPCR, dev_priv->ppcr ); /* Power up panel */
I915_WRITE( DVOC, dev_priv->dvoc );
I915_WRITE( DVOB, dev_priv->dvob );
break;
case 1:
/* Standby */
sr01 |= SR01_SCREEN_OFF;
adpa = (adpa & ADPA_DPMS_MASK) | ADPA_DPMS_STANDBY;
I915_WRITE( PPCR, ppcr & ~PPCR_ON ); /* Power off panel*/
#if 0
I915_WRITE( LVDS, lvds & ~LVDS_ON ); /* Power off LVDS */
#endif
I915_WRITE( DVOC, dvoc & ~DVOC_ON );
I915_WRITE( DVOB, dvob & ~DVOB_ON );
break;
case 2:
/* Suspend */
sr01 |= SR01_SCREEN_OFF;
adpa = (adpa & ADPA_DPMS_MASK) | ADPA_DPMS_SUSPEND;
I915_WRITE( PPCR, ppcr & ~PPCR_ON ); /* Power off panel*/
#if 0
I915_WRITE( LVDS, lvds & ~LVDS_ON ); /* Power off LVDS */
#endif
I915_WRITE( DVOC, dvoc & ~DVOC_ON );
I915_WRITE( DVOB, dvob & ~DVOB_ON );
break;
case 3:
/* Off */
sr01 |= SR01_SCREEN_OFF;
adpa = (adpa & ADPA_DPMS_MASK) | ADPA_DPMS_OFF;
I915_WRITE( PPCR, ppcr & ~PPCR_ON ); /* Power off panel*/
#if 0
I915_WRITE( LVDS, lvds & ~LVDS_ON ); /* Power off LVDS */
#endif
I915_WRITE( DVOC, dvoc & ~DVOC_ON );
I915_WRITE( DVOB, dvob & ~DVOB_ON );
break;
}
I915_WRITE( SRX_DATA, sr01 );
I915_WRITE( ADPA, adpa );
return 0;
}
int i915_suspend( struct pci_dev *pdev, unsigned state )
{
drm_device_t *dev = (drm_device_t *)pci_get_drvdata(pdev);
drm_i915_private_t *dev_priv =
(drm_i915_private_t *)dev->dev_private;
DRM_DEBUG("%s state=%d\n", __FUNCTION__, state);
if (!dev_priv) return 0;
2005-06-27 05:41:40 -06:00
/* Save state for power up later */
if (state != 0) {
I915_WRITE( SRX_INDEX, SR01 );
dev_priv->sr01 = I915_READ( SRX_DATA );
dev_priv->dvoc = I915_READ( DVOC );
dev_priv->dvob = I915_READ( DVOB );
dev_priv->lvds = I915_READ( LVDS );
dev_priv->adpa = I915_READ( ADPA );
dev_priv->ppcr = I915_READ( PPCR );
}
switch(state) {
case 0:
/* D0: set DPMS mode on */
i915_set_dpms(dev, 0);
break;
case 1:
/* D1: set DPMS mode standby */
i915_set_dpms(dev, 1);
break;
case 2:
/* D2: set DPMS mode suspend */
i915_set_dpms(dev, 2);
break;
case 3:
/* D3: set DPMS mode off */
i915_set_dpms(dev, 3);
break;
}
return 0;
}
int i915_resume( struct pci_dev *pdev )
{
drm_device_t *dev = (drm_device_t *)pci_get_drvdata(pdev);
/* D0: set DPMS mode on */
i915_set_dpms(dev, 0);
return 0;
}