2011-11-03 18:22:26 +00:00
/**************************************************************************
* 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 <linux/backlight.h>
2019-05-19 21:55:26 +02:00
# include <linux/delay.h>
2011-11-03 18:22:26 +00:00
# include <linux/dmi.h>
2019-05-19 21:55:26 +02:00
# include <linux/module.h>
2019-05-19 21:55:22 +02:00
2013-10-17 15:35:27 -07:00
# include <asm/intel-mid.h>
2011-11-03 18:22:26 +00:00
# include <asm/intel_scu_ipc.h>
2019-05-19 21:55:26 +02:00
# include <drm/drm.h>
2011-11-29 22:27:45 +00:00
# include "intel_bios.h"
2019-05-19 21:55:26 +02:00
# include "mid_bios.h"
# include "psb_drv.h"
# include "psb_intel_reg.h"
# include "psb_reg.h"
2011-11-03 18:22:26 +00:00
static int oaktrail_output_init ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
if ( dev_priv - > iLVDS_enable )
oaktrail_lvds_init ( dev , & dev_priv - > mode_dev ) ;
else
dev_err ( dev - > dev , " DSI is not supported \n " ) ;
if ( dev_priv - > hdmi_priv )
oaktrail_hdmi_init ( dev , & dev_priv - > mode_dev ) ;
2013-11-08 16:14:08 +01:00
psb_intel_sdvo_init ( dev , SDVOB ) ;
2011-11-03 18:22:26 +00:00
return 0 ;
}
/*
* Provide the low level interfaces for the Moorestown backlight
*/
# 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 BLC_ADJUSTMENT_MAX 100
static struct backlight_device * oaktrail_backlight_device ;
static int oaktrail_brightness ;
static int oaktrail_set_brightness ( struct backlight_device * bd )
{
struct drm_device * dev = bl_get_data ( oaktrail_backlight_device ) ;
struct drm_psb_private * dev_priv = dev - > dev_private ;
int level = bd - > props . brightness ;
u32 blc_pwm_ctl ;
u32 max_pwm_blc ;
/* Percentage 1-100% being valid */
if ( level < 1 )
level = 1 ;
if ( gma_power_begin ( dev , 0 ) ) {
/* Calculate and set the brightness value */
max_pwm_blc = REG_READ ( BLC_PWM_CTL ) > > 16 ;
blc_pwm_ctl = level * max_pwm_blc / 100 ;
/* Adjust the backlight level with the percent in
* dev_priv - > blc_adj1 ;
*/
blc_pwm_ctl = blc_pwm_ctl * dev_priv - > blc_adj1 ;
blc_pwm_ctl = blc_pwm_ctl / 100 ;
/* Adjust the backlight level with the percent in
* dev_priv - > blc_adj2 ;
*/
blc_pwm_ctl = blc_pwm_ctl * dev_priv - > blc_adj2 ;
blc_pwm_ctl = blc_pwm_ctl / 100 ;
/* force PWM bit on */
REG_WRITE ( BLC_PWM_CTL2 , ( 0x80000000 | REG_READ ( BLC_PWM_CTL2 ) ) ) ;
REG_WRITE ( BLC_PWM_CTL , ( max_pwm_blc < < 16 ) | blc_pwm_ctl ) ;
gma_power_end ( dev ) ;
}
oaktrail_brightness = level ;
return 0 ;
}
static int oaktrail_get_brightness ( struct backlight_device * bd )
{
/* return locally cached var instead of HW read (due to DPST etc.) */
/* FIXME: ideally return actual value in case firmware fiddled with
it */
return oaktrail_brightness ;
}
static int device_backlight_init ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
unsigned long core_clock ;
u16 bl_max_freq ;
uint32_t value ;
uint32_t blc_pwm_precision_factor ;
dev_priv - > blc_adj1 = BLC_ADJUSTMENT_MAX ;
dev_priv - > blc_adj2 = BLC_ADJUSTMENT_MAX ;
bl_max_freq = 256 ;
/* this needs to be set elsewhere */
blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR ;
core_clock = dev_priv - > core_freq ;
value = ( core_clock * MHz ) / BLC_PWM_FREQ_CALC_CONSTANT ;
value * = blc_pwm_precision_factor ;
value / = bl_max_freq ;
value / = blc_pwm_precision_factor ;
if ( value > ( unsigned long long ) MRST_BLC_MAX_PWM_REG_FREQ )
return - ERANGE ;
if ( gma_power_begin ( dev , false ) ) {
REG_WRITE ( BLC_PWM_CTL2 , ( 0x80000000 | REG_READ ( BLC_PWM_CTL2 ) ) ) ;
REG_WRITE ( BLC_PWM_CTL , value | ( value < < 16 ) ) ;
gma_power_end ( dev ) ;
}
return 0 ;
}
static const struct backlight_ops oaktrail_ops = {
. get_brightness = oaktrail_get_brightness ,
. update_status = oaktrail_set_brightness ,
} ;
2012-03-08 16:13:10 +00:00
static int oaktrail_backlight_init ( struct drm_device * dev )
2011-11-03 18:22:26 +00:00
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
int ret ;
struct backlight_properties props ;
memset ( & props , 0 , sizeof ( struct backlight_properties ) ) ;
props . max_brightness = 100 ;
props . type = BACKLIGHT_PLATFORM ;
oaktrail_backlight_device = backlight_device_register ( " oaktrail-bl " ,
NULL , ( void * ) dev , & oaktrail_ops , & props ) ;
if ( IS_ERR ( oaktrail_backlight_device ) )
return PTR_ERR ( oaktrail_backlight_device ) ;
ret = device_backlight_init ( dev ) ;
if ( ret < 0 ) {
backlight_device_unregister ( oaktrail_backlight_device ) ;
return ret ;
}
oaktrail_backlight_device - > props . brightness = 100 ;
oaktrail_backlight_device - > props . max_brightness = 100 ;
backlight_update_status ( oaktrail_backlight_device ) ;
dev_priv - > backlight_device = oaktrail_backlight_device ;
return 0 ;
}
# endif
/*
* Provide the Moorestown specific chip logic and low level methods
* for power management
*/
/**
* oaktrail_save_display_registers - save registers lost on suspend
* @ dev : our DRM device
*
* Save the state we need in order to be able to restore the interface
* upon resume from suspend
*/
static int oaktrail_save_display_registers ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
2012-03-08 16:02:05 +00:00
struct psb_save_area * regs = & dev_priv - > regs ;
2012-05-11 11:30:16 +01:00
struct psb_pipe * p = & regs - > pipe [ 0 ] ;
2011-11-03 18:22:26 +00:00
int i ;
u32 pp_stat ;
/* Display arbitration control + watermarks */
2012-03-08 16:02:05 +00:00
regs - > psb . saveDSPARB = PSB_RVDC32 ( DSPARB ) ;
regs - > psb . saveDSPFW1 = PSB_RVDC32 ( DSPFW1 ) ;
regs - > psb . saveDSPFW2 = PSB_RVDC32 ( DSPFW2 ) ;
regs - > psb . saveDSPFW3 = PSB_RVDC32 ( DSPFW3 ) ;
regs - > psb . saveDSPFW4 = PSB_RVDC32 ( DSPFW4 ) ;
regs - > psb . saveDSPFW5 = PSB_RVDC32 ( DSPFW5 ) ;
regs - > psb . saveDSPFW6 = PSB_RVDC32 ( DSPFW6 ) ;
regs - > psb . saveCHICKENBIT = PSB_RVDC32 ( DSPCHICKENBIT ) ;
2011-11-03 18:22:26 +00:00
/* Pipe & plane A info */
2012-05-11 11:30:16 +01:00
p - > conf = PSB_RVDC32 ( PIPEACONF ) ;
p - > src = PSB_RVDC32 ( PIPEASRC ) ;
p - > fp0 = PSB_RVDC32 ( MRST_FPA0 ) ;
p - > fp1 = PSB_RVDC32 ( MRST_FPA1 ) ;
p - > dpll = PSB_RVDC32 ( MRST_DPLL_A ) ;
p - > htotal = PSB_RVDC32 ( HTOTAL_A ) ;
p - > hblank = PSB_RVDC32 ( HBLANK_A ) ;
p - > hsync = PSB_RVDC32 ( HSYNC_A ) ;
p - > vtotal = PSB_RVDC32 ( VTOTAL_A ) ;
p - > vblank = PSB_RVDC32 ( VBLANK_A ) ;
p - > vsync = PSB_RVDC32 ( VSYNC_A ) ;
2012-03-08 16:02:05 +00:00
regs - > psb . saveBCLRPAT_A = PSB_RVDC32 ( BCLRPAT_A ) ;
2012-05-11 11:30:16 +01:00
p - > cntr = PSB_RVDC32 ( DSPACNTR ) ;
p - > stride = PSB_RVDC32 ( DSPASTRIDE ) ;
p - > addr = PSB_RVDC32 ( DSPABASE ) ;
p - > surf = PSB_RVDC32 ( DSPASURF ) ;
p - > linoff = PSB_RVDC32 ( DSPALINOFF ) ;
p - > tileoff = PSB_RVDC32 ( DSPATILEOFF ) ;
2011-11-03 18:22:26 +00:00
/* Save cursor regs */
2012-03-08 16:02:05 +00:00
regs - > psb . saveDSPACURSOR_CTRL = PSB_RVDC32 ( CURACNTR ) ;
regs - > psb . saveDSPACURSOR_BASE = PSB_RVDC32 ( CURABASE ) ;
regs - > psb . saveDSPACURSOR_POS = PSB_RVDC32 ( CURAPOS ) ;
2011-11-03 18:22:26 +00:00
/* Save palette (gamma) */
for ( i = 0 ; i < 256 ; i + + )
2012-05-11 11:30:16 +01:00
p - > palette [ i ] = PSB_RVDC32 ( PALETTE_A + ( i < < 2 ) ) ;
2011-11-03 18:22:26 +00:00
if ( dev_priv - > hdmi_priv )
oaktrail_hdmi_save ( dev ) ;
/* Save performance state */
2012-03-08 16:02:05 +00:00
regs - > psb . savePERF_MODE = PSB_RVDC32 ( MRST_PERF_MODE ) ;
2011-11-03 18:22:26 +00:00
/* LVDS state */
2012-03-08 16:02:05 +00:00
regs - > psb . savePP_CONTROL = PSB_RVDC32 ( PP_CONTROL ) ;
regs - > psb . savePFIT_PGM_RATIOS = PSB_RVDC32 ( PFIT_PGM_RATIOS ) ;
regs - > psb . savePFIT_AUTO_RATIOS = PSB_RVDC32 ( PFIT_AUTO_RATIOS ) ;
2012-03-08 16:00:31 +00:00
regs - > saveBLC_PWM_CTL = PSB_RVDC32 ( BLC_PWM_CTL ) ;
regs - > saveBLC_PWM_CTL2 = PSB_RVDC32 ( BLC_PWM_CTL2 ) ;
2012-03-08 16:02:05 +00:00
regs - > psb . saveLVDS = PSB_RVDC32 ( LVDS ) ;
regs - > psb . savePFIT_CONTROL = PSB_RVDC32 ( PFIT_CONTROL ) ;
regs - > psb . savePP_ON_DELAYS = PSB_RVDC32 ( LVDSPP_ON ) ;
regs - > psb . savePP_OFF_DELAYS = PSB_RVDC32 ( LVDSPP_OFF ) ;
regs - > psb . savePP_DIVISOR = PSB_RVDC32 ( PP_CYCLE ) ;
2011-11-03 18:22:26 +00:00
/* HW overlay */
2012-03-08 16:02:05 +00:00
regs - > psb . saveOV_OVADD = PSB_RVDC32 ( OV_OVADD ) ;
regs - > psb . saveOV_OGAMC0 = PSB_RVDC32 ( OV_OGAMC0 ) ;
regs - > psb . saveOV_OGAMC1 = PSB_RVDC32 ( OV_OGAMC1 ) ;
regs - > psb . saveOV_OGAMC2 = PSB_RVDC32 ( OV_OGAMC2 ) ;
regs - > psb . saveOV_OGAMC3 = PSB_RVDC32 ( OV_OGAMC3 ) ;
regs - > psb . saveOV_OGAMC4 = PSB_RVDC32 ( OV_OGAMC4 ) ;
regs - > psb . saveOV_OGAMC5 = PSB_RVDC32 ( OV_OGAMC5 ) ;
2011-11-03 18:22:26 +00:00
/* DPST registers */
2012-03-08 16:02:05 +00:00
regs - > psb . saveHISTOGRAM_INT_CONTROL_REG =
2011-11-03 18:22:26 +00:00
PSB_RVDC32 ( HISTOGRAM_INT_CONTROL ) ;
2012-03-08 16:02:05 +00:00
regs - > psb . saveHISTOGRAM_LOGIC_CONTROL_REG =
2011-11-03 18:22:26 +00:00
PSB_RVDC32 ( HISTOGRAM_LOGIC_CONTROL ) ;
2012-03-08 16:02:05 +00:00
regs - > psb . savePWM_CONTROL_LOGIC = PSB_RVDC32 ( PWM_CONTROL_LOGIC ) ;
2011-11-03 18:22:26 +00:00
if ( dev_priv - > iLVDS_enable ) {
/* Shut down the panel */
PSB_WVDC32 ( 0 , PP_CONTROL ) ;
do {
pp_stat = PSB_RVDC32 ( PP_STATUS ) ;
} while ( pp_stat & 0x80000000 ) ;
/* Turn off the plane */
PSB_WVDC32 ( 0x58000000 , DSPACNTR ) ;
/* Trigger the plane disable */
PSB_WVDC32 ( 0 , DSPASURF ) ;
/* Wait ~4 ticks */
msleep ( 4 ) ;
/* Turn off pipe */
PSB_WVDC32 ( 0x0 , PIPEACONF ) ;
/* Wait ~8 ticks */
msleep ( 8 ) ;
/* Turn off PLLs */
PSB_WVDC32 ( 0 , MRST_DPLL_A ) ;
}
return 0 ;
}
/**
* oaktrail_restore_display_registers - restore lost register state
* @ dev : our DRM device
*
* Restore register state that was lost during suspend and resume .
*/
static int oaktrail_restore_display_registers ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
2012-03-08 16:02:05 +00:00
struct psb_save_area * regs = & dev_priv - > regs ;
2012-05-11 11:30:16 +01:00
struct psb_pipe * p = & regs - > pipe [ 0 ] ;
2011-11-03 18:22:26 +00:00
u32 pp_stat ;
int i ;
/* Display arbitration + watermarks */
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveDSPARB , DSPARB ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW1 , DSPFW1 ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW2 , DSPFW2 ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW3 , DSPFW3 ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW4 , DSPFW4 ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW5 , DSPFW5 ) ;
PSB_WVDC32 ( regs - > psb . saveDSPFW6 , DSPFW6 ) ;
PSB_WVDC32 ( regs - > psb . saveCHICKENBIT , DSPCHICKENBIT ) ;
2011-11-03 18:22:26 +00:00
/* Make sure VGA plane is off. it initializes to on after reset!*/
PSB_WVDC32 ( 0x80000000 , VGACNTRL ) ;
/* set the plls */
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > fp0 , MRST_FPA0 ) ;
PSB_WVDC32 ( p - > fp1 , MRST_FPA1 ) ;
2011-11-03 18:22:26 +00:00
/* Actually enable it */
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > dpll , MRST_DPLL_A ) ;
2019-05-19 21:55:25 +02:00
udelay ( 150 ) ;
2011-11-03 18:22:26 +00:00
/* Restore mode */
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > htotal , HTOTAL_A ) ;
PSB_WVDC32 ( p - > hblank , HBLANK_A ) ;
PSB_WVDC32 ( p - > hsync , HSYNC_A ) ;
PSB_WVDC32 ( p - > vtotal , VTOTAL_A ) ;
PSB_WVDC32 ( p - > vblank , VBLANK_A ) ;
PSB_WVDC32 ( p - > vsync , VSYNC_A ) ;
PSB_WVDC32 ( p - > src , PIPEASRC ) ;
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveBCLRPAT_A , BCLRPAT_A ) ;
2011-11-03 18:22:26 +00:00
/* Restore performance mode*/
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . savePERF_MODE , MRST_PERF_MODE ) ;
2011-11-03 18:22:26 +00:00
/* Enable the pipe*/
if ( dev_priv - > iLVDS_enable )
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > conf , PIPEACONF ) ;
2011-11-03 18:22:26 +00:00
/* Set up the plane*/
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > linoff , DSPALINOFF ) ;
PSB_WVDC32 ( p - > stride , DSPASTRIDE ) ;
PSB_WVDC32 ( p - > tileoff , DSPATILEOFF ) ;
2011-11-03 18:22:26 +00:00
/* Enable the plane */
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > cntr , DSPACNTR ) ;
PSB_WVDC32 ( p - > surf , DSPASURF ) ;
2011-11-03 18:22:26 +00:00
/* Enable Cursor A */
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveDSPACURSOR_CTRL , CURACNTR ) ;
PSB_WVDC32 ( regs - > psb . saveDSPACURSOR_POS , CURAPOS ) ;
PSB_WVDC32 ( regs - > psb . saveDSPACURSOR_BASE , CURABASE ) ;
2011-11-03 18:22:26 +00:00
/* Restore palette (gamma) */
for ( i = 0 ; i < 256 ; i + + )
2012-05-11 11:30:16 +01:00
PSB_WVDC32 ( p - > palette [ i ] , PALETTE_A + ( i < < 2 ) ) ;
2011-11-03 18:22:26 +00:00
if ( dev_priv - > hdmi_priv )
oaktrail_hdmi_restore ( dev ) ;
if ( dev_priv - > iLVDS_enable ) {
2012-03-08 16:00:31 +00:00
PSB_WVDC32 ( regs - > saveBLC_PWM_CTL2 , BLC_PWM_CTL2 ) ;
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveLVDS , LVDS ) ; /*port 61180h*/
PSB_WVDC32 ( regs - > psb . savePFIT_CONTROL , PFIT_CONTROL ) ;
PSB_WVDC32 ( regs - > psb . savePFIT_PGM_RATIOS , PFIT_PGM_RATIOS ) ;
PSB_WVDC32 ( regs - > psb . savePFIT_AUTO_RATIOS , PFIT_AUTO_RATIOS ) ;
2012-03-08 16:00:31 +00:00
PSB_WVDC32 ( regs - > saveBLC_PWM_CTL , BLC_PWM_CTL ) ;
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . savePP_ON_DELAYS , LVDSPP_ON ) ;
PSB_WVDC32 ( regs - > psb . savePP_OFF_DELAYS , LVDSPP_OFF ) ;
PSB_WVDC32 ( regs - > psb . savePP_DIVISOR , PP_CYCLE ) ;
PSB_WVDC32 ( regs - > psb . savePP_CONTROL , PP_CONTROL ) ;
2011-11-03 18:22:26 +00:00
}
/* Wait for cycle delay */
do {
pp_stat = PSB_RVDC32 ( PP_STATUS ) ;
} while ( pp_stat & 0x08000000 ) ;
/* Wait for panel power up */
do {
pp_stat = PSB_RVDC32 ( PP_STATUS ) ;
} while ( pp_stat & 0x10000000 ) ;
/* Restore HW overlay */
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveOV_OVADD , OV_OVADD ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC0 , OV_OGAMC0 ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC1 , OV_OGAMC1 ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC2 , OV_OGAMC2 ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC3 , OV_OGAMC3 ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC4 , OV_OGAMC4 ) ;
PSB_WVDC32 ( regs - > psb . saveOV_OGAMC5 , OV_OGAMC5 ) ;
2011-11-03 18:22:26 +00:00
/* DPST registers */
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveHISTOGRAM_INT_CONTROL_REG ,
2011-11-03 18:22:26 +00:00
HISTOGRAM_INT_CONTROL ) ;
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . saveHISTOGRAM_LOGIC_CONTROL_REG ,
2011-11-03 18:22:26 +00:00
HISTOGRAM_LOGIC_CONTROL ) ;
2012-03-08 16:02:05 +00:00
PSB_WVDC32 ( regs - > psb . savePWM_CONTROL_LOGIC , PWM_CONTROL_LOGIC ) ;
2011-11-03 18:22:26 +00:00
return 0 ;
}
/**
* oaktrail_power_down - power down the display island
* @ dev : our DRM device
*
* Power down the display interface of our device
*/
static int oaktrail_power_down ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
u32 pwr_mask ;
u32 pwr_sts ;
pwr_mask = PSB_PWRGT_DISPLAY_MASK ;
outl ( pwr_mask , dev_priv - > ospm_base + PSB_PM_SSC ) ;
while ( true ) {
pwr_sts = inl ( dev_priv - > ospm_base + PSB_PM_SSS ) ;
if ( ( pwr_sts & pwr_mask ) = = pwr_mask )
break ;
else
udelay ( 10 ) ;
}
return 0 ;
}
/*
* oaktrail_power_up
*
* Restore power to the specified island ( s ) ( powergating )
*/
static int oaktrail_power_up ( struct drm_device * dev )
{
struct drm_psb_private * dev_priv = dev - > dev_private ;
u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK ;
u32 pwr_sts , pwr_cnt ;
pwr_cnt = inl ( dev_priv - > ospm_base + PSB_PM_SSC ) ;
pwr_cnt & = ~ pwr_mask ;
outl ( pwr_cnt , ( dev_priv - > ospm_base + PSB_PM_SSC ) ) ;
while ( true ) {
pwr_sts = inl ( dev_priv - > ospm_base + PSB_PM_SSS ) ;
if ( ( pwr_sts & pwr_mask ) = = 0 )
break ;
else
udelay ( 10 ) ;
}
return 0 ;
}
2012-05-11 11:30:53 +01:00
/* Oaktrail */
static const struct psb_offset oaktrail_regmap [ 2 ] = {
{
. 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 ,
2012-05-11 11:31:22 +01:00
. addr = MRST_DSPABASE ,
2012-09-12 10:05:04 +00:00
. base = MRST_DSPABASE ,
2012-05-11 11:30:53 +01:00
. status = PIPEASTAT ,
. linoff = DSPALINOFF ,
. tileoff = DSPATILEOFF ,
. palette = PALETTE_A ,
} ,
{
. fp0 = FPB0 ,
. fp1 = FPB1 ,
. cntr = DSPBCNTR ,
. conf = PIPEBCONF ,
. src = PIPEBSRC ,
. dpll = 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 = DSPBBASE ,
2012-09-12 10:05:04 +00:00
. base = DSPBBASE ,
2012-05-11 11:30:53 +01:00
. status = PIPEBSTAT ,
. linoff = DSPBLINOFF ,
. tileoff = DSPBTILEOFF ,
. palette = PALETTE_B ,
} ,
} ;
2011-11-03 18:22:26 +00:00
2011-11-29 22:27:57 +00:00
static int oaktrail_chip_setup ( struct drm_device * dev )
2011-11-29 22:27:45 +00:00
{
2011-11-29 22:27:57 +00:00
struct drm_psb_private * dev_priv = dev - > dev_private ;
int ret ;
2012-05-11 11:30:53 +01:00
2012-05-11 11:33:03 +01:00
if ( pci_enable_msi ( dev - > pdev ) )
dev_warn ( dev - > dev , " Enabling MSI failed! \n " ) ;
2012-05-11 11:30:53 +01:00
dev_priv - > regmap = oaktrail_regmap ;
2012-05-03 16:27:21 +01:00
2011-11-29 22:27:57 +00:00
ret = mid_chip_setup ( dev ) ;
2011-11-29 22:27:45 +00:00
if ( ret < 0 )
return ret ;
2012-05-03 16:27:21 +01:00
if ( ! dev_priv - > has_gct ) {
2011-11-29 22:27:45 +00:00
/* Now pull the BIOS data */
2012-05-03 15:06:18 +01:00
psb_intel_opregion_init ( dev ) ;
2011-11-29 22:27:45 +00:00
psb_intel_init_bios ( dev ) ;
}
2013-11-07 03:04:04 +01:00
gma_intel_setup_gmbus ( dev ) ;
2012-05-03 15:05:40 +01:00
oaktrail_hdmi_setup ( dev ) ;
2011-11-29 22:27:45 +00:00
return 0 ;
}
2011-11-03 18:22:26 +00:00
static void oaktrail_teardown ( struct drm_device * dev )
{
2011-11-29 22:27:57 +00:00
struct drm_psb_private * dev_priv = dev - > dev_private ;
2013-11-07 03:04:04 +01:00
gma_intel_teardown_gmbus ( dev ) ;
2011-11-03 18:22:26 +00:00
oaktrail_hdmi_teardown ( dev ) ;
2012-05-03 16:27:21 +01:00
if ( ! dev_priv - > has_gct )
2011-11-29 22:27:45 +00:00
psb_intel_destroy_bios ( dev ) ;
2011-11-03 18:22:26 +00:00
}
const struct psb_ops oaktrail_chip_ops = {
. name = " Oaktrail " ,
. accel_2d = 1 ,
. pipes = 2 ,
. crtcs = 2 ,
2012-11-06 13:49:23 +00:00
. hdmi_mask = ( 1 < < 1 ) ,
2012-04-25 14:38:07 +01:00
. lvds_mask = ( 1 < < 0 ) ,
2013-09-16 17:54:54 +02:00
. sdvo_mask = ( 1 < < 1 ) ,
2012-05-21 15:27:30 +01:00
. cursor_needs_phys = 0 ,
2011-11-03 18:22:26 +00:00
. sgx_offset = MRST_SGX_OFFSET ,
2011-11-29 22:27:45 +00:00
. chip_setup = oaktrail_chip_setup ,
2011-11-03 18:22:26 +00:00
. chip_teardown = oaktrail_teardown ,
. crtc_helper = & oaktrail_helper_funcs ,
. crtc_funcs = & psb_intel_crtc_funcs ,
. output_init = oaktrail_output_init ,
# ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
. backlight_init = oaktrail_backlight_init ,
# endif
. save_regs = oaktrail_save_display_registers ,
. restore_regs = oaktrail_restore_display_registers ,
2015-12-04 09:45:53 +01:00
. save_crtc = gma_crtc_save ,
. restore_crtc = gma_crtc_restore ,
2011-11-03 18:22:26 +00:00
. power_down = oaktrail_power_down ,
. power_up = oaktrail_power_up ,
. i2c_bus = 1 ,
} ;