diff options
Diffstat (limited to 'drivers/gpu/drm')
47 files changed, 506 insertions, 284 deletions
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 66d4a28ad5a2..0303935d10e2 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c | |||
| @@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
| 119 | { | 119 | { |
| 120 | const struct firmware *fw; | 120 | const struct firmware *fw; |
| 121 | struct platform_device *pdev; | 121 | struct platform_device *pdev; |
| 122 | u8 *fwdata = NULL, *edid; | 122 | u8 *fwdata = NULL, *edid, *new_edid; |
| 123 | int fwsize, expected; | 123 | int fwsize, expected; |
| 124 | int builtin = 0, err = 0; | 124 | int builtin = 0, err = 0; |
| 125 | int i, valid_extensions = 0; | 125 | int i, valid_extensions = 0; |
| @@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
| 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, | 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, |
| 196 | edid[0x7e], name, connector_name); | 196 | edid[0x7e], name, connector_name); |
| 197 | edid[0x7e] = valid_extensions; | 197 | edid[0x7e] = valid_extensions; |
| 198 | edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, | 198 | new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, |
| 199 | GFP_KERNEL); | 199 | GFP_KERNEL); |
| 200 | if (edid == NULL) { | 200 | if (new_edid == NULL) { |
| 201 | err = -ENOMEM; | 201 | err = -ENOMEM; |
| 202 | kfree(edid); | ||
| 202 | goto relfw_out; | 203 | goto relfw_out; |
| 203 | } | 204 | } |
| 205 | edid = new_edid; | ||
| 204 | } | 206 | } |
| 205 | 207 | ||
| 206 | connector->display_info.raw_edid = edid; | 208 | connector->display_info.raw_edid = edid; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ed22612bc847..a24ffbe97c01 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
| 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ | 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ |
| 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ | 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ |
| 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ | 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ |
| 349 | INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ | ||
| 349 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ | 350 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ |
| 350 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ | 351 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ |
| 352 | INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ | ||
| 351 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ | 353 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ |
| 352 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ | 354 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ |
| 353 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ | 355 | INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ |
| 356 | INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ | ||
| 357 | INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
| 358 | INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
| 359 | INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ | ||
| 360 | INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
| 361 | INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
| 362 | INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ | ||
| 363 | INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
| 364 | INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
| 365 | INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ | ||
| 366 | INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
| 367 | INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
| 368 | INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ | ||
| 369 | INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
| 370 | INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
| 371 | INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ | ||
| 372 | INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
| 373 | INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
| 374 | INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ | ||
| 375 | INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
| 376 | INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
| 377 | INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ | ||
| 378 | INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
| 379 | INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
| 380 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ | ||
| 381 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
| 382 | INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
| 354 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | 383 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), |
| 355 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | 384 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), |
| 356 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | 385 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index da8b01fb1bf8..a9d58d72bb4d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -451,7 +451,6 @@ int i915_switch_context(struct intel_ring_buffer *ring, | |||
| 451 | struct drm_i915_file_private *file_priv = NULL; | 451 | struct drm_i915_file_private *file_priv = NULL; |
| 452 | struct i915_hw_context *to; | 452 | struct i915_hw_context *to; |
| 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; | 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; |
| 454 | int ret; | ||
| 455 | 454 | ||
| 456 | if (dev_priv->hw_contexts_disabled) | 455 | if (dev_priv->hw_contexts_disabled) |
| 457 | return 0; | 456 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5af631e788c8..ff2819ea0813 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -291,6 +291,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
| 291 | target_i915_obj = to_intel_bo(target_obj); | 291 | target_i915_obj = to_intel_bo(target_obj); |
| 292 | target_offset = target_i915_obj->gtt_offset; | 292 | target_offset = target_i915_obj->gtt_offset; |
| 293 | 293 | ||
| 294 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
| 295 | * pipe_control writes because the gpu doesn't properly redirect them | ||
| 296 | * through the ppgtt for non_secure batchbuffers. */ | ||
| 297 | if (unlikely(IS_GEN6(dev) && | ||
| 298 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
| 299 | !target_i915_obj->has_global_gtt_mapping)) { | ||
| 300 | i915_gem_gtt_bind_object(target_i915_obj, | ||
| 301 | target_i915_obj->cache_level); | ||
| 302 | } | ||
| 303 | |||
| 294 | /* The target buffer should have appeared before us in the | 304 | /* The target buffer should have appeared before us in the |
| 295 | * exec_object list, so it should have a GTT space bound by now. | 305 | * exec_object list, so it should have a GTT space bound by now. |
| 296 | */ | 306 | */ |
| @@ -399,16 +409,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
| 399 | io_mapping_unmap_atomic(reloc_page); | 409 | io_mapping_unmap_atomic(reloc_page); |
| 400 | } | 410 | } |
| 401 | 411 | ||
| 402 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
| 403 | * pipe_control writes because the gpu doesn't properly redirect them | ||
| 404 | * through the ppgtt for non_secure batchbuffers. */ | ||
| 405 | if (unlikely(IS_GEN6(dev) && | ||
| 406 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
| 407 | !target_i915_obj->has_global_gtt_mapping)) { | ||
| 408 | i915_gem_gtt_bind_object(target_i915_obj, | ||
| 409 | target_i915_obj->cache_level); | ||
| 410 | } | ||
| 411 | |||
| 412 | /* and update the user's relocation entry */ | 412 | /* and update the user's relocation entry */ |
| 413 | reloc->presumed_offset = target_offset; | 413 | reloc->presumed_offset = target_offset; |
| 414 | 414 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9fd25a435536..ee9b68f6bc36 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -361,7 +361,8 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | |||
| 361 | struct drm_device *dev = obj->base.dev; | 361 | struct drm_device *dev = obj->base.dev; |
| 362 | struct drm_i915_private *dev_priv = dev->dev_private; | 362 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 363 | 363 | ||
| 364 | if (dev_priv->mm.gtt->needs_dmar) | 364 | /* don't map imported dma buf objects */ |
| 365 | if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table) | ||
| 365 | return intel_gtt_map_memory(obj->pages, | 366 | return intel_gtt_map_memory(obj->pages, |
| 366 | obj->base.size >> PAGE_SHIFT, | 367 | obj->base.size >> PAGE_SHIFT, |
| 367 | &obj->sg_list, | 368 | &obj->sg_list, |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 2f5388af8df9..7631807a2788 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "intel_drv.h" | 32 | #include "intel_drv.h" |
| 33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
| 34 | 34 | ||
| 35 | #ifdef CONFIG_PM | ||
| 35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 36 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
| 36 | { | 37 | { |
| 37 | struct drm_i915_private *dev_priv = dev->dev_private; | 38 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -224,3 +225,14 @@ void i915_teardown_sysfs(struct drm_device *dev) | |||
| 224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | 225 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); |
| 225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 226 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
| 226 | } | 227 | } |
| 228 | #else | ||
| 229 | void i915_setup_sysfs(struct drm_device *dev) | ||
| 230 | { | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | |||
| 234 | void i915_teardown_sysfs(struct drm_device *dev) | ||
| 235 | { | ||
| 236 | return; | ||
| 237 | } | ||
| 238 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6159765f1eb..a69a3d0d3acf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -869,6 +869,7 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
| 869 | unsigned long bestppm, ppm, absppm; | 869 | unsigned long bestppm, ppm, absppm; |
| 870 | int dotclk, flag; | 870 | int dotclk, flag; |
| 871 | 871 | ||
| 872 | flag = 0; | ||
| 872 | dotclk = target * 1000; | 873 | dotclk = target * 1000; |
| 873 | bestppm = 1000000; | 874 | bestppm = 1000000; |
| 874 | ppm = absppm = 0; | 875 | ppm = absppm = 0; |
| @@ -3753,17 +3754,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
| 3753 | continue; | 3754 | continue; |
| 3754 | } | 3755 | } |
| 3755 | 3756 | ||
| 3756 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
| 3757 | /* Use VBT settings if we have an eDP panel */ | ||
| 3758 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
| 3759 | |||
| 3760 | if (edp_bpc < display_bpc) { | ||
| 3761 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
| 3762 | display_bpc = edp_bpc; | ||
| 3763 | } | ||
| 3764 | continue; | ||
| 3765 | } | ||
| 3766 | |||
| 3767 | /* Not one of the known troublemakers, check the EDID */ | 3757 | /* Not one of the known troublemakers, check the EDID */ |
| 3768 | list_for_each_entry(connector, &dev->mode_config.connector_list, | 3758 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
| 3769 | head) { | 3759 | head) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a56b9ab0f58..a6c426afaa7a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1174,10 +1174,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
| 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); |
| 1175 | 1175 | ||
| 1176 | pp = ironlake_get_pp_control(dev_priv); | 1176 | pp = ironlake_get_pp_control(dev_priv); |
| 1177 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1177 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
| 1178 | * panels get very unhappy and cease to work. */ | ||
| 1179 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | ||
| 1178 | I915_WRITE(PCH_PP_CONTROL, pp); | 1180 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 1179 | POSTING_READ(PCH_PP_CONTROL); | 1181 | POSTING_READ(PCH_PP_CONTROL); |
| 1180 | 1182 | ||
| 1183 | intel_dp->want_panel_vdd = false; | ||
| 1184 | |||
| 1181 | ironlake_wait_panel_off(intel_dp); | 1185 | ironlake_wait_panel_off(intel_dp); |
| 1182 | } | 1186 | } |
| 1183 | 1187 | ||
| @@ -1287,11 +1291,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
| 1287 | * ensure that we have vdd while we switch off the panel. */ | 1291 | * ensure that we have vdd while we switch off the panel. */ |
| 1288 | ironlake_edp_panel_vdd_on(intel_dp); | 1292 | ironlake_edp_panel_vdd_on(intel_dp); |
| 1289 | ironlake_edp_backlight_off(intel_dp); | 1293 | ironlake_edp_backlight_off(intel_dp); |
| 1290 | ironlake_edp_panel_off(intel_dp); | ||
| 1291 | |||
| 1292 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1294 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
| 1295 | ironlake_edp_panel_off(intel_dp); | ||
| 1293 | intel_dp_link_down(intel_dp); | 1296 | intel_dp_link_down(intel_dp); |
| 1294 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1295 | } | 1297 | } |
| 1296 | 1298 | ||
| 1297 | static void intel_dp_commit(struct drm_encoder *encoder) | 1299 | static void intel_dp_commit(struct drm_encoder *encoder) |
| @@ -1326,11 +1328,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
| 1326 | /* Switching the panel off requires vdd. */ | 1328 | /* Switching the panel off requires vdd. */ |
| 1327 | ironlake_edp_panel_vdd_on(intel_dp); | 1329 | ironlake_edp_panel_vdd_on(intel_dp); |
| 1328 | ironlake_edp_backlight_off(intel_dp); | 1330 | ironlake_edp_backlight_off(intel_dp); |
| 1329 | ironlake_edp_panel_off(intel_dp); | ||
| 1330 | |||
| 1331 | intel_dp_sink_dpms(intel_dp, mode); | 1331 | intel_dp_sink_dpms(intel_dp, mode); |
| 1332 | ironlake_edp_panel_off(intel_dp); | ||
| 1332 | intel_dp_link_down(intel_dp); | 1333 | intel_dp_link_down(intel_dp); |
| 1333 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1334 | 1334 | ||
| 1335 | if (is_cpu_edp(intel_dp)) | 1335 | if (is_cpu_edp(intel_dp)) |
| 1336 | ironlake_edp_pll_off(encoder); | 1336 | ironlake_edp_pll_off(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 84353559441c..132ab511b90c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -46,15 +46,16 @@ | |||
| 46 | }) | 46 | }) |
| 47 | 47 | ||
| 48 | #define wait_for_atomic_us(COND, US) ({ \ | 48 | #define wait_for_atomic_us(COND, US) ({ \ |
| 49 | int i, ret__ = -ETIMEDOUT; \ | 49 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US); \ |
| 50 | for (i = 0; i < (US); i++) { \ | 50 | int ret__ = 0; \ |
| 51 | if ((COND)) { \ | 51 | while (!(COND)) { \ |
| 52 | ret__ = 0; \ | 52 | if (time_after(jiffies, timeout__)) { \ |
| 53 | break; \ | 53 | ret__ = -ETIMEDOUT; \ |
| 54 | } \ | 54 | break; \ |
| 55 | udelay(1); \ | 55 | } \ |
| 56 | } \ | 56 | cpu_relax(); \ |
| 57 | ret__; \ | 57 | } \ |
| 58 | ret__; \ | ||
| 58 | }) | 59 | }) |
| 59 | 60 | ||
| 60 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 61 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
| @@ -380,7 +381,6 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
| 380 | const struct drm_display_mode *mode, | 381 | const struct drm_display_mode *mode, |
| 381 | struct drm_display_mode *adjusted_mode); | 382 | struct drm_display_mode *adjusted_mode); |
| 382 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 383 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
| 383 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | ||
| 384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
| 385 | extern int intel_panel_setup_backlight(struct drm_device *dev); | 385 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
| 386 | extern void intel_panel_enable_backlight(struct drm_device *dev, | 386 | extern void intel_panel_enable_backlight(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 1991a4408cf9..b9755f6378d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
| @@ -486,9 +486,6 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
| 486 | bus->dev_priv = dev_priv; | 486 | bus->dev_priv = dev_priv; |
| 487 | 487 | ||
| 488 | bus->adapter.algo = &gmbus_algorithm; | 488 | bus->adapter.algo = &gmbus_algorithm; |
| 489 | ret = i2c_add_adapter(&bus->adapter); | ||
| 490 | if (ret) | ||
| 491 | goto err; | ||
| 492 | 489 | ||
| 493 | /* By default use a conservative clock rate */ | 490 | /* By default use a conservative clock rate */ |
| 494 | bus->reg0 = port | GMBUS_RATE_100KHZ; | 491 | bus->reg0 = port | GMBUS_RATE_100KHZ; |
| @@ -498,6 +495,10 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
| 498 | bus->force_bit = true; | 495 | bus->force_bit = true; |
| 499 | 496 | ||
| 500 | intel_gpio_setup(bus, port); | 497 | intel_gpio_setup(bus, port); |
| 498 | |||
| 499 | ret = i2c_add_adapter(&bus->adapter); | ||
| 500 | if (ret) | ||
| 501 | goto err; | ||
| 501 | } | 502 | } |
| 502 | 503 | ||
| 503 | intel_i2c_reset(dev_priv->dev); | 504 | intel_i2c_reset(dev_priv->dev); |
| @@ -540,9 +541,6 @@ void intel_teardown_gmbus(struct drm_device *dev) | |||
| 540 | struct drm_i915_private *dev_priv = dev->dev_private; | 541 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 541 | int i; | 542 | int i; |
| 542 | 543 | ||
| 543 | if (dev_priv->gmbus == NULL) | ||
| 544 | return; | ||
| 545 | |||
| 546 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 544 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
| 547 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 545 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
| 548 | i2c_del_adapter(&bus->adapter); | 546 | i2c_del_adapter(&bus->adapter); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 10c7d39034e1..3df4f5fa892a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -213,7 +213,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
| 213 | return val; | 213 | return val; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | u32 intel_panel_get_backlight(struct drm_device *dev) | 216 | static u32 intel_panel_get_backlight(struct drm_device *dev) |
| 217 | { | 217 | { |
| 218 | struct drm_i915_private *dev_priv = dev->dev_private; | 218 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 219 | u32 val; | 219 | u32 val; |
| @@ -311,9 +311,6 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 311 | if (dev_priv->backlight_level == 0) | 311 | if (dev_priv->backlight_level == 0) |
| 312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | 312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); |
| 313 | 313 | ||
| 314 | dev_priv->backlight_enabled = true; | ||
| 315 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
| 316 | |||
| 317 | if (INTEL_INFO(dev)->gen >= 4) { | 314 | if (INTEL_INFO(dev)->gen >= 4) { |
| 318 | uint32_t reg, tmp; | 315 | uint32_t reg, tmp; |
| 319 | 316 | ||
| @@ -326,7 +323,7 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 326 | * we don't track the backlight dpms state, hence check whether | 323 | * we don't track the backlight dpms state, hence check whether |
| 327 | * we have to do anything first. */ | 324 | * we have to do anything first. */ |
| 328 | if (tmp & BLM_PWM_ENABLE) | 325 | if (tmp & BLM_PWM_ENABLE) |
| 329 | return; | 326 | goto set_level; |
| 330 | 327 | ||
| 331 | if (dev_priv->num_pipe == 3) | 328 | if (dev_priv->num_pipe == 3) |
| 332 | tmp &= ~BLM_PIPE_SELECT_IVB; | 329 | tmp &= ~BLM_PIPE_SELECT_IVB; |
| @@ -347,6 +344,14 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | 344 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); |
| 348 | } | 345 | } |
| 349 | } | 346 | } |
| 347 | |||
| 348 | set_level: | ||
| 349 | /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. | ||
| 350 | * BLC_PWM_CPU_CTL may be cleared to zero automatically when these | ||
| 351 | * registers are set. | ||
| 352 | */ | ||
| 353 | dev_priv->backlight_enabled = true; | ||
| 354 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | static void intel_panel_init_backlight(struct drm_device *dev) | 357 | static void intel_panel_init_backlight(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 94aabcaa3a67..58c07cdafb7e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -3963,6 +3963,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
| 3963 | DRM_ERROR("Force wake wait timed out\n"); | 3963 | DRM_ERROR("Force wake wait timed out\n"); |
| 3964 | 3964 | ||
| 3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | 3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
| 3966 | POSTING_READ(FORCEWAKE); | ||
| 3966 | 3967 | ||
| 3967 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3968 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
| 3968 | DRM_ERROR("Force wake wait timed out\n"); | 3969 | DRM_ERROR("Force wake wait timed out\n"); |
| @@ -3983,6 +3984,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
| 3983 | DRM_ERROR("Force wake wait timed out\n"); | 3984 | DRM_ERROR("Force wake wait timed out\n"); |
| 3984 | 3985 | ||
| 3985 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | 3986 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); |
| 3987 | POSTING_READ(FORCEWAKE_MT); | ||
| 3986 | 3988 | ||
| 3987 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3989 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
| 3988 | DRM_ERROR("Force wake wait timed out\n"); | 3990 | DRM_ERROR("Force wake wait timed out\n"); |
| @@ -4018,14 +4020,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | |||
| 4018 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 4020 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
| 4019 | { | 4021 | { |
| 4020 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 4022 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
| 4021 | /* The below doubles as a POSTING_READ */ | 4023 | POSTING_READ(FORCEWAKE); |
| 4022 | gen6_gt_check_fifodbg(dev_priv); | 4024 | gen6_gt_check_fifodbg(dev_priv); |
| 4023 | } | 4025 | } |
| 4024 | 4026 | ||
| 4025 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | 4027 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
| 4026 | { | 4028 | { |
| 4027 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | 4029 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); |
| 4028 | /* The below doubles as a POSTING_READ */ | 4030 | POSTING_READ(FORCEWAKE_MT); |
| 4029 | gen6_gt_check_fifodbg(dev_priv); | 4031 | gen6_gt_check_fifodbg(dev_priv); |
| 4030 | } | 4032 | } |
| 4031 | 4033 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bf0195a96d53..e2a73b38abe9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -227,31 +227,36 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
| 227 | * number of bits based on the write domains has little performance | 227 | * number of bits based on the write domains has little performance |
| 228 | * impact. | 228 | * impact. |
| 229 | */ | 229 | */ |
| 230 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | 230 | if (flush_domains) { |
| 231 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | 231 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; |
| 232 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | 232 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; |
| 233 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | 233 | /* |
| 234 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | 234 | * Ensure that any following seqno writes only happen |
| 235 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 235 | * when the render cache is indeed flushed. |
| 236 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 236 | */ |
| 237 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
| 238 | /* | ||
| 239 | * Ensure that any following seqno writes only happen when the render | ||
| 240 | * cache is indeed flushed (but only if the caller actually wants that). | ||
| 241 | */ | ||
| 242 | if (flush_domains) | ||
| 243 | flags |= PIPE_CONTROL_CS_STALL; | 237 | flags |= PIPE_CONTROL_CS_STALL; |
| 238 | } | ||
| 239 | if (invalidate_domains) { | ||
| 240 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
| 241 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
| 242 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
| 243 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
| 244 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
| 245 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
| 246 | /* | ||
| 247 | * TLB invalidate requires a post-sync write. | ||
| 248 | */ | ||
| 249 | flags |= PIPE_CONTROL_QW_WRITE; | ||
| 250 | } | ||
| 244 | 251 | ||
| 245 | ret = intel_ring_begin(ring, 6); | 252 | ret = intel_ring_begin(ring, 4); |
| 246 | if (ret) | 253 | if (ret) |
| 247 | return ret; | 254 | return ret; |
| 248 | 255 | ||
| 249 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | 256 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); |
| 250 | intel_ring_emit(ring, flags); | 257 | intel_ring_emit(ring, flags); |
| 251 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | 258 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); |
| 252 | intel_ring_emit(ring, 0); /* lower dword */ | 259 | intel_ring_emit(ring, 0); |
| 253 | intel_ring_emit(ring, 0); /* uppwer dword */ | ||
| 254 | intel_ring_emit(ring, MI_NOOP); | ||
| 255 | intel_ring_advance(ring); | 260 | intel_ring_advance(ring); |
| 256 | 261 | ||
| 257 | return 0; | 262 | return 0; |
| @@ -289,8 +294,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 289 | I915_WRITE_HEAD(ring, 0); | 294 | I915_WRITE_HEAD(ring, 0); |
| 290 | ring->write_tail(ring, 0); | 295 | ring->write_tail(ring, 0); |
| 291 | 296 | ||
| 292 | /* Initialize the ring. */ | ||
| 293 | I915_WRITE_START(ring, obj->gtt_offset); | ||
| 294 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 297 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
| 295 | 298 | ||
| 296 | /* G45 ring initialization fails to reset head to zero */ | 299 | /* G45 ring initialization fails to reset head to zero */ |
| @@ -316,6 +319,11 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 316 | } | 319 | } |
| 317 | } | 320 | } |
| 318 | 321 | ||
| 322 | /* Initialize the ring. This must happen _after_ we've cleared the ring | ||
| 323 | * registers with the above sequence (the readback of the HEAD registers | ||
| 324 | * also enforces ordering), otherwise the hw might lose the new ring | ||
| 325 | * register values. */ | ||
| 326 | I915_WRITE_START(ring, obj->gtt_offset); | ||
| 319 | I915_WRITE_CTL(ring, | 327 | I915_WRITE_CTL(ring, |
| 320 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 328 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
| 321 | | RING_VALID); | 329 | | RING_VALID); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 26a6a4d0d078..d172e9873131 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -444,13 +444,16 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
| 444 | struct i2c_msg *msgs; | 444 | struct i2c_msg *msgs; |
| 445 | int i, ret = true; | 445 | int i, ret = true; |
| 446 | 446 | ||
| 447 | /* Would be simpler to allocate both in one go ? */ | ||
| 447 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); | 448 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); |
| 448 | if (!buf) | 449 | if (!buf) |
| 449 | return false; | 450 | return false; |
| 450 | 451 | ||
| 451 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); | 452 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); |
| 452 | if (!msgs) | 453 | if (!msgs) { |
| 454 | kfree(buf); | ||
| 453 | return false; | 455 | return false; |
| 456 | } | ||
| 454 | 457 | ||
| 455 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 458 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
| 456 | 459 | ||
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a4d7c500c97b..b69642d5d850 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
| @@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
| 468 | { | 468 | { |
| 469 | unsigned int vcomax, vcomin, pllreffreq; | 469 | unsigned int vcomax, vcomin, pllreffreq; |
| 470 | unsigned int delta, tmpdelta; | 470 | unsigned int delta, tmpdelta; |
| 471 | unsigned int testr, testn, testm, testo; | 471 | int testr, testn, testm, testo; |
| 472 | unsigned int p, m, n; | 472 | unsigned int p, m, n; |
| 473 | unsigned int computed; | 473 | unsigned int computed, vco; |
| 474 | int tmp; | 474 | int tmp; |
| 475 | const unsigned int m_div_val[] = { 1, 2, 4, 8 }; | ||
| 475 | 476 | ||
| 476 | m = n = p = 0; | 477 | m = n = p = 0; |
| 477 | vcomax = 1488000; | 478 | vcomax = 1488000; |
| @@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
| 490 | if (delta == 0) | 491 | if (delta == 0) |
| 491 | break; | 492 | break; |
| 492 | for (testo = 5; testo < 33; testo++) { | 493 | for (testo = 5; testo < 33; testo++) { |
| 493 | computed = pllreffreq * (testn + 1) / | 494 | vco = pllreffreq * (testn + 1) / |
| 494 | (testr + 1); | 495 | (testr + 1); |
| 495 | if (computed < vcomin) | 496 | if (vco < vcomin) |
| 496 | continue; | 497 | continue; |
| 497 | if (computed > vcomax) | 498 | if (vco > vcomax) |
| 498 | continue; | 499 | continue; |
| 500 | computed = vco / (m_div_val[testm] * (testo + 1)); | ||
| 499 | if (computed > clock) | 501 | if (computed > clock) |
| 500 | tmpdelta = computed - clock; | 502 | tmpdelta = computed - clock; |
| 501 | else | 503 | else |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 77e564667b5c..240cf962c999 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 229 | } | 229 | } |
| 230 | break; | 230 | break; |
| 231 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
| 232 | port->drive = entry[0]; | 232 | port->drive = entry[0] & 0x0f; |
| 233 | port->sense = port->drive; | 233 | port->sense = port->drive; |
| 234 | port->adapter.algo = &nouveau_dp_i2c_algo; | 234 | port->adapter.algo = &nouveau_dp_i2c_algo; |
| 235 | break; | 235 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1cdfd6e757ce..1866dbb49979 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -731,7 +731,6 @@ nouveau_card_init(struct drm_device *dev) | |||
| 731 | case 0xa3: | 731 | case 0xa3: |
| 732 | case 0xa5: | 732 | case 0xa5: |
| 733 | case 0xa8: | 733 | case 0xa8: |
| 734 | case 0xaf: | ||
| 735 | nva3_copy_create(dev); | 734 | nva3_copy_create(dev); |
| 736 | break; | 735 | break; |
| 737 | } | 736 | } |
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c index cc82d799fc3b..c564c5e4c30a 100644 --- a/drivers/gpu/drm/nouveau/nv84_fifo.c +++ b/drivers/gpu/drm/nouveau/nv84_fifo.c | |||
| @@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine) | |||
| 117 | struct drm_device *dev = chan->dev; | 117 | struct drm_device *dev = chan->dev; |
| 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 119 | unsigned long flags; | 119 | unsigned long flags; |
| 120 | u32 save; | ||
| 120 | 121 | ||
| 121 | /* remove channel from playlist, will context switch if active */ | 122 | /* remove channel from playlist, will context switch if active */ |
| 122 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 123 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
| 123 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); | 124 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); |
| 124 | nv50_fifo_playlist_update(dev); | 125 | nv50_fifo_playlist_update(dev); |
| 125 | 126 | ||
| 127 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
| 128 | |||
| 126 | /* tell any engines on this channel to unload their contexts */ | 129 | /* tell any engines on this channel to unload their contexts */ |
| 127 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); | 130 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); |
| 128 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) | 131 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) |
| 129 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); | 132 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); |
| 130 | 133 | ||
| 134 | nv_wr32(dev, 0x002520, save); | ||
| 135 | |||
| 131 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); | 136 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); |
| 132 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 137 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
| 133 | 138 | ||
| @@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
| 184 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 189 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 185 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); | 190 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); |
| 186 | int i; | 191 | int i; |
| 192 | u32 save; | ||
| 187 | 193 | ||
| 188 | /* set playlist length to zero, fifo will unload context */ | 194 | /* set playlist length to zero, fifo will unload context */ |
| 189 | nv_wr32(dev, 0x0032ec, 0); | 195 | nv_wr32(dev, 0x0032ec, 0); |
| 190 | 196 | ||
| 197 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
| 198 | |||
| 191 | /* tell all connected engines to unload their contexts */ | 199 | /* tell all connected engines to unload their contexts */ |
| 192 | for (i = 0; i < priv->base.channels; i++) { | 200 | for (i = 0; i < priv->base.channels; i++) { |
| 193 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; | 201 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; |
| @@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
| 199 | } | 207 | } |
| 200 | } | 208 | } |
| 201 | 209 | ||
| 210 | nv_wr32(dev, 0x002520, save); | ||
| 202 | nv_wr32(dev, 0x002140, 0); | 211 | nv_wr32(dev, 0x002140, 0); |
| 203 | return 0; | 212 | return 0; |
| 204 | } | 213 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c index 7c95c44e2887..4e712b10ebdb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_pm.c +++ b/drivers/gpu/drm/nouveau/nvc0_pm.c | |||
| @@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) | |||
| 557 | nouveau_mem_exec(&exec, info->perflvl); | 557 | nouveau_mem_exec(&exec, info->perflvl); |
| 558 | 558 | ||
| 559 | if (dev_priv->chipset < 0xd0) | 559 | if (dev_priv->chipset < 0xd0) |
| 560 | nv_wr32(dev, 0x611200, 0x00003300); | 560 | nv_wr32(dev, 0x611200, 0x00003330); |
| 561 | else | 561 | else |
| 562 | nv_wr32(dev, 0x62c000, 0x03030300); | 562 | nv_wr32(dev, 0x62c000, 0x03030300); |
| 563 | } | 563 | } |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index d0d60e1e7f95..dac525b2994e 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
| @@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
| 791 | int ch = EVO_CURS(nv_crtc->index); | 791 | int ch = EVO_CURS(nv_crtc->index); |
| 792 | 792 | ||
| 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); | 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff)); |
| 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); | 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); |
| 795 | return 0; | 795 | return 0; |
| 796 | } | 796 | } |
diff --git a/drivers/gpu/drm/nouveau/nve0_fifo.c b/drivers/gpu/drm/nouveau/nve0_fifo.c index 1855ecbd843b..e98d144e6eb9 100644 --- a/drivers/gpu/drm/nouveau/nve0_fifo.c +++ b/drivers/gpu/drm/nouveau/nve0_fifo.c | |||
| @@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit) | |||
| 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); | 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | static int | ||
| 298 | nve0_fifo_page_flip(struct drm_device *dev, u32 chid) | ||
| 299 | { | ||
| 300 | struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO); | ||
| 301 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 302 | struct nouveau_channel *chan = NULL; | ||
| 303 | unsigned long flags; | ||
| 304 | int ret = -EINVAL; | ||
| 305 | |||
| 306 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | ||
| 307 | if (likely(chid >= 0 && chid < priv->base.channels)) { | ||
| 308 | chan = dev_priv->channels.ptr[chid]; | ||
| 309 | if (likely(chan)) | ||
| 310 | ret = nouveau_finish_page_flip(chan, NULL); | ||
| 311 | } | ||
| 312 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); | ||
| 313 | return ret; | ||
| 314 | } | ||
| 315 | |||
| 297 | static void | 316 | static void |
| 298 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | 317 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) |
| 299 | { | 318 | { |
| @@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
| 303 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; | 322 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; |
| 304 | u32 subc = (addr & 0x00070000); | 323 | u32 subc = (addr & 0x00070000); |
| 305 | u32 mthd = (addr & 0x00003ffc); | 324 | u32 mthd = (addr & 0x00003ffc); |
| 325 | u32 show = stat; | ||
| 326 | |||
| 327 | if (stat & 0x00200000) { | ||
| 328 | if (mthd == 0x0054) { | ||
| 329 | if (!nve0_fifo_page_flip(dev, chid)) | ||
| 330 | show &= ~0x00200000; | ||
| 331 | } | ||
| 332 | } | ||
| 306 | 333 | ||
| 307 | NV_INFO(dev, "PSUBFIFO %d:", unit); | 334 | if (show) { |
| 308 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat); | 335 | NV_INFO(dev, "PFIFO%d:", unit); |
| 309 | NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", | 336 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, show); |
| 310 | unit, chid, subc, mthd, data); | 337 | NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n", |
| 338 | unit, chid, subc, mthd, data); | ||
| 339 | } | ||
| 311 | 340 | ||
| 312 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); | 341 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); |
| 313 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); | 342 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9e6f76fec527..c6fcb5b86a45 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -259,7 +259,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
| 260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
| 261 | /* disable crtc pair power gating before programming */ | 261 | /* disable crtc pair power gating before programming */ |
| 262 | if (ASIC_IS_DCE6(rdev)) | 262 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
| 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
| 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
| @@ -279,7 +279,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
| 280 | radeon_crtc->enabled = false; | 280 | radeon_crtc->enabled = false; |
| 281 | /* power gating is per-pair */ | 281 | /* power gating is per-pair */ |
| 282 | if (ASIC_IS_DCE6(rdev)) { | 282 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { |
| 283 | struct drm_crtc *other_crtc; | 283 | struct drm_crtc *other_crtc; |
| 284 | struct radeon_crtc *other_radeon_crtc; | 284 | struct radeon_crtc *other_radeon_crtc; |
| 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { |
| @@ -1531,12 +1531,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1531 | * crtc virtual pixel clock. | 1531 | * crtc virtual pixel clock. |
| 1532 | */ | 1532 | */ |
| 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
| 1534 | if (ASIC_IS_DCE5(rdev)) | 1534 | if (rdev->clock.dp_extclk) |
| 1535 | return ATOM_DCPLL; | 1535 | return ATOM_PPLL_INVALID; |
| 1536 | else if (ASIC_IS_DCE6(rdev)) | 1536 | else if (ASIC_IS_DCE6(rdev)) |
| 1537 | return ATOM_PPLL0; | 1537 | return ATOM_PPLL0; |
| 1538 | else if (rdev->clock.dp_extclk) | 1538 | else if (ASIC_IS_DCE5(rdev)) |
| 1539 | return ATOM_PPLL_INVALID; | 1539 | return ATOM_DCPLL; |
| 1540 | } | 1540 | } |
| 1541 | } | 1541 | } |
| 1542 | } | 1542 | } |
| @@ -1635,18 +1635,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
| 1636 | { | 1636 | { |
| 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 1638 | struct drm_device *dev = crtc->dev; | ||
| 1639 | struct radeon_device *rdev = dev->dev_private; | ||
| 1638 | 1640 | ||
| 1641 | radeon_crtc->in_mode_set = true; | ||
| 1639 | /* pick pll */ | 1642 | /* pick pll */ |
| 1640 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | 1643 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
| 1641 | 1644 | ||
| 1645 | /* disable crtc pair power gating before programming */ | ||
| 1646 | if (ASIC_IS_DCE6(rdev)) | ||
| 1647 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | ||
| 1648 | |||
| 1642 | atombios_lock_crtc(crtc, ATOM_ENABLE); | 1649 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
| 1643 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1650 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1644 | } | 1651 | } |
| 1645 | 1652 | ||
| 1646 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1653 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
| 1647 | { | 1654 | { |
| 1655 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1656 | |||
| 1648 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1657 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
| 1649 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1658 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
| 1659 | radeon_crtc->in_mode_set = false; | ||
| 1650 | } | 1660 | } |
| 1651 | 1661 | ||
| 1652 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1662 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e585a3b947eb..e93b80a6d4e9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
| 1229 | 1229 | ||
| 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
| 1231 | { | 1231 | { |
| 1232 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
| 1233 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
| 1234 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1232 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
| 1235 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1233 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
| 1236 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
| 1237 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
| 1238 | if (rdev->num_crtc >= 4) { | ||
| 1239 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
| 1240 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
| 1241 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
| 1242 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
| 1243 | } | ||
| 1244 | if (rdev->num_crtc >= 6) { | ||
| 1245 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
| 1246 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
| 1247 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
| 1248 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 1249 | } | ||
| 1250 | 1234 | ||
| 1251 | /* Stop all video */ | 1235 | /* Stop all video */ |
| 1252 | WREG32(VGA_RENDER_CONTROL, 0); | 1236 | WREG32(VGA_RENDER_CONTROL, 0); |
| @@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
| 1357 | /* Unlock host access */ | 1341 | /* Unlock host access */ |
| 1358 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1342 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
| 1359 | mdelay(1); | 1343 | mdelay(1); |
| 1360 | /* Restore video state */ | ||
| 1361 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
| 1362 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
| 1363 | if (rdev->num_crtc >= 4) { | ||
| 1364 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
| 1365 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
| 1366 | } | ||
| 1367 | if (rdev->num_crtc >= 6) { | ||
| 1368 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
| 1369 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
| 1370 | } | ||
| 1371 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
| 1372 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
| 1373 | if (rdev->num_crtc >= 4) { | ||
| 1374 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
| 1375 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
| 1376 | } | ||
| 1377 | if (rdev->num_crtc >= 6) { | ||
| 1378 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
| 1379 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
| 1380 | } | ||
| 1381 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
| 1382 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
| 1383 | if (rdev->num_crtc >= 4) { | ||
| 1384 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
| 1385 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
| 1386 | } | ||
| 1387 | if (rdev->num_crtc >= 6) { | ||
| 1388 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
| 1389 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
| 1390 | } | ||
| 1391 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
| 1392 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
| 1393 | if (rdev->num_crtc >= 4) { | ||
| 1394 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
| 1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
| 1396 | } | ||
| 1397 | if (rdev->num_crtc >= 6) { | ||
| 1398 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
| 1399 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 1400 | } | ||
| 1401 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1344 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
| 1402 | } | 1345 | } |
| 1403 | 1346 | ||
| @@ -1986,10 +1929,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1986 | if (rdev->flags & RADEON_IS_IGP) | 1929 | if (rdev->flags & RADEON_IS_IGP) |
| 1987 | rdev->config.evergreen.tile_config |= 1 << 4; | 1930 | rdev->config.evergreen.tile_config |= 1 << 4; |
| 1988 | else { | 1931 | else { |
| 1989 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1932 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1990 | rdev->config.evergreen.tile_config |= 1 << 4; | 1933 | case 0: /* four banks */ |
| 1991 | else | ||
| 1992 | rdev->config.evergreen.tile_config |= 0 << 4; | 1934 | rdev->config.evergreen.tile_config |= 0 << 4; |
| 1935 | break; | ||
| 1936 | case 1: /* eight banks */ | ||
| 1937 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
| 1938 | break; | ||
| 1939 | case 2: /* sixteen banks */ | ||
| 1940 | default: | ||
| 1941 | rdev->config.evergreen.tile_config |= 2 << 4; | ||
| 1942 | break; | ||
| 1943 | } | ||
| 1993 | } | 1944 | } |
| 1994 | rdev->config.evergreen.tile_config |= 0 << 8; | 1945 | rdev->config.evergreen.tile_config |= 0 << 8; |
| 1995 | rdev->config.evergreen.tile_config |= | 1946 | rdev->config.evergreen.tile_config |= |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c16554122ccd..e44a62a07fe3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
| 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: |
| 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: |
| 790 | depth = 1; | 790 | depth = 1; |
| 791 | break; | ||
| 792 | case V_030000_SQ_TEX_DIM_2D_MSAA: | ||
| 793 | case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: | ||
| 794 | surf.nsamples = 1 << llevel; | ||
| 795 | llevel = 0; | ||
| 796 | depth = 1; | ||
| 797 | break; | ||
| 791 | case V_030000_SQ_TEX_DIM_3D: | 798 | case V_030000_SQ_TEX_DIM_3D: |
| 792 | break; | 799 | break; |
| 793 | default: | 800 | default: |
| @@ -961,13 +968,15 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
| 961 | 968 | ||
| 962 | if (track->db_dirty) { | 969 | if (track->db_dirty) { |
| 963 | /* Check stencil buffer */ | 970 | /* Check stencil buffer */ |
| 964 | if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { | 971 | if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID && |
| 972 | G_028800_STENCIL_ENABLE(track->db_depth_control)) { | ||
| 965 | r = evergreen_cs_track_validate_stencil(p); | 973 | r = evergreen_cs_track_validate_stencil(p); |
| 966 | if (r) | 974 | if (r) |
| 967 | return r; | 975 | return r; |
| 968 | } | 976 | } |
| 969 | /* Check depth buffer */ | 977 | /* Check depth buffer */ |
| 970 | if (G_028800_Z_ENABLE(track->db_depth_control)) { | 978 | if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID && |
| 979 | G_028800_Z_ENABLE(track->db_depth_control)) { | ||
| 971 | r = evergreen_cs_track_validate_depth(p); | 980 | r = evergreen_cs_track_validate_depth(p); |
| 972 | if (r) | 981 | if (r) |
| 973 | return r; | 982 | return r; |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index d3bd098e4e19..79347855d9bf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -1277,6 +1277,8 @@ | |||
| 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) | 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) |
| 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) | 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) |
| 1279 | #define C_028044_FORMAT 0xFFFFFFFE | 1279 | #define C_028044_FORMAT 0xFFFFFFFE |
| 1280 | #define V_028044_STENCIL_INVALID 0 | ||
| 1281 | #define V_028044_STENCIL_8 1 | ||
| 1280 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) | 1282 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) |
| 1281 | #define DB_Z_READ_BASE 0x28048 | 1283 | #define DB_Z_READ_BASE 0x28048 |
| 1282 | #define DB_STENCIL_READ_BASE 0x2804c | 1284 | #define DB_STENCIL_READ_BASE 0x2804c |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 9945d86d9001..853800e8582f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
| 574 | if (rdev->flags & RADEON_IS_IGP) | 574 | if (rdev->flags & RADEON_IS_IGP) |
| 575 | rdev->config.cayman.tile_config |= 1 << 4; | 575 | rdev->config.cayman.tile_config |= 1 << 4; |
| 576 | else { | 576 | else { |
| 577 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 577 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 578 | rdev->config.cayman.tile_config |= 1 << 4; | 578 | case 0: /* four banks */ |
| 579 | else | ||
| 580 | rdev->config.cayman.tile_config |= 0 << 4; | 579 | rdev->config.cayman.tile_config |= 0 << 4; |
| 580 | break; | ||
| 581 | case 1: /* eight banks */ | ||
| 582 | rdev->config.cayman.tile_config |= 1 << 4; | ||
| 583 | break; | ||
| 584 | case 2: /* sixteen banks */ | ||
| 585 | default: | ||
| 586 | rdev->config.cayman.tile_config |= 2 << 4; | ||
| 587 | break; | ||
| 588 | } | ||
| 581 | } | 589 | } |
| 582 | rdev->config.cayman.tile_config |= | 590 | rdev->config.cayman.tile_config |= |
| 583 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 591 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f541a3..d79c639ae739 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
| 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); |
| 3790 | } | 3790 | } |
| 3791 | } | 3791 | } |
| 3792 | |||
| 3793 | /** | ||
| 3794 | * r600_get_gpu_clock - return GPU clock counter snapshot | ||
| 3795 | * | ||
| 3796 | * @rdev: radeon_device pointer | ||
| 3797 | * | ||
| 3798 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | ||
| 3799 | * Returns the 64 bit clock counter snapshot. | ||
| 3800 | */ | ||
| 3801 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | ||
| 3802 | { | ||
| 3803 | uint64_t clock; | ||
| 3804 | |||
| 3805 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3806 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3807 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3808 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3809 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3810 | return clock; | ||
| 3811 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..3dab49cb1d4a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -764,8 +764,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 764 | } | 764 | } |
| 765 | 765 | ||
| 766 | /* Check depth buffer */ | 766 | /* Check depth buffer */ |
| 767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 767 | if (track->db_dirty && |
| 768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 768 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
| 769 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
| 770 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
| 769 | r = r600_cs_track_validate_db(p); | 771 | r = r600_cs_track_validate_db(p); |
| 770 | if (r) | 772 | if (r) |
| 771 | return r; | 773 | return r; |
| @@ -1557,13 +1559,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1557 | u32 tiling_flags) | 1559 | u32 tiling_flags) |
| 1558 | { | 1560 | { |
| 1559 | struct r600_cs_track *track = p->track; | 1561 | struct r600_cs_track *track = p->track; |
| 1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1562 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
| 1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1563 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
| 1562 | u32 height_align, pitch, pitch_align, depth_align; | 1564 | u32 height_align, pitch, pitch_align, depth_align; |
| 1563 | u32 array, barray, larray; | 1565 | u32 barray, larray; |
| 1564 | u64 base_align; | 1566 | u64 base_align; |
| 1565 | struct array_mode_checker array_check; | 1567 | struct array_mode_checker array_check; |
| 1566 | u32 format; | 1568 | u32 format; |
| 1569 | bool is_array; | ||
| 1567 | 1570 | ||
| 1568 | /* on legacy kernel we don't perform advanced check */ | 1571 | /* on legacy kernel we don't perform advanced check */ |
| 1569 | if (p->rdev == NULL) | 1572 | if (p->rdev == NULL) |
| @@ -1581,12 +1584,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1584 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
| 1582 | } | 1585 | } |
| 1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1586 | word1 = radeon_get_ib_value(p, idx + 1); |
| 1587 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1588 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1589 | word4 = radeon_get_ib_value(p, idx + 4); | ||
| 1590 | word5 = radeon_get_ib_value(p, idx + 5); | ||
| 1591 | dim = G_038000_DIM(word0); | ||
| 1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1592 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
| 1593 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1594 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
| 1586 | d0 = G_038004_TEX_DEPTH(word1); | 1595 | d0 = G_038004_TEX_DEPTH(word1); |
| 1596 | format = G_038004_DATA_FORMAT(word1); | ||
| 1597 | blevel = G_038010_BASE_LEVEL(word4); | ||
| 1598 | llevel = G_038014_LAST_LEVEL(word5); | ||
| 1599 | /* pitch in texels */ | ||
| 1600 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1601 | array_check.group_size = track->group_size; | ||
| 1602 | array_check.nbanks = track->nbanks; | ||
| 1603 | array_check.npipes = track->npipes; | ||
| 1604 | array_check.nsamples = 1; | ||
| 1605 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1587 | nfaces = 1; | 1606 | nfaces = 1; |
| 1588 | array = 0; | 1607 | is_array = false; |
| 1589 | switch (G_038000_DIM(word0)) { | 1608 | switch (dim) { |
| 1590 | case V_038000_SQ_TEX_DIM_1D: | 1609 | case V_038000_SQ_TEX_DIM_1D: |
| 1591 | case V_038000_SQ_TEX_DIM_2D: | 1610 | case V_038000_SQ_TEX_DIM_2D: |
| 1592 | case V_038000_SQ_TEX_DIM_3D: | 1611 | case V_038000_SQ_TEX_DIM_3D: |
| @@ -1599,29 +1618,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1599 | break; | 1618 | break; |
| 1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1619 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
| 1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1620 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
| 1602 | array = 1; | 1621 | is_array = true; |
| 1603 | break; | 1622 | break; |
| 1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1623 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
| 1624 | is_array = true; | ||
| 1625 | /* fall through */ | ||
| 1626 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1627 | array_check.nsamples = 1 << llevel; | ||
| 1628 | llevel = 0; | ||
| 1629 | break; | ||
| 1606 | default: | 1630 | default: |
| 1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1631 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
| 1608 | return -EINVAL; | 1632 | return -EINVAL; |
| 1609 | } | 1633 | } |
| 1610 | format = G_038004_DATA_FORMAT(word1); | ||
| 1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1634 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
| 1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1635 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
| 1613 | __func__, __LINE__, format); | 1636 | __func__, __LINE__, format); |
| 1614 | return -EINVAL; | 1637 | return -EINVAL; |
| 1615 | } | 1638 | } |
| 1616 | 1639 | ||
| 1617 | /* pitch in texels */ | ||
| 1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1620 | array_check.group_size = track->group_size; | ||
| 1621 | array_check.nbanks = track->nbanks; | ||
| 1622 | array_check.npipes = track->npipes; | ||
| 1623 | array_check.nsamples = 1; | ||
| 1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1625 | if (r600_get_array_mode_alignment(&array_check, | 1640 | if (r600_get_array_mode_alignment(&array_check, |
| 1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1641 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| 1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1642 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
| @@ -1647,20 +1662,13 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1647 | return -EINVAL; | 1662 | return -EINVAL; |
| 1648 | } | 1663 | } |
| 1649 | 1664 | ||
| 1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1652 | |||
| 1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
| 1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
| 1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
| 1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
| 1657 | if (blevel > llevel) { | 1665 | if (blevel > llevel) { |
| 1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1666 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
| 1659 | blevel, llevel); | 1667 | blevel, llevel); |
| 1660 | } | 1668 | } |
| 1661 | if (array == 1) { | 1669 | if (is_array) { |
| 1662 | barray = G_038014_BASE_ARRAY(word1); | 1670 | barray = G_038014_BASE_ARRAY(word5); |
| 1663 | larray = G_038014_LAST_ARRAY(word1); | 1671 | larray = G_038014_LAST_ARRAY(word5); |
| 1664 | 1672 | ||
| 1665 | nfaces = larray - barray + 1; | 1673 | nfaces = larray - barray + 1; |
| 1666 | } | 1674 | } |
| @@ -1677,7 +1685,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1677 | return -EINVAL; | 1685 | return -EINVAL; |
| 1678 | } | 1686 | } |
| 1679 | /* using get ib will give us the offset into the mipmap bo */ | 1687 | /* using get ib will give us the offset into the mipmap bo */ |
| 1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1688 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
| 1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1689 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
| 1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1690 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae75fc2..fd328f4c3ea8 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -602,6 +602,9 @@ | |||
| 602 | #define RLC_HB_WPTR 0x3f1c | 602 | #define RLC_HB_WPTR 0x3f1c |
| 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 |
| 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 |
| 605 | #define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 | ||
| 606 | #define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c | ||
| 607 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 | ||
| 605 | #define RLC_MC_CNTL 0x3f44 | 608 | #define RLC_MC_CNTL 0x3f44 |
| 606 | #define RLC_UCODE_CNTL 0x3f48 | 609 | #define RLC_UCODE_CNTL 0x3f48 |
| 607 | #define RLC_UCODE_ADDR 0x3f2c | 610 | #define RLC_UCODE_ADDR 0x3f2c |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5431af292408..99304194a65c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -300,6 +300,7 @@ struct radeon_bo_va { | |||
| 300 | uint64_t soffset; | 300 | uint64_t soffset; |
| 301 | uint64_t eoffset; | 301 | uint64_t eoffset; |
| 302 | uint32_t flags; | 302 | uint32_t flags; |
| 303 | struct radeon_fence *fence; | ||
| 303 | bool valid; | 304 | bool valid; |
| 304 | }; | 305 | }; |
| 305 | 306 | ||
| @@ -1533,6 +1534,7 @@ struct radeon_device { | |||
| 1533 | unsigned debugfs_count; | 1534 | unsigned debugfs_count; |
| 1534 | /* virtual memory */ | 1535 | /* virtual memory */ |
| 1535 | struct radeon_vm_manager vm_manager; | 1536 | struct radeon_vm_manager vm_manager; |
| 1537 | struct mutex gpu_clock_mutex; | ||
| 1536 | }; | 1538 | }; |
| 1537 | 1539 | ||
| 1538 | int radeon_device_init(struct radeon_device *rdev, | 1540 | int radeon_device_init(struct radeon_device *rdev, |
| @@ -1733,11 +1735,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
| 1733 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) | 1735 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) |
| 1734 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) | 1736 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) |
| 1735 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) | 1737 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) |
| 1736 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) | 1738 | #define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) |
| 1737 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) | 1739 | #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) |
| 1738 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) | 1740 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
| 1739 | #define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) | 1741 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
| 1740 | #define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) | 1742 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
| 1741 | 1743 | ||
| 1742 | /* Common functions */ | 1744 | /* Common functions */ |
| 1743 | /* AGP */ | 1745 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4af24310438..18c38d14c8cd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
| 255 | * rv515 | 255 | * rv515 |
| 256 | */ | 256 | */ |
| 257 | struct rv515_mc_save { | 257 | struct rv515_mc_save { |
| 258 | u32 d1vga_control; | ||
| 259 | u32 d2vga_control; | ||
| 260 | u32 vga_render_control; | 258 | u32 vga_render_control; |
| 261 | u32 vga_hdp_control; | 259 | u32 vga_hdp_control; |
| 262 | u32 d1crtc_control; | ||
| 263 | u32 d2crtc_control; | ||
| 264 | }; | 260 | }; |
| 261 | |||
| 265 | int rv515_init(struct radeon_device *rdev); | 262 | int rv515_init(struct radeon_device *rdev); |
| 266 | void rv515_fini(struct radeon_device *rdev); | 263 | void rv515_fini(struct radeon_device *rdev); |
| 267 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 264 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| @@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
| 371 | unsigned num_gpu_pages, | 368 | unsigned num_gpu_pages, |
| 372 | struct radeon_sa_bo *vb); | 369 | struct radeon_sa_bo *vb); |
| 373 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 370 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
| 371 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | ||
| 374 | 372 | ||
| 375 | /* | 373 | /* |
| 376 | * rv770,rv730,rv710,rv740 | 374 | * rv770,rv730,rv710,rv740 |
| @@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
| 389 | * evergreen | 387 | * evergreen |
| 390 | */ | 388 | */ |
| 391 | struct evergreen_mc_save { | 389 | struct evergreen_mc_save { |
| 392 | u32 vga_control[6]; | ||
| 393 | u32 vga_render_control; | 390 | u32 vga_render_control; |
| 394 | u32 vga_hdp_control; | 391 | u32 vga_hdp_control; |
| 395 | u32 crtc_control[6]; | ||
| 396 | }; | 392 | }; |
| 393 | |||
| 397 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
| 398 | int evergreen_init(struct radeon_device *rdev); | 395 | int evergreen_init(struct radeon_device *rdev); |
| 399 | void evergreen_fini(struct radeon_device *rdev); | 396 | void evergreen_fini(struct radeon_device *rdev); |
| @@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | |||
| 472 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); |
| 473 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); |
| 474 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
| 472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
| 475 | 473 | ||
| 476 | #endif | 474 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1e3820df363..f9c21f9d16bc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1263 | union igp_info { | 1263 | union igp_info { |
| 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
| 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
| 1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
| 1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
| 1266 | }; | 1268 | }; |
| 1267 | 1269 | ||
| 1268 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1270 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
| @@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | |||
| 1390 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1392 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 1391 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | 1393 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); |
| 1392 | u16 data_offset, size; | 1394 | u16 data_offset, size; |
| 1393 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | 1395 | union igp_info *igp_info; |
| 1394 | u8 frev, crev; | 1396 | u8 frev, crev; |
| 1395 | u16 percentage = 0, rate = 0; | 1397 | u16 percentage = 0, rate = 0; |
| 1396 | 1398 | ||
| 1397 | /* get any igp specific overrides */ | 1399 | /* get any igp specific overrides */ |
| 1398 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | 1400 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
| 1399 | &frev, &crev, &data_offset)) { | 1401 | &frev, &crev, &data_offset)) { |
| 1400 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | 1402 | igp_info = (union igp_info *) |
| 1401 | (mode_info->atom_context->bios + data_offset); | 1403 | (mode_info->atom_context->bios + data_offset); |
| 1402 | switch (id) { | 1404 | switch (crev) { |
| 1403 | case ASIC_INTERNAL_SS_ON_TMDS: | 1405 | case 6: |
| 1404 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | 1406 | switch (id) { |
| 1405 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | 1407 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1408 | percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); | ||
| 1409 | rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); | ||
| 1410 | break; | ||
| 1411 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1412 | percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); | ||
| 1413 | rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); | ||
| 1414 | break; | ||
| 1415 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1416 | percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); | ||
| 1417 | rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); | ||
| 1418 | break; | ||
| 1419 | } | ||
| 1406 | break; | 1420 | break; |
| 1407 | case ASIC_INTERNAL_SS_ON_HDMI: | 1421 | case 7: |
| 1408 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | 1422 | switch (id) { |
| 1409 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | 1423 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1424 | percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); | ||
| 1425 | rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); | ||
| 1426 | break; | ||
| 1427 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1428 | percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); | ||
| 1429 | rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); | ||
| 1430 | break; | ||
| 1431 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1432 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); | ||
| 1433 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); | ||
| 1434 | break; | ||
| 1435 | } | ||
| 1410 | break; | 1436 | break; |
| 1411 | case ASIC_INTERNAL_SS_ON_LVDS: | 1437 | default: |
| 1412 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | 1438 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
| 1413 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
| 1414 | break; | 1439 | break; |
| 1415 | } | 1440 | } |
| 1416 | if (percentage) | 1441 | if (percentage) |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..f75247d42ffd 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
| 719 | return i2c; | 719 | return i2c; |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) | ||
| 723 | { | ||
| 724 | struct drm_device *dev = rdev->ddev; | ||
| 725 | struct radeon_i2c_bus_rec i2c; | ||
| 726 | u16 offset; | ||
| 727 | u8 id, blocks, clk, data; | ||
| 728 | int i; | ||
| 729 | |||
| 730 | i2c.valid = false; | ||
| 731 | |||
| 732 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | ||
| 733 | if (offset) { | ||
| 734 | blocks = RBIOS8(offset + 2); | ||
| 735 | for (i = 0; i < blocks; i++) { | ||
| 736 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 737 | if (id == 136) { | ||
| 738 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 739 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 740 | /* gpiopad */ | ||
| 741 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 742 | (1 << clk), (1 << data)); | ||
| 743 | break; | ||
| 744 | } | ||
| 745 | } | ||
| 746 | } | ||
| 747 | return i2c; | ||
| 748 | } | ||
| 749 | |||
| 722 | void radeon_combios_i2c_init(struct radeon_device *rdev) | 750 | void radeon_combios_i2c_init(struct radeon_device *rdev) |
| 723 | { | 751 | { |
| 724 | struct drm_device *dev = rdev->ddev; | 752 | struct drm_device *dev = rdev->ddev; |
| @@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
| 755 | } else if (rdev->family == CHIP_RS300 || | 783 | } else if (rdev->family == CHIP_RS300 || |
| 756 | rdev->family == CHIP_RS400 || | 784 | rdev->family == CHIP_RS400 || |
| 757 | rdev->family == CHIP_RS480) { | 785 | rdev->family == CHIP_RS480) { |
| 758 | u16 offset; | ||
| 759 | u8 id, blocks, clk, data; | ||
| 760 | int i; | ||
| 761 | |||
| 762 | /* 0x68 */ | 786 | /* 0x68 */ |
| 763 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 787 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 764 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 788 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
| 765 | 789 | ||
| 766 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | 790 | /* gpiopad */ |
| 767 | if (offset) { | 791 | i2c = radeon_combios_get_i2c_info_from_table(rdev); |
| 768 | blocks = RBIOS8(offset + 2); | 792 | if (i2c.valid) |
| 769 | for (i = 0; i < blocks; i++) { | 793 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
| 770 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 771 | if (id == 136) { | ||
| 772 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 773 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 774 | /* gpiopad */ | ||
| 775 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 776 | (1 << clk), (1 << data)); | ||
| 777 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | } | ||
| 781 | } | ||
| 782 | } else if ((rdev->family == CHIP_R200) || | 794 | } else if ((rdev->family == CHIP_R200) || |
| 783 | (rdev->family >= CHIP_R300)) { | 795 | (rdev->family >= CHIP_R300)) { |
| 784 | /* 0x68 */ | 796 | /* 0x68 */ |
| @@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2321 | connector = (tmp >> 12) & 0xf; | 2333 | connector = (tmp >> 12) & 0xf; |
| 2322 | 2334 | ||
| 2323 | ddc_type = (tmp >> 8) & 0xf; | 2335 | ddc_type = (tmp >> 8) & 0xf; |
| 2324 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | 2336 | if (ddc_type == 5) |
| 2337 | ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); | ||
| 2338 | else | ||
| 2339 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | ||
| 2325 | 2340 | ||
| 2326 | switch (connector) { | 2341 | switch (connector) { |
| 2327 | case CONNECTOR_PROPRIETARY_LEGACY: | 2342 | case CONNECTOR_PROPRIETARY_LEGACY: |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8a4c49ef0cc4..b4a0db24f4dd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
| 278 | return 0; | 278 | return 0; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
| 282 | struct radeon_fence *fence) | ||
| 283 | { | ||
| 284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
| 285 | struct radeon_vm *vm = &fpriv->vm; | ||
| 286 | struct radeon_bo_list *lobj; | ||
| 287 | |||
| 288 | if (parser->chunk_ib_idx == -1) { | ||
| 289 | return; | ||
| 290 | } | ||
| 291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | |||
| 295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
| 296 | struct radeon_bo_va *bo_va; | ||
| 297 | struct radeon_bo *rbo = lobj->bo; | ||
| 298 | |||
| 299 | bo_va = radeon_bo_va(rbo, vm); | ||
| 300 | radeon_fence_unref(&bo_va->fence); | ||
| 301 | bo_va->fence = radeon_fence_ref(fence); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 281 | /** | 305 | /** |
| 282 | * cs_parser_fini() - clean parser states | 306 | * cs_parser_fini() - clean parser states |
| 283 | * @parser: parser structure holding parsing context. | 307 | * @parser: parser structure holding parsing context. |
| @@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 290 | { | 314 | { |
| 291 | unsigned i; | 315 | unsigned i; |
| 292 | 316 | ||
| 293 | if (!error) | 317 | if (!error) { |
| 318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
| 319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
| 294 | ttm_eu_fence_buffer_objects(&parser->validated, | 320 | ttm_eu_fence_buffer_objects(&parser->validated, |
| 295 | parser->ib.fence); | 321 | parser->ib.fence); |
| 296 | else | 322 | } else { |
| 297 | ttm_eu_backoff_reservation(&parser->validated); | 323 | ttm_eu_backoff_reservation(&parser->validated); |
| 324 | } | ||
| 298 | 325 | ||
| 299 | if (parser->relocs != NULL) { | 326 | if (parser->relocs != NULL) { |
| 300 | for (i = 0; i < parser->nrelocs; i++) { | 327 | for (i = 0; i < parser->nrelocs; i++) { |
| @@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 388 | 415 | ||
| 389 | if (parser->chunk_ib_idx == -1) | 416 | if (parser->chunk_ib_idx == -1) |
| 390 | return 0; | 417 | return 0; |
| 391 | |||
| 392 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 418 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
| 393 | return 0; | 419 | return 0; |
| 394 | 420 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 711e95ad39bf..8794744cdf1a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
| @@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
| 67 | 67 | ||
| 68 | if (ASIC_IS_DCE4(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
| 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 71 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 71 | } else if (ASIC_IS_AVIVO(rdev)) { | 72 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 73 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 74 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
| @@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
| 94 | if (ASIC_IS_DCE4(rdev)) { | 95 | if (ASIC_IS_DCE4(rdev)) { |
| 95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 96 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | 97 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
| 97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 98 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 99 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 98 | } else if (ASIC_IS_AVIVO(rdev)) { | 100 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 101 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 102 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af8244e89..d2e243867ac6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1009 | atomic_set(&rdev->ih.lock, 0); | 1009 | atomic_set(&rdev->ih.lock, 0); |
| 1010 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
| 1011 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
| 1012 | mutex_init(&rdev->gpu_clock_mutex); | ||
| 1012 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
| 1013 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
| 1014 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dcea6f01ae4e..d7269f48d37c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -59,9 +59,12 @@ | |||
| 59 | * 2.15.0 - add max_pipes query | 59 | * 2.15.0 - add max_pipes query |
| 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation | 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation |
| 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx | 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx |
| 62 | * 2.18.0 - r600-eg: allow "invalid" DB formats | ||
| 63 | * 2.19.0 - r600-eg: MSAA textures | ||
| 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | ||
| 62 | */ | 65 | */ |
| 63 | #define KMS_DRIVER_MAJOR 2 | 66 | #define KMS_DRIVER_MAJOR 2 |
| 64 | #define KMS_DRIVER_MINOR 17 | 67 | #define KMS_DRIVER_MINOR 20 |
| 65 | #define KMS_DRIVER_PATCHLEVEL 0 | 68 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 66 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 69 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
| 67 | int radeon_driver_unload_kms(struct drm_device *dev); | 70 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 814 | return -EINVAL; | 814 | return -EINVAL; |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
| 818 | return 0; | 818 | return 0; |
| 819 | 819 | ||
| 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
| @@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
| 859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
| 860 | { | 860 | { |
| 861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
| 862 | int r; | ||
| 862 | 863 | ||
| 863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
| 864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
| 865 | return 0; | 866 | return 0; |
| 866 | 867 | ||
| 868 | /* wait for va use to end */ | ||
| 869 | while (bo_va->fence) { | ||
| 870 | r = radeon_fence_wait(bo_va->fence, false); | ||
| 871 | if (r) { | ||
| 872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
| 873 | } | ||
| 874 | if (r == -EDEADLK) { | ||
| 875 | r = radeon_gpu_reset(rdev); | ||
| 876 | if (!r) | ||
| 877 | continue; | ||
| 878 | } | ||
| 879 | break; | ||
| 880 | } | ||
| 881 | radeon_fence_unref(&bo_va->fence); | ||
| 882 | |||
| 867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
| 868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
| 869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
| @@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 934 | } | 950 | } |
| 935 | 951 | ||
| 936 | /** | 952 | /** |
| 937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
| 938 | * | 954 | * |
| 939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
| 940 | * @vm: requested vm | 956 | * @vm: requested vm |
| @@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
| 953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
| 954 | 970 | ||
| 955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
| 972 | * waited for the last vm fence to signal | ||
| 973 | */ | ||
| 956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
| 957 | if (!r) { | 975 | if (!r) { |
| 958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
| 959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
| 960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
| 979 | radeon_fence_unref(&bo_va->fence); | ||
| 961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
| 962 | kfree(bo_va); | 981 | kfree(bo_va); |
| 963 | } | 982 | } |
| @@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
| 970 | if (!r) { | 989 | if (!r) { |
| 971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
| 991 | radeon_fence_unref(&bo_va->fence); | ||
| 972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
| 973 | kfree(bo_va); | 993 | kfree(bo_va); |
| 974 | } | 994 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d045245739..1b57b0058ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
| 134 | struct radeon_device *rdev = rbo->rdev; | 134 | struct radeon_device *rdev = rbo->rdev; |
| 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
| 136 | struct radeon_vm *vm = &fpriv->vm; | 136 | struct radeon_vm *vm = &fpriv->vm; |
| 137 | struct radeon_bo_va *bo_va, *tmp; | ||
| 138 | 137 | ||
| 139 | if (rdev->family < CHIP_CAYMAN) { | 138 | if (rdev->family < CHIP_CAYMAN) { |
| 140 | return; | 139 | return; |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | if (radeon_bo_reserve(rbo, false)) { | 142 | if (radeon_bo_reserve(rbo, false)) { |
| 143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | ||
| 144 | return; | 144 | return; |
| 145 | } | 145 | } |
| 146 | list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { | 146 | radeon_vm_bo_rmv(rdev, vm, rbo); |
| 147 | if (bo_va->vm == vm) { | ||
| 148 | /* remove from this vm address space */ | ||
| 149 | mutex_lock(&vm->mutex); | ||
| 150 | list_del(&bo_va->vm_list); | ||
| 151 | mutex_unlock(&vm->mutex); | ||
| 152 | list_del(&bo_va->bo_list); | ||
| 153 | kfree(bo_va); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | radeon_bo_unreserve(rbo); | 147 | radeon_bo_unreserve(rbo); |
| 157 | } | 148 | } |
| 158 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 1d73f16b5d97..414b4acf6947 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
| 30 | #include "radeon.h" | 30 | #include "radeon.h" |
| 31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
| 32 | #include "radeon_asic.h" | ||
| 32 | 33 | ||
| 33 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
| 167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 168 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
| 168 | { | 169 | { |
| 169 | struct radeon_device *rdev = dev->dev_private; | 170 | struct radeon_device *rdev = dev->dev_private; |
| 170 | struct drm_radeon_info *info; | 171 | struct drm_radeon_info *info = data; |
| 171 | struct radeon_mode_info *minfo = &rdev->mode_info; | 172 | struct radeon_mode_info *minfo = &rdev->mode_info; |
| 172 | uint32_t *value_ptr; | 173 | uint32_t value, *value_ptr; |
| 173 | uint32_t value; | 174 | uint64_t value64, *value_ptr64; |
| 174 | struct drm_crtc *crtc; | 175 | struct drm_crtc *crtc; |
| 175 | int i, found; | 176 | int i, found; |
| 176 | 177 | ||
| 177 | info = data; | 178 | /* TIMESTAMP is a 64-bit value, needs special handling. */ |
| 179 | if (info->request == RADEON_INFO_TIMESTAMP) { | ||
| 180 | if (rdev->family >= CHIP_R600) { | ||
| 181 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | ||
| 182 | if (rdev->family >= CHIP_TAHITI) { | ||
| 183 | value64 = si_get_gpu_clock(rdev); | ||
| 184 | } else { | ||
| 185 | value64 = r600_get_gpu_clock(rdev); | ||
| 186 | } | ||
| 187 | |||
| 188 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | ||
| 189 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | ||
| 190 | return -EFAULT; | ||
| 191 | } | ||
| 192 | return 0; | ||
| 193 | } else { | ||
| 194 | DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 178 | value_ptr = (uint32_t *)((unsigned long)info->value); | 199 | value_ptr = (uint32_t *)((unsigned long)info->value); |
| 179 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) | 200 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { |
| 201 | DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); | ||
| 180 | return -EFAULT; | 202 | return -EFAULT; |
| 203 | } | ||
| 181 | 204 | ||
| 182 | switch (info->request) { | 205 | switch (info->request) { |
| 183 | case RADEON_INFO_DEVICE_ID: | 206 | case RADEON_INFO_DEVICE_ID: |
| @@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 337 | return -EINVAL; | 360 | return -EINVAL; |
| 338 | } | 361 | } |
| 339 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 362 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
| 340 | DRM_ERROR("copy_to_user\n"); | 363 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
| 341 | return -EFAULT; | 364 | return -EFAULT; |
| 342 | } | 365 | } |
| 343 | return 0; | 366 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index d5fd615897ec..94b4a1c12893 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1025 | 1025 | ||
| 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
| 1027 | { | 1027 | { |
| 1028 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1028 | struct drm_device *dev = crtc->dev; | 1029 | struct drm_device *dev = crtc->dev; |
| 1029 | struct drm_crtc *crtci; | 1030 | struct drm_crtc *crtci; |
| 1030 | 1031 | ||
| 1032 | radeon_crtc->in_mode_set = true; | ||
| 1031 | /* | 1033 | /* |
| 1032 | * The hardware wedges sometimes if you reconfigure one CRTC | 1034 | * The hardware wedges sometimes if you reconfigure one CRTC |
| 1033 | * whilst another is running (see fdo bug #24611). | 1035 | * whilst another is running (see fdo bug #24611). |
| @@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
| 1038 | 1040 | ||
| 1039 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1041 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
| 1040 | { | 1042 | { |
| 1043 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1041 | struct drm_device *dev = crtc->dev; | 1044 | struct drm_device *dev = crtc->dev; |
| 1042 | struct drm_crtc *crtci; | 1045 | struct drm_crtc *crtci; |
| 1043 | 1046 | ||
| @@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
| 1048 | if (crtci->enabled) | 1051 | if (crtci->enabled) |
| 1049 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1052 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
| 1050 | } | 1053 | } |
| 1054 | radeon_crtc->in_mode_set = false; | ||
| 1051 | } | 1055 | } |
| 1052 | 1056 | ||
| 1053 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1057 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f380d59c5763..d56978949f34 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -275,6 +275,7 @@ struct radeon_crtc { | |||
| 275 | u16 lut_r[256], lut_g[256], lut_b[256]; | 275 | u16 lut_r[256], lut_g[256], lut_b[256]; |
| 276 | bool enabled; | 276 | bool enabled; |
| 277 | bool can_tile; | 277 | bool can_tile; |
| 278 | bool in_mode_set; | ||
| 278 | uint32_t crtc_offset; | 279 | uint32_t crtc_offset; |
| 279 | struct drm_gem_object *cursor_bo; | 280 | struct drm_gem_object *cursor_bo; |
| 280 | uint64_t cursor_addr; | 281 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f1a4c803c1d..1cb014b571ab 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
| 52 | 52 | ||
| 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
| 54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
| 55 | mutex_lock(&bo_va->vm->mutex); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); |
| 56 | list_del(&bo_va->vm_list); | ||
| 57 | mutex_unlock(&bo_va->vm->mutex); | ||
| 58 | list_del(&bo_va->bo_list); | ||
| 59 | kfree(bo_va); | ||
| 60 | } | 56 | } |
| 61 | } | 57 | } |
| 62 | 58 | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index a12fbcc8ccb6..aa8ef491ef3c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
| 281 | 281 | ||
| 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
| 283 | { | 283 | { |
| 284 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); | ||
| 285 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); | ||
| 286 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
| 287 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
| 288 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
| 289 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
| 290 | 286 | ||
| 291 | /* Stop all video */ | 287 | /* Stop all video */ |
| 292 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
| @@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
| 311 | /* Unlock host access */ | 307 | /* Unlock host access */ |
| 312 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
| 313 | mdelay(1); | 309 | mdelay(1); |
| 314 | /* Restore video state */ | ||
| 315 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
| 316 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
| 317 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
| 318 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
| 319 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
| 320 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
| 321 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
| 322 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 323 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
| 324 | } | 311 | } |
| 325 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c053f8193771..0139e227e3c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
| 1639 | /* XXX what about 12? */ | 1639 | /* XXX what about 12? */ |
| 1640 | rdev->config.si.tile_config |= (3 << 0); | 1640 | rdev->config.si.tile_config |= (3 << 0); |
| 1641 | break; | 1641 | break; |
| 1642 | } | 1642 | } |
| 1643 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1643 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1644 | rdev->config.si.tile_config |= 1 << 4; | 1644 | case 0: /* four banks */ |
| 1645 | else | ||
| 1646 | rdev->config.si.tile_config |= 0 << 4; | 1645 | rdev->config.si.tile_config |= 0 << 4; |
| 1646 | break; | ||
| 1647 | case 1: /* eight banks */ | ||
| 1648 | rdev->config.si.tile_config |= 1 << 4; | ||
| 1649 | break; | ||
| 1650 | case 2: /* sixteen banks */ | ||
| 1651 | default: | ||
| 1652 | rdev->config.si.tile_config |= 2 << 4; | ||
| 1653 | break; | ||
| 1654 | } | ||
| 1647 | rdev->config.si.tile_config |= | 1655 | rdev->config.si.tile_config |= |
| 1648 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 1656 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
| 1649 | rdev->config.si.tile_config |= | 1657 | rdev->config.si.tile_config |= |
| @@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) | |||
| 3960 | rdev->bios = NULL; | 3968 | rdev->bios = NULL; |
| 3961 | } | 3969 | } |
| 3962 | 3970 | ||
| 3971 | /** | ||
| 3972 | * si_get_gpu_clock - return GPU clock counter snapshot | ||
| 3973 | * | ||
| 3974 | * @rdev: radeon_device pointer | ||
| 3975 | * | ||
| 3976 | * Fetches a GPU clock counter snapshot (SI). | ||
| 3977 | * Returns the 64 bit clock counter snapshot. | ||
| 3978 | */ | ||
| 3979 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | ||
| 3980 | { | ||
| 3981 | uint64_t clock; | ||
| 3982 | |||
| 3983 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3984 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3985 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3986 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3987 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3988 | return clock; | ||
| 3989 | } | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089e8761..ef4815c27b1c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
| @@ -698,6 +698,9 @@ | |||
| 698 | #define RLC_UCODE_ADDR 0xC32C | 698 | #define RLC_UCODE_ADDR 0xC32C |
| 699 | #define RLC_UCODE_DATA 0xC330 | 699 | #define RLC_UCODE_DATA 0xC330 |
| 700 | 700 | ||
| 701 | #define RLC_GPU_CLOCK_COUNT_LSB 0xC338 | ||
| 702 | #define RLC_GPU_CLOCK_COUNT_MSB 0xC33C | ||
| 703 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 | ||
| 701 | #define RLC_MC_CNTL 0xC344 | 704 | #define RLC_MC_CNTL 0xC344 |
| 702 | #define RLC_UCODE_CNTL 0xC348 | 705 | #define RLC_UCODE_CNTL 0xC348 |
| 703 | 706 | ||
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 7bd65bdd15a8..291ecc145585 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c | |||
| @@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, | |||
| 308 | /* need to attach */ | 308 | /* need to attach */ |
| 309 | attach = dma_buf_attach(dma_buf, dev->dev); | 309 | attach = dma_buf_attach(dma_buf, dev->dev); |
| 310 | if (IS_ERR(attach)) | 310 | if (IS_ERR(attach)) |
| 311 | return ERR_PTR(PTR_ERR(attach)); | 311 | return ERR_CAST(attach); |
| 312 | 312 | ||
| 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
| 314 | if (IS_ERR(sg)) { | 314 | if (IS_ERR(sg)) { |
