diff options
26 files changed, 177 insertions, 73 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6c656392d67d..d44344140627 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1464,12 +1464,13 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) | |||
1464 | #else | 1464 | #else |
1465 | static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) | 1465 | static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) |
1466 | { | 1466 | { |
1467 | int ret; | 1467 | int ret = 0; |
1468 | 1468 | ||
1469 | DRM_INFO("Replacing VGA console driver\n"); | 1469 | DRM_INFO("Replacing VGA console driver\n"); |
1470 | 1470 | ||
1471 | console_lock(); | 1471 | console_lock(); |
1472 | ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); | 1472 | if (con_is_bound(&vga_con)) |
1473 | ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); | ||
1473 | if (ret == 0) { | 1474 | if (ret == 0) { |
1474 | ret = do_unregister_con_driver(&vga_con); | 1475 | ret = do_unregister_con_driver(&vga_con); |
1475 | 1476 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a47fbf60b781..374f964323ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -656,6 +656,7 @@ enum intel_sbi_destination { | |||
656 | #define QUIRK_PIPEA_FORCE (1<<0) | 656 | #define QUIRK_PIPEA_FORCE (1<<0) |
657 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) | 657 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) |
658 | #define QUIRK_INVERT_BRIGHTNESS (1<<2) | 658 | #define QUIRK_INVERT_BRIGHTNESS (1<<2) |
659 | #define QUIRK_BACKLIGHT_PRESENT (1<<3) | ||
659 | 660 | ||
660 | struct intel_fbdev; | 661 | struct intel_fbdev; |
661 | struct intel_fbc_work; | 662 | struct intel_fbc_work; |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 62ef55ba061c..7465ab0fd396 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) | |||
74 | if (base == 0) | 74 | if (base == 0) |
75 | return 0; | 75 | return 0; |
76 | 76 | ||
77 | /* make sure we don't clobber the GTT if it's within stolen memory */ | ||
78 | if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) { | ||
79 | struct { | ||
80 | u32 start, end; | ||
81 | } stolen[2] = { | ||
82 | { .start = base, .end = base + dev_priv->gtt.stolen_size, }, | ||
83 | { .start = base, .end = base + dev_priv->gtt.stolen_size, }, | ||
84 | }; | ||
85 | u64 gtt_start, gtt_end; | ||
86 | |||
87 | gtt_start = I915_READ(PGTBL_CTL); | ||
88 | if (IS_GEN4(dev)) | ||
89 | gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) | | ||
90 | (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; | ||
91 | else | ||
92 | gtt_start &= PGTBL_ADDRESS_LO_MASK; | ||
93 | gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4; | ||
94 | |||
95 | if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) | ||
96 | stolen[0].end = gtt_start; | ||
97 | if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end) | ||
98 | stolen[1].start = gtt_end; | ||
99 | |||
100 | /* pick the larger of the two chunks */ | ||
101 | if (stolen[0].end - stolen[0].start > | ||
102 | stolen[1].end - stolen[1].start) { | ||
103 | base = stolen[0].start; | ||
104 | dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start; | ||
105 | } else { | ||
106 | base = stolen[1].start; | ||
107 | dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start; | ||
108 | } | ||
109 | |||
110 | if (stolen[0].start != stolen[1].start || | ||
111 | stolen[0].end != stolen[1].end) { | ||
112 | DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n", | ||
113 | (unsigned long long) gtt_start, | ||
114 | (unsigned long long) gtt_end - 1); | ||
115 | DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", | ||
116 | base, base + (u32) dev_priv->gtt.stolen_size - 1); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | |||
77 | /* Verify that nothing else uses this physical address. Stolen | 121 | /* Verify that nothing else uses this physical address. Stolen |
78 | * memory should be reserved by the BIOS and hidden from the | 122 | * memory should be reserved by the BIOS and hidden from the |
79 | * kernel. So if the region is already marked as busy, something | 123 | * kernel. So if the region is already marked as busy, something |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e691b30b2817..a5bab61bfc00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -942,6 +942,9 @@ enum punit_power_well { | |||
942 | /* | 942 | /* |
943 | * Instruction and interrupt control regs | 943 | * Instruction and interrupt control regs |
944 | */ | 944 | */ |
945 | #define PGTBL_CTL 0x02020 | ||
946 | #define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */ | ||
947 | #define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */ | ||
945 | #define PGTBL_ER 0x02024 | 948 | #define PGTBL_ER 0x02024 |
946 | #define RENDER_RING_BASE 0x02000 | 949 | #define RENDER_RING_BASE 0x02000 |
947 | #define BSD_RING_BASE 0x04000 | 950 | #define BSD_RING_BASE 0x04000 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 556c916dbf9d..e27e7804c0b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -11591,6 +11591,14 @@ static void quirk_invert_brightness(struct drm_device *dev) | |||
11591 | DRM_INFO("applying inverted panel brightness quirk\n"); | 11591 | DRM_INFO("applying inverted panel brightness quirk\n"); |
11592 | } | 11592 | } |
11593 | 11593 | ||
11594 | /* Some VBT's incorrectly indicate no backlight is present */ | ||
11595 | static void quirk_backlight_present(struct drm_device *dev) | ||
11596 | { | ||
11597 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
11598 | dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT; | ||
11599 | DRM_INFO("applying backlight present quirk\n"); | ||
11600 | } | ||
11601 | |||
11594 | struct intel_quirk { | 11602 | struct intel_quirk { |
11595 | int device; | 11603 | int device; |
11596 | int subsystem_vendor; | 11604 | int subsystem_vendor; |
@@ -11659,6 +11667,12 @@ static struct intel_quirk intel_quirks[] = { | |||
11659 | 11667 | ||
11660 | /* Acer Aspire 5336 */ | 11668 | /* Acer Aspire 5336 */ |
11661 | { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness }, | 11669 | { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness }, |
11670 | |||
11671 | /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ | ||
11672 | { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, | ||
11673 | |||
11674 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ | ||
11675 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, | ||
11662 | }; | 11676 | }; |
11663 | 11677 | ||
11664 | static void intel_init_quirks(struct drm_device *dev) | 11678 | static void intel_init_quirks(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 52fda950fd2a..075170d1844f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/export.h> | 30 | #include <linux/export.h> |
31 | #include <linux/notifier.h> | ||
32 | #include <linux/reboot.h> | ||
31 | #include <drm/drmP.h> | 33 | #include <drm/drmP.h> |
32 | #include <drm/drm_crtc.h> | 34 | #include <drm/drm_crtc.h> |
33 | #include <drm/drm_crtc_helper.h> | 35 | #include <drm/drm_crtc_helper.h> |
@@ -336,6 +338,37 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp) | |||
336 | return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); | 338 | return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); |
337 | } | 339 | } |
338 | 340 | ||
341 | /* Reboot notifier handler to shutdown panel power to guarantee T12 timing | ||
342 | This function only applicable when panel PM state is not to be tracked */ | ||
343 | static int edp_notify_handler(struct notifier_block *this, unsigned long code, | ||
344 | void *unused) | ||
345 | { | ||
346 | struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), | ||
347 | edp_notifier); | ||
348 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
349 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
350 | u32 pp_div; | ||
351 | u32 pp_ctrl_reg, pp_div_reg; | ||
352 | enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); | ||
353 | |||
354 | if (!is_edp(intel_dp) || code != SYS_RESTART) | ||
355 | return 0; | ||
356 | |||
357 | if (IS_VALLEYVIEW(dev)) { | ||
358 | pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); | ||
359 | pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); | ||
360 | pp_div = I915_READ(pp_div_reg); | ||
361 | pp_div &= PP_REFERENCE_DIVIDER_MASK; | ||
362 | |||
363 | /* 0x1F write to PP_DIV_REG sets max cycle delay */ | ||
364 | I915_WRITE(pp_div_reg, pp_div | 0x1F); | ||
365 | I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF); | ||
366 | msleep(intel_dp->panel_power_cycle_delay); | ||
367 | } | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
339 | static bool edp_have_panel_power(struct intel_dp *intel_dp) | 372 | static bool edp_have_panel_power(struct intel_dp *intel_dp) |
340 | { | 373 | { |
341 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 374 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
@@ -3707,6 +3740,10 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) | |||
3707 | drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | 3740 | drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); |
3708 | edp_panel_vdd_off_sync(intel_dp); | 3741 | edp_panel_vdd_off_sync(intel_dp); |
3709 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | 3742 | drm_modeset_unlock(&dev->mode_config.connection_mutex); |
3743 | if (intel_dp->edp_notifier.notifier_call) { | ||
3744 | unregister_reboot_notifier(&intel_dp->edp_notifier); | ||
3745 | intel_dp->edp_notifier.notifier_call = NULL; | ||
3746 | } | ||
3710 | } | 3747 | } |
3711 | kfree(intel_dig_port); | 3748 | kfree(intel_dig_port); |
3712 | } | 3749 | } |
@@ -4184,6 +4221,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
4184 | } | 4221 | } |
4185 | mutex_unlock(&dev->mode_config.mutex); | 4222 | mutex_unlock(&dev->mode_config.mutex); |
4186 | 4223 | ||
4224 | if (IS_VALLEYVIEW(dev)) { | ||
4225 | intel_dp->edp_notifier.notifier_call = edp_notify_handler; | ||
4226 | register_reboot_notifier(&intel_dp->edp_notifier); | ||
4227 | } | ||
4228 | |||
4187 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); | 4229 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); |
4188 | intel_panel_setup_backlight(connector); | 4230 | intel_panel_setup_backlight(connector); |
4189 | 4231 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eaa27ee9e367..f67340ed2c12 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -538,6 +538,8 @@ struct intel_dp { | |||
538 | unsigned long last_power_on; | 538 | unsigned long last_power_on; |
539 | unsigned long last_backlight_off; | 539 | unsigned long last_backlight_off; |
540 | bool psr_setup_done; | 540 | bool psr_setup_done; |
541 | struct notifier_block edp_notifier; | ||
542 | |||
541 | bool use_tps3; | 543 | bool use_tps3; |
542 | struct intel_connector *attached_connector; | 544 | struct intel_connector *attached_connector; |
543 | 545 | ||
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 02f99d768d49..3fd082933c87 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -117,17 +117,18 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) | |||
117 | /* bandgap reset is needed after everytime we do power gate */ | 117 | /* bandgap reset is needed after everytime we do power gate */ |
118 | band_gap_reset(dev_priv); | 118 | band_gap_reset(dev_priv); |
119 | 119 | ||
120 | I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); | ||
121 | usleep_range(2500, 3000); | ||
122 | |||
120 | val = I915_READ(MIPI_PORT_CTRL(pipe)); | 123 | val = I915_READ(MIPI_PORT_CTRL(pipe)); |
121 | I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); | 124 | I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); |
122 | usleep_range(1000, 1500); | 125 | usleep_range(1000, 1500); |
123 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); | 126 | |
124 | usleep_range(2000, 2500); | 127 | I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); |
125 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); | 128 | usleep_range(2500, 3000); |
126 | usleep_range(2000, 2500); | 129 | |
127 | I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); | ||
128 | usleep_range(2000, 2500); | ||
129 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); | 130 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); |
130 | usleep_range(2000, 2500); | 131 | usleep_range(2500, 3000); |
131 | } | 132 | } |
132 | 133 | ||
133 | static void intel_dsi_enable(struct intel_encoder *encoder) | 134 | static void intel_dsi_enable(struct intel_encoder *encoder) |
@@ -271,23 +272,23 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) | |||
271 | 272 | ||
272 | DRM_DEBUG_KMS("\n"); | 273 | DRM_DEBUG_KMS("\n"); |
273 | 274 | ||
274 | I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); | 275 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); |
275 | usleep_range(2000, 2500); | 276 | usleep_range(2000, 2500); |
276 | 277 | ||
277 | I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); | 278 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); |
278 | usleep_range(2000, 2500); | 279 | usleep_range(2000, 2500); |
279 | 280 | ||
280 | I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); | 281 | I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); |
281 | usleep_range(2000, 2500); | 282 | usleep_range(2000, 2500); |
282 | 283 | ||
283 | val = I915_READ(MIPI_PORT_CTRL(pipe)); | ||
284 | I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); | ||
285 | usleep_range(1000, 1500); | ||
286 | |||
287 | if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) | 284 | if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) |
288 | == 0x00000), 30)) | 285 | == 0x00000), 30)) |
289 | DRM_ERROR("DSI LP not going Low\n"); | 286 | DRM_ERROR("DSI LP not going Low\n"); |
290 | 287 | ||
288 | val = I915_READ(MIPI_PORT_CTRL(pipe)); | ||
289 | I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); | ||
290 | usleep_range(1000, 1500); | ||
291 | |||
291 | I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); | 292 | I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); |
292 | usleep_range(2000, 2500); | 293 | usleep_range(2000, 2500); |
293 | 294 | ||
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 3eeb21b9fddf..933c86305237 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c | |||
@@ -404,12 +404,6 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) | |||
404 | else | 404 | else |
405 | cmd |= DPI_LP_MODE; | 405 | cmd |= DPI_LP_MODE; |
406 | 406 | ||
407 | /* DPI virtual channel?! */ | ||
408 | |||
409 | mask = DPI_FIFO_EMPTY; | ||
410 | if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50)) | ||
411 | DRM_ERROR("Timeout waiting for DPI FIFO empty.\n"); | ||
412 | |||
413 | /* clear bit */ | 407 | /* clear bit */ |
414 | I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT); | 408 | I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT); |
415 | 409 | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 38a98570d10c..628cd8938274 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -1118,8 +1118,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector) | |||
1118 | int ret; | 1118 | int ret; |
1119 | 1119 | ||
1120 | if (!dev_priv->vbt.backlight.present) { | 1120 | if (!dev_priv->vbt.backlight.present) { |
1121 | DRM_DEBUG_KMS("native backlight control not available per VBT\n"); | 1121 | if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { |
1122 | return 0; | 1122 | DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n"); |
1123 | } else { | ||
1124 | DRM_DEBUG_KMS("no backlight present per VBT\n"); | ||
1125 | return 0; | ||
1126 | } | ||
1123 | } | 1127 | } |
1124 | 1128 | ||
1125 | /* set level and max in panel struct */ | 1129 | /* set level and max in panel struct */ |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 26e962b7e702..2283c442a10d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -1516,11 +1516,11 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) | |||
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | switch ((ctrl & 0x000f0000) >> 16) { | 1518 | switch ((ctrl & 0x000f0000) >> 16) { |
1519 | case 6: datarate = pclk * 30 / 8; break; | 1519 | case 6: datarate = pclk * 30; break; |
1520 | case 5: datarate = pclk * 24 / 8; break; | 1520 | case 5: datarate = pclk * 24; break; |
1521 | case 2: | 1521 | case 2: |
1522 | default: | 1522 | default: |
1523 | datarate = pclk * 18 / 8; | 1523 | datarate = pclk * 18; |
1524 | break; | 1524 | break; |
1525 | } | 1525 | } |
1526 | 1526 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 48aa38a87e3f..fa30d8196f35 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | |||
@@ -1159,11 +1159,11 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head) | |||
1159 | if (outp->info.type == DCB_OUTPUT_DP) { | 1159 | if (outp->info.type == DCB_OUTPUT_DP) { |
1160 | u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); | 1160 | u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); |
1161 | switch ((sync & 0x000003c0) >> 6) { | 1161 | switch ((sync & 0x000003c0) >> 6) { |
1162 | case 6: pclk = pclk * 30 / 8; break; | 1162 | case 6: pclk = pclk * 30; break; |
1163 | case 5: pclk = pclk * 24 / 8; break; | 1163 | case 5: pclk = pclk * 24; break; |
1164 | case 2: | 1164 | case 2: |
1165 | default: | 1165 | default: |
1166 | pclk = pclk * 18 / 8; | 1166 | pclk = pclk * 18; |
1167 | break; | 1167 | break; |
1168 | } | 1168 | } |
1169 | 1169 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c index 52c299c3d300..eb2d7789555d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c | |||
@@ -34,7 +34,7 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) | |||
34 | struct nvkm_output_dp *outp = (void *)base; | 34 | struct nvkm_output_dp *outp = (void *)base; |
35 | bool retrain = true; | 35 | bool retrain = true; |
36 | u8 link[2], stat[3]; | 36 | u8 link[2], stat[3]; |
37 | u32 rate; | 37 | u32 linkrate; |
38 | int ret, i; | 38 | int ret, i; |
39 | 39 | ||
40 | /* check that the link is trained at a high enough rate */ | 40 | /* check that the link is trained at a high enough rate */ |
@@ -44,8 +44,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) | |||
44 | goto done; | 44 | goto done; |
45 | } | 45 | } |
46 | 46 | ||
47 | rate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET); | 47 | linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET); |
48 | if (rate < ((datarate / 8) * 10)) { | 48 | linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */ |
49 | datarate = (datarate + 9) / 10; /* -> decakilobits */ | ||
50 | if (linkrate < datarate) { | ||
49 | DBG("link not trained at sufficient rate\n"); | 51 | DBG("link not trained at sufficient rate\n"); |
50 | goto done; | 52 | goto done; |
51 | } | 53 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index e1832778e8b6..7a1ebdfa9e1b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |||
@@ -87,6 +87,7 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
87 | struct nvkm_output_dp *outpdp = (void *)outp; | 87 | struct nvkm_output_dp *outpdp = (void *)outp; |
88 | switch (data) { | 88 | switch (data) { |
89 | case NV94_DISP_SOR_DP_PWR_STATE_OFF: | 89 | case NV94_DISP_SOR_DP_PWR_STATE_OFF: |
90 | nouveau_event_put(outpdp->irq); | ||
90 | ((struct nvkm_output_dp_impl *)nv_oclass(outp)) | 91 | ((struct nvkm_output_dp_impl *)nv_oclass(outp)) |
91 | ->lnk_pwr(outpdp, 0); | 92 | ->lnk_pwr(outpdp, 0); |
92 | atomic_set(&outpdp->lt.done, 0); | 93 | atomic_set(&outpdp->lt.done, 0); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h index 0f57fcfe0bbf..2af9cfd2c60f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h | |||
@@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2) | |||
26 | }; | 26 | }; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline struct ramfuc_reg | 29 | static noinline struct ramfuc_reg |
30 | ramfuc_reg(u32 addr) | 30 | ramfuc_reg(u32 addr) |
31 | { | 31 | { |
32 | return ramfuc_reg2(addr, addr); | 32 | return ramfuc_reg2(addr, addr); |
@@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec) | |||
107 | 107 | ||
108 | #define ram_init(s,p) ramfuc_init(&(s)->base, (p)) | 108 | #define ram_init(s,p) ramfuc_init(&(s)->base, (p)) |
109 | #define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) | 109 | #define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) |
110 | #define ram_have(s,r) ((s)->r_##r.addr != 0x000000) | 110 | #define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000) |
111 | #define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) | 111 | #define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) |
112 | #define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) | 112 | #define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) |
113 | #define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) | 113 | #define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c index 1ad3ea503133..c5b46e302319 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c | |||
@@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc) | |||
200 | /* (re)program mempll, if required */ | 200 | /* (re)program mempll, if required */ |
201 | if (ram->mode == 2) { | 201 | if (ram->mode == 2) { |
202 | ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); | 202 | ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); |
203 | ram_mask(fuc, 0x132000, 0x80000000, 0x80000000); | ||
203 | ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); | 204 | ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); |
204 | ram_mask(fuc, 0x132004, 0x103fffff, mcoef); | 205 | ram_mask(fuc, 0x132004, 0x103fffff, mcoef); |
205 | ram_mask(fuc, 0x132000, 0x00000001, 0x00000001); | 206 | ram_mask(fuc, 0x132000, 0x00000001, 0x00000001); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ddd83756b9a2..5425ffe3931d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev) | |||
652 | ret = nouveau_do_resume(drm_dev); | 652 | ret = nouveau_do_resume(drm_dev); |
653 | if (ret) | 653 | if (ret) |
654 | return ret; | 654 | return ret; |
655 | if (drm_dev->mode_config.num_crtc) | ||
656 | nouveau_fbcon_set_suspend(drm_dev, 0); | ||
657 | 655 | ||
658 | nouveau_fbcon_zfill_all(drm_dev); | 656 | if (drm_dev->mode_config.num_crtc) { |
659 | if (drm_dev->mode_config.num_crtc) | ||
660 | nouveau_display_resume(drm_dev); | 657 | nouveau_display_resume(drm_dev); |
658 | nouveau_fbcon_set_suspend(drm_dev, 0); | ||
659 | } | ||
660 | |||
661 | return 0; | 661 | return 0; |
662 | } | 662 | } |
663 | 663 | ||
@@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev) | |||
683 | ret = nouveau_do_resume(drm_dev); | 683 | ret = nouveau_do_resume(drm_dev); |
684 | if (ret) | 684 | if (ret) |
685 | return ret; | 685 | return ret; |
686 | if (drm_dev->mode_config.num_crtc) | 686 | |
687 | nouveau_fbcon_set_suspend(drm_dev, 0); | 687 | if (drm_dev->mode_config.num_crtc) { |
688 | nouveau_fbcon_zfill_all(drm_dev); | ||
689 | if (drm_dev->mode_config.num_crtc) | ||
690 | nouveau_display_resume(drm_dev); | 688 | nouveau_display_resume(drm_dev); |
689 | nouveau_fbcon_set_suspend(drm_dev, 0); | ||
690 | } | ||
691 | |||
691 | return 0; | 692 | return 0; |
692 | } | 693 | } |
693 | 694 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 64a42cfd3717..191665ee7f52 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) | |||
531 | if (state == 1) | 531 | if (state == 1) |
532 | nouveau_fbcon_save_disable_accel(dev); | 532 | nouveau_fbcon_save_disable_accel(dev); |
533 | fb_set_suspend(drm->fbcon->helper.fbdev, state); | 533 | fb_set_suspend(drm->fbcon->helper.fbdev, state); |
534 | if (state == 0) | 534 | if (state == 0) { |
535 | nouveau_fbcon_restore_accel(dev); | 535 | nouveau_fbcon_restore_accel(dev); |
536 | nouveau_fbcon_zfill(dev, drm->fbcon); | ||
537 | } | ||
536 | console_unlock(); | 538 | console_unlock(); |
537 | } | 539 | } |
538 | } | 540 | } |
539 | |||
540 | void | ||
541 | nouveau_fbcon_zfill_all(struct drm_device *dev) | ||
542 | { | ||
543 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
544 | if (drm->fbcon) { | ||
545 | nouveau_fbcon_zfill(dev, drm->fbcon); | ||
546 | } | ||
547 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index fdfc0c94fbcc..fcff797d2084 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h | |||
@@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info); | |||
61 | int nouveau_fbcon_init(struct drm_device *dev); | 61 | int nouveau_fbcon_init(struct drm_device *dev); |
62 | void nouveau_fbcon_fini(struct drm_device *dev); | 62 | void nouveau_fbcon_fini(struct drm_device *dev); |
63 | void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); | 63 | void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); |
64 | void nouveau_fbcon_zfill_all(struct drm_device *dev); | ||
65 | void nouveau_fbcon_save_disable_accel(struct drm_device *dev); | 64 | void nouveau_fbcon_save_disable_accel(struct drm_device *dev); |
66 | void nouveau_fbcon_restore_accel(struct drm_device *dev); | 65 | void nouveau_fbcon_restore_accel(struct drm_device *dev); |
67 | 66 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index afdf607df3e6..4c534b7b04da 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -1741,7 +1741,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
1741 | } | 1741 | } |
1742 | } | 1742 | } |
1743 | 1743 | ||
1744 | mthd = (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2; | 1744 | mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3; |
1745 | mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2; | ||
1745 | mthd |= nv_encoder->or; | 1746 | mthd |= nv_encoder->or; |
1746 | 1747 | ||
1747 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { | 1748 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 35f4182c63b6..b1e11f8434e2 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -127,7 +127,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, | |||
127 | /* flags not zero */ | 127 | /* flags not zero */ |
128 | if (args.v1.ucReplyStatus == 2) { | 128 | if (args.v1.ucReplyStatus == 2) { |
129 | DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); | 129 | DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); |
130 | r = -EBUSY; | 130 | r = -EIO; |
131 | goto done; | 131 | goto done; |
132 | } | 132 | } |
133 | 133 | ||
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 10dae4106c08..584090ac3eb9 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
@@ -1179,7 +1179,7 @@ static int ci_stop_dpm(struct radeon_device *rdev) | |||
1179 | tmp &= ~GLOBAL_PWRMGT_EN; | 1179 | tmp &= ~GLOBAL_PWRMGT_EN; |
1180 | WREG32_SMC(GENERAL_PWRMGT, tmp); | 1180 | WREG32_SMC(GENERAL_PWRMGT, tmp); |
1181 | 1181 | ||
1182 | tmp = RREG32(SCLK_PWRMGT_CNTL); | 1182 | tmp = RREG32_SMC(SCLK_PWRMGT_CNTL); |
1183 | tmp &= ~DYNAMIC_PM_EN; | 1183 | tmp &= ~DYNAMIC_PM_EN; |
1184 | WREG32_SMC(SCLK_PWRMGT_CNTL, tmp); | 1184 | WREG32_SMC(SCLK_PWRMGT_CNTL, tmp); |
1185 | 1185 | ||
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index dcd4518a9b08..0b2471107137 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -7676,14 +7676,16 @@ restart_ih: | |||
7676 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | 7676 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); |
7677 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); | 7677 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); |
7678 | mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); | 7678 | mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); |
7679 | /* reset addr and status */ | ||
7680 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
7681 | if (addr == 0x0 && status == 0x0) | ||
7682 | break; | ||
7679 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); | 7683 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); |
7680 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 7684 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |
7681 | addr); | 7685 | addr); |
7682 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | 7686 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", |
7683 | status); | 7687 | status); |
7684 | cik_vm_decode_fault(rdev, status, addr, mc_client); | 7688 | cik_vm_decode_fault(rdev, status, addr, mc_client); |
7685 | /* reset addr and status */ | ||
7686 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
7687 | break; | 7689 | break; |
7688 | case 167: /* VCE */ | 7690 | case 167: /* VCE */ |
7689 | DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data); | 7691 | DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e2f605224e8c..f7ece0ff431b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -189,7 +189,7 @@ static const u32 evergreen_golden_registers[] = | |||
189 | 0x8c1c, 0xffffffff, 0x00001010, | 189 | 0x8c1c, 0xffffffff, 0x00001010, |
190 | 0x28350, 0xffffffff, 0x00000000, | 190 | 0x28350, 0xffffffff, 0x00000000, |
191 | 0xa008, 0xffffffff, 0x00010000, | 191 | 0xa008, 0xffffffff, 0x00010000, |
192 | 0x5cc, 0xffffffff, 0x00000001, | 192 | 0x5c4, 0xffffffff, 0x00000001, |
193 | 0x9508, 0xffffffff, 0x00000002, | 193 | 0x9508, 0xffffffff, 0x00000002, |
194 | 0x913c, 0x0000000f, 0x0000000a | 194 | 0x913c, 0x0000000f, 0x0000000a |
195 | }; | 195 | }; |
@@ -476,7 +476,7 @@ static const u32 cedar_golden_registers[] = | |||
476 | 0x8c1c, 0xffffffff, 0x00001010, | 476 | 0x8c1c, 0xffffffff, 0x00001010, |
477 | 0x28350, 0xffffffff, 0x00000000, | 477 | 0x28350, 0xffffffff, 0x00000000, |
478 | 0xa008, 0xffffffff, 0x00010000, | 478 | 0xa008, 0xffffffff, 0x00010000, |
479 | 0x5cc, 0xffffffff, 0x00000001, | 479 | 0x5c4, 0xffffffff, 0x00000001, |
480 | 0x9508, 0xffffffff, 0x00000002 | 480 | 0x9508, 0xffffffff, 0x00000002 |
481 | }; | 481 | }; |
482 | 482 | ||
@@ -635,7 +635,7 @@ static const u32 juniper_mgcg_init[] = | |||
635 | static const u32 supersumo_golden_registers[] = | 635 | static const u32 supersumo_golden_registers[] = |
636 | { | 636 | { |
637 | 0x5eb4, 0xffffffff, 0x00000002, | 637 | 0x5eb4, 0xffffffff, 0x00000002, |
638 | 0x5cc, 0xffffffff, 0x00000001, | 638 | 0x5c4, 0xffffffff, 0x00000001, |
639 | 0x7030, 0xffffffff, 0x00000011, | 639 | 0x7030, 0xffffffff, 0x00000011, |
640 | 0x7c30, 0xffffffff, 0x00000011, | 640 | 0x7c30, 0xffffffff, 0x00000011, |
641 | 0x6104, 0x01000300, 0x00000000, | 641 | 0x6104, 0x01000300, 0x00000000, |
@@ -719,7 +719,7 @@ static const u32 sumo_golden_registers[] = | |||
719 | static const u32 wrestler_golden_registers[] = | 719 | static const u32 wrestler_golden_registers[] = |
720 | { | 720 | { |
721 | 0x5eb4, 0xffffffff, 0x00000002, | 721 | 0x5eb4, 0xffffffff, 0x00000002, |
722 | 0x5cc, 0xffffffff, 0x00000001, | 722 | 0x5c4, 0xffffffff, 0x00000001, |
723 | 0x7030, 0xffffffff, 0x00000011, | 723 | 0x7030, 0xffffffff, 0x00000011, |
724 | 0x7c30, 0xffffffff, 0x00000011, | 724 | 0x7c30, 0xffffffff, 0x00000011, |
725 | 0x6104, 0x01000300, 0x00000000, | 725 | 0x6104, 0x01000300, 0x00000000, |
@@ -5066,14 +5066,16 @@ restart_ih: | |||
5066 | case 147: | 5066 | case 147: |
5067 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | 5067 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); |
5068 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); | 5068 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); |
5069 | /* reset addr and status */ | ||
5070 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
5071 | if (addr == 0x0 && status == 0x0) | ||
5072 | break; | ||
5069 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); | 5073 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); |
5070 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 5074 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |
5071 | addr); | 5075 | addr); |
5072 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | 5076 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", |
5073 | status); | 5077 | status); |
5074 | cayman_vm_decode_fault(rdev, status, addr); | 5078 | cayman_vm_decode_fault(rdev, status, addr); |
5075 | /* reset addr and status */ | ||
5076 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
5077 | break; | 5079 | break; |
5078 | case 176: /* CP_INT in ring buffer */ | 5080 | case 176: /* CP_INT in ring buffer */ |
5079 | case 177: /* CP_INT in IB1 */ | 5081 | case 177: /* CP_INT in IB1 */ |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index da041a43d82e..3c76e1dcdf04 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2329,12 +2329,6 @@ void rv770_get_engine_memory_ss(struct radeon_device *rdev) | |||
2329 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | 2329 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
2330 | ASIC_INTERNAL_MEMORY_SS, 0); | 2330 | ASIC_INTERNAL_MEMORY_SS, 0); |
2331 | 2331 | ||
2332 | /* disable ss, causes hangs on some cayman boards */ | ||
2333 | if (rdev->family == CHIP_CAYMAN) { | ||
2334 | pi->sclk_ss = false; | ||
2335 | pi->mclk_ss = false; | ||
2336 | } | ||
2337 | |||
2338 | if (pi->sclk_ss || pi->mclk_ss) | 2332 | if (pi->sclk_ss || pi->mclk_ss) |
2339 | pi->dynamic_ss = true; | 2333 | pi->dynamic_ss = true; |
2340 | else | 2334 | else |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 730cee2c34cf..eba0225259a4 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -6376,14 +6376,16 @@ restart_ih: | |||
6376 | case 147: | 6376 | case 147: |
6377 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | 6377 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); |
6378 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); | 6378 | status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); |
6379 | /* reset addr and status */ | ||
6380 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
6381 | if (addr == 0x0 && status == 0x0) | ||
6382 | break; | ||
6379 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); | 6383 | dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); |
6380 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | 6384 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", |
6381 | addr); | 6385 | addr); |
6382 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | 6386 | dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", |
6383 | status); | 6387 | status); |
6384 | si_vm_decode_fault(rdev, status, addr); | 6388 | si_vm_decode_fault(rdev, status, addr); |
6385 | /* reset addr and status */ | ||
6386 | WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); | ||
6387 | break; | 6389 | break; |
6388 | case 176: /* RINGID0 CP_INT */ | 6390 | case 176: /* RINGID0 CP_INT */ |
6389 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 6391 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |