diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 32d1b3e829c8..0defd4270594 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -52,9 +52,12 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
| 52 | unsigned int i915_semaphores = 0; | 52 | unsigned int i915_semaphores = 0; |
| 53 | module_param_named(semaphores, i915_semaphores, int, 0600); | 53 | module_param_named(semaphores, i915_semaphores, int, 0600); |
| 54 | 54 | ||
| 55 | unsigned int i915_enable_rc6 = 0; | 55 | unsigned int i915_enable_rc6 = 1; |
| 56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); |
| 57 | 57 | ||
| 58 | unsigned int i915_enable_fbc = 0; | ||
| 59 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); | ||
| 60 | |||
| 58 | unsigned int i915_lvds_downclock = 0; | 61 | unsigned int i915_lvds_downclock = 0; |
| 59 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); | 62 | module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); |
| 60 | 63 | ||
| @@ -169,7 +172,7 @@ static const struct intel_device_info intel_ironlake_d_info = { | |||
| 169 | static const struct intel_device_info intel_ironlake_m_info = { | 172 | static const struct intel_device_info intel_ironlake_m_info = { |
| 170 | .gen = 5, .is_mobile = 1, | 173 | .gen = 5, .is_mobile = 1, |
| 171 | .need_gfx_hws = 1, .has_hotplug = 1, | 174 | .need_gfx_hws = 1, .has_hotplug = 1, |
| 172 | .has_fbc = 0, /* disabled due to buggy hardware */ | 175 | .has_fbc = 1, |
| 173 | .has_bsd_ring = 1, | 176 | .has_bsd_ring = 1, |
| 174 | }; | 177 | }; |
| 175 | 178 | ||
| @@ -188,6 +191,21 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
| 188 | .has_blt_ring = 1, | 191 | .has_blt_ring = 1, |
| 189 | }; | 192 | }; |
| 190 | 193 | ||
| 194 | static const struct intel_device_info intel_ivybridge_d_info = { | ||
| 195 | .is_ivybridge = 1, .gen = 7, | ||
| 196 | .need_gfx_hws = 1, .has_hotplug = 1, | ||
| 197 | .has_bsd_ring = 1, | ||
| 198 | .has_blt_ring = 1, | ||
| 199 | }; | ||
| 200 | |||
| 201 | static const struct intel_device_info intel_ivybridge_m_info = { | ||
| 202 | .is_ivybridge = 1, .gen = 7, .is_mobile = 1, | ||
| 203 | .need_gfx_hws = 1, .has_hotplug = 1, | ||
| 204 | .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ | ||
| 205 | .has_bsd_ring = 1, | ||
| 206 | .has_blt_ring = 1, | ||
| 207 | }; | ||
| 208 | |||
| 191 | static const struct pci_device_id pciidlist[] = { /* aka */ | 209 | static const struct pci_device_id pciidlist[] = { /* aka */ |
| 192 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ | 210 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ |
| 193 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ | 211 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ |
| @@ -227,6 +245,11 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
| 227 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), | 245 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), |
| 228 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | 246 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), |
| 229 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), | 247 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), |
| 248 | INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ | ||
| 249 | INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ | ||
| 250 | INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ | ||
| 251 | INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ | ||
| 252 | INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ | ||
| 230 | {0, 0, 0} | 253 | {0, 0, 0} |
| 231 | }; | 254 | }; |
| 232 | 255 | ||
| @@ -235,7 +258,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist); | |||
| 235 | #endif | 258 | #endif |
| 236 | 259 | ||
| 237 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 | 260 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 |
| 261 | #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 | ||
| 238 | #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 | 262 | #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 |
| 263 | #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 | ||
| 239 | 264 | ||
| 240 | void intel_detect_pch (struct drm_device *dev) | 265 | void intel_detect_pch (struct drm_device *dev) |
| 241 | { | 266 | { |
| @@ -254,16 +279,23 @@ void intel_detect_pch (struct drm_device *dev) | |||
| 254 | int id; | 279 | int id; |
| 255 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; | 280 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; |
| 256 | 281 | ||
| 257 | if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { | 282 | if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { |
| 283 | dev_priv->pch_type = PCH_IBX; | ||
| 284 | DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); | ||
| 285 | } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { | ||
| 258 | dev_priv->pch_type = PCH_CPT; | 286 | dev_priv->pch_type = PCH_CPT; |
| 259 | DRM_DEBUG_KMS("Found CougarPoint PCH\n"); | 287 | DRM_DEBUG_KMS("Found CougarPoint PCH\n"); |
| 288 | } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { | ||
| 289 | /* PantherPoint is CPT compatible */ | ||
| 290 | dev_priv->pch_type = PCH_CPT; | ||
| 291 | DRM_DEBUG_KMS("Found PatherPoint PCH\n"); | ||
| 260 | } | 292 | } |
| 261 | } | 293 | } |
| 262 | pci_dev_put(pch); | 294 | pci_dev_put(pch); |
| 263 | } | 295 | } |
| 264 | } | 296 | } |
| 265 | 297 | ||
| 266 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 298 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
| 267 | { | 299 | { |
| 268 | int count; | 300 | int count; |
| 269 | 301 | ||
| @@ -279,12 +311,38 @@ void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
| 279 | udelay(10); | 311 | udelay(10); |
| 280 | } | 312 | } |
| 281 | 313 | ||
| 282 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 314 | /* |
| 315 | * Generally this is called implicitly by the register read function. However, | ||
| 316 | * if some sequence requires the GT to not power down then this function should | ||
| 317 | * be called at the beginning of the sequence followed by a call to | ||
| 318 | * gen6_gt_force_wake_put() at the end of the sequence. | ||
| 319 | */ | ||
| 320 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | ||
| 321 | { | ||
| 322 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | ||
| 323 | |||
| 324 | /* Forcewake is atomic in case we get in here without the lock */ | ||
| 325 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) | ||
| 326 | __gen6_gt_force_wake_get(dev_priv); | ||
| 327 | } | ||
| 328 | |||
| 329 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
| 283 | { | 330 | { |
| 284 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 331 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
| 285 | POSTING_READ(FORCEWAKE); | 332 | POSTING_READ(FORCEWAKE); |
| 286 | } | 333 | } |
| 287 | 334 | ||
| 335 | /* | ||
| 336 | * see gen6_gt_force_wake_get() | ||
| 337 | */ | ||
| 338 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | ||
| 339 | { | ||
| 340 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | ||
| 341 | |||
| 342 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) | ||
| 343 | __gen6_gt_force_wake_put(dev_priv); | ||
| 344 | } | ||
| 345 | |||
| 288 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | 346 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
| 289 | { | 347 | { |
| 290 | int loop = 500; | 348 | int loop = 500; |
