|
@@ -405,7 +405,7 @@ void intel_update_fbc(struct drm_device *dev)
|
|
|
* - going to an unsupported config (interlace, pixel multiply, etc.)
|
|
|
*/
|
|
|
list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
|
|
|
- if (tmp_crtc->enabled &&
|
|
|
+ if (to_intel_crtc(tmp_crtc)->active &&
|
|
|
!to_intel_crtc(tmp_crtc)->primary_disabled &&
|
|
|
tmp_crtc->fb) {
|
|
|
if (crtc) {
|
|
@@ -992,7 +992,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
|
|
|
struct drm_crtc *crtc, *enabled = NULL;
|
|
|
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
|
|
- if (crtc->enabled && crtc->fb) {
|
|
|
+ if (to_intel_crtc(crtc)->active && crtc->fb) {
|
|
|
if (enabled)
|
|
|
return NULL;
|
|
|
enabled = crtc;
|
|
@@ -1086,7 +1086,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
|
|
|
int entries, tlb_miss;
|
|
|
|
|
|
crtc = intel_get_crtc_for_plane(dev, plane);
|
|
|
- if (crtc->fb == NULL || !crtc->enabled) {
|
|
|
+ if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
|
|
|
*cursor_wm = cursor->guard_size;
|
|
|
*plane_wm = display->guard_size;
|
|
|
return false;
|
|
@@ -1215,7 +1215,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
|
|
|
int entries;
|
|
|
|
|
|
crtc = intel_get_crtc_for_plane(dev, plane);
|
|
|
- if (crtc->fb == NULL || !crtc->enabled)
|
|
|
+ if (crtc->fb == NULL || !to_intel_crtc(crtc)->active)
|
|
|
return false;
|
|
|
|
|
|
clock = crtc->mode.clock; /* VESA DOT Clock */
|
|
@@ -1286,6 +1286,7 @@ static void valleyview_update_wm(struct drm_device *dev)
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
|
|
|
int plane_sr, cursor_sr;
|
|
|
+ int ignore_plane_sr, ignore_cursor_sr;
|
|
|
unsigned int enabled = 0;
|
|
|
|
|
|
vlv_update_drain_latency(dev);
|
|
@@ -1302,17 +1303,23 @@ static void valleyview_update_wm(struct drm_device *dev)
|
|
|
&planeb_wm, &cursorb_wm))
|
|
|
enabled |= 2;
|
|
|
|
|
|
- plane_sr = cursor_sr = 0;
|
|
|
if (single_plane_enabled(enabled) &&
|
|
|
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
|
|
sr_latency_ns,
|
|
|
&valleyview_wm_info,
|
|
|
&valleyview_cursor_wm_info,
|
|
|
- &plane_sr, &cursor_sr))
|
|
|
+ &plane_sr, &ignore_cursor_sr) &&
|
|
|
+ g4x_compute_srwm(dev, ffs(enabled) - 1,
|
|
|
+ 2*sr_latency_ns,
|
|
|
+ &valleyview_wm_info,
|
|
|
+ &valleyview_cursor_wm_info,
|
|
|
+ &ignore_plane_sr, &cursor_sr)) {
|
|
|
I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN);
|
|
|
- else
|
|
|
+ } else {
|
|
|
I915_WRITE(FW_BLC_SELF_VLV,
|
|
|
I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN);
|
|
|
+ plane_sr = cursor_sr = 0;
|
|
|
+ }
|
|
|
|
|
|
DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n",
|
|
|
planea_wm, cursora_wm,
|
|
@@ -1352,17 +1359,18 @@ static void g4x_update_wm(struct drm_device *dev)
|
|
|
&planeb_wm, &cursorb_wm))
|
|
|
enabled |= 2;
|
|
|
|
|
|
- plane_sr = cursor_sr = 0;
|
|
|
if (single_plane_enabled(enabled) &&
|
|
|
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
|
|
sr_latency_ns,
|
|
|
&g4x_wm_info,
|
|
|
&g4x_cursor_wm_info,
|
|
|
- &plane_sr, &cursor_sr))
|
|
|
+ &plane_sr, &cursor_sr)) {
|
|
|
I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
|
|
|
- else
|
|
|
+ } else {
|
|
|
I915_WRITE(FW_BLC_SELF,
|
|
|
I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN);
|
|
|
+ plane_sr = cursor_sr = 0;
|
|
|
+ }
|
|
|
|
|
|
DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n",
|
|
|
planea_wm, cursora_wm,
|
|
@@ -1468,7 +1476,7 @@ static void i9xx_update_wm(struct drm_device *dev)
|
|
|
|
|
|
fifo_size = dev_priv->display.get_fifo_size(dev, 0);
|
|
|
crtc = intel_get_crtc_for_plane(dev, 0);
|
|
|
- if (crtc->enabled && crtc->fb) {
|
|
|
+ if (to_intel_crtc(crtc)->active && crtc->fb) {
|
|
|
int cpp = crtc->fb->bits_per_pixel / 8;
|
|
|
if (IS_GEN2(dev))
|
|
|
cpp = 4;
|
|
@@ -1482,7 +1490,7 @@ static void i9xx_update_wm(struct drm_device *dev)
|
|
|
|
|
|
fifo_size = dev_priv->display.get_fifo_size(dev, 1);
|
|
|
crtc = intel_get_crtc_for_plane(dev, 1);
|
|
|
- if (crtc->enabled && crtc->fb) {
|
|
|
+ if (to_intel_crtc(crtc)->active && crtc->fb) {
|
|
|
int cpp = crtc->fb->bits_per_pixel / 8;
|
|
|
if (IS_GEN2(dev))
|
|
|
cpp = 4;
|
|
@@ -1811,8 +1819,110 @@ static void sandybridge_update_wm(struct drm_device *dev)
|
|
|
enabled |= 2;
|
|
|
}
|
|
|
|
|
|
- if ((dev_priv->num_pipe == 3) &&
|
|
|
- g4x_compute_wm0(dev, 2,
|
|
|
+ /*
|
|
|
+ * Calculate and update the self-refresh watermark only when one
|
|
|
+ * display plane is used.
|
|
|
+ *
|
|
|
+ * SNB support 3 levels of watermark.
|
|
|
+ *
|
|
|
+ * WM1/WM2/WM2 watermarks have to be enabled in the ascending order,
|
|
|
+ * and disabled in the descending order
|
|
|
+ *
|
|
|
+ */
|
|
|
+ I915_WRITE(WM3_LP_ILK, 0);
|
|
|
+ I915_WRITE(WM2_LP_ILK, 0);
|
|
|
+ I915_WRITE(WM1_LP_ILK, 0);
|
|
|
+
|
|
|
+ if (!single_plane_enabled(enabled) ||
|
|
|
+ dev_priv->sprite_scaling_enabled)
|
|
|
+ return;
|
|
|
+ enabled = ffs(enabled) - 1;
|
|
|
+
|
|
|
+ /* WM1 */
|
|
|
+ if (!ironlake_compute_srwm(dev, 1, enabled,
|
|
|
+ SNB_READ_WM1_LATENCY() * 500,
|
|
|
+ &sandybridge_display_srwm_info,
|
|
|
+ &sandybridge_cursor_srwm_info,
|
|
|
+ &fbc_wm, &plane_wm, &cursor_wm))
|
|
|
+ return;
|
|
|
+
|
|
|
+ I915_WRITE(WM1_LP_ILK,
|
|
|
+ WM1_LP_SR_EN |
|
|
|
+ (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) |
|
|
|
+ (fbc_wm << WM1_LP_FBC_SHIFT) |
|
|
|
+ (plane_wm << WM1_LP_SR_SHIFT) |
|
|
|
+ cursor_wm);
|
|
|
+
|
|
|
+ /* WM2 */
|
|
|
+ if (!ironlake_compute_srwm(dev, 2, enabled,
|
|
|
+ SNB_READ_WM2_LATENCY() * 500,
|
|
|
+ &sandybridge_display_srwm_info,
|
|
|
+ &sandybridge_cursor_srwm_info,
|
|
|
+ &fbc_wm, &plane_wm, &cursor_wm))
|
|
|
+ return;
|
|
|
+
|
|
|
+ I915_WRITE(WM2_LP_ILK,
|
|
|
+ WM2_LP_EN |
|
|
|
+ (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) |
|
|
|
+ (fbc_wm << WM1_LP_FBC_SHIFT) |
|
|
|
+ (plane_wm << WM1_LP_SR_SHIFT) |
|
|
|
+ cursor_wm);
|
|
|
+
|
|
|
+ /* WM3 */
|
|
|
+ if (!ironlake_compute_srwm(dev, 3, enabled,
|
|
|
+ SNB_READ_WM3_LATENCY() * 500,
|
|
|
+ &sandybridge_display_srwm_info,
|
|
|
+ &sandybridge_cursor_srwm_info,
|
|
|
+ &fbc_wm, &plane_wm, &cursor_wm))
|
|
|
+ return;
|
|
|
+
|
|
|
+ I915_WRITE(WM3_LP_ILK,
|
|
|
+ WM3_LP_EN |
|
|
|
+ (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) |
|
|
|
+ (fbc_wm << WM1_LP_FBC_SHIFT) |
|
|
|
+ (plane_wm << WM1_LP_SR_SHIFT) |
|
|
|
+ cursor_wm);
|
|
|
+}
|
|
|
+
|
|
|
+static void ivybridge_update_wm(struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */
|
|
|
+ u32 val;
|
|
|
+ int fbc_wm, plane_wm, cursor_wm;
|
|
|
+ int ignore_fbc_wm, ignore_plane_wm, ignore_cursor_wm;
|
|
|
+ unsigned int enabled;
|
|
|
+
|
|
|
+ enabled = 0;
|
|
|
+ if (g4x_compute_wm0(dev, 0,
|
|
|
+ &sandybridge_display_wm_info, latency,
|
|
|
+ &sandybridge_cursor_wm_info, latency,
|
|
|
+ &plane_wm, &cursor_wm)) {
|
|
|
+ val = I915_READ(WM0_PIPEA_ILK);
|
|
|
+ val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
|
|
|
+ I915_WRITE(WM0_PIPEA_ILK, val |
|
|
|
+ ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm));
|
|
|
+ DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
|
|
+ " plane %d, " "cursor: %d\n",
|
|
|
+ plane_wm, cursor_wm);
|
|
|
+ enabled |= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g4x_compute_wm0(dev, 1,
|
|
|
+ &sandybridge_display_wm_info, latency,
|
|
|
+ &sandybridge_cursor_wm_info, latency,
|
|
|
+ &plane_wm, &cursor_wm)) {
|
|
|
+ val = I915_READ(WM0_PIPEB_ILK);
|
|
|
+ val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
|
|
|
+ I915_WRITE(WM0_PIPEB_ILK, val |
|
|
|
+ ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm));
|
|
|
+ DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
|
|
+ " plane %d, cursor: %d\n",
|
|
|
+ plane_wm, cursor_wm);
|
|
|
+ enabled |= 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g4x_compute_wm0(dev, 2,
|
|
|
&sandybridge_display_wm_info, latency,
|
|
|
&sandybridge_cursor_wm_info, latency,
|
|
|
&plane_wm, &cursor_wm)) {
|
|
@@ -1875,12 +1985,17 @@ static void sandybridge_update_wm(struct drm_device *dev)
|
|
|
(plane_wm << WM1_LP_SR_SHIFT) |
|
|
|
cursor_wm);
|
|
|
|
|
|
- /* WM3 */
|
|
|
+ /* WM3, note we have to correct the cursor latency */
|
|
|
if (!ironlake_compute_srwm(dev, 3, enabled,
|
|
|
SNB_READ_WM3_LATENCY() * 500,
|
|
|
&sandybridge_display_srwm_info,
|
|
|
&sandybridge_cursor_srwm_info,
|
|
|
- &fbc_wm, &plane_wm, &cursor_wm))
|
|
|
+ &fbc_wm, &plane_wm, &ignore_cursor_wm) ||
|
|
|
+ !ironlake_compute_srwm(dev, 3, enabled,
|
|
|
+ 2 * SNB_READ_WM3_LATENCY() * 500,
|
|
|
+ &sandybridge_display_srwm_info,
|
|
|
+ &sandybridge_cursor_srwm_info,
|
|
|
+ &ignore_fbc_wm, &ignore_plane_wm, &cursor_wm))
|
|
|
return;
|
|
|
|
|
|
I915_WRITE(WM3_LP_ILK,
|
|
@@ -1929,7 +2044,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
|
|
|
int entries, tlb_miss;
|
|
|
|
|
|
crtc = intel_get_crtc_for_plane(dev, plane);
|
|
|
- if (crtc->fb == NULL || !crtc->enabled) {
|
|
|
+ if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
|
|
|
*sprite_wm = display->guard_size;
|
|
|
return false;
|
|
|
}
|
|
@@ -3471,6 +3586,15 @@ static void gen6_init_clock_gating(struct drm_device *dev)
|
|
|
I915_READ(ILK_DISPLAY_CHICKEN2) |
|
|
|
ILK_ELPIN_409_SELECT);
|
|
|
|
|
|
+ /* WaDisableHiZPlanesWhenMSAAEnabled */
|
|
|
+ I915_WRITE(_3D_CHICKEN,
|
|
|
+ _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
|
|
|
+
|
|
|
+ /* WaSetupGtModeTdRowDispatch */
|
|
|
+ if (IS_SNB_GT1(dev))
|
|
|
+ I915_WRITE(GEN6_GT_MODE,
|
|
|
+ _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE));
|
|
|
+
|
|
|
I915_WRITE(WM3_LP_ILK, 0);
|
|
|
I915_WRITE(WM2_LP_ILK, 0);
|
|
|
I915_WRITE(WM1_LP_ILK, 0);
|
|
@@ -3999,7 +4123,7 @@ void intel_init_pm(struct drm_device *dev)
|
|
|
} else if (IS_IVYBRIDGE(dev)) {
|
|
|
/* FIXME: detect B0+ stepping and use auto training */
|
|
|
if (SNB_READ_WM0_LATENCY()) {
|
|
|
- dev_priv->display.update_wm = sandybridge_update_wm;
|
|
|
+ dev_priv->display.update_wm = ivybridge_update_wm;
|
|
|
dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;
|
|
|
} else {
|
|
|
DRM_DEBUG_KMS("Failed to read display plane latency. "
|