diff options
Diffstat (limited to 'drivers/gpu/drm')
37 files changed, 545 insertions, 213 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 82db1850666..fe738f05309 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -499,6 +499,7 @@ void drm_connector_cleanup(struct drm_connector *connector) | |||
499 | mutex_lock(&dev->mode_config.mutex); | 499 | mutex_lock(&dev->mode_config.mutex); |
500 | drm_mode_object_put(dev, &connector->base); | 500 | drm_mode_object_put(dev, &connector->base); |
501 | list_del(&connector->head); | 501 | list_del(&connector->head); |
502 | dev->mode_config.num_connector--; | ||
502 | mutex_unlock(&dev->mode_config.mutex); | 503 | mutex_unlock(&dev->mode_config.mutex); |
503 | } | 504 | } |
504 | EXPORT_SYMBOL(drm_connector_cleanup); | 505 | EXPORT_SYMBOL(drm_connector_cleanup); |
@@ -529,6 +530,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) | |||
529 | mutex_lock(&dev->mode_config.mutex); | 530 | mutex_lock(&dev->mode_config.mutex); |
530 | drm_mode_object_put(dev, &encoder->base); | 531 | drm_mode_object_put(dev, &encoder->base); |
531 | list_del(&encoder->head); | 532 | list_del(&encoder->head); |
533 | dev->mode_config.num_encoder--; | ||
532 | mutex_unlock(&dev->mode_config.mutex); | 534 | mutex_unlock(&dev->mode_config.mutex); |
533 | } | 535 | } |
534 | EXPORT_SYMBOL(drm_encoder_cleanup); | 536 | EXPORT_SYMBOL(drm_encoder_cleanup); |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 802b61ac313..f7c6854eb4d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -256,7 +256,6 @@ int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed, | |||
256 | { | 256 | { |
257 | printk(KERN_ERR "panic occurred, switching back to text console\n"); | 257 | printk(KERN_ERR "panic occurred, switching back to text console\n"); |
258 | return drm_fb_helper_force_kernel_mode(); | 258 | return drm_fb_helper_force_kernel_mode(); |
259 | return 0; | ||
260 | } | 259 | } |
261 | EXPORT_SYMBOL(drm_fb_helper_panic); | 260 | EXPORT_SYMBOL(drm_fb_helper_panic); |
262 | 261 | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a8ab6263e0d..3c395a59da3 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -499,7 +499,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
499 | seq_printf(m, "Interrupts received: %d\n", | 499 | seq_printf(m, "Interrupts received: %d\n", |
500 | atomic_read(&dev_priv->irq_received)); | 500 | atomic_read(&dev_priv->irq_received)); |
501 | for (i = 0; i < I915_NUM_RINGS; i++) { | 501 | for (i = 0; i < I915_NUM_RINGS; i++) { |
502 | if (IS_GEN6(dev)) { | 502 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
503 | seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", | 503 | seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", |
504 | dev_priv->ring[i].name, | 504 | dev_priv->ring[i].name, |
505 | I915_READ_IMR(&dev_priv->ring[i])); | 505 | I915_READ_IMR(&dev_priv->ring[i])); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index feb4f164fd1..7916bd97d5c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/io-mapping.h> | 36 | #include <linux/io-mapping.h> |
37 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
38 | #include <drm/intel-gtt.h> | 38 | #include <drm/intel-gtt.h> |
39 | #include <linux/backlight.h> | ||
39 | 40 | ||
40 | /* General customization: | 41 | /* General customization: |
41 | */ | 42 | */ |
@@ -690,6 +691,7 @@ typedef struct drm_i915_private { | |||
690 | int child_dev_num; | 691 | int child_dev_num; |
691 | struct child_device_config *child_dev; | 692 | struct child_device_config *child_dev; |
692 | struct drm_connector *int_lvds_connector; | 693 | struct drm_connector *int_lvds_connector; |
694 | struct drm_connector *int_edp_connector; | ||
693 | 695 | ||
694 | bool mchbar_need_disable; | 696 | bool mchbar_need_disable; |
695 | 697 | ||
@@ -723,6 +725,8 @@ typedef struct drm_i915_private { | |||
723 | /* list of fbdev register on this device */ | 725 | /* list of fbdev register on this device */ |
724 | struct intel_fbdev *fbdev; | 726 | struct intel_fbdev *fbdev; |
725 | 727 | ||
728 | struct backlight_device *backlight; | ||
729 | |||
726 | struct drm_property *broadcast_rgb_property; | 730 | struct drm_property *broadcast_rgb_property; |
727 | struct drm_property *force_audio_property; | 731 | struct drm_property *force_audio_property; |
728 | 732 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 02f96fd0d52..9cbb0cd8f46 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2058,8 +2058,10 @@ void intel_irq_init(struct drm_device *dev) | |||
2058 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; | 2058 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; |
2059 | } | 2059 | } |
2060 | 2060 | ||
2061 | 2061 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | |
2062 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; | 2062 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
2063 | else | ||
2064 | dev->driver->get_vblank_timestamp = NULL; | ||
2063 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; | 2065 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
2064 | 2066 | ||
2065 | if (IS_IVYBRIDGE(dev)) { | 2067 | if (IS_IVYBRIDGE(dev)) { |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d1331f771e2..542453f7498 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -375,6 +375,7 @@ | |||
375 | # define MI_FLUSH_ENABLE (1 << 11) | 375 | # define MI_FLUSH_ENABLE (1 << 11) |
376 | 376 | ||
377 | #define GFX_MODE 0x02520 | 377 | #define GFX_MODE 0x02520 |
378 | #define GFX_MODE_GEN7 0x0229c | ||
378 | #define GFX_RUN_LIST_ENABLE (1<<15) | 379 | #define GFX_RUN_LIST_ENABLE (1<<15) |
379 | #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) | 380 | #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) |
380 | #define GFX_SURFACE_FAULT_ENABLE (1<<12) | 381 | #define GFX_SURFACE_FAULT_ENABLE (1<<12) |
@@ -382,6 +383,9 @@ | |||
382 | #define GFX_PSMI_GRANULARITY (1<<10) | 383 | #define GFX_PSMI_GRANULARITY (1<<10) |
383 | #define GFX_PPGTT_ENABLE (1<<9) | 384 | #define GFX_PPGTT_ENABLE (1<<9) |
384 | 385 | ||
386 | #define GFX_MODE_ENABLE(bit) (((bit) << 16) | (bit)) | ||
387 | #define GFX_MODE_DISABLE(bit) (((bit) << 16) | (0)) | ||
388 | |||
385 | #define SCPD0 0x0209c /* 915+ only */ | 389 | #define SCPD0 0x0209c /* 915+ only */ |
386 | #define IER 0x020a0 | 390 | #define IER 0x020a0 |
387 | #define IIR 0x020a4 | 391 | #define IIR 0x020a4 |
@@ -1318,6 +1322,7 @@ | |||
1318 | #define ADPA_PIPE_SELECT_MASK (1<<30) | 1322 | #define ADPA_PIPE_SELECT_MASK (1<<30) |
1319 | #define ADPA_PIPE_A_SELECT 0 | 1323 | #define ADPA_PIPE_A_SELECT 0 |
1320 | #define ADPA_PIPE_B_SELECT (1<<30) | 1324 | #define ADPA_PIPE_B_SELECT (1<<30) |
1325 | #define ADPA_PIPE_SELECT(pipe) ((pipe) << 30) | ||
1321 | #define ADPA_USE_VGA_HVPOLARITY (1<<15) | 1326 | #define ADPA_USE_VGA_HVPOLARITY (1<<15) |
1322 | #define ADPA_SETS_HVPOLARITY 0 | 1327 | #define ADPA_SETS_HVPOLARITY 0 |
1323 | #define ADPA_VSYNC_CNTL_DISABLE (1<<11) | 1328 | #define ADPA_VSYNC_CNTL_DISABLE (1<<11) |
@@ -1460,6 +1465,7 @@ | |||
1460 | /* Selects pipe B for LVDS data. Must be set on pre-965. */ | 1465 | /* Selects pipe B for LVDS data. Must be set on pre-965. */ |
1461 | #define LVDS_PIPEB_SELECT (1 << 30) | 1466 | #define LVDS_PIPEB_SELECT (1 << 30) |
1462 | #define LVDS_PIPE_MASK (1 << 30) | 1467 | #define LVDS_PIPE_MASK (1 << 30) |
1468 | #define LVDS_PIPE(pipe) ((pipe) << 30) | ||
1463 | /* LVDS dithering flag on 965/g4x platform */ | 1469 | /* LVDS dithering flag on 965/g4x platform */ |
1464 | #define LVDS_ENABLE_DITHER (1 << 25) | 1470 | #define LVDS_ENABLE_DITHER (1 << 25) |
1465 | /* LVDS sync polarity flags. Set to invert (i.e. negative) */ | 1471 | /* LVDS sync polarity flags. Set to invert (i.e. negative) */ |
@@ -1499,9 +1505,6 @@ | |||
1499 | #define LVDS_B0B3_POWER_DOWN (0 << 2) | 1505 | #define LVDS_B0B3_POWER_DOWN (0 << 2) |
1500 | #define LVDS_B0B3_POWER_UP (3 << 2) | 1506 | #define LVDS_B0B3_POWER_UP (3 << 2) |
1501 | 1507 | ||
1502 | #define LVDS_PIPE_ENABLED(V, P) \ | ||
1503 | (((V) & (LVDS_PIPE_MASK | LVDS_PORT_EN)) == ((P) << 30 | LVDS_PORT_EN)) | ||
1504 | |||
1505 | /* Video Data Island Packet control */ | 1508 | /* Video Data Island Packet control */ |
1506 | #define VIDEO_DIP_DATA 0x61178 | 1509 | #define VIDEO_DIP_DATA 0x61178 |
1507 | #define VIDEO_DIP_CTL 0x61170 | 1510 | #define VIDEO_DIP_CTL 0x61170 |
@@ -3256,14 +3259,12 @@ | |||
3256 | #define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) | 3259 | #define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) |
3257 | #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) | 3260 | #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) |
3258 | 3261 | ||
3259 | #define ADPA_PIPE_ENABLED(V, P) \ | ||
3260 | (((V) & (ADPA_TRANS_SELECT_MASK | ADPA_DAC_ENABLE)) == ((P) << 30 | ADPA_DAC_ENABLE)) | ||
3261 | |||
3262 | /* or SDVOB */ | 3262 | /* or SDVOB */ |
3263 | #define HDMIB 0xe1140 | 3263 | #define HDMIB 0xe1140 |
3264 | #define PORT_ENABLE (1 << 31) | 3264 | #define PORT_ENABLE (1 << 31) |
3265 | #define TRANSCODER_A (0) | 3265 | #define TRANSCODER_A (0) |
3266 | #define TRANSCODER_B (1 << 30) | 3266 | #define TRANSCODER_B (1 << 30) |
3267 | #define TRANSCODER(pipe) ((pipe) << 30) | ||
3267 | #define TRANSCODER_MASK (1 << 30) | 3268 | #define TRANSCODER_MASK (1 << 30) |
3268 | #define COLOR_FORMAT_8bpc (0) | 3269 | #define COLOR_FORMAT_8bpc (0) |
3269 | #define COLOR_FORMAT_12bpc (3 << 26) | 3270 | #define COLOR_FORMAT_12bpc (3 << 26) |
@@ -3280,9 +3281,6 @@ | |||
3280 | #define HSYNC_ACTIVE_HIGH (1 << 3) | 3281 | #define HSYNC_ACTIVE_HIGH (1 << 3) |
3281 | #define PORT_DETECTED (1 << 2) | 3282 | #define PORT_DETECTED (1 << 2) |
3282 | 3283 | ||
3283 | #define HDMI_PIPE_ENABLED(V, P) \ | ||
3284 | (((V) & (TRANSCODER_MASK | PORT_ENABLE)) == ((P) << 30 | PORT_ENABLE)) | ||
3285 | |||
3286 | /* PCH SDVOB multiplex with HDMIB */ | 3284 | /* PCH SDVOB multiplex with HDMIB */ |
3287 | #define PCH_SDVOB HDMIB | 3285 | #define PCH_SDVOB HDMIB |
3288 | 3286 | ||
@@ -3349,6 +3347,7 @@ | |||
3349 | #define PORT_TRANS_B_SEL_CPT (1<<29) | 3347 | #define PORT_TRANS_B_SEL_CPT (1<<29) |
3350 | #define PORT_TRANS_C_SEL_CPT (2<<29) | 3348 | #define PORT_TRANS_C_SEL_CPT (2<<29) |
3351 | #define PORT_TRANS_SEL_MASK (3<<29) | 3349 | #define PORT_TRANS_SEL_MASK (3<<29) |
3350 | #define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29) | ||
3352 | 3351 | ||
3353 | #define TRANS_DP_CTL_A 0xe0300 | 3352 | #define TRANS_DP_CTL_A 0xe0300 |
3354 | #define TRANS_DP_CTL_B 0xe1300 | 3353 | #define TRANS_DP_CTL_B 0xe1300 |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 87677d60d0d..f10742359ec 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -871,7 +871,8 @@ int i915_restore_state(struct drm_device *dev) | |||
871 | } | 871 | } |
872 | mutex_unlock(&dev->struct_mutex); | 872 | mutex_unlock(&dev->struct_mutex); |
873 | 873 | ||
874 | intel_init_clock_gating(dev); | 874 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
875 | intel_init_clock_gating(dev); | ||
875 | 876 | ||
876 | if (IS_IRONLAKE_M(dev)) { | 877 | if (IS_IRONLAKE_M(dev)) { |
877 | ironlake_enable_drps(dev); | 878 | ironlake_enable_drps(dev); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 35364e68a09..56a8554d903 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -878,7 +878,7 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv, | |||
878 | int pp_reg, lvds_reg; | 878 | int pp_reg, lvds_reg; |
879 | u32 val; | 879 | u32 val; |
880 | enum pipe panel_pipe = PIPE_A; | 880 | enum pipe panel_pipe = PIPE_A; |
881 | bool locked = locked; | 881 | bool locked = true; |
882 | 882 | ||
883 | if (HAS_PCH_SPLIT(dev_priv->dev)) { | 883 | if (HAS_PCH_SPLIT(dev_priv->dev)) { |
884 | pp_reg = PCH_PP_CONTROL; | 884 | pp_reg = PCH_PP_CONTROL; |
@@ -980,8 +980,8 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, | |||
980 | pipe_name(pipe)); | 980 | pipe_name(pipe)); |
981 | } | 981 | } |
982 | 982 | ||
983 | static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, | 983 | static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, |
984 | int reg, u32 port_sel, u32 val) | 984 | enum pipe pipe, u32 port_sel, u32 val) |
985 | { | 985 | { |
986 | if ((val & DP_PORT_EN) == 0) | 986 | if ((val & DP_PORT_EN) == 0) |
987 | return false; | 987 | return false; |
@@ -998,11 +998,58 @@ static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, | |||
998 | return true; | 998 | return true; |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv, | ||
1002 | enum pipe pipe, u32 val) | ||
1003 | { | ||
1004 | if ((val & PORT_ENABLE) == 0) | ||
1005 | return false; | ||
1006 | |||
1007 | if (HAS_PCH_CPT(dev_priv->dev)) { | ||
1008 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | ||
1009 | return false; | ||
1010 | } else { | ||
1011 | if ((val & TRANSCODER_MASK) != TRANSCODER(pipe)) | ||
1012 | return false; | ||
1013 | } | ||
1014 | return true; | ||
1015 | } | ||
1016 | |||
1017 | static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv, | ||
1018 | enum pipe pipe, u32 val) | ||
1019 | { | ||
1020 | if ((val & LVDS_PORT_EN) == 0) | ||
1021 | return false; | ||
1022 | |||
1023 | if (HAS_PCH_CPT(dev_priv->dev)) { | ||
1024 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | ||
1025 | return false; | ||
1026 | } else { | ||
1027 | if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe)) | ||
1028 | return false; | ||
1029 | } | ||
1030 | return true; | ||
1031 | } | ||
1032 | |||
1033 | static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv, | ||
1034 | enum pipe pipe, u32 val) | ||
1035 | { | ||
1036 | if ((val & ADPA_DAC_ENABLE) == 0) | ||
1037 | return false; | ||
1038 | if (HAS_PCH_CPT(dev_priv->dev)) { | ||
1039 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | ||
1040 | return false; | ||
1041 | } else { | ||
1042 | if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe)) | ||
1043 | return false; | ||
1044 | } | ||
1045 | return true; | ||
1046 | } | ||
1047 | |||
1001 | static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | 1048 | static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, |
1002 | enum pipe pipe, int reg, u32 port_sel) | 1049 | enum pipe pipe, int reg, u32 port_sel) |
1003 | { | 1050 | { |
1004 | u32 val = I915_READ(reg); | 1051 | u32 val = I915_READ(reg); |
1005 | WARN(dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val), | 1052 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), |
1006 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1053 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1007 | reg, pipe_name(pipe)); | 1054 | reg, pipe_name(pipe)); |
1008 | } | 1055 | } |
@@ -1011,7 +1058,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1011 | enum pipe pipe, int reg) | 1058 | enum pipe pipe, int reg) |
1012 | { | 1059 | { |
1013 | u32 val = I915_READ(reg); | 1060 | u32 val = I915_READ(reg); |
1014 | WARN(HDMI_PIPE_ENABLED(val, pipe), | 1061 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), |
1015 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1062 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1016 | reg, pipe_name(pipe)); | 1063 | reg, pipe_name(pipe)); |
1017 | } | 1064 | } |
@@ -1028,13 +1075,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | |||
1028 | 1075 | ||
1029 | reg = PCH_ADPA; | 1076 | reg = PCH_ADPA; |
1030 | val = I915_READ(reg); | 1077 | val = I915_READ(reg); |
1031 | WARN(ADPA_PIPE_ENABLED(val, pipe), | 1078 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), |
1032 | "PCH VGA enabled on transcoder %c, should be disabled\n", | 1079 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
1033 | pipe_name(pipe)); | 1080 | pipe_name(pipe)); |
1034 | 1081 | ||
1035 | reg = PCH_LVDS; | 1082 | reg = PCH_LVDS; |
1036 | val = I915_READ(reg); | 1083 | val = I915_READ(reg); |
1037 | WARN(LVDS_PIPE_ENABLED(val, pipe), | 1084 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), |
1038 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | 1085 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1039 | pipe_name(pipe)); | 1086 | pipe_name(pipe)); |
1040 | 1087 | ||
@@ -1360,7 +1407,7 @@ static void disable_pch_dp(struct drm_i915_private *dev_priv, | |||
1360 | enum pipe pipe, int reg, u32 port_sel) | 1407 | enum pipe pipe, int reg, u32 port_sel) |
1361 | { | 1408 | { |
1362 | u32 val = I915_READ(reg); | 1409 | u32 val = I915_READ(reg); |
1363 | if (dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val)) { | 1410 | if (dp_pipe_enabled(dev_priv, pipe, port_sel, val)) { |
1364 | DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); | 1411 | DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); |
1365 | I915_WRITE(reg, val & ~DP_PORT_EN); | 1412 | I915_WRITE(reg, val & ~DP_PORT_EN); |
1366 | } | 1413 | } |
@@ -1370,7 +1417,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, | |||
1370 | enum pipe pipe, int reg) | 1417 | enum pipe pipe, int reg) |
1371 | { | 1418 | { |
1372 | u32 val = I915_READ(reg); | 1419 | u32 val = I915_READ(reg); |
1373 | if (HDMI_PIPE_ENABLED(val, pipe)) { | 1420 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { |
1374 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", | 1421 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
1375 | reg, pipe); | 1422 | reg, pipe); |
1376 | I915_WRITE(reg, val & ~PORT_ENABLE); | 1423 | I915_WRITE(reg, val & ~PORT_ENABLE); |
@@ -1392,12 +1439,13 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
1392 | 1439 | ||
1393 | reg = PCH_ADPA; | 1440 | reg = PCH_ADPA; |
1394 | val = I915_READ(reg); | 1441 | val = I915_READ(reg); |
1395 | if (ADPA_PIPE_ENABLED(val, pipe)) | 1442 | if (adpa_pipe_enabled(dev_priv, val, pipe)) |
1396 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); | 1443 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
1397 | 1444 | ||
1398 | reg = PCH_LVDS; | 1445 | reg = PCH_LVDS; |
1399 | val = I915_READ(reg); | 1446 | val = I915_READ(reg); |
1400 | if (LVDS_PIPE_ENABLED(val, pipe)) { | 1447 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { |
1448 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); | ||
1401 | I915_WRITE(reg, val & ~LVDS_PORT_EN); | 1449 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
1402 | POSTING_READ(reg); | 1450 | POSTING_READ(reg); |
1403 | udelay(100); | 1451 | udelay(100); |
@@ -5049,6 +5097,81 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5049 | return ret; | 5097 | return ret; |
5050 | } | 5098 | } |
5051 | 5099 | ||
5100 | static void ironlake_update_pch_refclk(struct drm_device *dev) | ||
5101 | { | ||
5102 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5103 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
5104 | struct drm_crtc *crtc; | ||
5105 | struct intel_encoder *encoder; | ||
5106 | struct intel_encoder *has_edp_encoder = NULL; | ||
5107 | u32 temp; | ||
5108 | bool has_lvds = false; | ||
5109 | |||
5110 | /* We need to take the global config into account */ | ||
5111 | list_for_each_entry(crtc, &mode_config->crtc_list, head) { | ||
5112 | if (!crtc->enabled) | ||
5113 | continue; | ||
5114 | |||
5115 | list_for_each_entry(encoder, &mode_config->encoder_list, | ||
5116 | base.head) { | ||
5117 | if (encoder->base.crtc != crtc) | ||
5118 | continue; | ||
5119 | |||
5120 | switch (encoder->type) { | ||
5121 | case INTEL_OUTPUT_LVDS: | ||
5122 | has_lvds = true; | ||
5123 | case INTEL_OUTPUT_EDP: | ||
5124 | has_edp_encoder = encoder; | ||
5125 | break; | ||
5126 | } | ||
5127 | } | ||
5128 | } | ||
5129 | |||
5130 | /* Ironlake: try to setup display ref clock before DPLL | ||
5131 | * enabling. This is only under driver's control after | ||
5132 | * PCH B stepping, previous chipset stepping should be | ||
5133 | * ignoring this setting. | ||
5134 | */ | ||
5135 | temp = I915_READ(PCH_DREF_CONTROL); | ||
5136 | /* Always enable nonspread source */ | ||
5137 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
5138 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; | ||
5139 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
5140 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
5141 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5142 | |||
5143 | POSTING_READ(PCH_DREF_CONTROL); | ||
5144 | udelay(200); | ||
5145 | |||
5146 | if (has_edp_encoder) { | ||
5147 | if (intel_panel_use_ssc(dev_priv)) { | ||
5148 | temp |= DREF_SSC1_ENABLE; | ||
5149 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5150 | |||
5151 | POSTING_READ(PCH_DREF_CONTROL); | ||
5152 | udelay(200); | ||
5153 | } | ||
5154 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
5155 | |||
5156 | /* Enable CPU source on CPU attached eDP */ | ||
5157 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
5158 | if (intel_panel_use_ssc(dev_priv)) | ||
5159 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | ||
5160 | else | ||
5161 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | ||
5162 | } else { | ||
5163 | /* Enable SSC on PCH eDP if needed */ | ||
5164 | if (intel_panel_use_ssc(dev_priv)) { | ||
5165 | DRM_ERROR("enabling SSC on PCH\n"); | ||
5166 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; | ||
5167 | } | ||
5168 | } | ||
5169 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5170 | POSTING_READ(PCH_DREF_CONTROL); | ||
5171 | udelay(200); | ||
5172 | } | ||
5173 | } | ||
5174 | |||
5052 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | 5175 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, |
5053 | struct drm_display_mode *mode, | 5176 | struct drm_display_mode *mode, |
5054 | struct drm_display_mode *adjusted_mode, | 5177 | struct drm_display_mode *adjusted_mode, |
@@ -5244,49 +5367,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5244 | ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, | 5367 | ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, |
5245 | &m_n); | 5368 | &m_n); |
5246 | 5369 | ||
5247 | /* Ironlake: try to setup display ref clock before DPLL | 5370 | ironlake_update_pch_refclk(dev); |
5248 | * enabling. This is only under driver's control after | ||
5249 | * PCH B stepping, previous chipset stepping should be | ||
5250 | * ignoring this setting. | ||
5251 | */ | ||
5252 | temp = I915_READ(PCH_DREF_CONTROL); | ||
5253 | /* Always enable nonspread source */ | ||
5254 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
5255 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; | ||
5256 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
5257 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
5258 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5259 | |||
5260 | POSTING_READ(PCH_DREF_CONTROL); | ||
5261 | udelay(200); | ||
5262 | |||
5263 | if (has_edp_encoder) { | ||
5264 | if (intel_panel_use_ssc(dev_priv)) { | ||
5265 | temp |= DREF_SSC1_ENABLE; | ||
5266 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5267 | |||
5268 | POSTING_READ(PCH_DREF_CONTROL); | ||
5269 | udelay(200); | ||
5270 | } | ||
5271 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
5272 | |||
5273 | /* Enable CPU source on CPU attached eDP */ | ||
5274 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
5275 | if (intel_panel_use_ssc(dev_priv)) | ||
5276 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | ||
5277 | else | ||
5278 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | ||
5279 | } else { | ||
5280 | /* Enable SSC on PCH eDP if needed */ | ||
5281 | if (intel_panel_use_ssc(dev_priv)) { | ||
5282 | DRM_ERROR("enabling SSC on PCH\n"); | ||
5283 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; | ||
5284 | } | ||
5285 | } | ||
5286 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5287 | POSTING_READ(PCH_DREF_CONTROL); | ||
5288 | udelay(200); | ||
5289 | } | ||
5290 | 5371 | ||
5291 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; | 5372 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; |
5292 | if (has_reduced_clock) | 5373 | if (has_reduced_clock) |
@@ -7157,8 +7238,6 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
7157 | intel_encoder_clones(dev, encoder->clone_mask); | 7238 | intel_encoder_clones(dev, encoder->clone_mask); |
7158 | } | 7239 | } |
7159 | 7240 | ||
7160 | intel_panel_setup_backlight(dev); | ||
7161 | |||
7162 | /* disable all the possible outputs/crtcs before entering KMS mode */ | 7241 | /* disable all the possible outputs/crtcs before entering KMS mode */ |
7163 | drm_helper_disable_unused_functions(dev); | 7242 | drm_helper_disable_unused_functions(dev); |
7164 | } | 7243 | } |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0feae908bb3..44fef5e1c49 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1841,6 +1841,11 @@ done: | |||
1841 | static void | 1841 | static void |
1842 | intel_dp_destroy (struct drm_connector *connector) | 1842 | intel_dp_destroy (struct drm_connector *connector) |
1843 | { | 1843 | { |
1844 | struct drm_device *dev = connector->dev; | ||
1845 | |||
1846 | if (intel_dpd_is_edp(dev)) | ||
1847 | intel_panel_destroy_backlight(dev); | ||
1848 | |||
1844 | drm_sysfs_connector_remove(connector); | 1849 | drm_sysfs_connector_remove(connector); |
1845 | drm_connector_cleanup(connector); | 1850 | drm_connector_cleanup(connector); |
1846 | kfree(connector); | 1851 | kfree(connector); |
@@ -2072,6 +2077,8 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2072 | DRM_MODE_TYPE_PREFERRED; | 2077 | DRM_MODE_TYPE_PREFERRED; |
2073 | } | 2078 | } |
2074 | } | 2079 | } |
2080 | dev_priv->int_edp_connector = connector; | ||
2081 | intel_panel_setup_backlight(dev); | ||
2075 | } | 2082 | } |
2076 | 2083 | ||
2077 | intel_dp_add_properties(intel_dp, connector); | 2084 | intel_dp_add_properties(intel_dp, connector); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7b330e76a43..0b2ee9d3998 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -297,9 +297,10 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
297 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 297 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
298 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | 298 | extern u32 intel_panel_get_backlight(struct drm_device *dev); |
299 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 299 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
300 | extern void intel_panel_setup_backlight(struct drm_device *dev); | 300 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
301 | extern void intel_panel_enable_backlight(struct drm_device *dev); | 301 | extern void intel_panel_enable_backlight(struct drm_device *dev); |
302 | extern void intel_panel_disable_backlight(struct drm_device *dev); | 302 | extern void intel_panel_disable_backlight(struct drm_device *dev); |
303 | extern void intel_panel_destroy_backlight(struct drm_device *dev); | ||
303 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); | 304 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); |
304 | 305 | ||
305 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 306 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2e8ddfcba40..31da77f5c05 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -72,14 +72,16 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) | |||
72 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
74 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
75 | u32 ctl_reg, lvds_reg; | 75 | u32 ctl_reg, lvds_reg, stat_reg; |
76 | 76 | ||
77 | if (HAS_PCH_SPLIT(dev)) { | 77 | if (HAS_PCH_SPLIT(dev)) { |
78 | ctl_reg = PCH_PP_CONTROL; | 78 | ctl_reg = PCH_PP_CONTROL; |
79 | lvds_reg = PCH_LVDS; | 79 | lvds_reg = PCH_LVDS; |
80 | stat_reg = PCH_PP_STATUS; | ||
80 | } else { | 81 | } else { |
81 | ctl_reg = PP_CONTROL; | 82 | ctl_reg = PP_CONTROL; |
82 | lvds_reg = LVDS; | 83 | lvds_reg = LVDS; |
84 | stat_reg = PP_STATUS; | ||
83 | } | 85 | } |
84 | 86 | ||
85 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | 87 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
@@ -94,17 +96,16 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) | |||
94 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | 96 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", |
95 | intel_lvds->pfit_control, | 97 | intel_lvds->pfit_control, |
96 | intel_lvds->pfit_pgm_ratios); | 98 | intel_lvds->pfit_pgm_ratios); |
97 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { | 99 | |
98 | DRM_ERROR("timed out waiting for panel to power off\n"); | 100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
99 | } else { | 101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | 102 | intel_lvds->pfit_dirty = false; |
101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
102 | intel_lvds->pfit_dirty = false; | ||
103 | } | ||
104 | } | 103 | } |
105 | 104 | ||
106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | 105 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
107 | POSTING_READ(lvds_reg); | 106 | POSTING_READ(lvds_reg); |
107 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) | ||
108 | DRM_ERROR("timed out waiting for panel to power on\n"); | ||
108 | 109 | ||
109 | intel_panel_enable_backlight(dev); | 110 | intel_panel_enable_backlight(dev); |
110 | } | 111 | } |
@@ -113,24 +114,25 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds) | |||
113 | { | 114 | { |
114 | struct drm_device *dev = intel_lvds->base.base.dev; | 115 | struct drm_device *dev = intel_lvds->base.base.dev; |
115 | struct drm_i915_private *dev_priv = dev->dev_private; | 116 | struct drm_i915_private *dev_priv = dev->dev_private; |
116 | u32 ctl_reg, lvds_reg; | 117 | u32 ctl_reg, lvds_reg, stat_reg; |
117 | 118 | ||
118 | if (HAS_PCH_SPLIT(dev)) { | 119 | if (HAS_PCH_SPLIT(dev)) { |
119 | ctl_reg = PCH_PP_CONTROL; | 120 | ctl_reg = PCH_PP_CONTROL; |
120 | lvds_reg = PCH_LVDS; | 121 | lvds_reg = PCH_LVDS; |
122 | stat_reg = PCH_PP_STATUS; | ||
121 | } else { | 123 | } else { |
122 | ctl_reg = PP_CONTROL; | 124 | ctl_reg = PP_CONTROL; |
123 | lvds_reg = LVDS; | 125 | lvds_reg = LVDS; |
126 | stat_reg = PP_STATUS; | ||
124 | } | 127 | } |
125 | 128 | ||
126 | intel_panel_disable_backlight(dev); | 129 | intel_panel_disable_backlight(dev); |
127 | 130 | ||
128 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | 131 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
132 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) | ||
133 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
129 | 134 | ||
130 | if (intel_lvds->pfit_control) { | 135 | if (intel_lvds->pfit_control) { |
131 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
132 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
133 | |||
134 | I915_WRITE(PFIT_CONTROL, 0); | 136 | I915_WRITE(PFIT_CONTROL, 0); |
135 | intel_lvds->pfit_dirty = true; | 137 | intel_lvds->pfit_dirty = true; |
136 | } | 138 | } |
@@ -398,53 +400,21 @@ out: | |||
398 | 400 | ||
399 | static void intel_lvds_prepare(struct drm_encoder *encoder) | 401 | static void intel_lvds_prepare(struct drm_encoder *encoder) |
400 | { | 402 | { |
401 | struct drm_device *dev = encoder->dev; | ||
402 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
403 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 403 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
404 | 404 | ||
405 | /* We try to do the minimum that is necessary in order to unlock | 405 | /* |
406 | * the registers for mode setting. | ||
407 | * | ||
408 | * On Ironlake, this is quite simple as we just set the unlock key | ||
409 | * and ignore all subtleties. (This may cause some issues...) | ||
410 | * | ||
411 | * Prior to Ironlake, we must disable the pipe if we want to adjust | 406 | * Prior to Ironlake, we must disable the pipe if we want to adjust |
412 | * the panel fitter. However at all other times we can just reset | 407 | * the panel fitter. However at all other times we can just reset |
413 | * the registers regardless. | 408 | * the registers regardless. |
414 | */ | 409 | */ |
415 | 410 | if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) | |
416 | if (HAS_PCH_SPLIT(dev)) { | 411 | intel_lvds_disable(intel_lvds); |
417 | I915_WRITE(PCH_PP_CONTROL, | ||
418 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
419 | } else if (intel_lvds->pfit_dirty) { | ||
420 | I915_WRITE(PP_CONTROL, | ||
421 | (I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS) | ||
422 | & ~POWER_TARGET_ON); | ||
423 | } else { | ||
424 | I915_WRITE(PP_CONTROL, | ||
425 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
426 | } | ||
427 | } | 412 | } |
428 | 413 | ||
429 | static void intel_lvds_commit(struct drm_encoder *encoder) | 414 | static void intel_lvds_commit(struct drm_encoder *encoder) |
430 | { | 415 | { |
431 | struct drm_device *dev = encoder->dev; | ||
432 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
433 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 416 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
434 | 417 | ||
435 | /* Undo any unlocking done in prepare to prevent accidental | ||
436 | * adjustment of the registers. | ||
437 | */ | ||
438 | if (HAS_PCH_SPLIT(dev)) { | ||
439 | u32 val = I915_READ(PCH_PP_CONTROL); | ||
440 | if ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS) | ||
441 | I915_WRITE(PCH_PP_CONTROL, val & 0x3); | ||
442 | } else { | ||
443 | u32 val = I915_READ(PP_CONTROL); | ||
444 | if ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS) | ||
445 | I915_WRITE(PP_CONTROL, val & 0x3); | ||
446 | } | ||
447 | |||
448 | /* Always do a full power on as we do not know what state | 418 | /* Always do a full power on as we do not know what state |
449 | * we were left in. | 419 | * we were left in. |
450 | */ | 420 | */ |
@@ -582,6 +552,8 @@ static void intel_lvds_destroy(struct drm_connector *connector) | |||
582 | struct drm_device *dev = connector->dev; | 552 | struct drm_device *dev = connector->dev; |
583 | struct drm_i915_private *dev_priv = dev->dev_private; | 553 | struct drm_i915_private *dev_priv = dev->dev_private; |
584 | 554 | ||
555 | intel_panel_destroy_backlight(dev); | ||
556 | |||
585 | if (dev_priv->lid_notifier.notifier_call) | 557 | if (dev_priv->lid_notifier.notifier_call) |
586 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); | 558 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); |
587 | drm_sysfs_connector_remove(connector); | 559 | drm_sysfs_connector_remove(connector); |
@@ -1040,6 +1012,19 @@ out: | |||
1040 | pwm = I915_READ(BLC_PWM_PCH_CTL1); | 1012 | pwm = I915_READ(BLC_PWM_PCH_CTL1); |
1041 | pwm |= PWM_PCH_ENABLE; | 1013 | pwm |= PWM_PCH_ENABLE; |
1042 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); | 1014 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); |
1015 | /* | ||
1016 | * Unlock registers and just | ||
1017 | * leave them unlocked | ||
1018 | */ | ||
1019 | I915_WRITE(PCH_PP_CONTROL, | ||
1020 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
1021 | } else { | ||
1022 | /* | ||
1023 | * Unlock registers and just | ||
1024 | * leave them unlocked | ||
1025 | */ | ||
1026 | I915_WRITE(PP_CONTROL, | ||
1027 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
1043 | } | 1028 | } |
1044 | dev_priv->lid_notifier.notifier_call = intel_lid_notify; | 1029 | dev_priv->lid_notifier.notifier_call = intel_lid_notify; |
1045 | if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { | 1030 | if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { |
@@ -1049,6 +1034,9 @@ out: | |||
1049 | /* keep the LVDS connector */ | 1034 | /* keep the LVDS connector */ |
1050 | dev_priv->int_lvds_connector = connector; | 1035 | dev_priv->int_lvds_connector = connector; |
1051 | drm_sysfs_connector_add(connector); | 1036 | drm_sysfs_connector_add(connector); |
1037 | |||
1038 | intel_panel_setup_backlight(dev); | ||
1039 | |||
1052 | return true; | 1040 | return true; |
1053 | 1041 | ||
1054 | failed: | 1042 | failed: |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index b7c5ddb564d..b8e8158bb16 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -227,7 +227,6 @@ void intel_opregion_asle_intr(struct drm_device *dev) | |||
227 | asle->aslc = asle_stat; | 227 | asle->aslc = asle_stat; |
228 | } | 228 | } |
229 | 229 | ||
230 | /* Only present on Ironlake+ */ | ||
231 | void intel_opregion_gse_intr(struct drm_device *dev) | 230 | void intel_opregion_gse_intr(struct drm_device *dev) |
232 | { | 231 | { |
233 | struct drm_i915_private *dev_priv = dev->dev_private; | 232 | struct drm_i915_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 05f500cd9c2..a9e0c7bcd31 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -277,7 +277,7 @@ void intel_panel_enable_backlight(struct drm_device *dev) | |||
277 | dev_priv->backlight_enabled = true; | 277 | dev_priv->backlight_enabled = true; |
278 | } | 278 | } |
279 | 279 | ||
280 | void intel_panel_setup_backlight(struct drm_device *dev) | 280 | static void intel_panel_init_backlight(struct drm_device *dev) |
281 | { | 281 | { |
282 | struct drm_i915_private *dev_priv = dev->dev_private; | 282 | struct drm_i915_private *dev_priv = dev->dev_private; |
283 | 283 | ||
@@ -309,3 +309,73 @@ intel_panel_detect(struct drm_device *dev) | |||
309 | 309 | ||
310 | return connector_status_unknown; | 310 | return connector_status_unknown; |
311 | } | 311 | } |
312 | |||
313 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | ||
314 | static int intel_panel_update_status(struct backlight_device *bd) | ||
315 | { | ||
316 | struct drm_device *dev = bl_get_data(bd); | ||
317 | intel_panel_set_backlight(dev, bd->props.brightness); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int intel_panel_get_brightness(struct backlight_device *bd) | ||
322 | { | ||
323 | struct drm_device *dev = bl_get_data(bd); | ||
324 | return intel_panel_get_backlight(dev); | ||
325 | } | ||
326 | |||
327 | static const struct backlight_ops intel_panel_bl_ops = { | ||
328 | .update_status = intel_panel_update_status, | ||
329 | .get_brightness = intel_panel_get_brightness, | ||
330 | }; | ||
331 | |||
332 | int intel_panel_setup_backlight(struct drm_device *dev) | ||
333 | { | ||
334 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
335 | struct backlight_properties props; | ||
336 | struct drm_connector *connector; | ||
337 | |||
338 | intel_panel_init_backlight(dev); | ||
339 | |||
340 | if (dev_priv->int_lvds_connector) | ||
341 | connector = dev_priv->int_lvds_connector; | ||
342 | else if (dev_priv->int_edp_connector) | ||
343 | connector = dev_priv->int_edp_connector; | ||
344 | else | ||
345 | return -ENODEV; | ||
346 | |||
347 | props.type = BACKLIGHT_RAW; | ||
348 | props.max_brightness = intel_panel_get_max_backlight(dev); | ||
349 | dev_priv->backlight = | ||
350 | backlight_device_register("intel_backlight", | ||
351 | &connector->kdev, dev, | ||
352 | &intel_panel_bl_ops, &props); | ||
353 | |||
354 | if (IS_ERR(dev_priv->backlight)) { | ||
355 | DRM_ERROR("Failed to register backlight: %ld\n", | ||
356 | PTR_ERR(dev_priv->backlight)); | ||
357 | dev_priv->backlight = NULL; | ||
358 | return -ENODEV; | ||
359 | } | ||
360 | dev_priv->backlight->props.brightness = intel_panel_get_backlight(dev); | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | void intel_panel_destroy_backlight(struct drm_device *dev) | ||
365 | { | ||
366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
367 | if (dev_priv->backlight) | ||
368 | backlight_device_unregister(dev_priv->backlight); | ||
369 | } | ||
370 | #else | ||
371 | int intel_panel_setup_backlight(struct drm_device *dev) | ||
372 | { | ||
373 | intel_panel_init_backlight(dev); | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | void intel_panel_destroy_backlight(struct drm_device *dev) | ||
378 | { | ||
379 | return; | ||
380 | } | ||
381 | #endif | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 47b9b277703..c30626ea9f9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -290,6 +290,10 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
290 | if (IS_GEN6(dev) || IS_GEN7(dev)) | 290 | if (IS_GEN6(dev) || IS_GEN7(dev)) |
291 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | 291 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; |
292 | I915_WRITE(MI_MODE, mode); | 292 | I915_WRITE(MI_MODE, mode); |
293 | if (IS_GEN7(dev)) | ||
294 | I915_WRITE(GFX_MODE_GEN7, | ||
295 | GFX_MODE_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | | ||
296 | GFX_MODE_ENABLE(GFX_REPLAY_MODE)); | ||
293 | } | 297 | } |
294 | 298 | ||
295 | if (INTEL_INFO(dev)->gen >= 6) { | 299 | if (INTEL_INFO(dev)->gen >= 6) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 8d02d875376..c919cfc8f2f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -530,7 +530,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
530 | nouveau_gpuobj_ref(NULL, &obj); | 530 | nouveau_gpuobj_ref(NULL, &obj); |
531 | if (ret) | 531 | if (ret) |
532 | return ret; | 532 | return ret; |
533 | } else { | 533 | } else |
534 | if (USE_SEMA(dev)) { | ||
534 | /* map fence bo into channel's vm */ | 535 | /* map fence bo into channel's vm */ |
535 | ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm, | 536 | ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm, |
536 | &chan->fence.vma); | 537 | &chan->fence.vma); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index c444cadbf84..2706cb3d871 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -37,8 +37,11 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, | |||
37 | return -ENOMEM; | 37 | return -ENOMEM; |
38 | 38 | ||
39 | nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL); | 39 | nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL); |
40 | if (!nvbe->ttm_alloced) | 40 | if (!nvbe->ttm_alloced) { |
41 | kfree(nvbe->pages); | ||
42 | nvbe->pages = NULL; | ||
41 | return -ENOMEM; | 43 | return -ENOMEM; |
44 | } | ||
42 | 45 | ||
43 | nvbe->nr_pages = 0; | 46 | nvbe->nr_pages = 0; |
44 | while (num_pages--) { | 47 | while (num_pages--) { |
@@ -126,7 +129,7 @@ nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) | |||
126 | 129 | ||
127 | for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) { | 130 | for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) { |
128 | nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); | 131 | nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); |
129 | dma_offset += NV_CTXDMA_PAGE_SIZE; | 132 | offset_l += NV_CTXDMA_PAGE_SIZE; |
130 | } | 133 | } |
131 | } | 134 | } |
132 | 135 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 118261d4927..5e45398a9e2 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
@@ -781,11 +781,20 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
781 | struct drm_device *dev = crtc->dev; | 781 | struct drm_device *dev = crtc->dev; |
782 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 782 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
783 | struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; | 783 | struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; |
784 | struct drm_framebuffer *drm_fb = nv_crtc->base.fb; | 784 | struct drm_framebuffer *drm_fb; |
785 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); | 785 | struct nouveau_framebuffer *fb; |
786 | int arb_burst, arb_lwm; | 786 | int arb_burst, arb_lwm; |
787 | int ret; | 787 | int ret; |
788 | 788 | ||
789 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | ||
790 | |||
791 | /* no fb bound */ | ||
792 | if (!atomic && !crtc->fb) { | ||
793 | NV_DEBUG_KMS(dev, "No FB bound\n"); | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | |||
789 | /* If atomic, we want to switch to the fb we were passed, so | 798 | /* If atomic, we want to switch to the fb we were passed, so |
790 | * now we update pointers to do that. (We don't pin; just | 799 | * now we update pointers to do that. (We don't pin; just |
791 | * assume we're already pinned and update the base address.) | 800 | * assume we're already pinned and update the base address.) |
@@ -794,6 +803,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
794 | drm_fb = passed_fb; | 803 | drm_fb = passed_fb; |
795 | fb = nouveau_framebuffer(passed_fb); | 804 | fb = nouveau_framebuffer(passed_fb); |
796 | } else { | 805 | } else { |
806 | drm_fb = crtc->fb; | ||
807 | fb = nouveau_framebuffer(crtc->fb); | ||
797 | /* If not atomic, we can go ahead and pin, and unpin the | 808 | /* If not atomic, we can go ahead and pin, and unpin the |
798 | * old fb we were passed. | 809 | * old fb we were passed. |
799 | */ | 810 | */ |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 46ad59ea218..5d989073ba6 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -519,12 +519,18 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
519 | struct drm_device *dev = nv_crtc->base.dev; | 519 | struct drm_device *dev = nv_crtc->base.dev; |
520 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 520 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
521 | struct nouveau_channel *evo = nv50_display(dev)->master; | 521 | struct nouveau_channel *evo = nv50_display(dev)->master; |
522 | struct drm_framebuffer *drm_fb = nv_crtc->base.fb; | 522 | struct drm_framebuffer *drm_fb; |
523 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); | 523 | struct nouveau_framebuffer *fb; |
524 | int ret; | 524 | int ret; |
525 | 525 | ||
526 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | 526 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
527 | 527 | ||
528 | /* no fb bound */ | ||
529 | if (!atomic && !crtc->fb) { | ||
530 | NV_DEBUG_KMS(dev, "No FB bound\n"); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
528 | /* If atomic, we want to switch to the fb we were passed, so | 534 | /* If atomic, we want to switch to the fb we were passed, so |
529 | * now we update pointers to do that. (We don't pin; just | 535 | * now we update pointers to do that. (We don't pin; just |
530 | * assume we're already pinned and update the base address.) | 536 | * assume we're already pinned and update the base address.) |
@@ -533,6 +539,8 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
533 | drm_fb = passed_fb; | 539 | drm_fb = passed_fb; |
534 | fb = nouveau_framebuffer(passed_fb); | 540 | fb = nouveau_framebuffer(passed_fb); |
535 | } else { | 541 | } else { |
542 | drm_fb = crtc->fb; | ||
543 | fb = nouveau_framebuffer(crtc->fb); | ||
536 | /* If not atomic, we can go ahead and pin, and unpin the | 544 | /* If not atomic, we can go ahead and pin, and unpin the |
537 | * old fb we were passed. | 545 | * old fb we were passed. |
538 | */ | 546 | */ |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 645b84b3d20..7ad43c6b1db 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -613,6 +613,18 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, | |||
613 | return true; | 613 | return true; |
614 | } | 614 | } |
615 | 615 | ||
616 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) | ||
617 | { | ||
618 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
619 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | ||
620 | |||
621 | if (!radeon_dp_get_link_status(radeon_connector, link_status)) | ||
622 | return false; | ||
623 | if (dp_channel_eq_ok(link_status, dig->dp_lane_count)) | ||
624 | return false; | ||
625 | return true; | ||
626 | } | ||
627 | |||
616 | struct radeon_dp_link_train_info { | 628 | struct radeon_dp_link_train_info { |
617 | struct radeon_device *rdev; | 629 | struct radeon_device *rdev; |
618 | struct drm_encoder *encoder; | 630 | struct drm_encoder *encoder; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 14dce9f2217..e8a746712b5 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev); | |||
41 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
43 | 43 | ||
44 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | ||
45 | { | ||
46 | u16 ctl, v; | ||
47 | int cap, err; | ||
48 | |||
49 | cap = pci_pcie_cap(rdev->pdev); | ||
50 | if (!cap) | ||
51 | return; | ||
52 | |||
53 | err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); | ||
54 | if (err) | ||
55 | return; | ||
56 | |||
57 | v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; | ||
58 | |||
59 | /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it | ||
60 | * to avoid hangs or perfomance issues | ||
61 | */ | ||
62 | if ((v == 0) || (v == 6) || (v == 7)) { | ||
63 | ctl &= ~PCI_EXP_DEVCTL_READRQ; | ||
64 | ctl |= (2 << 12); | ||
65 | pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); | ||
66 | } | ||
67 | } | ||
68 | |||
44 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | 69 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) |
45 | { | 70 | { |
46 | /* enable the pflip int */ | 71 | /* enable the pflip int */ |
@@ -743,7 +768,7 @@ static void evergreen_program_watermarks(struct radeon_device *rdev, | |||
743 | !evergreen_average_bandwidth_vs_available_bandwidth(&wm) || | 768 | !evergreen_average_bandwidth_vs_available_bandwidth(&wm) || |
744 | !evergreen_check_latency_hiding(&wm) || | 769 | !evergreen_check_latency_hiding(&wm) || |
745 | (rdev->disp_priority == 2)) { | 770 | (rdev->disp_priority == 2)) { |
746 | DRM_INFO("force priority to high\n"); | 771 | DRM_DEBUG_KMS("force priority to high\n"); |
747 | priority_a_cnt |= PRIORITY_ALWAYS_ON; | 772 | priority_a_cnt |= PRIORITY_ALWAYS_ON; |
748 | priority_b_cnt |= PRIORITY_ALWAYS_ON; | 773 | priority_b_cnt |= PRIORITY_ALWAYS_ON; |
749 | } | 774 | } |
@@ -1357,6 +1382,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
1357 | SOFT_RESET_PA | | 1382 | SOFT_RESET_PA | |
1358 | SOFT_RESET_SH | | 1383 | SOFT_RESET_SH | |
1359 | SOFT_RESET_VGT | | 1384 | SOFT_RESET_VGT | |
1385 | SOFT_RESET_SPI | | ||
1360 | SOFT_RESET_SX)); | 1386 | SOFT_RESET_SX)); |
1361 | RREG32(GRBM_SOFT_RESET); | 1387 | RREG32(GRBM_SOFT_RESET); |
1362 | mdelay(15); | 1388 | mdelay(15); |
@@ -1378,7 +1404,8 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
1378 | /* Initialize the ring buffer's read and write pointers */ | 1404 | /* Initialize the ring buffer's read and write pointers */ |
1379 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 1405 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
1380 | WREG32(CP_RB_RPTR_WR, 0); | 1406 | WREG32(CP_RB_RPTR_WR, 0); |
1381 | WREG32(CP_RB_WPTR, 0); | 1407 | rdev->cp.wptr = 0; |
1408 | WREG32(CP_RB_WPTR, rdev->cp.wptr); | ||
1382 | 1409 | ||
1383 | /* set the wb address wether it's enabled or not */ | 1410 | /* set the wb address wether it's enabled or not */ |
1384 | WREG32(CP_RB_RPTR_ADDR, | 1411 | WREG32(CP_RB_RPTR_ADDR, |
@@ -1400,7 +1427,6 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
1400 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); | 1427 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); |
1401 | 1428 | ||
1402 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 1429 | rdev->cp.rptr = RREG32(CP_RB_RPTR); |
1403 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | ||
1404 | 1430 | ||
1405 | evergreen_cp_start(rdev); | 1431 | evergreen_cp_start(rdev); |
1406 | rdev->cp.ready = true; | 1432 | rdev->cp.ready = true; |
@@ -1862,6 +1888,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1862 | 1888 | ||
1863 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); | 1889 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); |
1864 | 1890 | ||
1891 | evergreen_fix_pci_max_read_req_size(rdev); | ||
1892 | |||
1865 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; | 1893 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; |
1866 | 1894 | ||
1867 | cc_gc_shader_pipe_config |= | 1895 | cc_gc_shader_pipe_config |= |
@@ -3143,21 +3171,23 @@ int evergreen_suspend(struct radeon_device *rdev) | |||
3143 | } | 3171 | } |
3144 | 3172 | ||
3145 | int evergreen_copy_blit(struct radeon_device *rdev, | 3173 | int evergreen_copy_blit(struct radeon_device *rdev, |
3146 | uint64_t src_offset, uint64_t dst_offset, | 3174 | uint64_t src_offset, |
3147 | unsigned num_pages, struct radeon_fence *fence) | 3175 | uint64_t dst_offset, |
3176 | unsigned num_gpu_pages, | ||
3177 | struct radeon_fence *fence) | ||
3148 | { | 3178 | { |
3149 | int r; | 3179 | int r; |
3150 | 3180 | ||
3151 | mutex_lock(&rdev->r600_blit.mutex); | 3181 | mutex_lock(&rdev->r600_blit.mutex); |
3152 | rdev->r600_blit.vb_ib = NULL; | 3182 | rdev->r600_blit.vb_ib = NULL; |
3153 | r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | 3183 | r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); |
3154 | if (r) { | 3184 | if (r) { |
3155 | if (rdev->r600_blit.vb_ib) | 3185 | if (rdev->r600_blit.vb_ib) |
3156 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | 3186 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); |
3157 | mutex_unlock(&rdev->r600_blit.mutex); | 3187 | mutex_unlock(&rdev->r600_blit.mutex); |
3158 | return r; | 3188 | return r; |
3159 | } | 3189 | } |
3160 | evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); | 3190 | evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); |
3161 | evergreen_blit_done_copy(rdev, fence); | 3191 | evergreen_blit_done_copy(rdev, fence); |
3162 | mutex_unlock(&rdev->r600_blit.mutex); | 3192 | mutex_unlock(&rdev->r600_blit.mutex); |
3163 | return 0; | 3193 | return 0; |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 44c4750f451..99fbd793c08 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -39,6 +39,7 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); | |||
39 | extern void evergreen_mc_program(struct radeon_device *rdev); | 39 | extern void evergreen_mc_program(struct radeon_device *rdev); |
40 | extern void evergreen_irq_suspend(struct radeon_device *rdev); | 40 | extern void evergreen_irq_suspend(struct radeon_device *rdev); |
41 | extern int evergreen_mc_init(struct radeon_device *rdev); | 41 | extern int evergreen_mc_init(struct radeon_device *rdev); |
42 | extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); | ||
42 | 43 | ||
43 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | 44 | #define EVERGREEN_PFP_UCODE_SIZE 1120 |
44 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | 45 | #define EVERGREEN_PM4_UCODE_SIZE 1376 |
@@ -669,6 +670,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
669 | 670 | ||
670 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); | 671 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); |
671 | 672 | ||
673 | evergreen_fix_pci_max_read_req_size(rdev); | ||
674 | |||
672 | mc_shared_chmap = RREG32(MC_SHARED_CHMAP); | 675 | mc_shared_chmap = RREG32(MC_SHARED_CHMAP); |
673 | mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | 676 | mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); |
674 | 677 | ||
@@ -1159,6 +1162,7 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1159 | SOFT_RESET_PA | | 1162 | SOFT_RESET_PA | |
1160 | SOFT_RESET_SH | | 1163 | SOFT_RESET_SH | |
1161 | SOFT_RESET_VGT | | 1164 | SOFT_RESET_VGT | |
1165 | SOFT_RESET_SPI | | ||
1162 | SOFT_RESET_SX)); | 1166 | SOFT_RESET_SX)); |
1163 | RREG32(GRBM_SOFT_RESET); | 1167 | RREG32(GRBM_SOFT_RESET); |
1164 | mdelay(15); | 1168 | mdelay(15); |
@@ -1183,7 +1187,8 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1183 | 1187 | ||
1184 | /* Initialize the ring buffer's read and write pointers */ | 1188 | /* Initialize the ring buffer's read and write pointers */ |
1185 | WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); | 1189 | WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); |
1186 | WREG32(CP_RB0_WPTR, 0); | 1190 | rdev->cp.wptr = 0; |
1191 | WREG32(CP_RB0_WPTR, rdev->cp.wptr); | ||
1187 | 1192 | ||
1188 | /* set the wb address wether it's enabled or not */ | 1193 | /* set the wb address wether it's enabled or not */ |
1189 | WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); | 1194 | WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); |
@@ -1203,7 +1208,6 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1203 | WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); | 1208 | WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); |
1204 | 1209 | ||
1205 | rdev->cp.rptr = RREG32(CP_RB0_RPTR); | 1210 | rdev->cp.rptr = RREG32(CP_RB0_RPTR); |
1206 | rdev->cp.wptr = RREG32(CP_RB0_WPTR); | ||
1207 | 1211 | ||
1208 | /* ring1 - compute only */ | 1212 | /* ring1 - compute only */ |
1209 | /* Set ring buffer size */ | 1213 | /* Set ring buffer size */ |
@@ -1216,7 +1220,8 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1216 | 1220 | ||
1217 | /* Initialize the ring buffer's read and write pointers */ | 1221 | /* Initialize the ring buffer's read and write pointers */ |
1218 | WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); | 1222 | WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); |
1219 | WREG32(CP_RB1_WPTR, 0); | 1223 | rdev->cp1.wptr = 0; |
1224 | WREG32(CP_RB1_WPTR, rdev->cp1.wptr); | ||
1220 | 1225 | ||
1221 | /* set the wb address wether it's enabled or not */ | 1226 | /* set the wb address wether it's enabled or not */ |
1222 | WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); | 1227 | WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); |
@@ -1228,7 +1233,6 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1228 | WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); | 1233 | WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); |
1229 | 1234 | ||
1230 | rdev->cp1.rptr = RREG32(CP_RB1_RPTR); | 1235 | rdev->cp1.rptr = RREG32(CP_RB1_RPTR); |
1231 | rdev->cp1.wptr = RREG32(CP_RB1_WPTR); | ||
1232 | 1236 | ||
1233 | /* ring2 - compute only */ | 1237 | /* ring2 - compute only */ |
1234 | /* Set ring buffer size */ | 1238 | /* Set ring buffer size */ |
@@ -1241,7 +1245,8 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1241 | 1245 | ||
1242 | /* Initialize the ring buffer's read and write pointers */ | 1246 | /* Initialize the ring buffer's read and write pointers */ |
1243 | WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); | 1247 | WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); |
1244 | WREG32(CP_RB2_WPTR, 0); | 1248 | rdev->cp2.wptr = 0; |
1249 | WREG32(CP_RB2_WPTR, rdev->cp2.wptr); | ||
1245 | 1250 | ||
1246 | /* set the wb address wether it's enabled or not */ | 1251 | /* set the wb address wether it's enabled or not */ |
1247 | WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); | 1252 | WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); |
@@ -1253,7 +1258,6 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1253 | WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); | 1258 | WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); |
1254 | 1259 | ||
1255 | rdev->cp2.rptr = RREG32(CP_RB2_RPTR); | 1260 | rdev->cp2.rptr = RREG32(CP_RB2_RPTR); |
1256 | rdev->cp2.wptr = RREG32(CP_RB2_WPTR); | ||
1257 | 1261 | ||
1258 | /* start the rings */ | 1262 | /* start the rings */ |
1259 | cayman_cp_start(rdev); | 1263 | cayman_cp_start(rdev); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index f2204cb1ccd..5b1837b4aac 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -721,11 +721,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev, | |||
721 | int r100_copy_blit(struct radeon_device *rdev, | 721 | int r100_copy_blit(struct radeon_device *rdev, |
722 | uint64_t src_offset, | 722 | uint64_t src_offset, |
723 | uint64_t dst_offset, | 723 | uint64_t dst_offset, |
724 | unsigned num_pages, | 724 | unsigned num_gpu_pages, |
725 | struct radeon_fence *fence) | 725 | struct radeon_fence *fence) |
726 | { | 726 | { |
727 | uint32_t cur_pages; | 727 | uint32_t cur_pages; |
728 | uint32_t stride_bytes = PAGE_SIZE; | 728 | uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; |
729 | uint32_t pitch; | 729 | uint32_t pitch; |
730 | uint32_t stride_pixels; | 730 | uint32_t stride_pixels; |
731 | unsigned ndw; | 731 | unsigned ndw; |
@@ -737,7 +737,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
737 | /* radeon pitch is /64 */ | 737 | /* radeon pitch is /64 */ |
738 | pitch = stride_bytes / 64; | 738 | pitch = stride_bytes / 64; |
739 | stride_pixels = stride_bytes / 4; | 739 | stride_pixels = stride_bytes / 4; |
740 | num_loops = DIV_ROUND_UP(num_pages, 8191); | 740 | num_loops = DIV_ROUND_UP(num_gpu_pages, 8191); |
741 | 741 | ||
742 | /* Ask for enough room for blit + flush + fence */ | 742 | /* Ask for enough room for blit + flush + fence */ |
743 | ndw = 64 + (10 * num_loops); | 743 | ndw = 64 + (10 * num_loops); |
@@ -746,12 +746,12 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
746 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); | 746 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); |
747 | return -EINVAL; | 747 | return -EINVAL; |
748 | } | 748 | } |
749 | while (num_pages > 0) { | 749 | while (num_gpu_pages > 0) { |
750 | cur_pages = num_pages; | 750 | cur_pages = num_gpu_pages; |
751 | if (cur_pages > 8191) { | 751 | if (cur_pages > 8191) { |
752 | cur_pages = 8191; | 752 | cur_pages = 8191; |
753 | } | 753 | } |
754 | num_pages -= cur_pages; | 754 | num_gpu_pages -= cur_pages; |
755 | 755 | ||
756 | /* pages are in Y direction - height | 756 | /* pages are in Y direction - height |
757 | page width in X direction - width */ | 757 | page width in X direction - width */ |
@@ -773,8 +773,8 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
773 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); | 773 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); |
774 | radeon_ring_write(rdev, 0); | 774 | radeon_ring_write(rdev, 0); |
775 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); | 775 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); |
776 | radeon_ring_write(rdev, num_pages); | 776 | radeon_ring_write(rdev, cur_pages); |
777 | radeon_ring_write(rdev, num_pages); | 777 | radeon_ring_write(rdev, cur_pages); |
778 | radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); | 778 | radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); |
779 | } | 779 | } |
780 | radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); | 780 | radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); |
@@ -990,7 +990,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
990 | /* Force read & write ptr to 0 */ | 990 | /* Force read & write ptr to 0 */ |
991 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); | 991 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); |
992 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | 992 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
993 | WREG32(RADEON_CP_RB_WPTR, 0); | 993 | rdev->cp.wptr = 0; |
994 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); | ||
994 | 995 | ||
995 | /* set the wb address whether it's enabled or not */ | 996 | /* set the wb address whether it's enabled or not */ |
996 | WREG32(R_00070C_CP_RB_RPTR_ADDR, | 997 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
@@ -1007,9 +1008,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1007 | WREG32(RADEON_CP_RB_CNTL, tmp); | 1008 | WREG32(RADEON_CP_RB_CNTL, tmp); |
1008 | udelay(10); | 1009 | udelay(10); |
1009 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); | 1010 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
1010 | rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); | ||
1011 | /* protect against crazy HW on resume */ | ||
1012 | rdev->cp.wptr &= rdev->cp.ptr_mask; | ||
1013 | /* Set cp mode to bus mastering & enable cp*/ | 1011 | /* Set cp mode to bus mastering & enable cp*/ |
1014 | WREG32(RADEON_CP_CSQ_MODE, | 1012 | WREG32(RADEON_CP_CSQ_MODE, |
1015 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | | 1013 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index f2405830041..a1f3ba063c2 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
@@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) | |||
84 | int r200_copy_dma(struct radeon_device *rdev, | 84 | int r200_copy_dma(struct radeon_device *rdev, |
85 | uint64_t src_offset, | 85 | uint64_t src_offset, |
86 | uint64_t dst_offset, | 86 | uint64_t dst_offset, |
87 | unsigned num_pages, | 87 | unsigned num_gpu_pages, |
88 | struct radeon_fence *fence) | 88 | struct radeon_fence *fence) |
89 | { | 89 | { |
90 | uint32_t size; | 90 | uint32_t size; |
@@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev, | |||
93 | int r = 0; | 93 | int r = 0; |
94 | 94 | ||
95 | /* radeon pitch is /64 */ | 95 | /* radeon pitch is /64 */ |
96 | size = num_pages << PAGE_SHIFT; | 96 | size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; |
97 | num_loops = DIV_ROUND_UP(size, 0x1FFFFF); | 97 | num_loops = DIV_ROUND_UP(size, 0x1FFFFF); |
98 | r = radeon_ring_lock(rdev, num_loops * 4 + 64); | 98 | r = radeon_ring_lock(rdev, num_loops * 4 + 64); |
99 | if (r) { | 99 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index aa5571b73aa..720dd99163f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2209,7 +2209,8 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2209 | /* Initialize the ring buffer's read and write pointers */ | 2209 | /* Initialize the ring buffer's read and write pointers */ |
2210 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 2210 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
2211 | WREG32(CP_RB_RPTR_WR, 0); | 2211 | WREG32(CP_RB_RPTR_WR, 0); |
2212 | WREG32(CP_RB_WPTR, 0); | 2212 | rdev->cp.wptr = 0; |
2213 | WREG32(CP_RB_WPTR, rdev->cp.wptr); | ||
2213 | 2214 | ||
2214 | /* set the wb address whether it's enabled or not */ | 2215 | /* set the wb address whether it's enabled or not */ |
2215 | WREG32(CP_RB_RPTR_ADDR, | 2216 | WREG32(CP_RB_RPTR_ADDR, |
@@ -2231,7 +2232,6 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2231 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); | 2232 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); |
2232 | 2233 | ||
2233 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 2234 | rdev->cp.rptr = RREG32(CP_RB_RPTR); |
2234 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | ||
2235 | 2235 | ||
2236 | r600_cp_start(rdev); | 2236 | r600_cp_start(rdev); |
2237 | rdev->cp.ready = true; | 2237 | rdev->cp.ready = true; |
@@ -2353,21 +2353,23 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
2353 | } | 2353 | } |
2354 | 2354 | ||
2355 | int r600_copy_blit(struct radeon_device *rdev, | 2355 | int r600_copy_blit(struct radeon_device *rdev, |
2356 | uint64_t src_offset, uint64_t dst_offset, | 2356 | uint64_t src_offset, |
2357 | unsigned num_pages, struct radeon_fence *fence) | 2357 | uint64_t dst_offset, |
2358 | unsigned num_gpu_pages, | ||
2359 | struct radeon_fence *fence) | ||
2358 | { | 2360 | { |
2359 | int r; | 2361 | int r; |
2360 | 2362 | ||
2361 | mutex_lock(&rdev->r600_blit.mutex); | 2363 | mutex_lock(&rdev->r600_blit.mutex); |
2362 | rdev->r600_blit.vb_ib = NULL; | 2364 | rdev->r600_blit.vb_ib = NULL; |
2363 | r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | 2365 | r = r600_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); |
2364 | if (r) { | 2366 | if (r) { |
2365 | if (rdev->r600_blit.vb_ib) | 2367 | if (rdev->r600_blit.vb_ib) |
2366 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | 2368 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); |
2367 | mutex_unlock(&rdev->r600_blit.mutex); | 2369 | mutex_unlock(&rdev->r600_blit.mutex); |
2368 | return r; | 2370 | return r; |
2369 | } | 2371 | } |
2370 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); | 2372 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); |
2371 | r600_blit_done_copy(rdev, fence); | 2373 | r600_blit_done_copy(rdev, fence); |
2372 | mutex_unlock(&rdev->r600_blit.mutex); | 2374 | mutex_unlock(&rdev->r600_blit.mutex); |
2373 | return 0; | 2375 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 32807baf55e..c1e056b35b2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -322,6 +322,7 @@ union radeon_gart_table { | |||
322 | 322 | ||
323 | #define RADEON_GPU_PAGE_SIZE 4096 | 323 | #define RADEON_GPU_PAGE_SIZE 4096 |
324 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) | 324 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) |
325 | #define RADEON_GPU_PAGE_SHIFT 12 | ||
325 | 326 | ||
326 | struct radeon_gart { | 327 | struct radeon_gart { |
327 | dma_addr_t table_addr; | 328 | dma_addr_t table_addr; |
@@ -914,17 +915,17 @@ struct radeon_asic { | |||
914 | int (*copy_blit)(struct radeon_device *rdev, | 915 | int (*copy_blit)(struct radeon_device *rdev, |
915 | uint64_t src_offset, | 916 | uint64_t src_offset, |
916 | uint64_t dst_offset, | 917 | uint64_t dst_offset, |
917 | unsigned num_pages, | 918 | unsigned num_gpu_pages, |
918 | struct radeon_fence *fence); | 919 | struct radeon_fence *fence); |
919 | int (*copy_dma)(struct radeon_device *rdev, | 920 | int (*copy_dma)(struct radeon_device *rdev, |
920 | uint64_t src_offset, | 921 | uint64_t src_offset, |
921 | uint64_t dst_offset, | 922 | uint64_t dst_offset, |
922 | unsigned num_pages, | 923 | unsigned num_gpu_pages, |
923 | struct radeon_fence *fence); | 924 | struct radeon_fence *fence); |
924 | int (*copy)(struct radeon_device *rdev, | 925 | int (*copy)(struct radeon_device *rdev, |
925 | uint64_t src_offset, | 926 | uint64_t src_offset, |
926 | uint64_t dst_offset, | 927 | uint64_t dst_offset, |
927 | unsigned num_pages, | 928 | unsigned num_gpu_pages, |
928 | struct radeon_fence *fence); | 929 | struct radeon_fence *fence); |
929 | uint32_t (*get_engine_clock)(struct radeon_device *rdev); | 930 | uint32_t (*get_engine_clock)(struct radeon_device *rdev); |
930 | void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); | 931 | void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 3d7a0d7c6a9..3dedaa07aac 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); | |||
75 | int r100_copy_blit(struct radeon_device *rdev, | 75 | int r100_copy_blit(struct radeon_device *rdev, |
76 | uint64_t src_offset, | 76 | uint64_t src_offset, |
77 | uint64_t dst_offset, | 77 | uint64_t dst_offset, |
78 | unsigned num_pages, | 78 | unsigned num_gpu_pages, |
79 | struct radeon_fence *fence); | 79 | struct radeon_fence *fence); |
80 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, | 80 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, |
81 | uint32_t tiling_flags, uint32_t pitch, | 81 | uint32_t tiling_flags, uint32_t pitch, |
@@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); | |||
143 | extern int r200_copy_dma(struct radeon_device *rdev, | 143 | extern int r200_copy_dma(struct radeon_device *rdev, |
144 | uint64_t src_offset, | 144 | uint64_t src_offset, |
145 | uint64_t dst_offset, | 145 | uint64_t dst_offset, |
146 | unsigned num_pages, | 146 | unsigned num_gpu_pages, |
147 | struct radeon_fence *fence); | 147 | struct radeon_fence *fence); |
148 | void r200_set_safe_registers(struct radeon_device *rdev); | 148 | void r200_set_safe_registers(struct radeon_device *rdev); |
149 | 149 | ||
@@ -311,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | |||
311 | int r600_ring_test(struct radeon_device *rdev); | 311 | int r600_ring_test(struct radeon_device *rdev); |
312 | int r600_copy_blit(struct radeon_device *rdev, | 312 | int r600_copy_blit(struct radeon_device *rdev, |
313 | uint64_t src_offset, uint64_t dst_offset, | 313 | uint64_t src_offset, uint64_t dst_offset, |
314 | unsigned num_pages, struct radeon_fence *fence); | 314 | unsigned num_gpu_pages, struct radeon_fence *fence); |
315 | void r600_hpd_init(struct radeon_device *rdev); | 315 | void r600_hpd_init(struct radeon_device *rdev); |
316 | void r600_hpd_fini(struct radeon_device *rdev); | 316 | void r600_hpd_fini(struct radeon_device *rdev); |
317 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 317 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
@@ -403,7 +403,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev); | |||
403 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 403 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
404 | int evergreen_copy_blit(struct radeon_device *rdev, | 404 | int evergreen_copy_blit(struct radeon_device *rdev, |
405 | uint64_t src_offset, uint64_t dst_offset, | 405 | uint64_t src_offset, uint64_t dst_offset, |
406 | unsigned num_pages, struct radeon_fence *fence); | 406 | unsigned num_gpu_pages, struct radeon_fence *fence); |
407 | void evergreen_hpd_init(struct radeon_device *rdev); | 407 | void evergreen_hpd_init(struct radeon_device *rdev); |
408 | void evergreen_hpd_fini(struct radeon_device *rdev); | 408 | void evergreen_hpd_fini(struct radeon_device *rdev); |
409 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 409 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index dcd0863e31a..b6e18c8db9f 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -219,6 +219,9 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
219 | } else { | 219 | } else { |
220 | DRM_INFO("Using generic clock info\n"); | 220 | DRM_INFO("Using generic clock info\n"); |
221 | 221 | ||
222 | /* may need to be per card */ | ||
223 | rdev->clock.max_pixel_clock = 35000; | ||
224 | |||
222 | if (rdev->flags & RADEON_IS_IGP) { | 225 | if (rdev->flags & RADEON_IS_IGP) { |
223 | p1pll->reference_freq = 1432; | 226 | p1pll->reference_freq = 1432; |
224 | p2pll->reference_freq = 1432; | 227 | p2pll->reference_freq = 1432; |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e0138b674ac..63675241c7f 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -3298,6 +3298,14 @@ void radeon_combios_asic_init(struct drm_device *dev) | |||
3298 | rdev->pdev->subsystem_device == 0x30a4) | 3298 | rdev->pdev->subsystem_device == 0x30a4) |
3299 | return; | 3299 | return; |
3300 | 3300 | ||
3301 | /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume | ||
3302 | * - it hangs on resume inside the dynclk 1 table. | ||
3303 | */ | ||
3304 | if (rdev->family == CHIP_RS480 && | ||
3305 | rdev->pdev->subsystem_vendor == 0x103c && | ||
3306 | rdev->pdev->subsystem_device == 0x30ae) | ||
3307 | return; | ||
3308 | |||
3301 | /* DYN CLK 1 */ | 3309 | /* DYN CLK 1 */ |
3302 | table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); | 3310 | table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); |
3303 | if (table) | 3311 | if (table) |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 6d6b5f16bc0..c4b8741dbf5 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -60,18 +60,20 @@ void radeon_connector_hotplug(struct drm_connector *connector) | |||
60 | 60 | ||
61 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 61 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
62 | 62 | ||
63 | /* powering up/down the eDP panel generates hpd events which | 63 | /* if the connector is already off, don't turn it back on */ |
64 | * can interfere with modesetting. | 64 | if (connector->dpms != DRM_MODE_DPMS_ON) |
65 | */ | ||
66 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
67 | return; | 65 | return; |
68 | 66 | ||
69 | /* pre-r600 did not always have the hpd pins mapped accurately to connectors */ | 67 | /* just deal with DP (not eDP) here. */ |
70 | if (rdev->family >= CHIP_R600) { | 68 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
71 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | 69 | int saved_dpms = connector->dpms; |
70 | |||
71 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && | ||
72 | radeon_dp_needs_link_train(radeon_connector)) | ||
72 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 73 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); |
73 | else | 74 | else |
74 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 75 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
76 | connector->dpms = saved_dpms; | ||
75 | } | 77 | } |
76 | } | 78 | } |
77 | 79 | ||
@@ -464,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, | |||
464 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | 466 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
465 | return true; | 467 | return true; |
466 | } | 468 | } |
469 | /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 | ||
470 | * (RS690M) sends data to i2c bus for a HDMI connector that | ||
471 | * is not implemented */ | ||
472 | if ((dev->pdev->device == 0x791f) && | ||
473 | (dev->pdev->subsystem_vendor == 0x1179) && | ||
474 | (dev->pdev->subsystem_device == 0xff68)) { | ||
475 | if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
476 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
477 | return true; | ||
478 | } | ||
467 | 479 | ||
468 | /* Default: no EDID header probe required for DDC probing */ | 480 | /* Default: no EDID header probe required for DDC probing */ |
469 | return false; | 481 | return false; |
@@ -474,11 +486,19 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | |||
474 | { | 486 | { |
475 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
476 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | 488 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
489 | struct drm_display_mode *t, *mode; | ||
490 | |||
491 | /* If the EDID preferred mode doesn't match the native mode, use it */ | ||
492 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { | ||
493 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { | ||
494 | if (mode->hdisplay != native_mode->hdisplay || | ||
495 | mode->vdisplay != native_mode->vdisplay) | ||
496 | memcpy(native_mode, mode, sizeof(*mode)); | ||
497 | } | ||
498 | } | ||
477 | 499 | ||
478 | /* Try to get native mode details from EDID if necessary */ | 500 | /* Try to get native mode details from EDID if necessary */ |
479 | if (!native_mode->clock) { | 501 | if (!native_mode->clock) { |
480 | struct drm_display_mode *t, *mode; | ||
481 | |||
482 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { | 502 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { |
483 | if (mode->hdisplay == native_mode->hdisplay && | 503 | if (mode->hdisplay == native_mode->hdisplay && |
484 | mode->vdisplay == native_mode->vdisplay) { | 504 | mode->vdisplay == native_mode->vdisplay) { |
@@ -489,6 +509,7 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | |||
489 | } | 509 | } |
490 | } | 510 | } |
491 | } | 511 | } |
512 | |||
492 | if (!native_mode->clock) { | 513 | if (!native_mode->clock) { |
493 | DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); | 514 | DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); |
494 | radeon_encoder->rmx_type = RMX_OFF; | 515 | radeon_encoder->rmx_type = RMX_OFF; |
@@ -1276,12 +1297,33 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1276 | if (!radeon_dig_connector->edp_on) | 1297 | if (!radeon_dig_connector->edp_on) |
1277 | atombios_set_edp_panel_power(connector, | 1298 | atombios_set_edp_panel_power(connector, |
1278 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1299 | ATOM_TRANSMITTER_ACTION_POWER_OFF); |
1279 | } else { | 1300 | } else if (radeon_connector_encoder_is_dp_bridge(connector)) { |
1280 | /* need to setup ddc on the bridge */ | 1301 | /* DP bridges are always DP */ |
1281 | if (radeon_connector_encoder_is_dp_bridge(connector)) { | 1302 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
1303 | /* get the DPCD from the bridge */ | ||
1304 | radeon_dp_getdpcd(radeon_connector); | ||
1305 | |||
1306 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
1307 | ret = connector_status_connected; | ||
1308 | else { | ||
1309 | /* need to setup ddc on the bridge */ | ||
1282 | if (encoder) | 1310 | if (encoder) |
1283 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1311 | radeon_atom_ext_encoder_setup_ddc(encoder); |
1312 | if (radeon_ddc_probe(radeon_connector, | ||
1313 | radeon_connector->requires_extended_probe)) | ||
1314 | ret = connector_status_connected; | ||
1315 | } | ||
1316 | |||
1317 | if ((ret == connector_status_disconnected) && | ||
1318 | radeon_connector->dac_load_detect) { | ||
1319 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
1320 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
1321 | if (encoder) { | ||
1322 | encoder_funcs = encoder->helper_private; | ||
1323 | ret = encoder_funcs->detect(encoder, connector); | ||
1324 | } | ||
1284 | } | 1325 | } |
1326 | } else { | ||
1285 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); | 1327 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
1286 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { | 1328 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { |
1287 | ret = connector_status_connected; | 1329 | ret = connector_status_connected; |
@@ -1297,16 +1339,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1297 | ret = connector_status_connected; | 1339 | ret = connector_status_connected; |
1298 | } | 1340 | } |
1299 | } | 1341 | } |
1300 | |||
1301 | if ((ret == connector_status_disconnected) && | ||
1302 | radeon_connector->dac_load_detect) { | ||
1303 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
1304 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
1305 | if (encoder) { | ||
1306 | encoder_funcs = encoder->helper_private; | ||
1307 | ret = encoder_funcs->detect(encoder, connector); | ||
1308 | } | ||
1309 | } | ||
1310 | } | 1342 | } |
1311 | 1343 | ||
1312 | radeon_connector_update_scratch_regs(connector, ret); | 1344 | radeon_connector_update_scratch_regs(connector, ret); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 440e6ecccc4..b51e15725c6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <drm/radeon_drm.h> | 32 | #include <drm/radeon_drm.h> |
33 | #include <linux/vgaarb.h> | 33 | #include <linux/vgaarb.h> |
34 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
35 | #include <linux/efi.h> | ||
35 | #include "radeon_reg.h" | 36 | #include "radeon_reg.h" |
36 | #include "radeon.h" | 37 | #include "radeon.h" |
37 | #include "atom.h" | 38 | #include "atom.h" |
@@ -300,6 +301,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
300 | mc->mc_vram_size = mc->aper_size; | 301 | mc->mc_vram_size = mc->aper_size; |
301 | } | 302 | } |
302 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 303 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
304 | if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) | ||
305 | mc->real_vram_size = radeon_vram_limit; | ||
303 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", | 306 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
304 | mc->mc_vram_size >> 20, mc->vram_start, | 307 | mc->mc_vram_size >> 20, mc->vram_start, |
305 | mc->vram_end, mc->real_vram_size >> 20); | 308 | mc->vram_end, mc->real_vram_size >> 20); |
@@ -348,6 +351,9 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
348 | { | 351 | { |
349 | uint32_t reg; | 352 | uint32_t reg; |
350 | 353 | ||
354 | if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) | ||
355 | return false; | ||
356 | |||
351 | /* first check CRTCs */ | 357 | /* first check CRTCs */ |
352 | if (ASIC_IS_DCE41(rdev)) { | 358 | if (ASIC_IS_DCE41(rdev)) { |
353 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | 359 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1a858944e4f..6adb3e58aff 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -473,8 +473,8 @@ pflip_cleanup: | |||
473 | spin_lock_irqsave(&dev->event_lock, flags); | 473 | spin_lock_irqsave(&dev->event_lock, flags); |
474 | radeon_crtc->unpin_work = NULL; | 474 | radeon_crtc->unpin_work = NULL; |
475 | unlock_free: | 475 | unlock_free: |
476 | drm_gem_object_unreference_unlocked(old_radeon_fb->obj); | ||
477 | spin_unlock_irqrestore(&dev->event_lock, flags); | 476 | spin_unlock_irqrestore(&dev->event_lock, flags); |
477 | drm_gem_object_unreference_unlocked(old_radeon_fb->obj); | ||
478 | radeon_fence_unref(&work->fence); | 478 | radeon_fence_unref(&work->fence); |
479 | kfree(work); | 479 | kfree(work); |
480 | 480 | ||
@@ -707,16 +707,21 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
707 | radeon_router_select_ddc_port(radeon_connector); | 707 | radeon_router_select_ddc_port(radeon_connector); |
708 | 708 | ||
709 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 709 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
710 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { | 710 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || |
711 | radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) { | ||
711 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 712 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
713 | |||
712 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || | 714 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || |
713 | dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) | 715 | dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) |
714 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | 716 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, |
715 | } | 717 | &dig->dp_i2c_bus->adapter); |
716 | if (!radeon_connector->ddc_bus) | 718 | else if (radeon_connector->ddc_bus && !radeon_connector->edid) |
717 | return -1; | 719 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, |
718 | if (!radeon_connector->edid) { | 720 | &radeon_connector->ddc_bus->adapter); |
719 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 721 | } else { |
722 | if (radeon_connector->ddc_bus && !radeon_connector->edid) | ||
723 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, | ||
724 | &radeon_connector->ddc_bus->adapter); | ||
720 | } | 725 | } |
721 | 726 | ||
722 | if (!radeon_connector->edid) { | 727 | if (!radeon_connector->edid) { |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index b293487e5aa..319d85d7e75 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -2323,6 +2323,9 @@ radeon_add_atom_encoder(struct drm_device *dev, | |||
2323 | default: | 2323 | default: |
2324 | encoder->possible_crtcs = 0x3; | 2324 | encoder->possible_crtcs = 0x3; |
2325 | break; | 2325 | break; |
2326 | case 4: | ||
2327 | encoder->possible_crtcs = 0xf; | ||
2328 | break; | ||
2326 | case 6: | 2329 | case 6: |
2327 | encoder->possible_crtcs = 0x3f; | 2330 | encoder->possible_crtcs = 0x3f; |
2328 | break; | 2331 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index d09031c03e2..68820f5f630 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -479,6 +479,7 @@ extern void radeon_dp_set_link_config(struct drm_connector *connector, | |||
479 | struct drm_display_mode *mode); | 479 | struct drm_display_mode *mode); |
480 | extern void radeon_dp_link_train(struct drm_encoder *encoder, | 480 | extern void radeon_dp_link_train(struct drm_encoder *encoder, |
481 | struct drm_connector *connector); | 481 | struct drm_connector *connector); |
482 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | ||
482 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | 483 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
483 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | 484 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
484 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); | 485 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index dee4a0c1b4b..602fa3541c4 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -40,10 +40,14 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
40 | size = 1024 * 1024; | 40 | size = 1024 * 1024; |
41 | 41 | ||
42 | /* Number of tests = | 42 | /* Number of tests = |
43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size | 43 | * (Total GTT - IB pool - writeback page - ring buffers) / test size |
44 | */ | 44 | */ |
45 | n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - | 45 | n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size; |
46 | rdev->cp.ring_size)) / size; | 46 | if (rdev->wb.wb_obj) |
47 | n -= RADEON_GPU_PAGE_SIZE; | ||
48 | if (rdev->ih.ring_obj) | ||
49 | n -= rdev->ih.ring_size; | ||
50 | n /= size; | ||
47 | 51 | ||
48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); | 52 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); |
49 | if (!gtt_obj) { | 53 | if (!gtt_obj) { |
@@ -132,9 +136,15 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
132 | gtt_start++, vram_start++) { | 136 | gtt_start++, vram_start++) { |
133 | if (*vram_start != gtt_start) { | 137 | if (*vram_start != gtt_start) { |
134 | DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " | 138 | DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " |
135 | "expected 0x%p (GTT map 0x%p-0x%p)\n", | 139 | "expected 0x%p (GTT/VRAM offset " |
136 | i, *vram_start, gtt_start, gtt_map, | 140 | "0x%16llx/0x%16llx)\n", |
137 | gtt_end); | 141 | i, *vram_start, gtt_start, |
142 | (unsigned long long) | ||
143 | (gtt_addr - rdev->mc.gtt_start + | ||
144 | (void*)gtt_start - gtt_map), | ||
145 | (unsigned long long) | ||
146 | (vram_addr - rdev->mc.vram_start + | ||
147 | (void*)gtt_start - gtt_map)); | ||
138 | radeon_bo_kunmap(vram_obj); | 148 | radeon_bo_kunmap(vram_obj); |
139 | goto out_cleanup; | 149 | goto out_cleanup; |
140 | } | 150 | } |
@@ -175,9 +185,15 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
175 | gtt_start++, vram_start++) { | 185 | gtt_start++, vram_start++) { |
176 | if (*gtt_start != vram_start) { | 186 | if (*gtt_start != vram_start) { |
177 | DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " | 187 | DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " |
178 | "expected 0x%p (VRAM map 0x%p-0x%p)\n", | 188 | "expected 0x%p (VRAM/GTT offset " |
179 | i, *gtt_start, vram_start, vram_map, | 189 | "0x%16llx/0x%16llx)\n", |
180 | vram_end); | 190 | i, *gtt_start, vram_start, |
191 | (unsigned long long) | ||
192 | (vram_addr - rdev->mc.vram_start + | ||
193 | (void*)vram_start - vram_map), | ||
194 | (unsigned long long) | ||
195 | (gtt_addr - rdev->mc.gtt_start + | ||
196 | (void*)vram_start - vram_map)); | ||
181 | radeon_bo_kunmap(gtt_obj[i]); | 197 | radeon_bo_kunmap(gtt_obj[i]); |
182 | goto out_cleanup; | 198 | goto out_cleanup; |
183 | } | 199 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 60125ddba1e..0b5468bfaf5 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -277,7 +277,12 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
277 | DRM_ERROR("Trying to move memory with CP turned off.\n"); | 277 | DRM_ERROR("Trying to move memory with CP turned off.\n"); |
278 | return -EINVAL; | 278 | return -EINVAL; |
279 | } | 279 | } |
280 | r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); | 280 | |
281 | BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); | ||
282 | |||
283 | r = radeon_copy(rdev, old_start, new_start, | ||
284 | new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ | ||
285 | fence); | ||
281 | /* FIXME: handle copy error */ | 286 | /* FIXME: handle copy error */ |
282 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, | 287 | r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, |
283 | evict, no_wait_reserve, no_wait_gpu, new_mem); | 288 | evict, no_wait_reserve, no_wait_gpu, new_mem); |
@@ -450,6 +455,29 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_ | |||
450 | return -EINVAL; | 455 | return -EINVAL; |
451 | mem->bus.base = rdev->mc.aper_base; | 456 | mem->bus.base = rdev->mc.aper_base; |
452 | mem->bus.is_iomem = true; | 457 | mem->bus.is_iomem = true; |
458 | #ifdef __alpha__ | ||
459 | /* | ||
460 | * Alpha: use bus.addr to hold the ioremap() return, | ||
461 | * so we can modify bus.base below. | ||
462 | */ | ||
463 | if (mem->placement & TTM_PL_FLAG_WC) | ||
464 | mem->bus.addr = | ||
465 | ioremap_wc(mem->bus.base + mem->bus.offset, | ||
466 | mem->bus.size); | ||
467 | else | ||
468 | mem->bus.addr = | ||
469 | ioremap_nocache(mem->bus.base + mem->bus.offset, | ||
470 | mem->bus.size); | ||
471 | |||
472 | /* | ||
473 | * Alpha: Use just the bus offset plus | ||
474 | * the hose/domain memory base for bus.base. | ||
475 | * It then can be used to build PTEs for VRAM | ||
476 | * access, as done in ttm_bo_vm_fault(). | ||
477 | */ | ||
478 | mem->bus.base = (mem->bus.base & 0x0ffffffffUL) + | ||
479 | rdev->ddev->hose->dense_mem_base; | ||
480 | #endif | ||
453 | break; | 481 | break; |
454 | default: | 482 | default: |
455 | return -EINVAL; | 483 | return -EINVAL; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 56619f64b6b..ef06194c5aa 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) | |||
353 | 353 | ||
354 | ret = ttm_tt_set_user(bo->ttm, current, | 354 | ret = ttm_tt_set_user(bo->ttm, current, |
355 | bo->buffer_start, bo->num_pages); | 355 | bo->buffer_start, bo->num_pages); |
356 | if (unlikely(ret != 0)) | 356 | if (unlikely(ret != 0)) { |
357 | ttm_tt_destroy(bo->ttm); | 357 | ttm_tt_destroy(bo->ttm); |
358 | bo->ttm = NULL; | ||
359 | } | ||
358 | break; | 360 | break; |
359 | default: | 361 | default: |
360 | printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); | 362 | printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); |
@@ -390,10 +392,13 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
390 | * Create and bind a ttm if required. | 392 | * Create and bind a ttm if required. |
391 | */ | 393 | */ |
392 | 394 | ||
393 | if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) { | 395 | if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) { |
394 | ret = ttm_bo_add_ttm(bo, false); | 396 | if (bo->ttm == NULL) { |
395 | if (ret) | 397 | bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); |
396 | goto out_err; | 398 | ret = ttm_bo_add_ttm(bo, zero); |
399 | if (ret) | ||
400 | goto out_err; | ||
401 | } | ||
397 | 402 | ||
398 | ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); | 403 | ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); |
399 | if (ret) | 404 | if (ret) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 77dbf408c0d..ae3c6f5dd2b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | |||
635 | if (ret) | 635 | if (ret) |
636 | return ret; | 636 | return ret; |
637 | 637 | ||
638 | ttm_bo_free_old_node(bo); | ||
639 | if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && | 638 | if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && |
640 | (bo->ttm != NULL)) { | 639 | (bo->ttm != NULL)) { |
641 | ttm_tt_unbind(bo->ttm); | 640 | ttm_tt_unbind(bo->ttm); |
642 | ttm_tt_destroy(bo->ttm); | 641 | ttm_tt_destroy(bo->ttm); |
643 | bo->ttm = NULL; | 642 | bo->ttm = NULL; |
644 | } | 643 | } |
644 | ttm_bo_free_old_node(bo); | ||
645 | } else { | 645 | } else { |
646 | /** | 646 | /** |
647 | * This should help pipeline ordinary buffer moves. | 647 | * This should help pipeline ordinary buffer moves. |