diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-04 07:05:43 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-04 07:05:43 -0800 | 
| commit | 91d3f9bacdb4950d2f79fe2ba296aa249f60d06c (patch) | |
| tree | 3409f69ef76a28734a492af8803ea9653ee0b4a8 | |
| parent | 51bb296b09a83ee1aae025778db38f9d2cc7bb1a (diff) | |
| parent | 4204878179c99d419d392d78d817729992b4c442 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel:
  drm/i915: Ironlake suspend/resume support
  drm/i915: kill warning in intel_find_pll_g4x_dp
  drm/i915: update watermarks before enabling PLLs
  drm/i915: add FIFO watermark support for G4x
  drm/i915: quiet DP i2c init
  drm/i915: fix panel fitting filter coefficient select for Ironlake
  drm/i915: fix to setup display reference clock control on Ironlake
  drm/i915: Install a fence register for fbc on g4x
  drm/i915: save/restore BLC histogram control reg across suspend/resume
  drm/i915: Fix FDI M/N setting according with correct color depth
  drm/i915: disable powersave feature for Ironlake currently
  drm/i915: Fix render reclock availability detection.
  drm/i915: Save and restore the GM45 FBC regs on suspend and resume.
  drm/i915: Set the LVDS_BORDER when using LVDS scaling mode
  drm/i915: disable FBC for Pineview, fixing a boot hang.
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 39 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 305 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 178 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 10 | 
8 files changed, 486 insertions, 95 deletions
| diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 92aeb918e0c0..e5b138be45fa 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1227,8 +1227,7 @@ static int i915_load_modeset_init(struct drm_device *dev,  		goto out;  	/* Try to set up FBC with a reasonable compressed buffer size */ -	if (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev) || IS_GM45(dev)) && -	    i915_powersave) { +	if (I915_HAS_FBC(dev) && i915_powersave) {  		int cfb_size;  		/* Try to get an 8M buffer... */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c5df2234418d..57204e298975 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -296,6 +296,12 @@ typedef struct drm_i915_private {  	u32 saveVBLANK_A;  	u32 saveVSYNC_A;  	u32 saveBCLRPAT_A; +	u32 saveTRANS_HTOTAL_A; +	u32 saveTRANS_HBLANK_A; +	u32 saveTRANS_HSYNC_A; +	u32 saveTRANS_VTOTAL_A; +	u32 saveTRANS_VBLANK_A; +	u32 saveTRANS_VSYNC_A;  	u32 savePIPEASTAT;  	u32 saveDSPASTRIDE;  	u32 saveDSPASIZE; @@ -304,8 +310,11 @@ typedef struct drm_i915_private {  	u32 saveDSPASURF;  	u32 saveDSPATILEOFF;  	u32 savePFIT_PGM_RATIOS; +	u32 saveBLC_HIST_CTL;  	u32 saveBLC_PWM_CTL;  	u32 saveBLC_PWM_CTL2; +	u32 saveBLC_CPU_PWM_CTL; +	u32 saveBLC_CPU_PWM_CTL2;  	u32 saveFPB0;  	u32 saveFPB1;  	u32 saveDPLL_B; @@ -317,6 +326,12 @@ typedef struct drm_i915_private {  	u32 saveVBLANK_B;  	u32 saveVSYNC_B;  	u32 saveBCLRPAT_B; +	u32 saveTRANS_HTOTAL_B; +	u32 saveTRANS_HBLANK_B; +	u32 saveTRANS_HSYNC_B; +	u32 saveTRANS_VTOTAL_B; +	u32 saveTRANS_VBLANK_B; +	u32 saveTRANS_VSYNC_B;  	u32 savePIPEBSTAT;  	u32 saveDSPBSTRIDE;  	u32 saveDSPBSIZE; @@ -342,6 +357,7 @@ typedef struct drm_i915_private {  	u32 savePFIT_CONTROL;  	u32 save_palette_a[256];  	u32 save_palette_b[256]; +	u32 saveDPFC_CB_BASE;  	u32 saveFBC_CFB_BASE;  	u32 saveFBC_LL_BASE;  	u32 saveFBC_CONTROL; @@ -349,6 +365,12 @@ typedef struct drm_i915_private {  	u32 saveIER;  	u32 saveIIR;  	u32 saveIMR; +	u32 saveDEIER; +	u32 saveDEIMR; +	u32 saveGTIER; +	u32 saveGTIMR; +	u32 saveFDI_RXA_IMR; +	u32 saveFDI_RXB_IMR;  	u32 saveCACHE_MODE_0;  	u32 saveD_STATE;  	u32 saveDSPCLK_GATE_D; @@ -382,6 +404,16 @@ typedef struct drm_i915_private {  	u32 savePIPEB_DP_LINK_M;  	u32 savePIPEA_DP_LINK_N;  	u32 savePIPEB_DP_LINK_N; +	u32 saveFDI_RXA_CTL; +	u32 saveFDI_TXA_CTL; +	u32 saveFDI_RXB_CTL; +	u32 saveFDI_TXB_CTL; +	u32 savePFA_CTL_1; +	u32 savePFB_CTL_1; +	u32 savePFA_WIN_SZ; +	u32 savePFB_WIN_SZ; +	u32 savePFA_WIN_POS; +	u32 savePFB_WIN_POS;  	struct {  		struct drm_mm gtt_space; @@ -492,6 +524,8 @@ typedef struct drm_i915_private {  		struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];  	} mm;  	struct sdvo_device_mapping sdvo_mappings[2]; +	/* indicate whether the LVDS_BORDER should be enabled or not */ +	unsigned int lvds_border_bits;  	/* Reclocking support */  	bool render_reclock_avail; @@ -981,7 +1015,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))  #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) -#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev))) +#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \ +			   (IS_I9XX(dev) || IS_GM45(dev)) && \ +			   !IS_IGD(dev) && \ +			   !IS_IGDNG(dev))  #define PRIMARY_RINGBUFFER_SIZE         (128*1024) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0466ddbeba32..1687edf68795 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -968,6 +968,8 @@  #define   LVDS_PORT_EN			(1 << 31)  /* Selects pipe B for LVDS data.  Must be set on pre-965. */  #define   LVDS_PIPEB_SELECT		(1 << 30) +/* Enable border for unscaled (or aspect-scaled) display */ +#define   LVDS_BORDER_ENABLE		(1 << 15)  /*   * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per   * pixel. @@ -1078,6 +1080,8 @@  #define   BACKLIGHT_DUTY_CYCLE_SHIFT		(0)  #define   BACKLIGHT_DUTY_CYCLE_MASK		(0xffff) +#define BLC_HIST_CTL		0x61260 +  /* TV port control */  #define TV_CTL			0x68000  /** Enables the TV encoder */ @@ -1780,6 +1784,11 @@  #define   PIPE_START_VBLANK_INTERRUPT_STATUS	(1UL<<2) /* 965 or later */  #define   PIPE_VBLANK_INTERRUPT_STATUS		(1UL<<1)  #define   PIPE_OVERLAY_UPDATED_STATUS		(1UL<<0) +#define   PIPE_BPC_MASK 			(7 << 5) /* Ironlake */ +#define   PIPE_8BPC				(0 << 5) +#define   PIPE_10BPC				(1 << 5) +#define   PIPE_6BPC				(2 << 5) +#define   PIPE_12BPC				(3 << 5)  #define DSPARB			0x70030  #define   DSPARB_CSTART_MASK	(0x7f << 7) @@ -1790,17 +1799,29 @@  #define   DSPARB_AEND_SHIFT	0  #define DSPFW1			0x70034 +#define   DSPFW_SR_SHIFT	23 +#define   DSPFW_CURSORB_SHIFT	16 +#define   DSPFW_PLANEB_SHIFT	8  #define DSPFW2			0x70038 +#define   DSPFW_CURSORA_MASK	0x00003f00 +#define   DSPFW_CURSORA_SHIFT	16  #define DSPFW3			0x7003c +#define   DSPFW_HPLL_SR_EN	(1<<31) +#define   DSPFW_CURSOR_SR_SHIFT	24  #define   IGD_SELF_REFRESH_EN	(1<<30)  /* FIFO watermark sizes etc */ +#define G4X_FIFO_LINE_SIZE	64  #define I915_FIFO_LINE_SIZE	64  #define I830_FIFO_LINE_SIZE	32 + +#define G4X_FIFO_SIZE		127  #define I945_FIFO_SIZE		127 /* 945 & 965 */  #define I915_FIFO_SIZE		95  #define I855GM_FIFO_SIZE	127 /* In cachelines */  #define I830_FIFO_SIZE		95 + +#define G4X_MAX_WM		0x3f  #define I915_MAX_WM		0x3f  #define IGD_DISPLAY_FIFO	512 /* in 64byte unit */ @@ -2030,6 +2051,11 @@  #define PFA_CTL_1               0x68080  #define PFB_CTL_1               0x68880  #define  PF_ENABLE              (1<<31) +#define  PF_FILTER_MASK		(3<<23) +#define  PF_FILTER_PROGRAMMED	(0<<23) +#define  PF_FILTER_MED_3x3	(1<<23) +#define  PF_FILTER_EDGE_ENHANCE	(2<<23) +#define  PF_FILTER_EDGE_SOFTEN	(3<<23)  #define PFA_WIN_SZ		0x68074  #define PFB_WIN_SZ		0x68874  #define PFA_WIN_POS		0x68070 @@ -2149,11 +2175,11 @@  #define  DREF_CPU_SOURCE_OUTPUT_MASK		(3<<13)  #define  DREF_SSC_SOURCE_DISABLE                (0<<11)  #define  DREF_SSC_SOURCE_ENABLE                 (2<<11) -#define  DREF_SSC_SOURCE_MASK			(2<<11) +#define  DREF_SSC_SOURCE_MASK			(3<<11)  #define  DREF_NONSPREAD_SOURCE_DISABLE          (0<<9)  #define  DREF_NONSPREAD_CK505_ENABLE		(1<<9)  #define  DREF_NONSPREAD_SOURCE_ENABLE           (2<<9) -#define  DREF_NONSPREAD_SOURCE_MASK		(2<<9) +#define  DREF_NONSPREAD_SOURCE_MASK		(3<<9)  #define  DREF_SUPERSPREAD_SOURCE_DISABLE        (0<<7)  #define  DREF_SUPERSPREAD_SOURCE_ENABLE         (2<<7)  #define  DREF_SSC4_DOWNSPREAD                   (0<<6) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index bd6d8d91ca9f..992d5617e798 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -32,11 +32,15 @@  static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)  {  	struct drm_i915_private *dev_priv = dev->dev_private; +	u32	dpll_reg; -	if (pipe == PIPE_A) -		return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); -	else -		return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); +	if (IS_IGDNG(dev)) { +		dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; +	} else { +		dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; +	} + +	return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE);  }  static void i915_save_palette(struct drm_device *dev, enum pipe pipe) @@ -49,6 +53,9 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe)  	if (!i915_pipe_enabled(dev, pipe))  		return; +	if (IS_IGDNG(dev)) +		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; +  	if (pipe == PIPE_A)  		array = dev_priv->save_palette_a;  	else @@ -68,6 +75,9 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)  	if (!i915_pipe_enabled(dev, pipe))  		return; +	if (IS_IGDNG(dev)) +		reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; +  	if (pipe == PIPE_A)  		array = dev_priv->save_palette_a;  	else @@ -232,10 +242,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)  	/* Pipe & plane A info */  	dev_priv->savePIPEACONF = I915_READ(PIPEACONF);  	dev_priv->savePIPEASRC = I915_READ(PIPEASRC); -	dev_priv->saveFPA0 = I915_READ(FPA0); -	dev_priv->saveFPA1 = I915_READ(FPA1); -	dev_priv->saveDPLL_A = I915_READ(DPLL_A); -	if (IS_I965G(dev)) +	if (IS_IGDNG(dev)) { +		dev_priv->saveFPA0 = I915_READ(PCH_FPA0); +		dev_priv->saveFPA1 = I915_READ(PCH_FPA1); +		dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); +	} else { +		dev_priv->saveFPA0 = I915_READ(FPA0); +		dev_priv->saveFPA1 = I915_READ(FPA1); +		dev_priv->saveDPLL_A = I915_READ(DPLL_A); +	} +	if (IS_I965G(dev) && !IS_IGDNG(dev))  		dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);  	dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);  	dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); @@ -243,7 +259,24 @@ static void i915_save_modeset_reg(struct drm_device *dev)  	dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);  	dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);  	dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); -	dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); +	if (!IS_IGDNG(dev)) +		dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); + +	if (IS_IGDNG(dev)) { +		dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); +		dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); + +		dev_priv->savePFA_CTL_1 = I915_READ(PFA_CTL_1); +		dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); +		dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); + +		dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); +		dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); +		dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); +		dev_priv->saveTRANS_VTOTAL_A = I915_READ(TRANS_VTOTAL_A); +		dev_priv->saveTRANS_VBLANK_A = I915_READ(TRANS_VBLANK_A); +		dev_priv->saveTRANS_VSYNC_A = I915_READ(TRANS_VSYNC_A); +	}  	dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);  	dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); @@ -260,10 +293,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)  	/* Pipe & plane B info */  	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);  	dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); -	dev_priv->saveFPB0 = I915_READ(FPB0); -	dev_priv->saveFPB1 = I915_READ(FPB1); -	dev_priv->saveDPLL_B = I915_READ(DPLL_B); -	if (IS_I965G(dev)) +	if (IS_IGDNG(dev)) { +		dev_priv->saveFPB0 = I915_READ(PCH_FPB0); +		dev_priv->saveFPB1 = I915_READ(PCH_FPB1); +		dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); +	} else { +		dev_priv->saveFPB0 = I915_READ(FPB0); +		dev_priv->saveFPB1 = I915_READ(FPB1); +		dev_priv->saveDPLL_B = I915_READ(DPLL_B); +	} +	if (IS_I965G(dev) && !IS_IGDNG(dev))  		dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);  	dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);  	dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); @@ -271,7 +310,24 @@ static void i915_save_modeset_reg(struct drm_device *dev)  	dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);  	dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);  	dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); -	dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); +	if (!IS_IGDNG(dev)) +		dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); + +	if (IS_IGDNG(dev)) { +		dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); +		dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); + +		dev_priv->savePFB_CTL_1 = I915_READ(PFB_CTL_1); +		dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); +		dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); + +		dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); +		dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); +		dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); +		dev_priv->saveTRANS_VTOTAL_B = I915_READ(TRANS_VTOTAL_B); +		dev_priv->saveTRANS_VBLANK_B = I915_READ(TRANS_VBLANK_B); +		dev_priv->saveTRANS_VSYNC_B = I915_READ(TRANS_VSYNC_B); +	}  	dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);  	dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); @@ -290,23 +346,41 @@ static void i915_save_modeset_reg(struct drm_device *dev)  static void i915_restore_modeset_reg(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private; +	int dpll_a_reg, fpa0_reg, fpa1_reg; +	int dpll_b_reg, fpb0_reg, fpb1_reg;  	if (drm_core_check_feature(dev, DRIVER_MODESET))  		return; +	if (IS_IGDNG(dev)) { +		dpll_a_reg = PCH_DPLL_A; +		dpll_b_reg = PCH_DPLL_B; +		fpa0_reg = PCH_FPA0; +		fpb0_reg = PCH_FPB0; +		fpa1_reg = PCH_FPA1; +		fpb1_reg = PCH_FPB1; +	} else { +		dpll_a_reg = DPLL_A; +		dpll_b_reg = DPLL_B; +		fpa0_reg = FPA0; +		fpb0_reg = FPB0; +		fpa1_reg = FPA1; +		fpb1_reg = FPB1; +	} +  	/* Pipe & plane A info */  	/* Prime the clock */  	if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { -		I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & +		I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A &  			   ~DPLL_VCO_ENABLE);  		DRM_UDELAY(150);  	} -	I915_WRITE(FPA0, dev_priv->saveFPA0); -	I915_WRITE(FPA1, dev_priv->saveFPA1); +	I915_WRITE(fpa0_reg, dev_priv->saveFPA0); +	I915_WRITE(fpa1_reg, dev_priv->saveFPA1);  	/* Actually enable it */ -	I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); +	I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);  	DRM_UDELAY(150); -	if (IS_I965G(dev)) +	if (IS_I965G(dev) && !IS_IGDNG(dev))  		I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);  	DRM_UDELAY(150); @@ -317,7 +391,24 @@ static void i915_restore_modeset_reg(struct drm_device *dev)  	I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);  	I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);  	I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); -	I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); +	if (!IS_IGDNG(dev)) +		I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); + +	if (IS_IGDNG(dev)) { +		I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); +		I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); + +		I915_WRITE(PFA_CTL_1, dev_priv->savePFA_CTL_1); +		I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); +		I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); + +		I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); +		I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); +		I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); +		I915_WRITE(TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A); +		I915_WRITE(TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A); +		I915_WRITE(TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A); +	}  	/* Restore plane info */  	I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); @@ -339,14 +430,14 @@ static void i915_restore_modeset_reg(struct drm_device *dev)  	/* Pipe & plane B info */  	if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { -		I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & +		I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B &  			   ~DPLL_VCO_ENABLE);  		DRM_UDELAY(150);  	} -	I915_WRITE(FPB0, dev_priv->saveFPB0); -	I915_WRITE(FPB1, dev_priv->saveFPB1); +	I915_WRITE(fpb0_reg, dev_priv->saveFPB0); +	I915_WRITE(fpb1_reg, dev_priv->saveFPB1);  	/* Actually enable it */ -	I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); +	I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);  	DRM_UDELAY(150);  	if (IS_I965G(dev))  		I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); @@ -359,7 +450,24 @@ static void i915_restore_modeset_reg(struct drm_device *dev)  	I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);  	I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);  	I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); -	I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); +	if (!IS_IGDNG(dev)) +		I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); + +	if (IS_IGDNG(dev)) { +		I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); +		I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); + +		I915_WRITE(PFB_CTL_1, dev_priv->savePFB_CTL_1); +		I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); +		I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); + +		I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); +		I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); +		I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); +		I915_WRITE(TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B); +		I915_WRITE(TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B); +		I915_WRITE(TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B); +	}  	/* Restore plane info */  	I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); @@ -404,21 +512,43 @@ void i915_save_display(struct drm_device *dev)  		dev_priv->saveCURSIZE = I915_READ(CURSIZE);  	/* CRT state */ -	dev_priv->saveADPA = I915_READ(ADPA); +	if (IS_IGDNG(dev)) { +		dev_priv->saveADPA = I915_READ(PCH_ADPA); +	} else { +		dev_priv->saveADPA = I915_READ(ADPA); +	}  	/* LVDS state */ -	dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); -	dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); -	dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); -	if (IS_I965G(dev)) -		dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); -	if (IS_MOBILE(dev) && !IS_I830(dev)) -		dev_priv->saveLVDS = I915_READ(LVDS); -	if (!IS_I830(dev) && !IS_845G(dev)) +	if (IS_IGDNG(dev)) { +		dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); +		dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); +		dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); +		dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL); +		dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2); +		dev_priv->saveLVDS = I915_READ(PCH_LVDS); +	} else { +		dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); +		dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); +		dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); +		dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); +		if (IS_I965G(dev)) +			dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); +		if (IS_MOBILE(dev) && !IS_I830(dev)) +			dev_priv->saveLVDS = I915_READ(LVDS); +	} + +	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))  		dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); -	dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); -	dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); -	dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); + +	if (IS_IGDNG(dev)) { +		dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); +		dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); +		dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); +	} else { +		dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); +		dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); +		dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); +	}  	/* Display Port state */  	if (SUPPORTS_INTEGRATED_DP(dev)) { @@ -437,16 +567,23 @@ void i915_save_display(struct drm_device *dev)  	/* FIXME: save TV & SDVO state */  	/* FBC state */ -	dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); -	dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); -	dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); -	dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); +	if (IS_GM45(dev)) { +		dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); +	} else { +		dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); +		dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); +		dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); +		dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); +	}  	/* VGA state */  	dev_priv->saveVGA0 = I915_READ(VGA0);  	dev_priv->saveVGA1 = I915_READ(VGA1);  	dev_priv->saveVGA_PD = I915_READ(VGA_PD); -	dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); +	if (IS_IGDNG(dev)) +		dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); +	else +		dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);  	i915_save_vga(dev);  } @@ -485,22 +622,41 @@ void i915_restore_display(struct drm_device *dev)  		I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);  	/* CRT state */ -	I915_WRITE(ADPA, dev_priv->saveADPA); +	if (IS_IGDNG(dev)) +		I915_WRITE(PCH_ADPA, dev_priv->saveADPA); +	else +		I915_WRITE(ADPA, dev_priv->saveADPA);  	/* LVDS state */ -	if (IS_I965G(dev)) +	if (IS_I965G(dev) && !IS_IGDNG(dev))  		I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); -	if (IS_MOBILE(dev) && !IS_I830(dev)) + +	if (IS_IGDNG(dev)) { +		I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); +	} else if (IS_MOBILE(dev) && !IS_I830(dev))  		I915_WRITE(LVDS, dev_priv->saveLVDS); -	if (!IS_I830(dev) && !IS_845G(dev)) + +	if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev))  		I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); -	I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); -	I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); -	I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); -	I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); -	I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); -	I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); +	if (IS_IGDNG(dev)) { +		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); +		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); +		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); +		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); +		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); +		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); +		I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); +		I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); +	} else { +		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); +		I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); +		I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL); +		I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); +		I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); +		I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); +		I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); +	}  	/* Display Port state */  	if (SUPPORTS_INTEGRATED_DP(dev)) { @@ -511,13 +667,22 @@ void i915_restore_display(struct drm_device *dev)  	/* FIXME: restore TV & SDVO state */  	/* FBC info */ -	I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); -	I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); -	I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); -	I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); +	if (IS_GM45(dev)) { +		g4x_disable_fbc(dev); +		I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); +	} else { +		i8xx_disable_fbc(dev); +		I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); +		I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); +		I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); +		I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); +	}  	/* VGA state */ -	I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); +	if (IS_IGDNG(dev)) +		I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); +	else +		I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);  	I915_WRITE(VGA0, dev_priv->saveVGA0);  	I915_WRITE(VGA1, dev_priv->saveVGA1);  	I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); @@ -543,8 +708,17 @@ int i915_save_state(struct drm_device *dev)  	i915_save_display(dev);  	/* Interrupt state */ -	dev_priv->saveIER = I915_READ(IER); -	dev_priv->saveIMR = I915_READ(IMR); +	if (IS_IGDNG(dev)) { +		dev_priv->saveDEIER = I915_READ(DEIER); +		dev_priv->saveDEIMR = I915_READ(DEIMR); +		dev_priv->saveGTIER = I915_READ(GTIER); +		dev_priv->saveGTIMR = I915_READ(GTIMR); +		dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); +		dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); +	} else { +		dev_priv->saveIER = I915_READ(IER); +		dev_priv->saveIMR = I915_READ(IMR); +	}  	/* Clock gating state */  	dev_priv->saveD_STATE = I915_READ(D_STATE); @@ -609,8 +783,17 @@ int i915_restore_state(struct drm_device *dev)  	i915_restore_display(dev);  	/* Interrupt state */ -	I915_WRITE (IER, dev_priv->saveIER); -	I915_WRITE (IMR,  dev_priv->saveIMR); +	if (IS_IGDNG(dev)) { +		I915_WRITE(DEIER, dev_priv->saveDEIER); +		I915_WRITE(DEIMR, dev_priv->saveDEIMR); +		I915_WRITE(GTIER, dev_priv->saveGTIER); +		I915_WRITE(GTIMR, dev_priv->saveGTIMR); +		I915_WRITE(FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); +		I915_WRITE(FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); +	} else { +		I915_WRITE (IER, dev_priv->saveIER); +		I915_WRITE (IMR,  dev_priv->saveIMR); +	}  	/* Clock gating state */  	I915_WRITE (D_STATE, dev_priv->saveD_STATE); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4337414846b6..96cd256e60e6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -351,20 +351,18 @@ parse_driver_features(struct drm_i915_private *dev_priv,  	struct drm_device *dev = dev_priv->dev;  	struct bdb_driver_features *driver; -	/* set default for chips without eDP */ -	if (!SUPPORTS_EDP(dev)) { -		dev_priv->edp_support = 0; -		return; -	} -  	driver = find_section(bdb, BDB_DRIVER_FEATURES);  	if (!driver)  		return; -	if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) +	if (driver && SUPPORTS_EDP(dev) && +	    driver->lvds_config == BDB_DRIVER_FEATURE_EDP) {  		dev_priv->edp_support = 1; +	} else { +		dev_priv->edp_support = 0; +	} -	if (driver->dual_frequency) +	if (driver && driver->dual_frequency)  		dev_priv->render_reclock_avail = true;  } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3c14240cc002..3ba6546b7c7f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -943,6 +943,7 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,      clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);      clock.p = (clock.p1 * clock.p2);      clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; +    clock.vco = 0;      memcpy(best_clock, &clock, sizeof(intel_clock_t));      return true;  } @@ -1260,9 +1261,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,  		return ret;  	} -	/* Pre-i965 needs to install a fence for tiled scan-out */ -	if (!IS_I965G(dev) && -	    obj_priv->fence_reg == I915_FENCE_REG_NONE && +	/* Install a fence for tiled scan-out. Pre-i965 always needs a fence, +	 * whereas 965+ only requires a fence if using framebuffer compression. +	 * For simplicity, we always install a fence as the cost is not that onerous. +	 */ +	if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&  	    obj_priv->tiling_mode != I915_TILING_NONE) {  		ret = i915_gem_object_get_fence_reg(obj);  		if (ret != 0) { @@ -1513,7 +1516,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)  		/* Enable panel fitting for LVDS */  		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {  			temp = I915_READ(pf_ctl_reg); -			I915_WRITE(pf_ctl_reg, temp | PF_ENABLE); +			I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);  			/* currently full aspect */  			I915_WRITE(pf_win_pos, 0); @@ -1801,6 +1804,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)  	case DRM_MODE_DPMS_ON:  	case DRM_MODE_DPMS_STANDBY:  	case DRM_MODE_DPMS_SUSPEND: +		intel_update_watermarks(dev); +  		/* Enable the DPLL */  		temp = I915_READ(dpll_reg);  		if ((temp & DPLL_VCO_ENABLE) == 0) { @@ -1838,7 +1843,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)  		/* Give the overlay scaler a chance to enable if it's on this pipe */  		//intel_crtc_dpms_video(crtc, true); TODO -		intel_update_watermarks(dev);  	break;  	case DRM_MODE_DPMS_OFF:  		intel_update_watermarks(dev); @@ -2082,7 +2086,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)  #define LINK_N 0x80000  static void -igdng_compute_m_n(int bytes_per_pixel, int nlanes, +igdng_compute_m_n(int bits_per_pixel, int nlanes,  		int pixel_clock, int link_clock,  		struct fdi_m_n *m_n)  { @@ -2092,7 +2096,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,  	temp = (u64) DATA_N * pixel_clock;  	temp = div_u64(temp, link_clock); -	m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); +	m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); +	m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */  	m_n->gmch_n = DATA_N;  	fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); @@ -2140,6 +2145,13 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = {  	IGD_CURSOR_GUARD_WM,  	IGD_FIFO_LINE_SIZE  }; +static struct intel_watermark_params g4x_wm_info = { +	G4X_FIFO_SIZE, +	G4X_MAX_WM, +	G4X_MAX_WM, +	2, +	G4X_FIFO_LINE_SIZE, +};  static struct intel_watermark_params i945_wm_info = {  	I945_FIFO_SIZE,  	I915_MAX_WM, @@ -2430,17 +2442,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)  	return size;  } -static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, -			  int unused3, int unused4) +static void g4x_update_wm(struct drm_device *dev,  int planea_clock, +			  int planeb_clock, int sr_hdisplay, int pixel_size)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	u32 fw_blc_self = I915_READ(FW_BLC_SELF); +	int total_size, cacheline_size; +	int planea_wm, planeb_wm, cursora_wm, cursorb_wm, cursor_sr; +	struct intel_watermark_params planea_params, planeb_params; +	unsigned long line_time_us; +	int sr_clock, sr_entries = 0, entries_required; -	if (i915_powersave) -		fw_blc_self |= FW_BLC_SELF_EN; -	else -		fw_blc_self &= ~FW_BLC_SELF_EN; -	I915_WRITE(FW_BLC_SELF, fw_blc_self); +	/* Create copies of the base settings for each pipe */ +	planea_params = planeb_params = g4x_wm_info; + +	/* Grab a couple of global values before we overwrite them */ +	total_size = planea_params.fifo_size; +	cacheline_size = planea_params.cacheline_size; + +	/* +	 * Note: we need to make sure we don't overflow for various clock & +	 * latency values. +	 * clocks go from a few thousand to several hundred thousand. +	 * latency is usually a few thousand +	 */ +	entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / +		1000; +	entries_required /= G4X_FIFO_LINE_SIZE; +	planea_wm = entries_required + planea_params.guard_size; + +	entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / +		1000; +	entries_required /= G4X_FIFO_LINE_SIZE; +	planeb_wm = entries_required + planeb_params.guard_size; + +	cursora_wm = cursorb_wm = 16; +	cursor_sr = 32; + +	DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); + +	/* Calc sr entries for one plane configs */ +	if (sr_hdisplay && (!planea_clock || !planeb_clock)) { +		/* self-refresh has much higher latency */ +		const static int sr_latency_ns = 12000; + +		sr_clock = planea_clock ? planea_clock : planeb_clock; +		line_time_us = ((sr_hdisplay * 1000) / sr_clock); + +		/* Use ns/us then divide to preserve precision */ +		sr_entries = (((sr_latency_ns / line_time_us) + 1) * +			      pixel_size * sr_hdisplay) / 1000; +		sr_entries = roundup(sr_entries / cacheline_size, 1); +		DRM_DEBUG("self-refresh entries: %d\n", sr_entries); +		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); +	} + +	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", +		  planea_wm, planeb_wm, sr_entries); + +	planea_wm &= 0x3f; +	planeb_wm &= 0x3f; + +	I915_WRITE(DSPFW1, (sr_entries << DSPFW_SR_SHIFT) | +		   (cursorb_wm << DSPFW_CURSORB_SHIFT) | +		   (planeb_wm << DSPFW_PLANEB_SHIFT) | planea_wm); +	I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | +		   (cursora_wm << DSPFW_CURSORA_SHIFT)); +	/* HPLL off in SR has some issues on G4x... disable it */ +	I915_WRITE(DSPFW3, (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | +		   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));  }  static void i965_update_wm(struct drm_device *dev, int unused, int unused2, @@ -2586,6 +2655,9 @@ static void intel_update_watermarks(struct drm_device *dev)  	unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;  	int enabled = 0, pixel_size = 0; +	if (!dev_priv->display.update_wm) +		return; +  	/* Get the clock config from both planes */  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {  		intel_crtc = to_intel_crtc(crtc); @@ -2763,7 +2835,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  	/* FDI link */  	if (IS_IGDNG(dev)) { -		int lane, link_bw; +		int lane, link_bw, bpp;  		/* eDP doesn't require FDI link, so just set DP M/N  		   according to current link config */  		if (is_edp) { @@ -2782,10 +2854,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  			lane = 4;  			link_bw = 270000;  		} -		igdng_compute_m_n(3, lane, target_clock, + +		/* determine panel color depth */ +		temp = I915_READ(pipeconf_reg); + +		switch (temp & PIPE_BPC_MASK) { +		case PIPE_8BPC: +			bpp = 24; +			break; +		case PIPE_10BPC: +			bpp = 30; +			break; +		case PIPE_6BPC: +			bpp = 18; +			break; +		case PIPE_12BPC: +			bpp = 36; +			break; +		default: +			DRM_ERROR("unknown pipe bpc value\n"); +			bpp = 24; +		} + +		igdng_compute_m_n(bpp, lane, target_clock,  				  link_bw, &m_n);  	} +	/* Ironlake: try to setup display ref clock before DPLL +	 * enabling. This is only under driver's control after +	 * PCH B stepping, previous chipset stepping should be +	 * ignoring this setting. +	 */ +	if (IS_IGDNG(dev)) { +		temp = I915_READ(PCH_DREF_CONTROL); +		/* Always enable nonspread source */ +		temp &= ~DREF_NONSPREAD_SOURCE_MASK; +		temp |= DREF_NONSPREAD_SOURCE_ENABLE; +		I915_WRITE(PCH_DREF_CONTROL, temp); +		POSTING_READ(PCH_DREF_CONTROL); + +		temp &= ~DREF_SSC_SOURCE_MASK; +		temp |= DREF_SSC_SOURCE_ENABLE; +		I915_WRITE(PCH_DREF_CONTROL, temp); +		POSTING_READ(PCH_DREF_CONTROL); + +		udelay(200); + +		if (is_edp) { +			if (dev_priv->lvds_use_ssc) { +				temp |= DREF_SSC1_ENABLE; +				I915_WRITE(PCH_DREF_CONTROL, temp); +				POSTING_READ(PCH_DREF_CONTROL); + +				udelay(200); + +				temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; +				temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; +				I915_WRITE(PCH_DREF_CONTROL, temp); +				POSTING_READ(PCH_DREF_CONTROL); +			} else { +				temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; +				I915_WRITE(PCH_DREF_CONTROL, temp); +				POSTING_READ(PCH_DREF_CONTROL); +			} +		} +	} +  	if (IS_IGD(dev)) {  		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;  		if (has_reduced_clock) @@ -2936,6 +3070,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  		lvds = I915_READ(lvds_reg);  		lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; +		/* set the corresponsding LVDS_BORDER bit */ +		lvds |= dev_priv->lvds_border_bits;  		/* Set the B0-B3 data pairs corresponding to whether we're going to  		 * set the DPLLs for dual-channel mode or not.  		 */ @@ -4124,7 +4260,9 @@ void intel_init_clock_gating(struct drm_device *dev)  	 * Disable clock gating reported to work incorrectly according to the  	 * specs, but enable as much else as we can.  	 */ -	if (IS_G4X(dev)) { +	if (IS_IGDNG(dev)) { +		return; +	} else if (IS_G4X(dev)) {  		uint32_t dspclk_gate;  		I915_WRITE(RENCLK_GATE_D1, 0);  		I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | @@ -4212,7 +4350,9 @@ static void intel_init_display(struct drm_device *dev)  			i830_get_display_clock_speed;  	/* For FIFO watermark updates */ -	if (IS_G4X(dev)) +	if (IS_IGDNG(dev)) +		dev_priv->display.update_wm = NULL; +	else if (IS_G4X(dev))  		dev_priv->display.update_wm = g4x_update_wm;  	else if (IS_I965G(dev))  		dev_priv->display.update_wm = i965_update_wm; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f4856a510476..d83447557f9b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -400,7 +400,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)  {  	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; -	DRM_ERROR("i2c_init %s\n", name); +	DRM_DEBUG_KMS("i2c_init %s\n", name);  	dp_priv->algo.running = false;  	dp_priv->algo.address = 0;  	dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 808bbe412ba8..05598ae10c4b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -380,7 +380,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,  				adjusted_mode->crtc_vblank_start + vsync_pos;  		/* keep the vsync width constant */  		adjusted_mode->crtc_vsync_end = -				adjusted_mode->crtc_vblank_start + vsync_width; +				adjusted_mode->crtc_vsync_start + vsync_width;  		border = 1;  		break;  	case DRM_MODE_SCALE_ASPECT: @@ -526,6 +526,14 @@ out:  	lvds_priv->pfit_control = pfit_control;  	lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;  	/* +	 * When there exists the border, it means that the LVDS_BORDR +	 * should be enabled. +	 */ +	if (border) +		dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE; +	else +		dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE); +	/*  	 * XXX: It would be nice to support lower refresh rates on the  	 * panels to reduce power consumption, and perhaps match the  	 * user's requested refresh rate. | 
