diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 66 |
4 files changed, 51 insertions, 36 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 213aa3f67314..322070c0c631 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -566,23 +566,14 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
| 566 | { | 566 | { |
| 567 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 567 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
| 568 | struct drm_device *dev = node->minor->dev; | 568 | struct drm_device *dev = node->minor->dev; |
| 569 | struct drm_crtc *crtc; | ||
| 570 | drm_i915_private_t *dev_priv = dev->dev_private; | 569 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 571 | bool fbc_enabled = false; | ||
| 572 | 570 | ||
| 573 | if (!dev_priv->display.fbc_enabled) { | 571 | if (!I915_HAS_FBC(dev)) { |
| 574 | seq_printf(m, "FBC unsupported on this chipset\n"); | 572 | seq_printf(m, "FBC unsupported on this chipset\n"); |
| 575 | return 0; | 573 | return 0; |
| 576 | } | 574 | } |
| 577 | 575 | ||
| 578 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 576 | if (intel_fbc_enabled(dev)) { |
| 579 | if (!crtc->enabled) | ||
| 580 | continue; | ||
| 581 | if (dev_priv->display.fbc_enabled(crtc)) | ||
| 582 | fbc_enabled = true; | ||
| 583 | } | ||
| 584 | |||
| 585 | if (fbc_enabled) { | ||
| 586 | seq_printf(m, "FBC enabled\n"); | 577 | seq_printf(m, "FBC enabled\n"); |
| 587 | } else { | 578 | } else { |
| 588 | seq_printf(m, "FBC disabled: "); | 579 | seq_printf(m, "FBC disabled: "); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 52e468bbd5e4..03d1d3a1a6c1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1357,11 +1357,10 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
| 1357 | 1357 | ||
| 1358 | dev_priv->cfb_size = size; | 1358 | dev_priv->cfb_size = size; |
| 1359 | 1359 | ||
| 1360 | intel_disable_fbc(dev); | ||
| 1360 | if (IS_GM45(dev)) { | 1361 | if (IS_GM45(dev)) { |
| 1361 | g4x_disable_fbc(dev); | ||
| 1362 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1362 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
| 1363 | } else { | 1363 | } else { |
| 1364 | i8xx_disable_fbc(dev); | ||
| 1365 | I915_WRITE(FBC_CFB_BASE, cfb_base); | 1364 | I915_WRITE(FBC_CFB_BASE, cfb_base); |
| 1366 | I915_WRITE(FBC_LL_BASE, ll_base); | 1365 | I915_WRITE(FBC_LL_BASE, ll_base); |
| 1367 | } | 1366 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 242993bedab3..c06d203b709b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -175,7 +175,7 @@ struct drm_i915_error_state { | |||
| 175 | 175 | ||
| 176 | struct drm_i915_display_funcs { | 176 | struct drm_i915_display_funcs { |
| 177 | void (*dpms)(struct drm_crtc *crtc, int mode); | 177 | void (*dpms)(struct drm_crtc *crtc, int mode); |
| 178 | bool (*fbc_enabled)(struct drm_crtc *crtc); | 178 | bool (*fbc_enabled)(struct drm_device *dev); |
| 179 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); | 179 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); |
| 180 | void (*disable_fbc)(struct drm_device *dev); | 180 | void (*disable_fbc)(struct drm_device *dev); |
| 181 | int (*get_display_clock_speed)(struct drm_device *dev); | 181 | int (*get_display_clock_speed)(struct drm_device *dev); |
| @@ -1006,6 +1006,9 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
| 1006 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 1006 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
| 1007 | extern void i8xx_disable_fbc(struct drm_device *dev); | 1007 | extern void i8xx_disable_fbc(struct drm_device *dev); |
| 1008 | extern void g4x_disable_fbc(struct drm_device *dev); | 1008 | extern void g4x_disable_fbc(struct drm_device *dev); |
| 1009 | extern void intel_disable_fbc(struct drm_device *dev); | ||
| 1010 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | ||
| 1011 | extern bool intel_fbc_enabled(struct drm_device *dev); | ||
| 1009 | 1012 | ||
| 1010 | extern void intel_detect_pch (struct drm_device *dev); | 1013 | extern void intel_detect_pch (struct drm_device *dev); |
| 1011 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1014 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 119a41ac3bb6..84c1aca8637e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -1048,9 +1048,8 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
| 1048 | DRM_DEBUG_KMS("disabled FBC\n"); | 1048 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1049 | } | 1049 | } |
| 1050 | 1050 | ||
| 1051 | static bool i8xx_fbc_enabled(struct drm_crtc *crtc) | 1051 | static bool i8xx_fbc_enabled(struct drm_device *dev) |
| 1052 | { | 1052 | { |
| 1053 | struct drm_device *dev = crtc->dev; | ||
| 1054 | struct drm_i915_private *dev_priv = dev->dev_private; | 1053 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1055 | 1054 | ||
| 1056 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; | 1055 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; |
| @@ -1107,14 +1106,43 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
| 1107 | DRM_DEBUG_KMS("disabled FBC\n"); | 1106 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1108 | } | 1107 | } |
| 1109 | 1108 | ||
| 1110 | static bool g4x_fbc_enabled(struct drm_crtc *crtc) | 1109 | static bool g4x_fbc_enabled(struct drm_device *dev) |
| 1111 | { | 1110 | { |
| 1112 | struct drm_device *dev = crtc->dev; | ||
| 1113 | struct drm_i915_private *dev_priv = dev->dev_private; | 1111 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1114 | 1112 | ||
| 1115 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | 1113 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
| 1116 | } | 1114 | } |
| 1117 | 1115 | ||
| 1116 | bool intel_fbc_enabled(struct drm_device *dev) | ||
| 1117 | { | ||
| 1118 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1119 | |||
| 1120 | if (!dev_priv->display.fbc_enabled) | ||
| 1121 | return false; | ||
| 1122 | |||
| 1123 | return dev_priv->display.fbc_enabled(dev); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
| 1127 | { | ||
| 1128 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | ||
| 1129 | |||
| 1130 | if (!dev_priv->display.enable_fbc) | ||
| 1131 | return; | ||
| 1132 | |||
| 1133 | dev_priv->display.enable_fbc(crtc, interval); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | void intel_disable_fbc(struct drm_device *dev) | ||
| 1137 | { | ||
| 1138 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1139 | |||
| 1140 | if (!dev_priv->display.disable_fbc) | ||
| 1141 | return; | ||
| 1142 | |||
| 1143 | dev_priv->display.disable_fbc(dev); | ||
| 1144 | } | ||
| 1145 | |||
| 1118 | /** | 1146 | /** |
| 1119 | * intel_update_fbc - enable/disable FBC as needed | 1147 | * intel_update_fbc - enable/disable FBC as needed |
| 1120 | * @crtc: CRTC to point the compressor at | 1148 | * @crtc: CRTC to point the compressor at |
| @@ -1149,9 +1177,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
| 1149 | if (!i915_powersave) | 1177 | if (!i915_powersave) |
| 1150 | return; | 1178 | return; |
| 1151 | 1179 | ||
| 1152 | if (!dev_priv->display.fbc_enabled || | 1180 | if (!I915_HAS_FBC(dev)) |
| 1153 | !dev_priv->display.enable_fbc || | ||
| 1154 | !dev_priv->display.disable_fbc) | ||
| 1155 | return; | 1181 | return; |
| 1156 | 1182 | ||
| 1157 | if (!crtc->fb) | 1183 | if (!crtc->fb) |
| @@ -1198,28 +1224,25 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
| 1198 | goto out_disable; | 1224 | goto out_disable; |
| 1199 | } | 1225 | } |
| 1200 | 1226 | ||
| 1201 | if (dev_priv->display.fbc_enabled(crtc)) { | 1227 | if (intel_fbc_enabled(dev)) { |
| 1202 | /* We can re-enable it in this case, but need to update pitch */ | 1228 | /* We can re-enable it in this case, but need to update pitch */ |
| 1203 | if (fb->pitch > dev_priv->cfb_pitch) | 1229 | if ((fb->pitch > dev_priv->cfb_pitch) || |
| 1204 | dev_priv->display.disable_fbc(dev); | 1230 | (obj_priv->fence_reg != dev_priv->cfb_fence) || |
| 1205 | if (obj_priv->fence_reg != dev_priv->cfb_fence) | 1231 | (plane != dev_priv->cfb_plane)) |
| 1206 | dev_priv->display.disable_fbc(dev); | 1232 | intel_disable_fbc(dev); |
| 1207 | if (plane != dev_priv->cfb_plane) | ||
| 1208 | dev_priv->display.disable_fbc(dev); | ||
| 1209 | } | 1233 | } |
| 1210 | 1234 | ||
| 1211 | if (!dev_priv->display.fbc_enabled(crtc)) { | 1235 | /* Now try to turn it back on if possible */ |
| 1212 | /* Now try to turn it back on if possible */ | 1236 | if (!intel_fbc_enabled(dev)) |
| 1213 | dev_priv->display.enable_fbc(crtc, 500); | 1237 | intel_enable_fbc(crtc, 500); |
| 1214 | } | ||
| 1215 | 1238 | ||
| 1216 | return; | 1239 | return; |
| 1217 | 1240 | ||
| 1218 | out_disable: | 1241 | out_disable: |
| 1219 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | 1242 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); |
| 1220 | /* Multiple disables should be harmless */ | 1243 | /* Multiple disables should be harmless */ |
| 1221 | if (dev_priv->display.fbc_enabled(crtc)) | 1244 | if (intel_fbc_enabled(dev)) |
| 1222 | dev_priv->display.disable_fbc(dev); | 1245 | intel_disable_fbc(dev); |
| 1223 | } | 1246 | } |
| 1224 | 1247 | ||
| 1225 | static int | 1248 | static int |
| @@ -5203,8 +5226,7 @@ static void intel_init_display(struct drm_device *dev) | |||
| 5203 | else | 5226 | else |
| 5204 | dev_priv->display.dpms = i9xx_crtc_dpms; | 5227 | dev_priv->display.dpms = i9xx_crtc_dpms; |
| 5205 | 5228 | ||
| 5206 | /* Only mobile has FBC, leave pointers NULL for other chips */ | 5229 | if (I915_HAS_FBC(dev)) { |
| 5207 | if (IS_MOBILE(dev)) { | ||
| 5208 | if (IS_GM45(dev)) { | 5230 | if (IS_GM45(dev)) { |
| 5209 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | 5231 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
| 5210 | dev_priv->display.enable_fbc = g4x_enable_fbc; | 5232 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
