diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 62 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo_regs.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 175 |
11 files changed, 243 insertions, 66 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c9bfd83dde64..61ae104dca8c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1505 | goto put_gmch; | 1505 | goto put_gmch; |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | i915_kick_out_firmware_fb(dev_priv); | 1508 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 1509 | i915_kick_out_firmware_fb(dev_priv); | ||
| 1509 | 1510 | ||
| 1510 | pci_set_master(dev->pdev); | 1511 | pci_set_master(dev->pdev); |
| 1511 | 1512 | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index f78061af7045..b726b478a4f5 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) | |||
| 729 | 729 | ||
| 730 | crt->base.type = INTEL_OUTPUT_ANALOG; | 730 | crt->base.type = INTEL_OUTPUT_ANALOG; |
| 731 | crt->base.cloneable = true; | 731 | crt->base.cloneable = true; |
| 732 | if (IS_HASWELL(dev)) | 732 | if (IS_HASWELL(dev) || IS_I830(dev)) |
| 733 | crt->base.crtc_mask = (1 << 0); | 733 | crt->base.crtc_mask = (1 << 0); |
| 734 | else | 734 | else |
| 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 495625914e4a..d7bc817f51a0 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -341,9 +341,17 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
| 341 | intel_ring_emit(ring, flip_addr); | 341 | intel_ring_emit(ring, flip_addr); |
| 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
| 343 | /* turn overlay off */ | 343 | /* turn overlay off */ |
| 344 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | 344 | if (IS_I830(dev)) { |
| 345 | intel_ring_emit(ring, flip_addr); | 345 | /* Workaround: Don't disable the overlay fully, since otherwise |
| 346 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 346 | * it dies on the next OVERLAY_ON cmd. */ |
| 347 | intel_ring_emit(ring, MI_NOOP); | ||
| 348 | intel_ring_emit(ring, MI_NOOP); | ||
| 349 | intel_ring_emit(ring, MI_NOOP); | ||
| 350 | } else { | ||
| 351 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | ||
| 352 | intel_ring_emit(ring, flip_addr); | ||
| 353 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | ||
| 354 | } | ||
| 347 | intel_ring_advance(ring); | 355 | intel_ring_advance(ring); |
| 348 | 356 | ||
| 349 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); | 357 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e019b2369861..e2aacd329545 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
| 435 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
| 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
| 437 | if (props.max_brightness == 0) { | 437 | if (props.max_brightness == 0) { |
| 438 | DRM_ERROR("Failed to get maximum backlight value\n"); | 438 | DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); |
| 439 | return -ENODEV; | 439 | return -ENODEV; |
| 440 | } | 440 | } |
| 441 | dev_priv->backlight = | 441 | dev_priv->backlight = |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c01d97db0061..79d308da29ff 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
| 894 | } | 894 | } |
| 895 | #endif | 895 | #endif |
| 896 | 896 | ||
| 897 | static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | ||
| 898 | unsigned if_index, uint8_t tx_rate, | ||
| 899 | uint8_t *data, unsigned length) | ||
| 900 | { | ||
| 901 | uint8_t set_buf_index[2] = { if_index, 0 }; | ||
| 902 | uint8_t hbuf_size, tmp[8]; | ||
| 903 | int i; | ||
| 904 | |||
| 905 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 906 | SDVO_CMD_SET_HBUF_INDEX, | ||
| 907 | set_buf_index, 2)) | ||
| 908 | return false; | ||
| 909 | |||
| 910 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | ||
| 911 | &hbuf_size, 1)) | ||
| 912 | return false; | ||
| 913 | |||
| 914 | /* Buffer size is 0 based, hooray! */ | ||
| 915 | hbuf_size++; | ||
| 916 | |||
| 917 | DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | ||
| 918 | if_index, length, hbuf_size); | ||
| 919 | |||
| 920 | for (i = 0; i < hbuf_size; i += 8) { | ||
| 921 | memset(tmp, 0, 8); | ||
| 922 | if (i < length) | ||
| 923 | memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | ||
| 924 | |||
| 925 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 926 | SDVO_CMD_SET_HBUF_DATA, | ||
| 927 | tmp, 8)) | ||
| 928 | return false; | ||
| 929 | } | ||
| 930 | |||
| 931 | return intel_sdvo_set_value(intel_sdvo, | ||
| 932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
| 933 | &tx_rate, 1); | ||
| 934 | } | ||
| 935 | |||
| 897 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
| 898 | { | 937 | { |
| 899 | struct dip_infoframe avi_if = { | 938 | struct dip_infoframe avi_if = { |
| @@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
| 901 | .ver = DIP_VERSION_AVI, | 940 | .ver = DIP_VERSION_AVI, |
| 902 | .len = DIP_LEN_AVI, | 941 | .len = DIP_LEN_AVI, |
| 903 | }; | 942 | }; |
| 904 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | ||
| 905 | uint8_t set_buf_index[2] = { 1, 0 }; | ||
| 906 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
| 907 | uint64_t *data = (uint64_t *)sdvo_data; | ||
| 908 | unsigned i; | ||
| 909 | 944 | ||
| 910 | intel_dip_infoframe_csum(&avi_if); | 945 | intel_dip_infoframe_csum(&avi_if); |
| 911 | 946 | ||
| @@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
| 915 | sdvo_data[3] = avi_if.checksum; | 950 | sdvo_data[3] = avi_if.checksum; |
| 916 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
| 917 | 952 | ||
| 918 | if (!intel_sdvo_set_value(intel_sdvo, | 953 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
| 919 | SDVO_CMD_SET_HBUF_INDEX, | 954 | SDVO_HBUF_TX_VSYNC, |
| 920 | set_buf_index, 2)) | 955 | sdvo_data, sizeof(sdvo_data)); |
| 921 | return false; | ||
| 922 | |||
| 923 | for (i = 0; i < sizeof(sdvo_data); i += 8) { | ||
| 924 | if (!intel_sdvo_set_value(intel_sdvo, | ||
| 925 | SDVO_CMD_SET_HBUF_DATA, | ||
| 926 | data, 8)) | ||
| 927 | return false; | ||
| 928 | data++; | ||
| 929 | } | ||
| 930 | |||
| 931 | return intel_sdvo_set_value(intel_sdvo, | ||
| 932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
| 933 | &tx_rate, 1); | ||
| 934 | } | 956 | } |
| 935 | 957 | ||
| 936 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 9d030142ee43..770bdd6ecd9f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
| @@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { | |||
| 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 | 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 |
| 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 | 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 |
| 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 | 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 |
| 711 | #define SDVO_HBUF_INDEX_ELD 0 | ||
| 712 | #define SDVO_HBUF_INDEX_AVI_IF 1 | ||
| 711 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 | 713 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 |
| 712 | #define SDVO_CMD_GET_HBUF_INFO 0x95 | 714 | #define SDVO_CMD_GET_HBUF_INFO 0x95 |
| 713 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 | 715 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 30271b641913..95e6318b6268 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, | |||
| 264 | /* macro tile width & height */ | 264 | /* macro tile width & height */ |
| 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; | 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; |
| 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; | 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; |
| 267 | mtileb = (palign / 8) * (halign / 8) * tileb;; | 267 | mtileb = (palign / 8) * (halign / 8) * tileb; |
| 268 | mtile_pr = surf->nbx / palign; | 268 | mtile_pr = surf->nbx / palign; |
| 269 | mtile_ps = (mtile_pr * surf->nby) / halign; | 269 | mtile_ps = (mtile_pr * surf->nby) / halign; |
| 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; | 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 37f6a907aea4..15f5ded65e0c 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
| @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | |||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | /** | 354 | /** |
| 355 | * radeon_atpx_switchto - switch to the requested GPU | 355 | * radeon_atpx_power_state - power down/up the requested GPU |
| 356 | * | 356 | * |
| 357 | * @id: GPU to switch to | 357 | * @id: GPU to power down/up |
| 358 | * @state: requested power state (0 = off, 1 = on) | 358 | * @state: requested power state (0 = off, 1 = on) |
| 359 | * | 359 | * |
| 360 | * Execute the necessary ATPX function to power down/up the discrete GPU | 360 | * Execute the necessary ATPX function to power down/up the discrete GPU |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 67cfc1795ecd..b884c362a8c2 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 941 | struct drm_mode_object *obj; | 941 | struct drm_mode_object *obj; |
| 942 | int i; | 942 | int i; |
| 943 | enum drm_connector_status ret = connector_status_disconnected; | 943 | enum drm_connector_status ret = connector_status_disconnected; |
| 944 | bool dret = false; | 944 | bool dret = false, broken_edid = false; |
| 945 | 945 | ||
| 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) |
| 947 | return connector->status; | 947 | return connector->status; |
| @@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 965 | ret = connector_status_disconnected; | 965 | ret = connector_status_disconnected; |
| 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); | 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); |
| 967 | radeon_connector->ddc_bus = NULL; | 967 | radeon_connector->ddc_bus = NULL; |
| 968 | } else { | ||
| 969 | ret = connector_status_connected; | ||
| 970 | broken_edid = true; /* defer use_digital to later */ | ||
| 968 | } | 971 | } |
| 969 | } else { | 972 | } else { |
| 970 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 973 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
| @@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1047 | 1050 | ||
| 1048 | encoder_funcs = encoder->helper_private; | 1051 | encoder_funcs = encoder->helper_private; |
| 1049 | if (encoder_funcs->detect) { | 1052 | if (encoder_funcs->detect) { |
| 1050 | if (ret != connector_status_connected) { | 1053 | if (!broken_edid) { |
| 1051 | ret = encoder_funcs->detect(encoder, connector); | 1054 | if (ret != connector_status_connected) { |
| 1052 | if (ret == connector_status_connected) { | 1055 | /* deal with analog monitors without DDC */ |
| 1053 | radeon_connector->use_digital = false; | 1056 | ret = encoder_funcs->detect(encoder, connector); |
| 1057 | if (ret == connector_status_connected) { | ||
| 1058 | radeon_connector->use_digital = false; | ||
| 1059 | } | ||
| 1060 | if (ret != connector_status_disconnected) | ||
| 1061 | radeon_connector->detected_by_load = true; | ||
| 1054 | } | 1062 | } |
| 1055 | if (ret != connector_status_disconnected) | 1063 | } else { |
| 1056 | radeon_connector->detected_by_load = true; | 1064 | enum drm_connector_status lret; |
| 1065 | /* assume digital unless load detected otherwise */ | ||
| 1066 | radeon_connector->use_digital = true; | ||
| 1067 | lret = encoder_funcs->detect(encoder, connector); | ||
| 1068 | DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); | ||
| 1069 | if (lret == connector_status_connected) | ||
| 1070 | radeon_connector->use_digital = false; | ||
| 1057 | } | 1071 | } |
| 1058 | break; | 1072 | break; |
| 1059 | } | 1073 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 5677a424b585..6857cb4efb76 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 296 | struct drm_device *dev = crtc->dev; | 296 | struct drm_device *dev = crtc->dev; |
| 297 | struct radeon_device *rdev = dev->dev_private; | 297 | struct radeon_device *rdev = dev->dev_private; |
| 298 | uint32_t crtc_ext_cntl = 0; | ||
| 298 | uint32_t mask; | 299 | uint32_t mask; |
| 299 | 300 | ||
| 300 | if (radeon_crtc->crtc_id) | 301 | if (radeon_crtc->crtc_id) |
| @@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 307 | RADEON_CRTC_VSYNC_DIS | | 308 | RADEON_CRTC_VSYNC_DIS | |
| 308 | RADEON_CRTC_HSYNC_DIS); | 309 | RADEON_CRTC_HSYNC_DIS); |
| 309 | 310 | ||
| 311 | /* | ||
| 312 | * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. | ||
| 313 | * Therefore it is set in the DAC DMPS function. | ||
| 314 | * This is different for GPU's with a single CRTC but a primary and a | ||
| 315 | * TV DAC: here it controls the single CRTC no matter where it is | ||
| 316 | * routed. Therefore we set it here. | ||
| 317 | */ | ||
| 318 | if (rdev->flags & RADEON_SINGLE_CRTC) | ||
| 319 | crtc_ext_cntl = RADEON_CRTC_CRT_ON; | ||
| 320 | |||
| 310 | switch (mode) { | 321 | switch (mode) { |
| 311 | case DRM_MODE_DPMS_ON: | 322 | case DRM_MODE_DPMS_ON: |
| 312 | radeon_crtc->enabled = true; | 323 | radeon_crtc->enabled = true; |
| @@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 317 | else { | 328 | else { |
| 318 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | | 329 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
| 319 | RADEON_CRTC_DISP_REQ_EN_B)); | 330 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 320 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | 331 | WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); |
| 321 | } | 332 | } |
| 322 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | 333 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
| 323 | radeon_crtc_load_lut(crtc); | 334 | radeon_crtc_load_lut(crtc); |
| @@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 331 | else { | 342 | else { |
| 332 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | | 343 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
| 333 | RADEON_CRTC_DISP_REQ_EN_B)); | 344 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 334 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); | 345 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); |
| 335 | } | 346 | } |
| 336 | radeon_crtc->enabled = false; | 347 | radeon_crtc->enabled = false; |
| 337 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 348 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 0063df9d166d..f5ba2241dacc 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
| @@ -537,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode | |||
| 537 | break; | 537 | break; |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | 540 | /* handled in radeon_crtc_dpms() */ |
| 541 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
| 542 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | ||
| 541 | WREG32(RADEON_DAC_CNTL, dac_cntl); | 543 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
| 542 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); | 544 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); |
| 543 | 545 | ||
| @@ -662,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
| 662 | 664 | ||
| 663 | if (ASIC_IS_R300(rdev)) | 665 | if (ASIC_IS_R300(rdev)) |
| 664 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); | 666 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | else if (ASIC_IS_RV100(rdev)) | ||
| 668 | tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); | ||
| 665 | else | 669 | else |
| 666 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); | 670 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | 671 | ||
| @@ -671,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
| 671 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; | 675 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; |
| 672 | WREG32(RADEON_DAC_CNTL, tmp); | 676 | WREG32(RADEON_DAC_CNTL, tmp); |
| 673 | 677 | ||
| 678 | tmp = dac_macro_cntl; | ||
| 674 | tmp &= ~(RADEON_DAC_PDWN_R | | 679 | tmp &= ~(RADEON_DAC_PDWN_R | |
| 675 | RADEON_DAC_PDWN_G | | 680 | RADEON_DAC_PDWN_G | |
| 676 | RADEON_DAC_PDWN_B); | 681 | RADEON_DAC_PDWN_B); |
| @@ -1092,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
| 1092 | } else { | 1097 | } else { |
| 1093 | if (is_tv) | 1098 | if (is_tv) |
| 1094 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); | 1099 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
| 1095 | else | 1100 | /* handled in radeon_crtc_dpms() */ |
| 1101 | else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
| 1096 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 1102 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1097 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1103 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1098 | } | 1104 | } |
| @@ -1416,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | |||
| 1416 | return found; | 1422 | return found; |
| 1417 | } | 1423 | } |
| 1418 | 1424 | ||
| 1425 | static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | ||
| 1426 | struct drm_connector *connector) | ||
| 1427 | { | ||
| 1428 | struct drm_device *dev = encoder->dev; | ||
| 1429 | struct radeon_device *rdev = dev->dev_private; | ||
| 1430 | uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | ||
| 1431 | uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | ||
| 1432 | uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | ||
| 1433 | uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | ||
| 1434 | uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | ||
| 1435 | bool found = false; | ||
| 1436 | int i; | ||
| 1437 | |||
| 1438 | /* save the regs we need */ | ||
| 1439 | gpio_monid = RREG32(RADEON_GPIO_MONID); | ||
| 1440 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | ||
| 1441 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
| 1442 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
| 1443 | disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); | ||
| 1444 | disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); | ||
| 1445 | disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); | ||
| 1446 | disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); | ||
| 1447 | disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); | ||
| 1448 | disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); | ||
| 1449 | crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); | ||
| 1450 | crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); | ||
| 1451 | crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); | ||
| 1452 | crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); | ||
| 1453 | |||
| 1454 | tmp = RREG32(RADEON_GPIO_MONID); | ||
| 1455 | tmp &= ~RADEON_GPIO_A_0; | ||
| 1456 | WREG32(RADEON_GPIO_MONID, tmp); | ||
| 1457 | |||
| 1458 | WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | | ||
| 1459 | RADEON_FP2_PANEL_FORMAT | | ||
| 1460 | R200_FP2_SOURCE_SEL_TRANS_UNIT | | ||
| 1461 | RADEON_FP2_DVO_EN | | ||
| 1462 | R200_FP2_DVO_RATE_SEL_SDR)); | ||
| 1463 | |||
| 1464 | WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | | ||
| 1465 | RADEON_DISP_TRANS_MATRIX_GRAPHICS)); | ||
| 1466 | |||
| 1467 | WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | | ||
| 1468 | RADEON_CRTC2_DISP_REQ_EN_B)); | ||
| 1469 | |||
| 1470 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); | ||
| 1471 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); | ||
| 1472 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); | ||
| 1473 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); | ||
| 1474 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); | ||
| 1475 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); | ||
| 1476 | |||
| 1477 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); | ||
| 1478 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); | ||
| 1479 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); | ||
| 1480 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); | ||
| 1481 | |||
| 1482 | for (i = 0; i < 200; i++) { | ||
| 1483 | tmp = RREG32(RADEON_GPIO_MONID); | ||
| 1484 | if (tmp & RADEON_GPIO_Y_0) | ||
| 1485 | found = true; | ||
| 1486 | |||
| 1487 | if (found) | ||
| 1488 | break; | ||
| 1489 | |||
| 1490 | if (!drm_can_sleep()) | ||
| 1491 | mdelay(1); | ||
| 1492 | else | ||
| 1493 | msleep(1); | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | /* restore the regs we used */ | ||
| 1497 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); | ||
| 1498 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); | ||
| 1499 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); | ||
| 1500 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); | ||
| 1501 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); | ||
| 1502 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); | ||
| 1503 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); | ||
| 1504 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); | ||
| 1505 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); | ||
| 1506 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); | ||
| 1507 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
| 1508 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
| 1509 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | ||
| 1510 | WREG32(RADEON_GPIO_MONID, gpio_monid); | ||
| 1511 | |||
| 1512 | return found; | ||
| 1513 | } | ||
| 1514 | |||
| 1419 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, | 1515 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
| 1420 | struct drm_connector *connector) | 1516 | struct drm_connector *connector) |
| 1421 | { | 1517 | { |
| 1422 | struct drm_device *dev = encoder->dev; | 1518 | struct drm_device *dev = encoder->dev; |
| 1423 | struct radeon_device *rdev = dev->dev_private; | 1519 | struct radeon_device *rdev = dev->dev_private; |
| 1424 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | 1520 | uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; |
| 1425 | uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | 1521 | uint32_t gpiopad_a = 0, pixclks_cntl, tmp; |
| 1522 | uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | ||
| 1426 | enum drm_connector_status found = connector_status_disconnected; | 1523 | enum drm_connector_status found = connector_status_disconnected; |
| 1427 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1428 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | 1525 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
| @@ -1459,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1459 | return connector_status_disconnected; | 1556 | return connector_status_disconnected; |
| 1460 | } | 1557 | } |
| 1461 | 1558 | ||
| 1559 | /* R200 uses an external DAC for secondary DAC */ | ||
| 1560 | if (rdev->family == CHIP_R200) { | ||
| 1561 | if (radeon_legacy_ext_dac_detect(encoder, connector)) | ||
| 1562 | found = connector_status_connected; | ||
| 1563 | return found; | ||
| 1564 | } | ||
| 1565 | |||
| 1462 | /* save the regs we need */ | 1566 | /* save the regs we need */ |
| 1463 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 1567 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| 1464 | gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; | 1568 | |
| 1465 | disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; | 1569 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1466 | disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); | 1570 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
| 1467 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | 1571 | } else { |
| 1572 | if (ASIC_IS_R300(rdev)) { | ||
| 1573 | gpiopad_a = RREG32(RADEON_GPIOPAD_A); | ||
| 1574 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
| 1575 | } else { | ||
| 1576 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | ||
| 1577 | } | ||
| 1578 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
| 1579 | } | ||
| 1468 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 1580 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
| 1469 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); | 1581 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); |
| 1470 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); | 1582 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); |
| @@ -1473,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1473 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); | 1585 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); |
| 1474 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 1586 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 1475 | 1587 | ||
| 1476 | if (ASIC_IS_R300(rdev)) | 1588 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1477 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | 1589 | tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; |
| 1478 | 1590 | WREG32(RADEON_CRTC_EXT_CNTL, tmp); | |
| 1479 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | ||
| 1480 | tmp |= RADEON_CRTC2_CRT2_ON | | ||
| 1481 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
| 1482 | |||
| 1483 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
| 1484 | |||
| 1485 | if (ASIC_IS_R300(rdev)) { | ||
| 1486 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
| 1487 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
| 1488 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
| 1489 | } else { | 1591 | } else { |
| 1490 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | 1592 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; |
| 1491 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | 1593 | tmp |= RADEON_CRTC2_CRT2_ON | |
| 1594 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
| 1595 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
| 1596 | |||
| 1597 | if (ASIC_IS_R300(rdev)) { | ||
| 1598 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | ||
| 1599 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
| 1600 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
| 1601 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
| 1602 | } else { | ||
| 1603 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | ||
| 1604 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | ||
| 1605 | } | ||
| 1492 | } | 1606 | } |
| 1493 | 1607 | ||
| 1494 | tmp = RADEON_TV_DAC_NBLANK | | 1608 | tmp = RADEON_TV_DAC_NBLANK | |
| @@ -1530,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
| 1530 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); | 1644 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); |
| 1531 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); | 1645 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); |
| 1532 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1646 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1533 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
| 1534 | 1647 | ||
| 1535 | if (ASIC_IS_R300(rdev)) { | 1648 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1536 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | 1649 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); |
| 1537 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
| 1538 | } else { | 1650 | } else { |
| 1539 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | 1651 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1652 | if (ASIC_IS_R300(rdev)) { | ||
| 1653 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
| 1654 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
| 1655 | } else { | ||
| 1656 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | ||
| 1657 | } | ||
| 1540 | } | 1658 | } |
| 1659 | |||
| 1541 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 1660 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
| 1542 | 1661 | ||
| 1543 | return found; | 1662 | return found; |
