Commit 91d3f9ba authored by Linus Torvalds's avatar Linus Torvalds

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.
parents 51bb296b 42048781
...@@ -1227,8 +1227,7 @@ static int i915_load_modeset_init(struct drm_device *dev, ...@@ -1227,8 +1227,7 @@ static int i915_load_modeset_init(struct drm_device *dev,
goto out; goto out;
/* Try to set up FBC with a reasonable compressed buffer size */ /* Try to set up FBC with a reasonable compressed buffer size */
if (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev) || IS_GM45(dev)) && if (I915_HAS_FBC(dev) && i915_powersave) {
i915_powersave) {
int cfb_size; int cfb_size;
/* Try to get an 8M buffer... */ /* Try to get an 8M buffer... */
......
...@@ -296,6 +296,12 @@ typedef struct drm_i915_private { ...@@ -296,6 +296,12 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A; u32 saveVBLANK_A;
u32 saveVSYNC_A; u32 saveVSYNC_A;
u32 saveBCLRPAT_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 savePIPEASTAT;
u32 saveDSPASTRIDE; u32 saveDSPASTRIDE;
u32 saveDSPASIZE; u32 saveDSPASIZE;
...@@ -304,8 +310,11 @@ typedef struct drm_i915_private { ...@@ -304,8 +310,11 @@ typedef struct drm_i915_private {
u32 saveDSPASURF; u32 saveDSPASURF;
u32 saveDSPATILEOFF; u32 saveDSPATILEOFF;
u32 savePFIT_PGM_RATIOS; u32 savePFIT_PGM_RATIOS;
u32 saveBLC_HIST_CTL;
u32 saveBLC_PWM_CTL; u32 saveBLC_PWM_CTL;
u32 saveBLC_PWM_CTL2; u32 saveBLC_PWM_CTL2;
u32 saveBLC_CPU_PWM_CTL;
u32 saveBLC_CPU_PWM_CTL2;
u32 saveFPB0; u32 saveFPB0;
u32 saveFPB1; u32 saveFPB1;
u32 saveDPLL_B; u32 saveDPLL_B;
...@@ -317,6 +326,12 @@ typedef struct drm_i915_private { ...@@ -317,6 +326,12 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B; u32 saveVBLANK_B;
u32 saveVSYNC_B; u32 saveVSYNC_B;
u32 saveBCLRPAT_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 savePIPEBSTAT;
u32 saveDSPBSTRIDE; u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE; u32 saveDSPBSIZE;
...@@ -342,6 +357,7 @@ typedef struct drm_i915_private { ...@@ -342,6 +357,7 @@ typedef struct drm_i915_private {
u32 savePFIT_CONTROL; u32 savePFIT_CONTROL;
u32 save_palette_a[256]; u32 save_palette_a[256];
u32 save_palette_b[256]; u32 save_palette_b[256];
u32 saveDPFC_CB_BASE;
u32 saveFBC_CFB_BASE; u32 saveFBC_CFB_BASE;
u32 saveFBC_LL_BASE; u32 saveFBC_LL_BASE;
u32 saveFBC_CONTROL; u32 saveFBC_CONTROL;
...@@ -349,6 +365,12 @@ typedef struct drm_i915_private { ...@@ -349,6 +365,12 @@ typedef struct drm_i915_private {
u32 saveIER; u32 saveIER;
u32 saveIIR; u32 saveIIR;
u32 saveIMR; u32 saveIMR;
u32 saveDEIER;
u32 saveDEIMR;
u32 saveGTIER;
u32 saveGTIMR;
u32 saveFDI_RXA_IMR;
u32 saveFDI_RXB_IMR;
u32 saveCACHE_MODE_0; u32 saveCACHE_MODE_0;
u32 saveD_STATE; u32 saveD_STATE;
u32 saveDSPCLK_GATE_D; u32 saveDSPCLK_GATE_D;
...@@ -382,6 +404,16 @@ typedef struct drm_i915_private { ...@@ -382,6 +404,16 @@ typedef struct drm_i915_private {
u32 savePIPEB_DP_LINK_M; u32 savePIPEB_DP_LINK_M;
u32 savePIPEA_DP_LINK_N; u32 savePIPEA_DP_LINK_N;
u32 savePIPEB_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 {
struct drm_mm gtt_space; struct drm_mm gtt_space;
...@@ -492,6 +524,8 @@ typedef struct drm_i915_private { ...@@ -492,6 +524,8 @@ typedef struct drm_i915_private {
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
} mm; } mm;
struct sdvo_device_mapping sdvo_mappings[2]; struct sdvo_device_mapping sdvo_mappings[2];
/* indicate whether the LVDS_BORDER should be enabled or not */
unsigned int lvds_border_bits;
/* Reclocking support */ /* Reclocking support */
bool render_reclock_avail; bool render_reclock_avail;
...@@ -981,7 +1015,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); ...@@ -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_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
#define HAS_PIPE_CXSR(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) #define PRIMARY_RINGBUFFER_SIZE (128*1024)
......
...@@ -968,6 +968,8 @@ ...@@ -968,6 +968,8 @@
#define LVDS_PORT_EN (1 << 31) #define LVDS_PORT_EN (1 << 31)
/* Selects pipe B for LVDS data. Must be set on pre-965. */ /* Selects pipe B for LVDS data. Must be set on pre-965. */
#define LVDS_PIPEB_SELECT (1 << 30) #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 * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
* pixel. * pixel.
...@@ -1078,6 +1080,8 @@ ...@@ -1078,6 +1080,8 @@
#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
#define BLC_HIST_CTL 0x61260
/* TV port control */ /* TV port control */
#define TV_CTL 0x68000 #define TV_CTL 0x68000
/** Enables the TV encoder */ /** Enables the TV encoder */
...@@ -1780,6 +1784,11 @@ ...@@ -1780,6 +1784,11 @@
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) #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 0x70030
#define DSPARB_CSTART_MASK (0x7f << 7) #define DSPARB_CSTART_MASK (0x7f << 7)
...@@ -1790,17 +1799,29 @@ ...@@ -1790,17 +1799,29 @@
#define DSPARB_AEND_SHIFT 0 #define DSPARB_AEND_SHIFT 0
#define DSPFW1 0x70034 #define DSPFW1 0x70034
#define DSPFW_SR_SHIFT 23
#define DSPFW_CURSORB_SHIFT 16
#define DSPFW_PLANEB_SHIFT 8
#define DSPFW2 0x70038 #define DSPFW2 0x70038
#define DSPFW_CURSORA_MASK 0x00003f00
#define DSPFW_CURSORA_SHIFT 16
#define DSPFW3 0x7003c #define DSPFW3 0x7003c
#define DSPFW_HPLL_SR_EN (1<<31)
#define DSPFW_CURSOR_SR_SHIFT 24
#define IGD_SELF_REFRESH_EN (1<<30) #define IGD_SELF_REFRESH_EN (1<<30)
/* FIFO watermark sizes etc */ /* FIFO watermark sizes etc */
#define G4X_FIFO_LINE_SIZE 64
#define I915_FIFO_LINE_SIZE 64 #define I915_FIFO_LINE_SIZE 64
#define I830_FIFO_LINE_SIZE 32 #define I830_FIFO_LINE_SIZE 32
#define G4X_FIFO_SIZE 127
#define I945_FIFO_SIZE 127 /* 945 & 965 */ #define I945_FIFO_SIZE 127 /* 945 & 965 */
#define I915_FIFO_SIZE 95 #define I915_FIFO_SIZE 95
#define I855GM_FIFO_SIZE 127 /* In cachelines */ #define I855GM_FIFO_SIZE 127 /* In cachelines */
#define I830_FIFO_SIZE 95 #define I830_FIFO_SIZE 95
#define G4X_MAX_WM 0x3f
#define I915_MAX_WM 0x3f #define I915_MAX_WM 0x3f
#define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */
...@@ -2030,6 +2051,11 @@ ...@@ -2030,6 +2051,11 @@
#define PFA_CTL_1 0x68080 #define PFA_CTL_1 0x68080
#define PFB_CTL_1 0x68880 #define PFB_CTL_1 0x68880
#define PF_ENABLE (1<<31) #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 PFA_WIN_SZ 0x68074
#define PFB_WIN_SZ 0x68874 #define PFB_WIN_SZ 0x68874
#define PFA_WIN_POS 0x68070 #define PFA_WIN_POS 0x68070
...@@ -2149,11 +2175,11 @@ ...@@ -2149,11 +2175,11 @@
#define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13) #define DREF_CPU_SOURCE_OUTPUT_MASK (3<<13)
#define DREF_SSC_SOURCE_DISABLE (0<<11) #define DREF_SSC_SOURCE_DISABLE (0<<11)
#define DREF_SSC_SOURCE_ENABLE (2<<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_SOURCE_DISABLE (0<<9)
#define DREF_NONSPREAD_CK505_ENABLE (1<<9) #define DREF_NONSPREAD_CK505_ENABLE (1<<9)
#define DREF_NONSPREAD_SOURCE_ENABLE (2<<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_DISABLE (0<<7)
#define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) #define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7)
#define DREF_SSC4_DOWNSPREAD (0<<6) #define DREF_SSC4_DOWNSPREAD (0<<6)
......
This diff is collapsed.
...@@ -351,20 +351,18 @@ parse_driver_features(struct drm_i915_private *dev_priv, ...@@ -351,20 +351,18 @@ parse_driver_features(struct drm_i915_private *dev_priv,
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
struct bdb_driver_features *driver; 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); driver = find_section(bdb, BDB_DRIVER_FEATURES);
if (!driver) if (!driver)
return; 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; 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; dev_priv->render_reclock_avail = true;
} }
......
...@@ -943,6 +943,7 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, ...@@ -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.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
clock.p = (clock.p1 * clock.p2); clock.p = (clock.p1 * clock.p2);
clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
clock.vco = 0;
memcpy(best_clock, &clock, sizeof(intel_clock_t)); memcpy(best_clock, &clock, sizeof(intel_clock_t));
return true; return true;
} }
...@@ -1260,9 +1261,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -1260,9 +1261,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return ret; return ret;
} }
/* Pre-i965 needs to install a fence for tiled scan-out */ /* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
if (!IS_I965G(dev) && * whereas 965+ only requires a fence if using framebuffer compression.
obj_priv->fence_reg == I915_FENCE_REG_NONE && * 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) { obj_priv->tiling_mode != I915_TILING_NONE) {
ret = i915_gem_object_get_fence_reg(obj); ret = i915_gem_object_get_fence_reg(obj);
if (ret != 0) { if (ret != 0) {
...@@ -1513,7 +1516,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1513,7 +1516,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Enable panel fitting for LVDS */ /* Enable panel fitting for LVDS */
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
temp = I915_READ(pf_ctl_reg); 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 */ /* currently full aspect */
I915_WRITE(pf_win_pos, 0); I915_WRITE(pf_win_pos, 0);
...@@ -1801,6 +1804,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -1801,6 +1804,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
intel_update_watermarks(dev);
/* Enable the DPLL */ /* Enable the DPLL */
temp = I915_READ(dpll_reg); temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) == 0) { if ((temp & DPLL_VCO_ENABLE) == 0) {
...@@ -1838,7 +1843,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -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 */ /* Give the overlay scaler a chance to enable if it's on this pipe */
//intel_crtc_dpms_video(crtc, true); TODO //intel_crtc_dpms_video(crtc, true); TODO
intel_update_watermarks(dev);
break; break;
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
intel_update_watermarks(dev); intel_update_watermarks(dev);
...@@ -2082,7 +2086,7 @@ fdi_reduce_ratio(u32 *num, u32 *den) ...@@ -2082,7 +2086,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)
#define LINK_N 0x80000 #define LINK_N 0x80000
static void 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, int pixel_clock, int link_clock,
struct fdi_m_n *m_n) struct fdi_m_n *m_n)
{ {
...@@ -2092,7 +2096,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, ...@@ -2092,7 +2096,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,
temp = (u64) DATA_N * pixel_clock; temp = (u64) DATA_N * pixel_clock;
temp = div_u64(temp, link_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; m_n->gmch_n = DATA_N;
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_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 = { ...@@ -2140,6 +2145,13 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = {
IGD_CURSOR_GUARD_WM, IGD_CURSOR_GUARD_WM,
IGD_FIFO_LINE_SIZE 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 = { static struct intel_watermark_params i945_wm_info = {
I945_FIFO_SIZE, I945_FIFO_SIZE,
I915_MAX_WM, I915_MAX_WM,
...@@ -2430,17 +2442,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) ...@@ -2430,17 +2442,74 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane)
return size; return size;
} }
static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, static void g4x_update_wm(struct drm_device *dev, int planea_clock,
int unused3, int unused4) int planeb_clock, int sr_hdisplay, int pixel_size)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; 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) /* Create copies of the base settings for each pipe */
fw_blc_self |= FW_BLC_SELF_EN; planea_params = planeb_params = g4x_wm_info;
else
fw_blc_self &= ~FW_BLC_SELF_EN; /* Grab a couple of global values before we overwrite them */
I915_WRITE(FW_BLC_SELF, fw_blc_self); 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, 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) ...@@ -2586,6 +2655,9 @@ static void intel_update_watermarks(struct drm_device *dev)
unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
int enabled = 0, pixel_size = 0; int enabled = 0, pixel_size = 0;
if (!dev_priv->display.update_wm)
return;
/* Get the clock config from both planes */ /* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc); intel_crtc = to_intel_crtc(crtc);
...@@ -2763,7 +2835,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -2763,7 +2835,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* FDI link */ /* FDI link */
if (IS_IGDNG(dev)) { 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 /* eDP doesn't require FDI link, so just set DP M/N
according to current link config */ according to current link config */
if (is_edp) { if (is_edp) {
...@@ -2782,10 +2854,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -2782,10 +2854,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lane = 4; lane = 4;
link_bw = 270000; 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); 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)) { if (IS_IGD(dev)) {
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock) if (has_reduced_clock)
...@@ -2936,6 +3070,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -2936,6 +3070,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lvds = I915_READ(lvds_reg); lvds = I915_READ(lvds_reg);
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; 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 B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not. * set the DPLLs for dual-channel mode or not.
*/ */
...@@ -4124,7 +4260,9 @@ void intel_init_clock_gating(struct drm_device *dev) ...@@ -4124,7 +4260,9 @@ void intel_init_clock_gating(struct drm_device *dev)
* Disable clock gating reported to work incorrectly according to the * Disable clock gating reported to work incorrectly according to the
* specs, but enable as much else as we can. * 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; uint32_t dspclk_gate;
I915_WRITE(RENCLK_GATE_D1, 0); I915_WRITE(RENCLK_GATE_D1, 0);
I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
...@@ -4212,7 +4350,9 @@ static void intel_init_display(struct drm_device *dev) ...@@ -4212,7 +4350,9 @@ static void intel_init_display(struct drm_device *dev)
i830_get_display_clock_speed; i830_get_display_clock_speed;
/* For FIFO watermark updates */ /* 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; dev_priv->display.update_wm = g4x_update_wm;
else if (IS_I965G(dev)) else if (IS_I965G(dev))
dev_priv->display.update_wm = i965_update_wm; dev_priv->display.update_wm = i965_update_wm;
......
...@@ -400,7 +400,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) ...@@ -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; 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.running = false;
dp_priv->algo.address = 0; dp_priv->algo.address = 0;
dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
......
...@@ -380,7 +380,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -380,7 +380,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
adjusted_mode->crtc_vblank_start + vsync_pos; adjusted_mode->crtc_vblank_start + vsync_pos;
/* keep the vsync width constant */ /* keep the vsync width constant */
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_end =
adjusted_mode->crtc_vblank_start + vsync_width; adjusted_mode->crtc_vsync_start + vsync_width;
border = 1; border = 1;
break; break;
case DRM_MODE_SCALE_ASPECT: case DRM_MODE_SCALE_ASPECT:
...@@ -525,6 +525,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -525,6 +525,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
out: out:
lvds_priv->pfit_control = pfit_control; lvds_priv->pfit_control = pfit_control;
lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; 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 * XXX: It would be nice to support lower refresh rates on the
* panels to reduce power consumption, and perhaps match the * panels to reduce power consumption, and perhaps match the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment