diff options
33 files changed, 2948 insertions, 2657 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 711d9653abd0..9a2e2a14b3bb 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -163,6 +163,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
| 163 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, | 163 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, |
| 164 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 164 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
| 165 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, | 165 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
| 166 | { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, | ||
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 169 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
| @@ -171,6 +172,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] = | |||
| 171 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, | 172 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, |
| 172 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, | 173 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, |
| 173 | { DRM_MODE_ENCODER_TVDAC, "TV" }, | 174 | { DRM_MODE_ENCODER_TVDAC, "TV" }, |
| 175 | { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, | ||
| 174 | }; | 176 | }; |
| 175 | 177 | ||
| 176 | char *drm_get_encoder_name(struct drm_encoder *encoder) | 178 | char *drm_get_encoder_name(struct drm_encoder *encoder) |
| @@ -464,8 +466,10 @@ void drm_connector_init(struct drm_device *dev, | |||
| 464 | list_add_tail(&connector->head, &dev->mode_config.connector_list); | 466 | list_add_tail(&connector->head, &dev->mode_config.connector_list); |
| 465 | dev->mode_config.num_connector++; | 467 | dev->mode_config.num_connector++; |
| 466 | 468 | ||
| 467 | drm_connector_attach_property(connector, | 469 | if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) |
| 468 | dev->mode_config.edid_property, 0); | 470 | drm_connector_attach_property(connector, |
| 471 | dev->mode_config.edid_property, | ||
| 472 | 0); | ||
| 469 | 473 | ||
| 470 | drm_connector_attach_property(connector, | 474 | drm_connector_attach_property(connector, |
| 471 | dev->mode_config.dpms_property, 0); | 475 | dev->mode_config.dpms_property, 0); |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 9f363e0c4b60..cf8b4bc3e73d 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
| @@ -70,7 +70,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
| 70 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 70 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
| 71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ | 71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
| 72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ | 72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ |
| 73 | radeon_trace_points.o ni.o cayman_blit_shaders.o | 73 | radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o |
| 74 | 74 | ||
| 75 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 75 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
| 76 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 76 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a515b2a09d85..87921c88a95c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -558,7 +558,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 558 | bpc = connector->display_info.bpc; | 558 | bpc = connector->display_info.bpc; |
| 559 | encoder_mode = atombios_get_encoder_mode(encoder); | 559 | encoder_mode = atombios_get_encoder_mode(encoder); |
| 560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
| 561 | radeon_encoder_is_dp_bridge(encoder)) { | 561 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
| 562 | if (connector) { | 562 | if (connector) { |
| 563 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 563 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 564 | struct radeon_connector_atom_dig *dig_connector = | 564 | struct radeon_connector_atom_dig *dig_connector = |
| @@ -638,44 +638,29 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 638 | if (ss_enabled && ss->percentage) | 638 | if (ss_enabled && ss->percentage) |
| 639 | args.v3.sInput.ucDispPllConfig |= | 639 | args.v3.sInput.ucDispPllConfig |= |
| 640 | DISPPLL_CONFIG_SS_ENABLE; | 640 | DISPPLL_CONFIG_SS_ENABLE; |
| 641 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) || | 641 | if (ENCODER_MODE_IS_DP(encoder_mode)) { |
| 642 | radeon_encoder_is_dp_bridge(encoder)) { | 642 | args.v3.sInput.ucDispPllConfig |= |
| 643 | DISPPLL_CONFIG_COHERENT_MODE; | ||
| 644 | /* 16200 or 27000 */ | ||
| 645 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
| 646 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 643 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 647 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 644 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | 648 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) |
| 649 | /* deep color support */ | ||
| 650 | args.v3.sInput.usPixelClock = | ||
| 651 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
| 652 | if (dig->coherent_mode) | ||
| 645 | args.v3.sInput.ucDispPllConfig |= | 653 | args.v3.sInput.ucDispPllConfig |= |
| 646 | DISPPLL_CONFIG_COHERENT_MODE; | 654 | DISPPLL_CONFIG_COHERENT_MODE; |
| 647 | /* 16200 or 27000 */ | 655 | if (mode->clock > 165000) |
| 648 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
| 649 | } else { | ||
| 650 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
| 651 | /* deep color support */ | ||
| 652 | args.v3.sInput.usPixelClock = | ||
| 653 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
| 654 | } | ||
| 655 | if (dig->coherent_mode) | ||
| 656 | args.v3.sInput.ucDispPllConfig |= | ||
| 657 | DISPPLL_CONFIG_COHERENT_MODE; | ||
| 658 | if (mode->clock > 165000) | ||
| 659 | args.v3.sInput.ucDispPllConfig |= | ||
| 660 | DISPPLL_CONFIG_DUAL_LINK; | ||
| 661 | } | ||
| 662 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 663 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
| 664 | args.v3.sInput.ucDispPllConfig |= | 656 | args.v3.sInput.ucDispPllConfig |= |
| 665 | DISPPLL_CONFIG_COHERENT_MODE; | 657 | DISPPLL_CONFIG_DUAL_LINK; |
| 666 | /* 16200 or 27000 */ | ||
| 667 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
| 668 | } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) { | ||
| 669 | if (mode->clock > 165000) | ||
| 670 | args.v3.sInput.ucDispPllConfig |= | ||
| 671 | DISPPLL_CONFIG_DUAL_LINK; | ||
| 672 | } | ||
| 673 | } | 658 | } |
| 674 | if (radeon_encoder_is_dp_bridge(encoder)) { | 659 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
| 675 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | 660 | ENCODER_OBJECT_ID_NONE) |
| 676 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | 661 | args.v3.sInput.ucExtTransmitterID = |
| 677 | args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id; | 662 | radeon_encoder_get_dp_bridge_encoder_id(encoder); |
| 678 | } else | 663 | else |
| 679 | args.v3.sInput.ucExtTransmitterID = 0; | 664 | args.v3.sInput.ucExtTransmitterID = 0; |
| 680 | 665 | ||
| 681 | atom_execute_table(rdev->mode_info.atom_context, | 666 | atom_execute_table(rdev->mode_info.atom_context, |
| @@ -945,6 +930,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 945 | bpc = connector->display_info.bpc; | 930 | bpc = connector->display_info.bpc; |
| 946 | 931 | ||
| 947 | switch (encoder_mode) { | 932 | switch (encoder_mode) { |
| 933 | case ATOM_ENCODER_MODE_DP_MST: | ||
| 948 | case ATOM_ENCODER_MODE_DP: | 934 | case ATOM_ENCODER_MODE_DP: |
| 949 | /* DP/eDP */ | 935 | /* DP/eDP */ |
| 950 | dp_clock = dig_connector->dp_clock / 10; | 936 | dp_clock = dig_connector->dp_clock / 10; |
| @@ -1450,7 +1436,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1450 | * PPLL/DCPLL programming and only program the DP DTO for the | 1436 | * PPLL/DCPLL programming and only program the DP DTO for the |
| 1451 | * crtc virtual pixel clock. | 1437 | * crtc virtual pixel clock. |
| 1452 | */ | 1438 | */ |
| 1453 | if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) { | 1439 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
| 1454 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) | 1440 | if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) |
| 1455 | return ATOM_PPLL_INVALID; | 1441 | return ATOM_PPLL_INVALID; |
| 1456 | } | 1442 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 79e8ebc05307..a0de48542f71 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -482,7 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, | |||
| 482 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); | 482 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); |
| 483 | int lane_num, max_pix_clock; | 483 | int lane_num, max_pix_clock; |
| 484 | 484 | ||
| 485 | if (radeon_connector_encoder_is_dp_bridge(connector)) | 485 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
| 486 | ENCODER_OBJECT_ID_NUTMEG) | ||
| 486 | return 270000; | 487 | return 270000; |
| 487 | 488 | ||
| 488 | lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); | 489 | lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); |
| @@ -553,17 +554,32 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | |||
| 553 | { | 554 | { |
| 554 | struct drm_device *dev = encoder->dev; | 555 | struct drm_device *dev = encoder->dev; |
| 555 | struct radeon_device *rdev = dev->dev_private; | 556 | struct radeon_device *rdev = dev->dev_private; |
| 557 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 556 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 557 | 559 | ||
| 558 | if (!ASIC_IS_DCE4(rdev)) | 560 | if (!ASIC_IS_DCE4(rdev)) |
| 559 | return; | 561 | return; |
| 560 | 562 | ||
| 561 | if (radeon_connector_encoder_is_dp_bridge(connector)) | 563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
| 564 | ENCODER_OBJECT_ID_NUTMEG) | ||
| 562 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
| 566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | ||
| 567 | ENCODER_OBJECT_ID_TRAVIS) | ||
| 568 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
| 569 | else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
| 570 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
| 571 | if (tmp & 1) | ||
| 572 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
| 573 | } | ||
| 563 | 574 | ||
| 564 | atombios_dig_encoder_setup(encoder, | 575 | atombios_dig_encoder_setup(encoder, |
| 565 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | 576 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, |
| 566 | panel_mode); | 577 | panel_mode); |
| 578 | |||
| 579 | if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && | ||
| 580 | (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
| 581 | radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
| 582 | } | ||
| 567 | } | 583 | } |
| 568 | 584 | ||
| 569 | void radeon_dp_set_link_config(struct drm_connector *connector, | 585 | void radeon_dp_set_link_config(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c new file mode 100644 index 000000000000..39c04c1b8472 --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -0,0 +1,2369 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2007-11 Advanced Micro Devices, Inc. | ||
| 3 | * Copyright 2008 Red Hat Inc. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice shall be included in | ||
| 13 | * all copies or substantial portions of the Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | * Authors: Dave Airlie | ||
| 24 | * Alex Deucher | ||
| 25 | */ | ||
| 26 | #include "drmP.h" | ||
| 27 | #include "drm_crtc_helper.h" | ||
| 28 | #include "radeon_drm.h" | ||
| 29 | #include "radeon.h" | ||
| 30 | #include "atom.h" | ||
| 31 | |||
| 32 | extern int atom_debug; | ||
| 33 | |||
| 34 | /* evil but including atombios.h is much worse */ | ||
| 35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
| 36 | struct drm_display_mode *mode); | ||
| 37 | |||
| 38 | |||
| 39 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
| 40 | { | ||
| 41 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 42 | switch (radeon_encoder->encoder_id) { | ||
| 43 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 44 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 45 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 46 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 47 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 48 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 49 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 50 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 51 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 52 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 53 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 54 | return true; | ||
| 55 | default: | ||
| 56 | return false; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | static struct drm_connector * | ||
| 61 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 62 | { | ||
| 63 | struct drm_device *dev = encoder->dev; | ||
| 64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 65 | struct drm_connector *connector; | ||
| 66 | struct radeon_connector *radeon_connector; | ||
| 67 | |||
| 68 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 69 | radeon_connector = to_radeon_connector(connector); | ||
| 70 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 71 | return connector; | ||
| 72 | } | ||
| 73 | return NULL; | ||
| 74 | } | ||
| 75 | |||
| 76 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | ||
| 77 | struct drm_display_mode *mode, | ||
| 78 | struct drm_display_mode *adjusted_mode) | ||
| 79 | { | ||
| 80 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 81 | struct drm_device *dev = encoder->dev; | ||
| 82 | struct radeon_device *rdev = dev->dev_private; | ||
| 83 | |||
| 84 | /* set the active encoder to connector routing */ | ||
| 85 | radeon_encoder_set_active_device(encoder); | ||
| 86 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 87 | |||
| 88 | /* hw bug */ | ||
| 89 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 90 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | ||
| 91 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | ||
| 92 | |||
| 93 | /* get the native mode for LVDS */ | ||
| 94 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 95 | radeon_panel_mode_fixup(encoder, adjusted_mode); | ||
| 96 | |||
| 97 | /* get the native mode for TV */ | ||
| 98 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
| 99 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
| 100 | if (tv_dac) { | ||
| 101 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
| 102 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
| 103 | tv_dac->tv_std == TV_STD_PAL_M) | ||
| 104 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
| 105 | else | ||
| 106 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | if (ASIC_IS_DCE3(rdev) && | ||
| 111 | ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
| 112 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) { | ||
| 113 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 114 | radeon_dp_set_link_config(connector, mode); | ||
| 115 | } | ||
| 116 | |||
| 117 | return true; | ||
| 118 | } | ||
| 119 | |||
| 120 | static void | ||
| 121 | atombios_dac_setup(struct drm_encoder *encoder, int action) | ||
| 122 | { | ||
| 123 | struct drm_device *dev = encoder->dev; | ||
| 124 | struct radeon_device *rdev = dev->dev_private; | ||
| 125 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 126 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | ||
| 127 | int index = 0; | ||
| 128 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
| 129 | |||
| 130 | memset(&args, 0, sizeof(args)); | ||
| 131 | |||
| 132 | switch (radeon_encoder->encoder_id) { | ||
| 133 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 134 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 135 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | ||
| 136 | break; | ||
| 137 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 138 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 139 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | |||
| 143 | args.ucAction = action; | ||
| 144 | |||
| 145 | if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) | ||
| 146 | args.ucDacStandard = ATOM_DAC1_PS2; | ||
| 147 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 148 | args.ucDacStandard = ATOM_DAC1_CV; | ||
| 149 | else { | ||
| 150 | switch (dac_info->tv_std) { | ||
| 151 | case TV_STD_PAL: | ||
| 152 | case TV_STD_PAL_M: | ||
| 153 | case TV_STD_SCART_PAL: | ||
| 154 | case TV_STD_SECAM: | ||
| 155 | case TV_STD_PAL_CN: | ||
| 156 | args.ucDacStandard = ATOM_DAC1_PAL; | ||
| 157 | break; | ||
| 158 | case TV_STD_NTSC: | ||
| 159 | case TV_STD_NTSC_J: | ||
| 160 | case TV_STD_PAL_60: | ||
| 161 | default: | ||
| 162 | args.ucDacStandard = ATOM_DAC1_NTSC; | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 167 | |||
| 168 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 169 | |||
| 170 | } | ||
| 171 | |||
| 172 | static void | ||
| 173 | atombios_tv_setup(struct drm_encoder *encoder, int action) | ||
| 174 | { | ||
| 175 | struct drm_device *dev = encoder->dev; | ||
| 176 | struct radeon_device *rdev = dev->dev_private; | ||
| 177 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 178 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | ||
| 179 | int index = 0; | ||
| 180 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
| 181 | |||
| 182 | memset(&args, 0, sizeof(args)); | ||
| 183 | |||
| 184 | index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); | ||
| 185 | |||
| 186 | args.sTVEncoder.ucAction = action; | ||
| 187 | |||
| 188 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 189 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | ||
| 190 | else { | ||
| 191 | switch (dac_info->tv_std) { | ||
| 192 | case TV_STD_NTSC: | ||
| 193 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
| 194 | break; | ||
| 195 | case TV_STD_PAL: | ||
| 196 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; | ||
| 197 | break; | ||
| 198 | case TV_STD_PAL_M: | ||
| 199 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; | ||
| 200 | break; | ||
| 201 | case TV_STD_PAL_60: | ||
| 202 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; | ||
| 203 | break; | ||
| 204 | case TV_STD_NTSC_J: | ||
| 205 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; | ||
| 206 | break; | ||
| 207 | case TV_STD_SCART_PAL: | ||
| 208 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ | ||
| 209 | break; | ||
| 210 | case TV_STD_SECAM: | ||
| 211 | args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; | ||
| 212 | break; | ||
| 213 | case TV_STD_PAL_CN: | ||
| 214 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; | ||
| 215 | break; | ||
| 216 | default: | ||
| 217 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 223 | |||
| 224 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 225 | |||
| 226 | } | ||
| 227 | |||
| 228 | union dvo_encoder_control { | ||
| 229 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; | ||
| 230 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; | ||
| 231 | DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; | ||
| 232 | }; | ||
| 233 | |||
| 234 | void | ||
| 235 | atombios_dvo_setup(struct drm_encoder *encoder, int action) | ||
| 236 | { | ||
| 237 | struct drm_device *dev = encoder->dev; | ||
| 238 | struct radeon_device *rdev = dev->dev_private; | ||
| 239 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 240 | union dvo_encoder_control args; | ||
| 241 | int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); | ||
| 242 | uint8_t frev, crev; | ||
| 243 | |||
| 244 | memset(&args, 0, sizeof(args)); | ||
| 245 | |||
| 246 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 247 | return; | ||
| 248 | |||
| 249 | switch (frev) { | ||
| 250 | case 1: | ||
| 251 | switch (crev) { | ||
| 252 | case 1: | ||
| 253 | /* R4xx, R5xx */ | ||
| 254 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | ||
| 255 | |||
| 256 | if (radeon_encoder->pixel_clock > 165000) | ||
| 257 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 258 | |||
| 259 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 260 | break; | ||
| 261 | case 2: | ||
| 262 | /* RS600/690/740 */ | ||
| 263 | args.dvo.sDVOEncoder.ucAction = action; | ||
| 264 | args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 265 | /* DFP1, CRT1, TV1 depending on the type of port */ | ||
| 266 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | ||
| 267 | |||
| 268 | if (radeon_encoder->pixel_clock > 165000) | ||
| 269 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | ||
| 270 | break; | ||
| 271 | case 3: | ||
| 272 | /* R6xx */ | ||
| 273 | args.dvo_v3.ucAction = action; | ||
| 274 | args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 275 | args.dvo_v3.ucDVOConfig = 0; /* XXX */ | ||
| 276 | break; | ||
| 277 | default: | ||
| 278 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 279 | break; | ||
| 280 | } | ||
| 281 | break; | ||
| 282 | default: | ||
| 283 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 284 | break; | ||
| 285 | } | ||
| 286 | |||
| 287 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 288 | } | ||
| 289 | |||
| 290 | union lvds_encoder_control { | ||
| 291 | LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 292 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | ||
| 293 | }; | ||
| 294 | |||
| 295 | void | ||
| 296 | atombios_digital_setup(struct drm_encoder *encoder, int action) | ||
| 297 | { | ||
| 298 | struct drm_device *dev = encoder->dev; | ||
| 299 | struct radeon_device *rdev = dev->dev_private; | ||
| 300 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 301 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 302 | union lvds_encoder_control args; | ||
| 303 | int index = 0; | ||
| 304 | int hdmi_detected = 0; | ||
| 305 | uint8_t frev, crev; | ||
| 306 | |||
| 307 | if (!dig) | ||
| 308 | return; | ||
| 309 | |||
| 310 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
| 311 | hdmi_detected = 1; | ||
| 312 | |||
| 313 | memset(&args, 0, sizeof(args)); | ||
| 314 | |||
| 315 | switch (radeon_encoder->encoder_id) { | ||
| 316 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 317 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
| 318 | break; | ||
| 319 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 320 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 321 | index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); | ||
| 322 | break; | ||
| 323 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 324 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 325 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
| 326 | else | ||
| 327 | index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | |||
| 331 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 332 | return; | ||
| 333 | |||
| 334 | switch (frev) { | ||
| 335 | case 1: | ||
| 336 | case 2: | ||
| 337 | switch (crev) { | ||
| 338 | case 1: | ||
| 339 | args.v1.ucMisc = 0; | ||
| 340 | args.v1.ucAction = action; | ||
| 341 | if (hdmi_detected) | ||
| 342 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
| 343 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 344 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 345 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
| 346 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 347 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 348 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 349 | } else { | ||
| 350 | if (dig->linkb) | ||
| 351 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
| 352 | if (radeon_encoder->pixel_clock > 165000) | ||
| 353 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 354 | /*if (pScrn->rgbBits == 8) */ | ||
| 355 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 356 | } | ||
| 357 | break; | ||
| 358 | case 2: | ||
| 359 | case 3: | ||
| 360 | args.v2.ucMisc = 0; | ||
| 361 | args.v2.ucAction = action; | ||
| 362 | if (crev == 3) { | ||
| 363 | if (dig->coherent_mode) | ||
| 364 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | ||
| 365 | } | ||
| 366 | if (hdmi_detected) | ||
| 367 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
| 368 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 369 | args.v2.ucTruncate = 0; | ||
| 370 | args.v2.ucSpatial = 0; | ||
| 371 | args.v2.ucTemporal = 0; | ||
| 372 | args.v2.ucFRC = 0; | ||
| 373 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 374 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
| 375 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 376 | if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { | ||
| 377 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | ||
| 378 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 379 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | ||
| 380 | } | ||
| 381 | if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { | ||
| 382 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | ||
| 383 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 384 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | ||
| 385 | if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) | ||
| 386 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | ||
| 387 | } | ||
| 388 | } else { | ||
| 389 | if (dig->linkb) | ||
| 390 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
| 391 | if (radeon_encoder->pixel_clock > 165000) | ||
| 392 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 393 | } | ||
| 394 | break; | ||
| 395 | default: | ||
| 396 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | break; | ||
| 400 | default: | ||
| 401 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 402 | break; | ||
| 403 | } | ||
| 404 | |||
| 405 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 406 | } | ||
| 407 | |||
| 408 | int | ||
| 409 | atombios_get_encoder_mode(struct drm_encoder *encoder) | ||
| 410 | { | ||
| 411 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 412 | struct drm_device *dev = encoder->dev; | ||
| 413 | struct radeon_device *rdev = dev->dev_private; | ||
| 414 | struct drm_connector *connector; | ||
| 415 | struct radeon_connector *radeon_connector; | ||
| 416 | struct radeon_connector_atom_dig *dig_connector; | ||
| 417 | |||
| 418 | /* dp bridges are always DP */ | ||
| 419 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) | ||
| 420 | return ATOM_ENCODER_MODE_DP; | ||
| 421 | |||
| 422 | /* DVO is always DVO */ | ||
| 423 | if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) | ||
| 424 | return ATOM_ENCODER_MODE_DVO; | ||
| 425 | |||
| 426 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 427 | /* if we don't have an active device yet, just use one of | ||
| 428 | * the connectors tied to the encoder. | ||
| 429 | */ | ||
| 430 | if (!connector) | ||
| 431 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 432 | radeon_connector = to_radeon_connector(connector); | ||
| 433 | |||
| 434 | switch (connector->connector_type) { | ||
| 435 | case DRM_MODE_CONNECTOR_DVII: | ||
| 436 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | ||
| 437 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 438 | /* fix me */ | ||
| 439 | if (ASIC_IS_DCE4(rdev)) | ||
| 440 | return ATOM_ENCODER_MODE_DVI; | ||
| 441 | else | ||
| 442 | return ATOM_ENCODER_MODE_HDMI; | ||
| 443 | } else if (radeon_connector->use_digital) | ||
| 444 | return ATOM_ENCODER_MODE_DVI; | ||
| 445 | else | ||
| 446 | return ATOM_ENCODER_MODE_CRT; | ||
| 447 | break; | ||
| 448 | case DRM_MODE_CONNECTOR_DVID: | ||
| 449 | case DRM_MODE_CONNECTOR_HDMIA: | ||
| 450 | default: | ||
| 451 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 452 | /* fix me */ | ||
| 453 | if (ASIC_IS_DCE4(rdev)) | ||
| 454 | return ATOM_ENCODER_MODE_DVI; | ||
| 455 | else | ||
| 456 | return ATOM_ENCODER_MODE_HDMI; | ||
| 457 | } else | ||
| 458 | return ATOM_ENCODER_MODE_DVI; | ||
| 459 | break; | ||
| 460 | case DRM_MODE_CONNECTOR_LVDS: | ||
| 461 | return ATOM_ENCODER_MODE_LVDS; | ||
| 462 | break; | ||
| 463 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
| 464 | dig_connector = radeon_connector->con_priv; | ||
| 465 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
| 466 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
| 467 | return ATOM_ENCODER_MODE_DP; | ||
| 468 | else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 469 | /* fix me */ | ||
| 470 | if (ASIC_IS_DCE4(rdev)) | ||
| 471 | return ATOM_ENCODER_MODE_DVI; | ||
| 472 | else | ||
| 473 | return ATOM_ENCODER_MODE_HDMI; | ||
| 474 | } else | ||
| 475 | return ATOM_ENCODER_MODE_DVI; | ||
| 476 | break; | ||
| 477 | case DRM_MODE_CONNECTOR_eDP: | ||
| 478 | return ATOM_ENCODER_MODE_DP; | ||
| 479 | case DRM_MODE_CONNECTOR_DVIA: | ||
| 480 | case DRM_MODE_CONNECTOR_VGA: | ||
| 481 | return ATOM_ENCODER_MODE_CRT; | ||
| 482 | break; | ||
| 483 | case DRM_MODE_CONNECTOR_Composite: | ||
| 484 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
| 485 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
| 486 | /* fix me */ | ||
| 487 | return ATOM_ENCODER_MODE_TV; | ||
| 488 | /*return ATOM_ENCODER_MODE_CV;*/ | ||
| 489 | break; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | /* | ||
| 494 | * DIG Encoder/Transmitter Setup | ||
| 495 | * | ||
| 496 | * DCE 3.0/3.1 | ||
| 497 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
| 498 | * Supports up to 3 digital outputs | ||
| 499 | * - 2 DIG encoder blocks. | ||
| 500 | * DIG1 can drive UNIPHY link A or link B | ||
| 501 | * DIG2 can drive UNIPHY link B or LVTMA | ||
| 502 | * | ||
| 503 | * DCE 3.2 | ||
| 504 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
| 505 | * Supports up to 5 digital outputs | ||
| 506 | * - 2 DIG encoder blocks. | ||
| 507 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 508 | * | ||
| 509 | * DCE 4.0/5.0 | ||
| 510 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
| 511 | * Supports up to 6 digital outputs | ||
| 512 | * - 6 DIG encoder blocks. | ||
| 513 | * - DIG to PHY mapping is hardcoded | ||
| 514 | * DIG1 drives UNIPHY0 link A, A+B | ||
| 515 | * DIG2 drives UNIPHY0 link B | ||
| 516 | * DIG3 drives UNIPHY1 link A, A+B | ||
| 517 | * DIG4 drives UNIPHY1 link B | ||
| 518 | * DIG5 drives UNIPHY2 link A, A+B | ||
| 519 | * DIG6 drives UNIPHY2 link B | ||
| 520 | * | ||
| 521 | * DCE 4.1 | ||
| 522 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
| 523 | * Supports up to 6 digital outputs | ||
| 524 | * - 2 DIG encoder blocks. | ||
| 525 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 526 | * | ||
| 527 | * Routing | ||
| 528 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
| 529 | * Examples: | ||
| 530 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
| 531 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
| 532 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
| 533 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
| 534 | */ | ||
| 535 | |||
| 536 | union dig_encoder_control { | ||
| 537 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 538 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
| 539 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
| 540 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; | ||
| 541 | }; | ||
| 542 | |||
| 543 | void | ||
| 544 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) | ||
| 545 | { | ||
| 546 | struct drm_device *dev = encoder->dev; | ||
| 547 | struct radeon_device *rdev = dev->dev_private; | ||
| 548 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 549 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 550 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 551 | union dig_encoder_control args; | ||
| 552 | int index = 0; | ||
| 553 | uint8_t frev, crev; | ||
| 554 | int dp_clock = 0; | ||
| 555 | int dp_lane_count = 0; | ||
| 556 | int hpd_id = RADEON_HPD_NONE; | ||
| 557 | int bpc = 8; | ||
| 558 | |||
| 559 | if (connector) { | ||
| 560 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 561 | struct radeon_connector_atom_dig *dig_connector = | ||
| 562 | radeon_connector->con_priv; | ||
| 563 | |||
| 564 | dp_clock = dig_connector->dp_clock; | ||
| 565 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 566 | hpd_id = radeon_connector->hpd.hpd; | ||
| 567 | bpc = connector->display_info.bpc; | ||
| 568 | } | ||
| 569 | |||
| 570 | /* no dig encoder assigned */ | ||
| 571 | if (dig->dig_encoder == -1) | ||
| 572 | return; | ||
| 573 | |||
| 574 | memset(&args, 0, sizeof(args)); | ||
| 575 | |||
| 576 | if (ASIC_IS_DCE4(rdev)) | ||
| 577 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); | ||
| 578 | else { | ||
| 579 | if (dig->dig_encoder) | ||
| 580 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
| 581 | else | ||
| 582 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
| 583 | } | ||
| 584 | |||
| 585 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 586 | return; | ||
| 587 | |||
| 588 | switch (frev) { | ||
| 589 | case 1: | ||
| 590 | switch (crev) { | ||
| 591 | case 1: | ||
| 592 | args.v1.ucAction = action; | ||
| 593 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 594 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
| 595 | args.v3.ucPanelMode = panel_mode; | ||
| 596 | else | ||
| 597 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 598 | |||
| 599 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
| 600 | args.v1.ucLaneNum = dp_lane_count; | ||
| 601 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 602 | args.v1.ucLaneNum = 8; | ||
| 603 | else | ||
| 604 | args.v1.ucLaneNum = 4; | ||
| 605 | |||
| 606 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) | ||
| 607 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 608 | switch (radeon_encoder->encoder_id) { | ||
| 609 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 610 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | ||
| 611 | break; | ||
| 612 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 613 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 614 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
| 615 | break; | ||
| 616 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 617 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | ||
| 618 | break; | ||
| 619 | } | ||
| 620 | if (dig->linkb) | ||
| 621 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
| 622 | else | ||
| 623 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
| 624 | break; | ||
| 625 | case 2: | ||
| 626 | case 3: | ||
| 627 | args.v3.ucAction = action; | ||
| 628 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 629 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
| 630 | args.v3.ucPanelMode = panel_mode; | ||
| 631 | else | ||
| 632 | args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 633 | |||
| 634 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
| 635 | args.v3.ucLaneNum = dp_lane_count; | ||
| 636 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 637 | args.v3.ucLaneNum = 8; | ||
| 638 | else | ||
| 639 | args.v3.ucLaneNum = 4; | ||
| 640 | |||
| 641 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) | ||
| 642 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 643 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
| 644 | switch (bpc) { | ||
| 645 | case 0: | ||
| 646 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 647 | break; | ||
| 648 | case 6: | ||
| 649 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 650 | break; | ||
| 651 | case 8: | ||
| 652 | default: | ||
| 653 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 654 | break; | ||
| 655 | case 10: | ||
| 656 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 657 | break; | ||
| 658 | case 12: | ||
| 659 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 660 | break; | ||
| 661 | case 16: | ||
| 662 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 663 | break; | ||
| 664 | } | ||
| 665 | break; | ||
| 666 | case 4: | ||
| 667 | args.v4.ucAction = action; | ||
| 668 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 669 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
| 670 | args.v4.ucPanelMode = panel_mode; | ||
| 671 | else | ||
| 672 | args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 673 | |||
| 674 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | ||
| 675 | args.v4.ucLaneNum = dp_lane_count; | ||
| 676 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 677 | args.v4.ucLaneNum = 8; | ||
| 678 | else | ||
| 679 | args.v4.ucLaneNum = 4; | ||
| 680 | |||
| 681 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) { | ||
| 682 | if (dp_clock == 270000) | ||
| 683 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | ||
| 684 | else if (dp_clock == 540000) | ||
| 685 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | ||
| 686 | } | ||
| 687 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | ||
| 688 | switch (bpc) { | ||
| 689 | case 0: | ||
| 690 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 691 | break; | ||
| 692 | case 6: | ||
| 693 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 694 | break; | ||
| 695 | case 8: | ||
| 696 | default: | ||
| 697 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 698 | break; | ||
| 699 | case 10: | ||
| 700 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 701 | break; | ||
| 702 | case 12: | ||
| 703 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 704 | break; | ||
| 705 | case 16: | ||
| 706 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 707 | break; | ||
| 708 | } | ||
| 709 | if (hpd_id == RADEON_HPD_NONE) | ||
| 710 | args.v4.ucHPD_ID = 0; | ||
| 711 | else | ||
| 712 | args.v4.ucHPD_ID = hpd_id + 1; | ||
| 713 | break; | ||
| 714 | default: | ||
| 715 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | break; | ||
| 719 | default: | ||
| 720 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 721 | break; | ||
| 722 | } | ||
| 723 | |||
| 724 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 725 | |||
| 726 | } | ||
| 727 | |||
| 728 | union dig_transmitter_control { | ||
| 729 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | ||
| 730 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | ||
| 731 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
| 732 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; | ||
| 733 | }; | ||
| 734 | |||
| 735 | void | ||
| 736 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) | ||
| 737 | { | ||
| 738 | struct drm_device *dev = encoder->dev; | ||
| 739 | struct radeon_device *rdev = dev->dev_private; | ||
| 740 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 741 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 742 | struct drm_connector *connector; | ||
| 743 | union dig_transmitter_control args; | ||
| 744 | int index = 0; | ||
| 745 | uint8_t frev, crev; | ||
| 746 | bool is_dp = false; | ||
| 747 | int pll_id = 0; | ||
| 748 | int dp_clock = 0; | ||
| 749 | int dp_lane_count = 0; | ||
| 750 | int connector_object_id = 0; | ||
| 751 | int igp_lane_info = 0; | ||
| 752 | int dig_encoder = dig->dig_encoder; | ||
| 753 | |||
| 754 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 755 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 756 | /* just needed to avoid bailing in the encoder check. the encoder | ||
| 757 | * isn't used for init | ||
| 758 | */ | ||
| 759 | dig_encoder = 0; | ||
| 760 | } else | ||
| 761 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 762 | |||
| 763 | if (connector) { | ||
| 764 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 765 | struct radeon_connector_atom_dig *dig_connector = | ||
| 766 | radeon_connector->con_priv; | ||
| 767 | |||
| 768 | dp_clock = dig_connector->dp_clock; | ||
| 769 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 770 | connector_object_id = | ||
| 771 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 772 | igp_lane_info = dig_connector->igp_lane_info; | ||
| 773 | } | ||
| 774 | |||
| 775 | if (encoder->crtc) { | ||
| 776 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 777 | pll_id = radeon_crtc->pll_id; | ||
| 778 | } | ||
| 779 | |||
| 780 | /* no dig encoder assigned */ | ||
| 781 | if (dig_encoder == -1) | ||
| 782 | return; | ||
| 783 | |||
| 784 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder))) | ||
| 785 | is_dp = true; | ||
| 786 | |||
| 787 | memset(&args, 0, sizeof(args)); | ||
| 788 | |||
| 789 | switch (radeon_encoder->encoder_id) { | ||
| 790 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 791 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
| 792 | break; | ||
| 793 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 794 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 795 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 796 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
| 797 | break; | ||
| 798 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 799 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | |||
| 803 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 804 | return; | ||
| 805 | |||
| 806 | switch (frev) { | ||
| 807 | case 1: | ||
| 808 | switch (crev) { | ||
| 809 | case 1: | ||
| 810 | args.v1.ucAction = action; | ||
| 811 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 812 | args.v1.usInitInfo = cpu_to_le16(connector_object_id); | ||
| 813 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 814 | args.v1.asMode.ucLaneSel = lane_num; | ||
| 815 | args.v1.asMode.ucLaneSet = lane_set; | ||
| 816 | } else { | ||
| 817 | if (is_dp) | ||
| 818 | args.v1.usPixelClock = | ||
| 819 | cpu_to_le16(dp_clock / 10); | ||
| 820 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 821 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 822 | else | ||
| 823 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 824 | } | ||
| 825 | |||
| 826 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | ||
| 827 | |||
| 828 | if (dig_encoder) | ||
| 829 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
| 830 | else | ||
| 831 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
| 832 | |||
| 833 | if ((rdev->flags & RADEON_IS_IGP) && | ||
| 834 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | ||
| 835 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | ||
| 836 | if (igp_lane_info & 0x1) | ||
| 837 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 838 | else if (igp_lane_info & 0x2) | ||
| 839 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | ||
| 840 | else if (igp_lane_info & 0x4) | ||
| 841 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | ||
| 842 | else if (igp_lane_info & 0x8) | ||
| 843 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | ||
| 844 | } else { | ||
| 845 | if (igp_lane_info & 0x3) | ||
| 846 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | ||
| 847 | else if (igp_lane_info & 0xc) | ||
| 848 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | ||
| 849 | } | ||
| 850 | } | ||
| 851 | |||
| 852 | if (dig->linkb) | ||
| 853 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
| 854 | else | ||
| 855 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
| 856 | |||
| 857 | if (is_dp) | ||
| 858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
| 859 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 860 | if (dig->coherent_mode) | ||
| 861 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
| 862 | if (radeon_encoder->pixel_clock > 165000) | ||
| 863 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
| 864 | } | ||
| 865 | break; | ||
| 866 | case 2: | ||
| 867 | args.v2.ucAction = action; | ||
| 868 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 869 | args.v2.usInitInfo = cpu_to_le16(connector_object_id); | ||
| 870 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 871 | args.v2.asMode.ucLaneSel = lane_num; | ||
| 872 | args.v2.asMode.ucLaneSet = lane_set; | ||
| 873 | } else { | ||
| 874 | if (is_dp) | ||
| 875 | args.v2.usPixelClock = | ||
| 876 | cpu_to_le16(dp_clock / 10); | ||
| 877 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 878 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 879 | else | ||
| 880 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 881 | } | ||
| 882 | |||
| 883 | args.v2.acConfig.ucEncoderSel = dig_encoder; | ||
| 884 | if (dig->linkb) | ||
| 885 | args.v2.acConfig.ucLinkSel = 1; | ||
| 886 | |||
| 887 | switch (radeon_encoder->encoder_id) { | ||
| 888 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 889 | args.v2.acConfig.ucTransmitterSel = 0; | ||
| 890 | break; | ||
| 891 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 892 | args.v2.acConfig.ucTransmitterSel = 1; | ||
| 893 | break; | ||
| 894 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 895 | args.v2.acConfig.ucTransmitterSel = 2; | ||
| 896 | break; | ||
| 897 | } | ||
| 898 | |||
| 899 | if (is_dp) { | ||
| 900 | args.v2.acConfig.fCoherentMode = 1; | ||
| 901 | args.v2.acConfig.fDPConnector = 1; | ||
| 902 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 903 | if (dig->coherent_mode) | ||
| 904 | args.v2.acConfig.fCoherentMode = 1; | ||
| 905 | if (radeon_encoder->pixel_clock > 165000) | ||
| 906 | args.v2.acConfig.fDualLinkConnector = 1; | ||
| 907 | } | ||
| 908 | break; | ||
| 909 | case 3: | ||
| 910 | args.v3.ucAction = action; | ||
| 911 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 912 | args.v3.usInitInfo = cpu_to_le16(connector_object_id); | ||
| 913 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 914 | args.v3.asMode.ucLaneSel = lane_num; | ||
| 915 | args.v3.asMode.ucLaneSet = lane_set; | ||
| 916 | } else { | ||
| 917 | if (is_dp) | ||
| 918 | args.v3.usPixelClock = | ||
| 919 | cpu_to_le16(dp_clock / 10); | ||
| 920 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 921 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 922 | else | ||
| 923 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 924 | } | ||
| 925 | |||
| 926 | if (is_dp) | ||
| 927 | args.v3.ucLaneNum = dp_lane_count; | ||
| 928 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 929 | args.v3.ucLaneNum = 8; | ||
| 930 | else | ||
| 931 | args.v3.ucLaneNum = 4; | ||
| 932 | |||
| 933 | if (dig->linkb) | ||
| 934 | args.v3.acConfig.ucLinkSel = 1; | ||
| 935 | if (dig_encoder & 1) | ||
| 936 | args.v3.acConfig.ucEncoderSel = 1; | ||
| 937 | |||
| 938 | /* Select the PLL for the PHY | ||
| 939 | * DP PHY should be clocked from external src if there is | ||
| 940 | * one. | ||
| 941 | */ | ||
| 942 | /* On DCE4, if there is an external clock, it generates the DP ref clock */ | ||
| 943 | if (is_dp && rdev->clock.dp_extclk) | ||
| 944 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
| 945 | else | ||
| 946 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
| 947 | |||
| 948 | switch (radeon_encoder->encoder_id) { | ||
| 949 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 950 | args.v3.acConfig.ucTransmitterSel = 0; | ||
| 951 | break; | ||
| 952 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 953 | args.v3.acConfig.ucTransmitterSel = 1; | ||
| 954 | break; | ||
| 955 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 956 | args.v3.acConfig.ucTransmitterSel = 2; | ||
| 957 | break; | ||
| 958 | } | ||
| 959 | |||
| 960 | if (is_dp) | ||
| 961 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
| 962 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 963 | if (dig->coherent_mode) | ||
| 964 | args.v3.acConfig.fCoherentMode = 1; | ||
| 965 | if (radeon_encoder->pixel_clock > 165000) | ||
| 966 | args.v3.acConfig.fDualLinkConnector = 1; | ||
| 967 | } | ||
| 968 | break; | ||
| 969 | case 4: | ||
| 970 | args.v4.ucAction = action; | ||
| 971 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 972 | args.v4.usInitInfo = cpu_to_le16(connector_object_id); | ||
| 973 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 974 | args.v4.asMode.ucLaneSel = lane_num; | ||
| 975 | args.v4.asMode.ucLaneSet = lane_set; | ||
| 976 | } else { | ||
| 977 | if (is_dp) | ||
| 978 | args.v4.usPixelClock = | ||
| 979 | cpu_to_le16(dp_clock / 10); | ||
| 980 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 981 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 982 | else | ||
| 983 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 984 | } | ||
| 985 | |||
| 986 | if (is_dp) | ||
| 987 | args.v4.ucLaneNum = dp_lane_count; | ||
| 988 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 989 | args.v4.ucLaneNum = 8; | ||
| 990 | else | ||
| 991 | args.v4.ucLaneNum = 4; | ||
| 992 | |||
| 993 | if (dig->linkb) | ||
| 994 | args.v4.acConfig.ucLinkSel = 1; | ||
| 995 | if (dig_encoder & 1) | ||
| 996 | args.v4.acConfig.ucEncoderSel = 1; | ||
| 997 | |||
| 998 | /* Select the PLL for the PHY | ||
| 999 | * DP PHY should be clocked from external src if there is | ||
| 1000 | * one. | ||
| 1001 | */ | ||
| 1002 | /* On DCE5 DCPLL usually generates the DP ref clock */ | ||
| 1003 | if (is_dp) { | ||
| 1004 | if (rdev->clock.dp_extclk) | ||
| 1005 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; | ||
| 1006 | else | ||
| 1007 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; | ||
| 1008 | } else | ||
| 1009 | args.v4.acConfig.ucRefClkSource = pll_id; | ||
| 1010 | |||
| 1011 | switch (radeon_encoder->encoder_id) { | ||
| 1012 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1013 | args.v4.acConfig.ucTransmitterSel = 0; | ||
| 1014 | break; | ||
| 1015 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1016 | args.v4.acConfig.ucTransmitterSel = 1; | ||
| 1017 | break; | ||
| 1018 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1019 | args.v4.acConfig.ucTransmitterSel = 2; | ||
| 1020 | break; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | if (is_dp) | ||
| 1024 | args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
| 1025 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 1026 | if (dig->coherent_mode) | ||
| 1027 | args.v4.acConfig.fCoherentMode = 1; | ||
| 1028 | if (radeon_encoder->pixel_clock > 165000) | ||
| 1029 | args.v4.acConfig.fDualLinkConnector = 1; | ||
| 1030 | } | ||
| 1031 | break; | ||
| 1032 | default: | ||
| 1033 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 1034 | break; | ||
| 1035 | } | ||
| 1036 | break; | ||
| 1037 | default: | ||
| 1038 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 1039 | break; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | bool | ||
| 1046 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) | ||
| 1047 | { | ||
| 1048 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1049 | struct drm_device *dev = radeon_connector->base.dev; | ||
| 1050 | struct radeon_device *rdev = dev->dev_private; | ||
| 1051 | union dig_transmitter_control args; | ||
| 1052 | int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
| 1053 | uint8_t frev, crev; | ||
| 1054 | |||
| 1055 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) | ||
| 1056 | goto done; | ||
| 1057 | |||
| 1058 | if (!ASIC_IS_DCE4(rdev)) | ||
| 1059 | goto done; | ||
| 1060 | |||
| 1061 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && | ||
| 1062 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | ||
| 1063 | goto done; | ||
| 1064 | |||
| 1065 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1066 | goto done; | ||
| 1067 | |||
| 1068 | memset(&args, 0, sizeof(args)); | ||
| 1069 | |||
| 1070 | args.v1.ucAction = action; | ||
| 1071 | |||
| 1072 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1073 | |||
| 1074 | /* wait for the panel to power up */ | ||
| 1075 | if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { | ||
| 1076 | int i; | ||
| 1077 | |||
| 1078 | for (i = 0; i < 300; i++) { | ||
| 1079 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
| 1080 | return true; | ||
| 1081 | mdelay(1); | ||
| 1082 | } | ||
| 1083 | return false; | ||
| 1084 | } | ||
| 1085 | done: | ||
| 1086 | return true; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | union external_encoder_control { | ||
| 1090 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 1091 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; | ||
| 1092 | }; | ||
| 1093 | |||
| 1094 | static void | ||
| 1095 | atombios_external_encoder_setup(struct drm_encoder *encoder, | ||
| 1096 | struct drm_encoder *ext_encoder, | ||
| 1097 | int action) | ||
| 1098 | { | ||
| 1099 | struct drm_device *dev = encoder->dev; | ||
| 1100 | struct radeon_device *rdev = dev->dev_private; | ||
| 1101 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1102 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | ||
| 1103 | union external_encoder_control args; | ||
| 1104 | struct drm_connector *connector; | ||
| 1105 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | ||
| 1106 | u8 frev, crev; | ||
| 1107 | int dp_clock = 0; | ||
| 1108 | int dp_lane_count = 0; | ||
| 1109 | int connector_object_id = 0; | ||
| 1110 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 1111 | int bpc = 8; | ||
| 1112 | |||
| 1113 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
| 1114 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 1115 | else | ||
| 1116 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 1117 | |||
| 1118 | if (connector) { | ||
| 1119 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1120 | struct radeon_connector_atom_dig *dig_connector = | ||
| 1121 | radeon_connector->con_priv; | ||
| 1122 | |||
| 1123 | dp_clock = dig_connector->dp_clock; | ||
| 1124 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 1125 | connector_object_id = | ||
| 1126 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 1127 | bpc = connector->display_info.bpc; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | memset(&args, 0, sizeof(args)); | ||
| 1131 | |||
| 1132 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1133 | return; | ||
| 1134 | |||
| 1135 | switch (frev) { | ||
| 1136 | case 1: | ||
| 1137 | /* no params on frev 1 */ | ||
| 1138 | break; | ||
| 1139 | case 2: | ||
| 1140 | switch (crev) { | ||
| 1141 | case 1: | ||
| 1142 | case 2: | ||
| 1143 | args.v1.sDigEncoder.ucAction = action; | ||
| 1144 | args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1145 | args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 1146 | |||
| 1147 | if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) { | ||
| 1148 | if (dp_clock == 270000) | ||
| 1149 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 1150 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | ||
| 1151 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 1152 | args.v1.sDigEncoder.ucLaneNum = 8; | ||
| 1153 | else | ||
| 1154 | args.v1.sDigEncoder.ucLaneNum = 4; | ||
| 1155 | break; | ||
| 1156 | case 3: | ||
| 1157 | args.v3.sExtEncoder.ucAction = action; | ||
| 1158 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
| 1159 | args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); | ||
| 1160 | else | ||
| 1161 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1162 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 1163 | |||
| 1164 | if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) { | ||
| 1165 | if (dp_clock == 270000) | ||
| 1166 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 1167 | else if (dp_clock == 540000) | ||
| 1168 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | ||
| 1169 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | ||
| 1170 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 1171 | args.v3.sExtEncoder.ucLaneNum = 8; | ||
| 1172 | else | ||
| 1173 | args.v3.sExtEncoder.ucLaneNum = 4; | ||
| 1174 | switch (ext_enum) { | ||
| 1175 | case GRAPH_OBJECT_ENUM_ID1: | ||
| 1176 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; | ||
| 1177 | break; | ||
| 1178 | case GRAPH_OBJECT_ENUM_ID2: | ||
| 1179 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; | ||
| 1180 | break; | ||
| 1181 | case GRAPH_OBJECT_ENUM_ID3: | ||
| 1182 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | ||
| 1183 | break; | ||
| 1184 | } | ||
| 1185 | switch (bpc) { | ||
| 1186 | case 0: | ||
| 1187 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 1188 | break; | ||
| 1189 | case 6: | ||
| 1190 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 1191 | break; | ||
| 1192 | case 8: | ||
| 1193 | default: | ||
| 1194 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 1195 | break; | ||
| 1196 | case 10: | ||
| 1197 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 1198 | break; | ||
| 1199 | case 12: | ||
| 1200 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 1201 | break; | ||
| 1202 | case 16: | ||
| 1203 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 1204 | break; | ||
| 1205 | } | ||
| 1206 | break; | ||
| 1207 | default: | ||
| 1208 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1209 | return; | ||
| 1210 | } | ||
| 1211 | break; | ||
| 1212 | default: | ||
| 1213 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1214 | return; | ||
| 1215 | } | ||
| 1216 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | static void | ||
| 1220 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | ||
| 1221 | { | ||
| 1222 | struct drm_device *dev = encoder->dev; | ||
| 1223 | struct radeon_device *rdev = dev->dev_private; | ||
| 1224 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1225 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1226 | ENABLE_YUV_PS_ALLOCATION args; | ||
| 1227 | int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); | ||
| 1228 | uint32_t temp, reg; | ||
| 1229 | |||
| 1230 | memset(&args, 0, sizeof(args)); | ||
| 1231 | |||
| 1232 | if (rdev->family >= CHIP_R600) | ||
| 1233 | reg = R600_BIOS_3_SCRATCH; | ||
| 1234 | else | ||
| 1235 | reg = RADEON_BIOS_3_SCRATCH; | ||
| 1236 | |||
| 1237 | /* XXX: fix up scratch reg handling */ | ||
| 1238 | temp = RREG32(reg); | ||
| 1239 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1240 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | | ||
| 1241 | (radeon_crtc->crtc_id << 18))); | ||
| 1242 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1243 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); | ||
| 1244 | else | ||
| 1245 | WREG32(reg, 0); | ||
| 1246 | |||
| 1247 | if (enable) | ||
| 1248 | args.ucEnable = ATOM_ENABLE; | ||
| 1249 | args.ucCRTC = radeon_crtc->crtc_id; | ||
| 1250 | |||
| 1251 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1252 | |||
| 1253 | WREG32(reg, temp); | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | static void | ||
| 1257 | radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode) | ||
| 1258 | { | ||
| 1259 | struct drm_device *dev = encoder->dev; | ||
| 1260 | struct radeon_device *rdev = dev->dev_private; | ||
| 1261 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1262 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | ||
| 1263 | int index = 0; | ||
| 1264 | |||
| 1265 | memset(&args, 0, sizeof(args)); | ||
| 1266 | |||
| 1267 | switch (radeon_encoder->encoder_id) { | ||
| 1268 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1269 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1270 | index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); | ||
| 1271 | break; | ||
| 1272 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1273 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1274 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1275 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
| 1276 | break; | ||
| 1277 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1278 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
| 1279 | break; | ||
| 1280 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1281 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1282 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
| 1283 | else | ||
| 1284 | index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); | ||
| 1285 | break; | ||
| 1286 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1287 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1288 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1289 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
| 1290 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1291 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
| 1292 | else | ||
| 1293 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | ||
| 1294 | break; | ||
| 1295 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1296 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1297 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1298 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
| 1299 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1300 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
| 1301 | else | ||
| 1302 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | ||
| 1303 | break; | ||
| 1304 | default: | ||
| 1305 | return; | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | switch (mode) { | ||
| 1309 | case DRM_MODE_DPMS_ON: | ||
| 1310 | args.ucAction = ATOM_ENABLE; | ||
| 1311 | /* workaround for DVOOutputControl on some RS690 systems */ | ||
| 1312 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { | ||
| 1313 | u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); | ||
| 1314 | WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); | ||
| 1315 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1316 | WREG32(RADEON_BIOS_3_SCRATCH, reg); | ||
| 1317 | } else | ||
| 1318 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1319 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 1320 | args.ucAction = ATOM_LCD_BLON; | ||
| 1321 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1322 | } | ||
| 1323 | break; | ||
| 1324 | case DRM_MODE_DPMS_STANDBY: | ||
| 1325 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1326 | case DRM_MODE_DPMS_OFF: | ||
| 1327 | args.ucAction = ATOM_DISABLE; | ||
| 1328 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1329 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 1330 | args.ucAction = ATOM_LCD_BLOFF; | ||
| 1331 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1332 | } | ||
| 1333 | break; | ||
| 1334 | } | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | static void | ||
| 1338 | radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | ||
| 1339 | { | ||
| 1340 | struct drm_device *dev = encoder->dev; | ||
| 1341 | struct radeon_device *rdev = dev->dev_private; | ||
| 1342 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1343 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1344 | struct radeon_connector *radeon_connector = NULL; | ||
| 1345 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | ||
| 1346 | |||
| 1347 | if (connector) { | ||
| 1348 | radeon_connector = to_radeon_connector(connector); | ||
| 1349 | radeon_dig_connector = radeon_connector->con_priv; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | switch (mode) { | ||
| 1353 | case DRM_MODE_DPMS_ON: | ||
| 1354 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
| 1355 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | ||
| 1356 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1357 | else | ||
| 1358 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
| 1359 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | ||
| 1360 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
| 1361 | atombios_set_edp_panel_power(connector, | ||
| 1362 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 1363 | radeon_dig_connector->edp_on = true; | ||
| 1364 | } | ||
| 1365 | if (ASIC_IS_DCE4(rdev)) | ||
| 1366 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
| 1367 | radeon_dp_link_train(encoder, connector); | ||
| 1368 | if (ASIC_IS_DCE4(rdev)) | ||
| 1369 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | ||
| 1370 | } | ||
| 1371 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1372 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | ||
| 1373 | break; | ||
| 1374 | case DRM_MODE_DPMS_STANDBY: | ||
| 1375 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1376 | case DRM_MODE_DPMS_OFF: | ||
| 1377 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1378 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | ||
| 1379 | if (ASIC_IS_DCE4(rdev)) | ||
| 1380 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
| 1381 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
| 1382 | atombios_set_edp_panel_power(connector, | ||
| 1383 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
| 1384 | radeon_dig_connector->edp_on = false; | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1388 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | ||
| 1389 | break; | ||
| 1390 | } | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | static void | ||
| 1394 | radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder, | ||
| 1395 | struct drm_encoder *ext_encoder, | ||
| 1396 | int mode) | ||
| 1397 | { | ||
| 1398 | struct drm_device *dev = encoder->dev; | ||
| 1399 | struct radeon_device *rdev = dev->dev_private; | ||
| 1400 | |||
| 1401 | switch (mode) { | ||
| 1402 | case DRM_MODE_DPMS_ON: | ||
| 1403 | default: | ||
| 1404 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1405 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1406 | EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); | ||
| 1407 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1408 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); | ||
| 1409 | } else | ||
| 1410 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1411 | break; | ||
| 1412 | case DRM_MODE_DPMS_STANDBY: | ||
| 1413 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1414 | case DRM_MODE_DPMS_OFF: | ||
| 1415 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1416 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1417 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); | ||
| 1418 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1419 | EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); | ||
| 1420 | } else | ||
| 1421 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); | ||
| 1422 | break; | ||
| 1423 | } | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | static void | ||
| 1427 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
| 1428 | { | ||
| 1429 | struct drm_device *dev = encoder->dev; | ||
| 1430 | struct radeon_device *rdev = dev->dev_private; | ||
| 1431 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1432 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1433 | |||
| 1434 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | ||
| 1435 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | ||
| 1436 | radeon_encoder->active_device); | ||
| 1437 | switch (radeon_encoder->encoder_id) { | ||
| 1438 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1439 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1440 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1441 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1442 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1443 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1444 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1445 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1446 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
| 1447 | break; | ||
| 1448 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1449 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1450 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1451 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1452 | radeon_atom_encoder_dpms_dig(encoder, mode); | ||
| 1453 | break; | ||
| 1454 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1455 | if (ASIC_IS_DCE5(rdev)) { | ||
| 1456 | switch (mode) { | ||
| 1457 | case DRM_MODE_DPMS_ON: | ||
| 1458 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
| 1459 | break; | ||
| 1460 | case DRM_MODE_DPMS_STANDBY: | ||
| 1461 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1462 | case DRM_MODE_DPMS_OFF: | ||
| 1463 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
| 1464 | break; | ||
| 1465 | } | ||
| 1466 | } else if (ASIC_IS_DCE3(rdev)) | ||
| 1467 | radeon_atom_encoder_dpms_dig(encoder, mode); | ||
| 1468 | else | ||
| 1469 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
| 1470 | break; | ||
| 1471 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1472 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1473 | if (ASIC_IS_DCE5(rdev)) { | ||
| 1474 | switch (mode) { | ||
| 1475 | case DRM_MODE_DPMS_ON: | ||
| 1476 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
| 1477 | break; | ||
| 1478 | case DRM_MODE_DPMS_STANDBY: | ||
| 1479 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1480 | case DRM_MODE_DPMS_OFF: | ||
| 1481 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
| 1482 | break; | ||
| 1483 | } | ||
| 1484 | } else | ||
| 1485 | radeon_atom_encoder_dpms_avivo(encoder, mode); | ||
| 1486 | break; | ||
| 1487 | default: | ||
| 1488 | return; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | if (ext_encoder) | ||
| 1492 | radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode); | ||
| 1493 | |||
| 1494 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | ||
| 1495 | |||
| 1496 | } | ||
| 1497 | |||
| 1498 | union crtc_source_param { | ||
| 1499 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | ||
| 1500 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | ||
| 1501 | }; | ||
| 1502 | |||
| 1503 | static void | ||
| 1504 | atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | ||
| 1505 | { | ||
| 1506 | struct drm_device *dev = encoder->dev; | ||
| 1507 | struct radeon_device *rdev = dev->dev_private; | ||
| 1508 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1509 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1510 | union crtc_source_param args; | ||
| 1511 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | ||
| 1512 | uint8_t frev, crev; | ||
| 1513 | struct radeon_encoder_atom_dig *dig; | ||
| 1514 | |||
| 1515 | memset(&args, 0, sizeof(args)); | ||
| 1516 | |||
| 1517 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1518 | return; | ||
| 1519 | |||
| 1520 | switch (frev) { | ||
| 1521 | case 1: | ||
| 1522 | switch (crev) { | ||
| 1523 | case 1: | ||
| 1524 | default: | ||
| 1525 | if (ASIC_IS_AVIVO(rdev)) | ||
| 1526 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
| 1527 | else { | ||
| 1528 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) { | ||
| 1529 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
| 1530 | } else { | ||
| 1531 | args.v1.ucCRTC = radeon_crtc->crtc_id << 2; | ||
| 1532 | } | ||
| 1533 | } | ||
| 1534 | switch (radeon_encoder->encoder_id) { | ||
| 1535 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1536 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1537 | args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; | ||
| 1538 | break; | ||
| 1539 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1540 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1541 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) | ||
| 1542 | args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; | ||
| 1543 | else | ||
| 1544 | args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; | ||
| 1545 | break; | ||
| 1546 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1547 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1548 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1549 | args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; | ||
| 1550 | break; | ||
| 1551 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1552 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1553 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1554 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
| 1555 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1556 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
| 1557 | else | ||
| 1558 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; | ||
| 1559 | break; | ||
| 1560 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1561 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1562 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1563 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
| 1564 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1565 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
| 1566 | else | ||
| 1567 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; | ||
| 1568 | break; | ||
| 1569 | } | ||
| 1570 | break; | ||
| 1571 | case 2: | ||
| 1572 | args.v2.ucCRTC = radeon_crtc->crtc_id; | ||
| 1573 | if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) { | ||
| 1574 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1575 | |||
| 1576 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | ||
| 1577 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; | ||
| 1578 | else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) | ||
| 1579 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; | ||
| 1580 | else | ||
| 1581 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 1582 | } else | ||
| 1583 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 1584 | switch (radeon_encoder->encoder_id) { | ||
| 1585 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1586 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1587 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1588 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1589 | dig = radeon_encoder->enc_priv; | ||
| 1590 | switch (dig->dig_encoder) { | ||
| 1591 | case 0: | ||
| 1592 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
| 1593 | break; | ||
| 1594 | case 1: | ||
| 1595 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
| 1596 | break; | ||
| 1597 | case 2: | ||
| 1598 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
| 1599 | break; | ||
| 1600 | case 3: | ||
| 1601 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
| 1602 | break; | ||
| 1603 | case 4: | ||
| 1604 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
| 1605 | break; | ||
| 1606 | case 5: | ||
| 1607 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
| 1608 | break; | ||
| 1609 | } | ||
| 1610 | break; | ||
| 1611 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1612 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | ||
| 1613 | break; | ||
| 1614 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1615 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1616 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1617 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1618 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1619 | else | ||
| 1620 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; | ||
| 1621 | break; | ||
| 1622 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1623 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1624 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1625 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1626 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1627 | else | ||
| 1628 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; | ||
| 1629 | break; | ||
| 1630 | } | ||
| 1631 | break; | ||
| 1632 | } | ||
| 1633 | break; | ||
| 1634 | default: | ||
| 1635 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1636 | return; | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1640 | |||
| 1641 | /* update scratch regs with new routing */ | ||
| 1642 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static void | ||
| 1646 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, | ||
| 1647 | struct drm_display_mode *mode) | ||
| 1648 | { | ||
| 1649 | struct drm_device *dev = encoder->dev; | ||
| 1650 | struct radeon_device *rdev = dev->dev_private; | ||
| 1651 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1652 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1653 | |||
| 1654 | /* Funky macbooks */ | ||
| 1655 | if ((dev->pdev->device == 0x71C5) && | ||
| 1656 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
| 1657 | (dev->pdev->subsystem_device == 0x0080)) { | ||
| 1658 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { | ||
| 1659 | uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL); | ||
| 1660 | |||
| 1661 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; | ||
| 1662 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; | ||
| 1663 | |||
| 1664 | WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); | ||
| 1665 | } | ||
| 1666 | } | ||
| 1667 | |||
| 1668 | /* set scaler clears this on some chips */ | ||
| 1669 | if (ASIC_IS_AVIVO(rdev) && | ||
| 1670 | (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { | ||
| 1671 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1672 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1673 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1674 | EVERGREEN_INTERLEAVE_EN); | ||
| 1675 | else | ||
| 1676 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1677 | } else { | ||
| 1678 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1679 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1680 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
| 1681 | else | ||
| 1682 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1683 | } | ||
| 1684 | } | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
| 1688 | { | ||
| 1689 | struct drm_device *dev = encoder->dev; | ||
| 1690 | struct radeon_device *rdev = dev->dev_private; | ||
| 1691 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1692 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1693 | struct drm_encoder *test_encoder; | ||
| 1694 | struct radeon_encoder_atom_dig *dig; | ||
| 1695 | uint32_t dig_enc_in_use = 0; | ||
| 1696 | |||
| 1697 | /* DCE4/5 */ | ||
| 1698 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1699 | dig = radeon_encoder->enc_priv; | ||
| 1700 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1701 | /* ontario follows DCE4 */ | ||
| 1702 | if (rdev->family == CHIP_PALM) { | ||
| 1703 | if (dig->linkb) | ||
| 1704 | return 1; | ||
| 1705 | else | ||
| 1706 | return 0; | ||
| 1707 | } else | ||
| 1708 | /* llano follows DCE3.2 */ | ||
| 1709 | return radeon_crtc->crtc_id; | ||
| 1710 | } else { | ||
| 1711 | switch (radeon_encoder->encoder_id) { | ||
| 1712 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1713 | if (dig->linkb) | ||
| 1714 | return 1; | ||
| 1715 | else | ||
| 1716 | return 0; | ||
| 1717 | break; | ||
| 1718 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1719 | if (dig->linkb) | ||
| 1720 | return 3; | ||
| 1721 | else | ||
| 1722 | return 2; | ||
| 1723 | break; | ||
| 1724 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1725 | if (dig->linkb) | ||
| 1726 | return 5; | ||
| 1727 | else | ||
| 1728 | return 4; | ||
| 1729 | break; | ||
| 1730 | } | ||
| 1731 | } | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
| 1735 | if (ASIC_IS_DCE32(rdev)) { | ||
| 1736 | return radeon_crtc->crtc_id; | ||
| 1737 | } | ||
| 1738 | |||
| 1739 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
| 1740 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
| 1741 | struct radeon_encoder *radeon_test_encoder; | ||
| 1742 | |||
| 1743 | if (encoder == test_encoder) | ||
| 1744 | continue; | ||
| 1745 | |||
| 1746 | if (!radeon_encoder_is_digital(test_encoder)) | ||
| 1747 | continue; | ||
| 1748 | |||
| 1749 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
| 1750 | dig = radeon_test_encoder->enc_priv; | ||
| 1751 | |||
| 1752 | if (dig->dig_encoder >= 0) | ||
| 1753 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
| 1757 | if (dig_enc_in_use & 0x2) | ||
| 1758 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
| 1759 | return 1; | ||
| 1760 | } | ||
| 1761 | if (!(dig_enc_in_use & 1)) | ||
| 1762 | return 0; | ||
| 1763 | return 1; | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | /* This only needs to be called once at startup */ | ||
| 1767 | void | ||
| 1768 | radeon_atom_encoder_init(struct radeon_device *rdev) | ||
| 1769 | { | ||
| 1770 | struct drm_device *dev = rdev->ddev; | ||
| 1771 | struct drm_encoder *encoder; | ||
| 1772 | |||
| 1773 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 1774 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1775 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1776 | |||
| 1777 | switch (radeon_encoder->encoder_id) { | ||
| 1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1779 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1780 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1781 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1782 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
| 1783 | break; | ||
| 1784 | default: | ||
| 1785 | break; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | if (ext_encoder && ASIC_IS_DCE41(rdev)) | ||
| 1789 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1790 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
| 1791 | } | ||
| 1792 | } | ||
| 1793 | |||
| 1794 | static void | ||
| 1795 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | ||
| 1796 | struct drm_display_mode *mode, | ||
| 1797 | struct drm_display_mode *adjusted_mode) | ||
| 1798 | { | ||
| 1799 | struct drm_device *dev = encoder->dev; | ||
| 1800 | struct radeon_device *rdev = dev->dev_private; | ||
| 1801 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1802 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1803 | |||
| 1804 | radeon_encoder->pixel_clock = adjusted_mode->clock; | ||
| 1805 | |||
| 1806 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | ||
| 1807 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | ||
| 1808 | atombios_yuv_setup(encoder, true); | ||
| 1809 | else | ||
| 1810 | atombios_yuv_setup(encoder, false); | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | switch (radeon_encoder->encoder_id) { | ||
| 1814 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1815 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1816 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1817 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1818 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); | ||
| 1819 | break; | ||
| 1820 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1821 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1822 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1823 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1824 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1825 | /* disable the transmitter */ | ||
| 1826 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1827 | /* setup and enable the encoder */ | ||
| 1828 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1829 | |||
| 1830 | /* enable the transmitter */ | ||
| 1831 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1832 | } else { | ||
| 1833 | /* disable the encoder and transmitter */ | ||
| 1834 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1835 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1836 | |||
| 1837 | /* setup and enable the encoder and transmitter */ | ||
| 1838 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1839 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1840 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1841 | } | ||
| 1842 | break; | ||
| 1843 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1844 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1845 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1846 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
| 1847 | break; | ||
| 1848 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1849 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1850 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1851 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1852 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
| 1853 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { | ||
| 1854 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
| 1855 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
| 1856 | else | ||
| 1857 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
| 1858 | } | ||
| 1859 | break; | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | if (ext_encoder) { | ||
| 1863 | if (ASIC_IS_DCE41(rdev)) | ||
| 1864 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1865 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1866 | else | ||
| 1867 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | ||
| 1871 | |||
| 1872 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
| 1873 | r600_hdmi_enable(encoder); | ||
| 1874 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
| 1875 | } | ||
| 1876 | } | ||
| 1877 | |||
| 1878 | static bool | ||
| 1879 | atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 1880 | { | ||
| 1881 | struct drm_device *dev = encoder->dev; | ||
| 1882 | struct radeon_device *rdev = dev->dev_private; | ||
| 1883 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1884 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1885 | |||
| 1886 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | | ||
| 1887 | ATOM_DEVICE_CV_SUPPORT | | ||
| 1888 | ATOM_DEVICE_CRT_SUPPORT)) { | ||
| 1889 | DAC_LOAD_DETECTION_PS_ALLOCATION args; | ||
| 1890 | int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); | ||
| 1891 | uint8_t frev, crev; | ||
| 1892 | |||
| 1893 | memset(&args, 0, sizeof(args)); | ||
| 1894 | |||
| 1895 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1896 | return false; | ||
| 1897 | |||
| 1898 | args.sDacload.ucMisc = 0; | ||
| 1899 | |||
| 1900 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || | ||
| 1901 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)) | ||
| 1902 | args.sDacload.ucDacType = ATOM_DAC_A; | ||
| 1903 | else | ||
| 1904 | args.sDacload.ucDacType = ATOM_DAC_B; | ||
| 1905 | |||
| 1906 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) | ||
| 1907 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); | ||
| 1908 | else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) | ||
| 1909 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); | ||
| 1910 | else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 1911 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); | ||
| 1912 | if (crev >= 3) | ||
| 1913 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
| 1914 | } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 1915 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); | ||
| 1916 | if (crev >= 3) | ||
| 1917 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
| 1918 | } | ||
| 1919 | |||
| 1920 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1921 | |||
| 1922 | return true; | ||
| 1923 | } else | ||
| 1924 | return false; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | static enum drm_connector_status | ||
| 1928 | radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 1929 | { | ||
| 1930 | struct drm_device *dev = encoder->dev; | ||
| 1931 | struct radeon_device *rdev = dev->dev_private; | ||
| 1932 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1933 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1934 | uint32_t bios_0_scratch; | ||
| 1935 | |||
| 1936 | if (!atombios_dac_load_detect(encoder, connector)) { | ||
| 1937 | DRM_DEBUG_KMS("detect returned false \n"); | ||
| 1938 | return connector_status_unknown; | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | if (rdev->family >= CHIP_R600) | ||
| 1942 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
| 1943 | else | ||
| 1944 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | ||
| 1945 | |||
| 1946 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
| 1947 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
| 1948 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
| 1949 | return connector_status_connected; | ||
| 1950 | } | ||
| 1951 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
| 1952 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
| 1953 | return connector_status_connected; | ||
| 1954 | } | ||
| 1955 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 1956 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
| 1957 | return connector_status_connected; | ||
| 1958 | } | ||
| 1959 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 1960 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
| 1961 | return connector_status_connected; /* CTV */ | ||
| 1962 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
| 1963 | return connector_status_connected; /* STV */ | ||
| 1964 | } | ||
| 1965 | return connector_status_disconnected; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | static enum drm_connector_status | ||
| 1969 | radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 1970 | { | ||
| 1971 | struct drm_device *dev = encoder->dev; | ||
| 1972 | struct radeon_device *rdev = dev->dev_private; | ||
| 1973 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1974 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1975 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1976 | u32 bios_0_scratch; | ||
| 1977 | |||
| 1978 | if (!ASIC_IS_DCE4(rdev)) | ||
| 1979 | return connector_status_unknown; | ||
| 1980 | |||
| 1981 | if (!ext_encoder) | ||
| 1982 | return connector_status_unknown; | ||
| 1983 | |||
| 1984 | if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0) | ||
| 1985 | return connector_status_unknown; | ||
| 1986 | |||
| 1987 | /* load detect on the dp bridge */ | ||
| 1988 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1989 | EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION); | ||
| 1990 | |||
| 1991 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
| 1992 | |||
| 1993 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
| 1994 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
| 1995 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
| 1996 | return connector_status_connected; | ||
| 1997 | } | ||
| 1998 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
| 1999 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
| 2000 | return connector_status_connected; | ||
| 2001 | } | ||
| 2002 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 2003 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
| 2004 | return connector_status_connected; | ||
| 2005 | } | ||
| 2006 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 2007 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
| 2008 | return connector_status_connected; /* CTV */ | ||
| 2009 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
| 2010 | return connector_status_connected; /* STV */ | ||
| 2011 | } | ||
| 2012 | return connector_status_disconnected; | ||
| 2013 | } | ||
| 2014 | |||
| 2015 | void | ||
| 2016 | radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | ||
| 2017 | { | ||
| 2018 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 2019 | |||
| 2020 | if (ext_encoder) | ||
| 2021 | /* ddc_setup on the dp bridge */ | ||
| 2022 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 2023 | EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); | ||
| 2024 | |||
| 2025 | } | ||
| 2026 | |||
| 2027 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | ||
| 2028 | { | ||
| 2029 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2030 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 2031 | |||
| 2032 | if ((radeon_encoder->active_device & | ||
| 2033 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
| 2034 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != | ||
| 2035 | ENCODER_OBJECT_ID_NONE)) { | ||
| 2036 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 2037 | if (dig) | ||
| 2038 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | radeon_atom_output_lock(encoder, true); | ||
| 2042 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2043 | |||
| 2044 | if (connector) { | ||
| 2045 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 2046 | |||
| 2047 | /* select the clock/data port if it uses a router */ | ||
| 2048 | if (radeon_connector->router.cd_valid) | ||
| 2049 | radeon_router_select_cd_port(radeon_connector); | ||
| 2050 | |||
| 2051 | /* turn eDP panel on for mode set */ | ||
| 2052 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
| 2053 | atombios_set_edp_panel_power(connector, | ||
| 2054 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | /* this is needed for the pll/ss setup to work correctly in some cases */ | ||
| 2058 | atombios_set_encoder_crtc_source(encoder); | ||
| 2059 | } | ||
| 2060 | |||
| 2061 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | ||
| 2062 | { | ||
| 2063 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | ||
| 2064 | radeon_atom_output_lock(encoder, false); | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | ||
| 2068 | { | ||
| 2069 | struct drm_device *dev = encoder->dev; | ||
| 2070 | struct radeon_device *rdev = dev->dev_private; | ||
| 2071 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2072 | struct radeon_encoder_atom_dig *dig; | ||
| 2073 | |||
| 2074 | /* check for pre-DCE3 cards with shared encoders; | ||
| 2075 | * can't really use the links individually, so don't disable | ||
| 2076 | * the encoder if it's in use by another connector | ||
| 2077 | */ | ||
| 2078 | if (!ASIC_IS_DCE3(rdev)) { | ||
| 2079 | struct drm_encoder *other_encoder; | ||
| 2080 | struct radeon_encoder *other_radeon_encoder; | ||
| 2081 | |||
| 2082 | list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { | ||
| 2083 | other_radeon_encoder = to_radeon_encoder(other_encoder); | ||
| 2084 | if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && | ||
| 2085 | drm_helper_encoder_in_use(other_encoder)) | ||
| 2086 | goto disable_done; | ||
| 2087 | } | ||
| 2088 | } | ||
| 2089 | |||
| 2090 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2091 | |||
| 2092 | switch (radeon_encoder->encoder_id) { | ||
| 2093 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 2094 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 2095 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 2096 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 2097 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); | ||
| 2098 | break; | ||
| 2099 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 2100 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 2101 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 2102 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 2103 | if (ASIC_IS_DCE4(rdev)) | ||
| 2104 | /* disable the transmitter */ | ||
| 2105 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2106 | else { | ||
| 2107 | /* disable the encoder and transmitter */ | ||
| 2108 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2109 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 2110 | } | ||
| 2111 | break; | ||
| 2112 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 2113 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 2114 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 2115 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
| 2116 | break; | ||
| 2117 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 2118 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 2119 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 2120 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 2121 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
| 2122 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
| 2123 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
| 2124 | break; | ||
| 2125 | } | ||
| 2126 | |||
| 2127 | disable_done: | ||
| 2128 | if (radeon_encoder_is_digital(encoder)) { | ||
| 2129 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
| 2130 | r600_hdmi_disable(encoder); | ||
| 2131 | dig = radeon_encoder->enc_priv; | ||
| 2132 | dig->dig_encoder = -1; | ||
| 2133 | } | ||
| 2134 | radeon_encoder->active_device = 0; | ||
| 2135 | } | ||
| 2136 | |||
| 2137 | /* these are handled by the primary encoders */ | ||
| 2138 | static void radeon_atom_ext_prepare(struct drm_encoder *encoder) | ||
| 2139 | { | ||
| 2140 | |||
| 2141 | } | ||
| 2142 | |||
| 2143 | static void radeon_atom_ext_commit(struct drm_encoder *encoder) | ||
| 2144 | { | ||
| 2145 | |||
| 2146 | } | ||
| 2147 | |||
| 2148 | static void | ||
| 2149 | radeon_atom_ext_mode_set(struct drm_encoder *encoder, | ||
| 2150 | struct drm_display_mode *mode, | ||
| 2151 | struct drm_display_mode *adjusted_mode) | ||
| 2152 | { | ||
| 2153 | |||
| 2154 | } | ||
| 2155 | |||
| 2156 | static void radeon_atom_ext_disable(struct drm_encoder *encoder) | ||
| 2157 | { | ||
| 2158 | |||
| 2159 | } | ||
| 2160 | |||
| 2161 | static void | ||
| 2162 | radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) | ||
| 2163 | { | ||
| 2164 | |||
| 2165 | } | ||
| 2166 | |||
| 2167 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, | ||
| 2168 | struct drm_display_mode *mode, | ||
| 2169 | struct drm_display_mode *adjusted_mode) | ||
| 2170 | { | ||
| 2171 | return true; | ||
| 2172 | } | ||
| 2173 | |||
| 2174 | static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { | ||
| 2175 | .dpms = radeon_atom_ext_dpms, | ||
| 2176 | .mode_fixup = radeon_atom_ext_mode_fixup, | ||
| 2177 | .prepare = radeon_atom_ext_prepare, | ||
| 2178 | .mode_set = radeon_atom_ext_mode_set, | ||
| 2179 | .commit = radeon_atom_ext_commit, | ||
| 2180 | .disable = radeon_atom_ext_disable, | ||
| 2181 | /* no detect for TMDS/LVDS yet */ | ||
| 2182 | }; | ||
| 2183 | |||
| 2184 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { | ||
| 2185 | .dpms = radeon_atom_encoder_dpms, | ||
| 2186 | .mode_fixup = radeon_atom_mode_fixup, | ||
| 2187 | .prepare = radeon_atom_encoder_prepare, | ||
| 2188 | .mode_set = radeon_atom_encoder_mode_set, | ||
| 2189 | .commit = radeon_atom_encoder_commit, | ||
| 2190 | .disable = radeon_atom_encoder_disable, | ||
| 2191 | .detect = radeon_atom_dig_detect, | ||
| 2192 | }; | ||
| 2193 | |||
| 2194 | static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { | ||
| 2195 | .dpms = radeon_atom_encoder_dpms, | ||
| 2196 | .mode_fixup = radeon_atom_mode_fixup, | ||
| 2197 | .prepare = radeon_atom_encoder_prepare, | ||
| 2198 | .mode_set = radeon_atom_encoder_mode_set, | ||
| 2199 | .commit = radeon_atom_encoder_commit, | ||
| 2200 | .detect = radeon_atom_dac_detect, | ||
| 2201 | }; | ||
| 2202 | |||
| 2203 | void radeon_enc_destroy(struct drm_encoder *encoder) | ||
| 2204 | { | ||
| 2205 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2206 | kfree(radeon_encoder->enc_priv); | ||
| 2207 | drm_encoder_cleanup(encoder); | ||
| 2208 | kfree(radeon_encoder); | ||
| 2209 | } | ||
| 2210 | |||
| 2211 | static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | ||
| 2212 | .destroy = radeon_enc_destroy, | ||
| 2213 | }; | ||
| 2214 | |||
| 2215 | struct radeon_encoder_atom_dac * | ||
| 2216 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | ||
| 2217 | { | ||
| 2218 | struct drm_device *dev = radeon_encoder->base.dev; | ||
| 2219 | struct radeon_device *rdev = dev->dev_private; | ||
| 2220 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | ||
| 2221 | |||
| 2222 | if (!dac) | ||
| 2223 | return NULL; | ||
| 2224 | |||
| 2225 | dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
| 2226 | return dac; | ||
| 2227 | } | ||
| 2228 | |||
| 2229 | struct radeon_encoder_atom_dig * | ||
| 2230 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | ||
| 2231 | { | ||
| 2232 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 2233 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | ||
| 2234 | |||
| 2235 | if (!dig) | ||
| 2236 | return NULL; | ||
| 2237 | |||
| 2238 | /* coherent mode by default */ | ||
| 2239 | dig->coherent_mode = true; | ||
| 2240 | dig->dig_encoder = -1; | ||
| 2241 | |||
| 2242 | if (encoder_enum == 2) | ||
| 2243 | dig->linkb = true; | ||
| 2244 | else | ||
| 2245 | dig->linkb = false; | ||
| 2246 | |||
| 2247 | return dig; | ||
| 2248 | } | ||
| 2249 | |||
| 2250 | void | ||
| 2251 | radeon_add_atom_encoder(struct drm_device *dev, | ||
| 2252 | uint32_t encoder_enum, | ||
| 2253 | uint32_t supported_device, | ||
| 2254 | u16 caps) | ||
| 2255 | { | ||
| 2256 | struct radeon_device *rdev = dev->dev_private; | ||
| 2257 | struct drm_encoder *encoder; | ||
| 2258 | struct radeon_encoder *radeon_encoder; | ||
| 2259 | |||
| 2260 | /* see if we already added it */ | ||
| 2261 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 2262 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 2263 | if (radeon_encoder->encoder_enum == encoder_enum) { | ||
| 2264 | radeon_encoder->devices |= supported_device; | ||
| 2265 | return; | ||
| 2266 | } | ||
| 2267 | |||
| 2268 | } | ||
| 2269 | |||
| 2270 | /* add a new one */ | ||
| 2271 | radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); | ||
| 2272 | if (!radeon_encoder) | ||
| 2273 | return; | ||
| 2274 | |||
| 2275 | encoder = &radeon_encoder->base; | ||
| 2276 | switch (rdev->num_crtc) { | ||
| 2277 | case 1: | ||
| 2278 | encoder->possible_crtcs = 0x1; | ||
| 2279 | break; | ||
| 2280 | case 2: | ||
| 2281 | default: | ||
| 2282 | encoder->possible_crtcs = 0x3; | ||
| 2283 | break; | ||
| 2284 | case 4: | ||
| 2285 | encoder->possible_crtcs = 0xf; | ||
| 2286 | break; | ||
| 2287 | case 6: | ||
| 2288 | encoder->possible_crtcs = 0x3f; | ||
| 2289 | break; | ||
| 2290 | } | ||
| 2291 | |||
| 2292 | radeon_encoder->enc_priv = NULL; | ||
| 2293 | |||
| 2294 | radeon_encoder->encoder_enum = encoder_enum; | ||
| 2295 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 2296 | radeon_encoder->devices = supported_device; | ||
| 2297 | radeon_encoder->rmx_type = RMX_OFF; | ||
| 2298 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | ||
| 2299 | radeon_encoder->is_ext_encoder = false; | ||
| 2300 | radeon_encoder->caps = caps; | ||
| 2301 | |||
| 2302 | switch (radeon_encoder->encoder_id) { | ||
| 2303 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 2304 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 2305 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 2306 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 2307 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 2308 | radeon_encoder->rmx_type = RMX_FULL; | ||
| 2309 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2310 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
| 2311 | } else { | ||
| 2312 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2313 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2314 | } | ||
| 2315 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
| 2316 | break; | ||
| 2317 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 2318 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2319 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
| 2320 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
| 2321 | break; | ||
| 2322 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 2323 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 2324 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 2325 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); | ||
| 2326 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
| 2327 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
| 2328 | break; | ||
| 2329 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 2330 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 2331 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 2332 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 2333 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 2334 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 2335 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 2336 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 2337 | radeon_encoder->rmx_type = RMX_FULL; | ||
| 2338 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2339 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
| 2340 | } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { | ||
| 2341 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2342 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2343 | } else { | ||
| 2344 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2345 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2346 | } | ||
| 2347 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
| 2348 | break; | ||
| 2349 | case ENCODER_OBJECT_ID_SI170B: | ||
| 2350 | case ENCODER_OBJECT_ID_CH7303: | ||
| 2351 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: | ||
| 2352 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: | ||
| 2353 | case ENCODER_OBJECT_ID_TITFP513: | ||
| 2354 | case ENCODER_OBJECT_ID_VT1623: | ||
| 2355 | case ENCODER_OBJECT_ID_HDMI_SI1930: | ||
| 2356 | case ENCODER_OBJECT_ID_TRAVIS: | ||
| 2357 | case ENCODER_OBJECT_ID_NUTMEG: | ||
| 2358 | /* these are handled by the primary encoders */ | ||
| 2359 | radeon_encoder->is_ext_encoder = true; | ||
| 2360 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 2361 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2362 | else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) | ||
| 2363 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2364 | else | ||
| 2365 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2366 | drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); | ||
| 2367 | break; | ||
| 2368 | } | ||
| 2369 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ed406e8404a3..e4c384b9511c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -353,6 +353,7 @@ void evergreen_hpd_init(struct radeon_device *rdev) | |||
| 353 | default: | 353 | default: |
| 354 | break; | 354 | break; |
| 355 | } | 355 | } |
| 356 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
| 356 | } | 357 | } |
| 357 | if (rdev->irq.installed) | 358 | if (rdev->irq.installed) |
| 358 | evergreen_irq_set(rdev); | 359 | evergreen_irq_set(rdev); |
| @@ -893,7 +894,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
| 893 | u32 tmp; | 894 | u32 tmp; |
| 894 | int r; | 895 | int r; |
| 895 | 896 | ||
| 896 | if (rdev->gart.table.vram.robj == NULL) { | 897 | if (rdev->gart.robj == NULL) { |
| 897 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 898 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 898 | return -EINVAL; | 899 | return -EINVAL; |
| 899 | } | 900 | } |
| @@ -945,7 +946,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
| 945 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) | 946 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) |
| 946 | { | 947 | { |
| 947 | u32 tmp; | 948 | u32 tmp; |
| 948 | int r; | ||
| 949 | 949 | ||
| 950 | /* Disable all tables */ | 950 | /* Disable all tables */ |
| 951 | WREG32(VM_CONTEXT0_CNTL, 0); | 951 | WREG32(VM_CONTEXT0_CNTL, 0); |
| @@ -965,14 +965,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev) | |||
| 965 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 965 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
| 966 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 966 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
| 967 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 967 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
| 968 | if (rdev->gart.table.vram.robj) { | 968 | radeon_gart_table_vram_unpin(rdev); |
| 969 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 970 | if (likely(r == 0)) { | ||
| 971 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 972 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 973 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 974 | } | ||
| 975 | } | ||
| 976 | } | 969 | } |
| 977 | 970 | ||
| 978 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) | 971 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) |
| @@ -3031,6 +3024,10 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 3031 | } | 3024 | } |
| 3032 | } | 3025 | } |
| 3033 | 3026 | ||
| 3027 | r = r600_vram_scratch_init(rdev); | ||
| 3028 | if (r) | ||
| 3029 | return r; | ||
| 3030 | |||
| 3034 | evergreen_mc_program(rdev); | 3031 | evergreen_mc_program(rdev); |
| 3035 | if (rdev->flags & RADEON_IS_AGP) { | 3032 | if (rdev->flags & RADEON_IS_AGP) { |
| 3036 | evergreen_agp_enable(rdev); | 3033 | evergreen_agp_enable(rdev); |
| @@ -3235,6 +3232,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
| 3235 | radeon_ib_pool_fini(rdev); | 3232 | radeon_ib_pool_fini(rdev); |
| 3236 | radeon_irq_kms_fini(rdev); | 3233 | radeon_irq_kms_fini(rdev); |
| 3237 | evergreen_pcie_gart_fini(rdev); | 3234 | evergreen_pcie_gart_fini(rdev); |
| 3235 | r600_vram_scratch_fini(rdev); | ||
| 3238 | radeon_gem_fini(rdev); | 3236 | radeon_gem_fini(rdev); |
| 3239 | radeon_fence_driver_fini(rdev); | 3237 | radeon_fence_driver_fini(rdev); |
| 3240 | radeon_agp_fini(rdev); | 3238 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index dcf11bbc06d9..914e5af84163 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
| @@ -94,6 +94,15 @@ cp_set_surface_sync(struct radeon_device *rdev, | |||
| 94 | else | 94 | else |
| 95 | cp_coher_size = ((size + 255) >> 8); | 95 | cp_coher_size = ((size + 255) >> 8); |
| 96 | 96 | ||
| 97 | if (rdev->family >= CHIP_CAYMAN) { | ||
| 98 | /* CP_COHER_CNTL2 has to be set manually when submitting a surface_sync | ||
| 99 | * to the RB directly. For IBs, the CP programs this as part of the | ||
| 100 | * surface_sync packet. | ||
| 101 | */ | ||
| 102 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
| 103 | radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); | ||
| 104 | radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */ | ||
| 105 | } | ||
| 97 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 106 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
| 98 | radeon_ring_write(rdev, sync_type); | 107 | radeon_ring_write(rdev, sync_type); |
| 99 | radeon_ring_write(rdev, cp_coher_size); | 108 | radeon_ring_write(rdev, cp_coher_size); |
| @@ -174,7 +183,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
| 174 | static void | 183 | static void |
| 175 | set_tex_resource(struct radeon_device *rdev, | 184 | set_tex_resource(struct radeon_device *rdev, |
| 176 | int format, int w, int h, int pitch, | 185 | int format, int w, int h, int pitch, |
| 177 | u64 gpu_addr) | 186 | u64 gpu_addr, u32 size) |
| 178 | { | 187 | { |
| 179 | u32 sq_tex_resource_word0, sq_tex_resource_word1; | 188 | u32 sq_tex_resource_word0, sq_tex_resource_word1; |
| 180 | u32 sq_tex_resource_word4, sq_tex_resource_word7; | 189 | u32 sq_tex_resource_word4, sq_tex_resource_word7; |
| @@ -196,6 +205,9 @@ set_tex_resource(struct radeon_device *rdev, | |||
| 196 | sq_tex_resource_word7 = format | | 205 | sq_tex_resource_word7 = format | |
| 197 | S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE); | 206 | S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE); |
| 198 | 207 | ||
| 208 | cp_set_surface_sync(rdev, | ||
| 209 | PACKET3_TC_ACTION_ENA, size, gpu_addr); | ||
| 210 | |||
| 199 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); | 211 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); |
| 200 | radeon_ring_write(rdev, 0); | 212 | radeon_ring_write(rdev, 0); |
| 201 | radeon_ring_write(rdev, sq_tex_resource_word0); | 213 | radeon_ring_write(rdev, sq_tex_resource_word0); |
| @@ -613,11 +625,13 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
| 613 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 625 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
| 614 | 626 | ||
| 615 | rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ | 627 | rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ |
| 616 | rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */ | 628 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ |
| 617 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 629 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
| 618 | rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */ | 630 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
| 619 | 631 | ||
| 620 | rdev->r600_blit.ring_size_per_loop = 74; | 632 | rdev->r600_blit.ring_size_per_loop = 74; |
| 633 | if (rdev->family >= CHIP_CAYMAN) | ||
| 634 | rdev->r600_blit.ring_size_per_loop += 9; /* additional DWs for surface sync */ | ||
| 621 | 635 | ||
| 622 | rdev->r600_blit.max_dim = 16384; | 636 | rdev->r600_blit.max_dim = 16384; |
| 623 | 637 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index fdb93f884575..0e5799857465 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -262,8 +262,11 @@ int ni_mc_load_microcode(struct radeon_device *rdev) | |||
| 262 | WREG32(MC_SEQ_SUP_CNTL, 0x00000001); | 262 | WREG32(MC_SEQ_SUP_CNTL, 0x00000001); |
| 263 | 263 | ||
| 264 | /* wait for training to complete */ | 264 | /* wait for training to complete */ |
| 265 | while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)) | 265 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 266 | udelay(10); | 266 | if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD) |
| 267 | break; | ||
| 268 | udelay(1); | ||
| 269 | } | ||
| 267 | 270 | ||
| 268 | if (running) | 271 | if (running) |
| 269 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); | 272 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); |
| @@ -933,7 +936,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 933 | { | 936 | { |
| 934 | int r; | 937 | int r; |
| 935 | 938 | ||
| 936 | if (rdev->gart.table.vram.robj == NULL) { | 939 | if (rdev->gart.robj == NULL) { |
| 937 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 940 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 938 | return -EINVAL; | 941 | return -EINVAL; |
| 939 | } | 942 | } |
| @@ -978,8 +981,6 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
| 978 | 981 | ||
| 979 | void cayman_pcie_gart_disable(struct radeon_device *rdev) | 982 | void cayman_pcie_gart_disable(struct radeon_device *rdev) |
| 980 | { | 983 | { |
| 981 | int r; | ||
| 982 | |||
| 983 | /* Disable all tables */ | 984 | /* Disable all tables */ |
| 984 | WREG32(VM_CONTEXT0_CNTL, 0); | 985 | WREG32(VM_CONTEXT0_CNTL, 0); |
| 985 | WREG32(VM_CONTEXT1_CNTL, 0); | 986 | WREG32(VM_CONTEXT1_CNTL, 0); |
| @@ -995,14 +996,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev) | |||
| 995 | WREG32(VM_L2_CNTL2, 0); | 996 | WREG32(VM_L2_CNTL2, 0); |
| 996 | WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | | 997 | WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | |
| 997 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); | 998 | L2_CACHE_BIGK_FRAGMENT_SIZE(6)); |
| 998 | if (rdev->gart.table.vram.robj) { | 999 | radeon_gart_table_vram_unpin(rdev); |
| 999 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 1000 | if (likely(r == 0)) { | ||
| 1001 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 1002 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 1003 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | } | 1000 | } |
| 1007 | 1001 | ||
| 1008 | void cayman_pcie_gart_fini(struct radeon_device *rdev) | 1002 | void cayman_pcie_gart_fini(struct radeon_device *rdev) |
| @@ -1362,6 +1356,10 @@ static int cayman_startup(struct radeon_device *rdev) | |||
| 1362 | return r; | 1356 | return r; |
| 1363 | } | 1357 | } |
| 1364 | 1358 | ||
| 1359 | r = r600_vram_scratch_init(rdev); | ||
| 1360 | if (r) | ||
| 1361 | return r; | ||
| 1362 | |||
| 1365 | evergreen_mc_program(rdev); | 1363 | evergreen_mc_program(rdev); |
| 1366 | r = cayman_pcie_gart_enable(rdev); | 1364 | r = cayman_pcie_gart_enable(rdev); |
| 1367 | if (r) | 1365 | if (r) |
| @@ -1557,6 +1555,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
| 1557 | radeon_ib_pool_fini(rdev); | 1555 | radeon_ib_pool_fini(rdev); |
| 1558 | radeon_irq_kms_fini(rdev); | 1556 | radeon_irq_kms_fini(rdev); |
| 1559 | cayman_pcie_gart_fini(rdev); | 1557 | cayman_pcie_gart_fini(rdev); |
| 1558 | r600_vram_scratch_fini(rdev); | ||
| 1560 | radeon_gem_fini(rdev); | 1559 | radeon_gem_fini(rdev); |
| 1561 | radeon_fence_driver_fini(rdev); | 1560 | radeon_fence_driver_fini(rdev); |
| 1562 | radeon_bo_fini(rdev); | 1561 | radeon_bo_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cbf49f4f408e..ad158ea49901 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -537,6 +537,7 @@ void r100_hpd_init(struct radeon_device *rdev) | |||
| 537 | default: | 537 | default: |
| 538 | break; | 538 | break; |
| 539 | } | 539 | } |
| 540 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
| 540 | } | 541 | } |
| 541 | if (rdev->irq.installed) | 542 | if (rdev->irq.installed) |
| 542 | r100_irq_set(rdev); | 543 | r100_irq_set(rdev); |
| @@ -577,7 +578,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
| 577 | { | 578 | { |
| 578 | int r; | 579 | int r; |
| 579 | 580 | ||
| 580 | if (rdev->gart.table.ram.ptr) { | 581 | if (rdev->gart.ptr) { |
| 581 | WARN(1, "R100 PCI GART already initialized\n"); | 582 | WARN(1, "R100 PCI GART already initialized\n"); |
| 582 | return 0; | 583 | return 0; |
| 583 | } | 584 | } |
| @@ -636,10 +637,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev) | |||
| 636 | 637 | ||
| 637 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 638 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
| 638 | { | 639 | { |
| 640 | u32 *gtt = rdev->gart.ptr; | ||
| 641 | |||
| 639 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 642 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
| 640 | return -EINVAL; | 643 | return -EINVAL; |
| 641 | } | 644 | } |
| 642 | rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr)); | 645 | gtt[i] = cpu_to_le32(lower_32_bits(addr)); |
| 643 | return 0; | 646 | return 0; |
| 644 | } | 647 | } |
| 645 | 648 | ||
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 33f2b68c680b..400b26df652a 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -74,7 +74,7 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
| 74 | 74 | ||
| 75 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 75 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
| 76 | { | 76 | { |
| 77 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 77 | void __iomem *ptr = rdev->gart.ptr; |
| 78 | 78 | ||
| 79 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 79 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
| 80 | return -EINVAL; | 80 | return -EINVAL; |
| @@ -93,7 +93,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) | |||
| 93 | { | 93 | { |
| 94 | int r; | 94 | int r; |
| 95 | 95 | ||
| 96 | if (rdev->gart.table.vram.robj) { | 96 | if (rdev->gart.robj) { |
| 97 | WARN(1, "RV370 PCIE GART already initialized\n"); | 97 | WARN(1, "RV370 PCIE GART already initialized\n"); |
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| @@ -116,7 +116,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
| 116 | uint32_t tmp; | 116 | uint32_t tmp; |
| 117 | int r; | 117 | int r; |
| 118 | 118 | ||
| 119 | if (rdev->gart.table.vram.robj == NULL) { | 119 | if (rdev->gart.robj == NULL) { |
| 120 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 120 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 121 | return -EINVAL; | 121 | return -EINVAL; |
| 122 | } | 122 | } |
| @@ -154,7 +154,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
| 154 | void rv370_pcie_gart_disable(struct radeon_device *rdev) | 154 | void rv370_pcie_gart_disable(struct radeon_device *rdev) |
| 155 | { | 155 | { |
| 156 | u32 tmp; | 156 | u32 tmp; |
| 157 | int r; | ||
| 158 | 157 | ||
| 159 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); | 158 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); |
| 160 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); | 159 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); |
| @@ -163,14 +162,7 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) | |||
| 163 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 162 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
| 164 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 163 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
| 165 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | 164 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); |
| 166 | if (rdev->gart.table.vram.robj) { | 165 | radeon_gart_table_vram_unpin(rdev); |
| 167 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 168 | if (likely(r == 0)) { | ||
| 169 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 170 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 171 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 172 | } | ||
| 173 | } | ||
| 174 | } | 166 | } |
| 175 | 167 | ||
| 176 | void rv370_pcie_gart_fini(struct radeon_device *rdev) | 168 | void rv370_pcie_gart_fini(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4e777c1e4b7b..19afc43ad173 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -763,13 +763,14 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
| 763 | struct drm_device *dev = rdev->ddev; | 763 | struct drm_device *dev = rdev->ddev; |
| 764 | struct drm_connector *connector; | 764 | struct drm_connector *connector; |
| 765 | 765 | ||
| 766 | if (ASIC_IS_DCE3(rdev)) { | 766 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 767 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | 767 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 768 | if (ASIC_IS_DCE32(rdev)) | 768 | |
| 769 | tmp |= DC_HPDx_EN; | 769 | if (ASIC_IS_DCE3(rdev)) { |
| 770 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
| 771 | if (ASIC_IS_DCE32(rdev)) | ||
| 772 | tmp |= DC_HPDx_EN; | ||
| 770 | 773 | ||
| 771 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 772 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 773 | switch (radeon_connector->hpd.hpd) { | 774 | switch (radeon_connector->hpd.hpd) { |
| 774 | case RADEON_HPD_1: | 775 | case RADEON_HPD_1: |
| 775 | WREG32(DC_HPD1_CONTROL, tmp); | 776 | WREG32(DC_HPD1_CONTROL, tmp); |
| @@ -799,10 +800,7 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
| 799 | default: | 800 | default: |
| 800 | break; | 801 | break; |
| 801 | } | 802 | } |
| 802 | } | 803 | } else { |
| 803 | } else { | ||
| 804 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 805 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 806 | switch (radeon_connector->hpd.hpd) { | 804 | switch (radeon_connector->hpd.hpd) { |
| 807 | case RADEON_HPD_1: | 805 | case RADEON_HPD_1: |
| 808 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | 806 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
| @@ -820,6 +818,7 @@ void r600_hpd_init(struct radeon_device *rdev) | |||
| 820 | break; | 818 | break; |
| 821 | } | 819 | } |
| 822 | } | 820 | } |
| 821 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
| 823 | } | 822 | } |
| 824 | if (rdev->irq.installed) | 823 | if (rdev->irq.installed) |
| 825 | r600_irq_set(rdev); | 824 | r600_irq_set(rdev); |
| @@ -897,7 +896,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
| 897 | /* flush hdp cache so updates hit vram */ | 896 | /* flush hdp cache so updates hit vram */ |
| 898 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 897 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
| 899 | !(rdev->flags & RADEON_IS_AGP)) { | 898 | !(rdev->flags & RADEON_IS_AGP)) { |
| 900 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 899 | void __iomem *ptr = (void *)rdev->gart.ptr; |
| 901 | u32 tmp; | 900 | u32 tmp; |
| 902 | 901 | ||
| 903 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 902 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
| @@ -932,7 +931,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) | |||
| 932 | { | 931 | { |
| 933 | int r; | 932 | int r; |
| 934 | 933 | ||
| 935 | if (rdev->gart.table.vram.robj) { | 934 | if (rdev->gart.robj) { |
| 936 | WARN(1, "R600 PCIE GART already initialized\n"); | 935 | WARN(1, "R600 PCIE GART already initialized\n"); |
| 937 | return 0; | 936 | return 0; |
| 938 | } | 937 | } |
| @@ -949,7 +948,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
| 949 | u32 tmp; | 948 | u32 tmp; |
| 950 | int r, i; | 949 | int r, i; |
| 951 | 950 | ||
| 952 | if (rdev->gart.table.vram.robj == NULL) { | 951 | if (rdev->gart.robj == NULL) { |
| 953 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 952 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 954 | return -EINVAL; | 953 | return -EINVAL; |
| 955 | } | 954 | } |
| @@ -1004,7 +1003,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
| 1004 | void r600_pcie_gart_disable(struct radeon_device *rdev) | 1003 | void r600_pcie_gart_disable(struct radeon_device *rdev) |
| 1005 | { | 1004 | { |
| 1006 | u32 tmp; | 1005 | u32 tmp; |
| 1007 | int i, r; | 1006 | int i; |
| 1008 | 1007 | ||
| 1009 | /* Disable all tables */ | 1008 | /* Disable all tables */ |
| 1010 | for (i = 0; i < 7; i++) | 1009 | for (i = 0; i < 7; i++) |
| @@ -1031,14 +1030,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
| 1031 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); | 1030 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); |
| 1032 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | 1031 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); |
| 1033 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | 1032 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); |
| 1034 | if (rdev->gart.table.vram.robj) { | 1033 | radeon_gart_table_vram_unpin(rdev); |
| 1035 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 1036 | if (likely(r == 0)) { | ||
| 1037 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 1038 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 1039 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 1040 | } | ||
| 1041 | } | ||
| 1042 | } | 1034 | } |
| 1043 | 1035 | ||
| 1044 | void r600_pcie_gart_fini(struct radeon_device *rdev) | 1036 | void r600_pcie_gart_fini(struct radeon_device *rdev) |
| @@ -1138,7 +1130,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
| 1138 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); | 1130 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); |
| 1139 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); | 1131 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); |
| 1140 | } | 1132 | } |
| 1141 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1133 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
| 1142 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 1134 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
| 1143 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 1135 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
| 1144 | WREG32(MC_VM_FB_LOCATION, tmp); | 1136 | WREG32(MC_VM_FB_LOCATION, tmp); |
| @@ -1277,6 +1269,53 @@ int r600_mc_init(struct radeon_device *rdev) | |||
| 1277 | return 0; | 1269 | return 0; |
| 1278 | } | 1270 | } |
| 1279 | 1271 | ||
| 1272 | int r600_vram_scratch_init(struct radeon_device *rdev) | ||
| 1273 | { | ||
| 1274 | int r; | ||
| 1275 | |||
| 1276 | if (rdev->vram_scratch.robj == NULL) { | ||
| 1277 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
| 1278 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
| 1279 | &rdev->vram_scratch.robj); | ||
| 1280 | if (r) { | ||
| 1281 | return r; | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 1286 | if (unlikely(r != 0)) | ||
| 1287 | return r; | ||
| 1288 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
| 1289 | RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr); | ||
| 1290 | if (r) { | ||
| 1291 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 1292 | return r; | ||
| 1293 | } | ||
| 1294 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
| 1295 | (void **)&rdev->vram_scratch.ptr); | ||
| 1296 | if (r) | ||
| 1297 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 1298 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 1299 | |||
| 1300 | return r; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | void r600_vram_scratch_fini(struct radeon_device *rdev) | ||
| 1304 | { | ||
| 1305 | int r; | ||
| 1306 | |||
| 1307 | if (rdev->vram_scratch.robj == NULL) { | ||
| 1308 | return; | ||
| 1309 | } | ||
| 1310 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 1311 | if (likely(r == 0)) { | ||
| 1312 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
| 1313 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 1314 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 1315 | } | ||
| 1316 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
| 1317 | } | ||
| 1318 | |||
| 1280 | /* We doesn't check that the GPU really needs a reset we simply do the | 1319 | /* We doesn't check that the GPU really needs a reset we simply do the |
| 1281 | * reset, it's up to the caller to determine if the GPU needs one. We | 1320 | * reset, it's up to the caller to determine if the GPU needs one. We |
| 1282 | * might add an helper function to check that. | 1321 | * might add an helper function to check that. |
| @@ -2332,6 +2371,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
| 2332 | if (rdev->wb.use_event) { | 2371 | if (rdev->wb.use_event) { |
| 2333 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + | 2372 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + |
| 2334 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); | 2373 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); |
| 2374 | /* flush read cache over gart */ | ||
| 2375 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | ||
| 2376 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | ||
| 2377 | PACKET3_VC_ACTION_ENA | | ||
| 2378 | PACKET3_SH_ACTION_ENA); | ||
| 2379 | radeon_ring_write(rdev, 0xFFFFFFFF); | ||
| 2380 | radeon_ring_write(rdev, 0); | ||
| 2381 | radeon_ring_write(rdev, 10); /* poll interval */ | ||
| 2335 | /* EVENT_WRITE_EOP - flush caches, send int */ | 2382 | /* EVENT_WRITE_EOP - flush caches, send int */ |
| 2336 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); | 2383 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); |
| 2337 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); | 2384 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); |
| @@ -2340,6 +2387,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev, | |||
| 2340 | radeon_ring_write(rdev, fence->seq); | 2387 | radeon_ring_write(rdev, fence->seq); |
| 2341 | radeon_ring_write(rdev, 0); | 2388 | radeon_ring_write(rdev, 0); |
| 2342 | } else { | 2389 | } else { |
| 2390 | /* flush read cache over gart */ | ||
| 2391 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | ||
| 2392 | radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | | ||
| 2393 | PACKET3_VC_ACTION_ENA | | ||
| 2394 | PACKET3_SH_ACTION_ENA); | ||
| 2395 | radeon_ring_write(rdev, 0xFFFFFFFF); | ||
| 2396 | radeon_ring_write(rdev, 0); | ||
| 2397 | radeon_ring_write(rdev, 10); /* poll interval */ | ||
| 2343 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | 2398 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); |
| 2344 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); | 2399 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); |
| 2345 | /* wait for 3D idle clean */ | 2400 | /* wait for 3D idle clean */ |
| @@ -2421,6 +2476,10 @@ int r600_startup(struct radeon_device *rdev) | |||
| 2421 | } | 2476 | } |
| 2422 | } | 2477 | } |
| 2423 | 2478 | ||
| 2479 | r = r600_vram_scratch_init(rdev); | ||
| 2480 | if (r) | ||
| 2481 | return r; | ||
| 2482 | |||
| 2424 | r600_mc_program(rdev); | 2483 | r600_mc_program(rdev); |
| 2425 | if (rdev->flags & RADEON_IS_AGP) { | 2484 | if (rdev->flags & RADEON_IS_AGP) { |
| 2426 | r600_agp_enable(rdev); | 2485 | r600_agp_enable(rdev); |
| @@ -2641,6 +2700,7 @@ void r600_fini(struct radeon_device *rdev) | |||
| 2641 | radeon_ib_pool_fini(rdev); | 2700 | radeon_ib_pool_fini(rdev); |
| 2642 | radeon_irq_kms_fini(rdev); | 2701 | radeon_irq_kms_fini(rdev); |
| 2643 | r600_pcie_gart_fini(rdev); | 2702 | r600_pcie_gart_fini(rdev); |
| 2703 | r600_vram_scratch_fini(rdev); | ||
| 2644 | radeon_agp_fini(rdev); | 2704 | radeon_agp_fini(rdev); |
| 2645 | radeon_gem_fini(rdev); | 2705 | radeon_gem_fini(rdev); |
| 2646 | radeon_fence_driver_fini(rdev); | 2706 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index c4cf1308d4a1..e09d2818f949 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -201,7 +201,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | |||
| 201 | static void | 201 | static void |
| 202 | set_tex_resource(struct radeon_device *rdev, | 202 | set_tex_resource(struct radeon_device *rdev, |
| 203 | int format, int w, int h, int pitch, | 203 | int format, int w, int h, int pitch, |
| 204 | u64 gpu_addr) | 204 | u64 gpu_addr, u32 size) |
| 205 | { | 205 | { |
| 206 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; | 206 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; |
| 207 | 207 | ||
| @@ -222,6 +222,9 @@ set_tex_resource(struct radeon_device *rdev, | |||
| 222 | S_038010_DST_SEL_Z(SQ_SEL_Z) | | 222 | S_038010_DST_SEL_Z(SQ_SEL_Z) | |
| 223 | S_038010_DST_SEL_W(SQ_SEL_W); | 223 | S_038010_DST_SEL_W(SQ_SEL_W); |
| 224 | 224 | ||
| 225 | cp_set_surface_sync(rdev, | ||
| 226 | PACKET3_TC_ACTION_ENA, size, gpu_addr); | ||
| 227 | |||
| 225 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); | 228 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); |
| 226 | radeon_ring_write(rdev, 0); | 229 | radeon_ring_write(rdev, 0); |
| 227 | radeon_ring_write(rdev, sq_tex_resource_word0); | 230 | radeon_ring_write(rdev, sq_tex_resource_word0); |
| @@ -500,9 +503,9 @@ int r600_blit_init(struct radeon_device *rdev) | |||
| 500 | rdev->r600_blit.primitives.set_default_state = set_default_state; | 503 | rdev->r600_blit.primitives.set_default_state = set_default_state; |
| 501 | 504 | ||
| 502 | rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ | 505 | rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ |
| 503 | rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */ | 506 | rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ |
| 504 | rdev->r600_blit.ring_size_common += 5; /* done copy */ | 507 | rdev->r600_blit.ring_size_common += 5; /* done copy */ |
| 505 | rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */ | 508 | rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ |
| 506 | 509 | ||
| 507 | rdev->r600_blit.ring_size_per_loop = 76; | 510 | rdev->r600_blit.ring_size_per_loop = 76; |
| 508 | /* set_render_target emits 2 extra dwords on rv6xx */ | 511 | /* set_render_target emits 2 extra dwords on rv6xx */ |
| @@ -760,10 +763,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
| 760 | vb[11] = i2f(h); | 763 | vb[11] = i2f(h); |
| 761 | 764 | ||
| 762 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, | 765 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, |
| 763 | w, h, w, src_gpu_addr); | 766 | w, h, w, src_gpu_addr, size_in_bytes); |
| 764 | rdev->r600_blit.primitives.cp_set_surface_sync(rdev, | ||
| 765 | PACKET3_TC_ACTION_ENA, | ||
| 766 | size_in_bytes, src_gpu_addr); | ||
| 767 | rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, | 767 | rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, |
| 768 | w, h, dst_gpu_addr); | 768 | w, h, dst_gpu_addr); |
| 769 | rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); | 769 | rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e3170c794c1d..b316b301152f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -93,6 +93,7 @@ extern int radeon_audio; | |||
| 93 | extern int radeon_disp_priority; | 93 | extern int radeon_disp_priority; |
| 94 | extern int radeon_hw_i2c; | 94 | extern int radeon_hw_i2c; |
| 95 | extern int radeon_pcie_gen2; | 95 | extern int radeon_pcie_gen2; |
| 96 | extern int radeon_msi; | ||
| 96 | 97 | ||
| 97 | /* | 98 | /* |
| 98 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 99 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
| @@ -306,30 +307,17 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv, | |||
| 306 | */ | 307 | */ |
| 307 | struct radeon_mc; | 308 | struct radeon_mc; |
| 308 | 309 | ||
| 309 | struct radeon_gart_table_ram { | ||
| 310 | volatile uint32_t *ptr; | ||
| 311 | }; | ||
| 312 | |||
| 313 | struct radeon_gart_table_vram { | ||
| 314 | struct radeon_bo *robj; | ||
| 315 | volatile uint32_t *ptr; | ||
| 316 | }; | ||
| 317 | |||
| 318 | union radeon_gart_table { | ||
| 319 | struct radeon_gart_table_ram ram; | ||
| 320 | struct radeon_gart_table_vram vram; | ||
| 321 | }; | ||
| 322 | |||
| 323 | #define RADEON_GPU_PAGE_SIZE 4096 | 310 | #define RADEON_GPU_PAGE_SIZE 4096 |
| 324 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) | 311 | #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) |
| 325 | #define RADEON_GPU_PAGE_SHIFT 12 | 312 | #define RADEON_GPU_PAGE_SHIFT 12 |
| 326 | 313 | ||
| 327 | struct radeon_gart { | 314 | struct radeon_gart { |
| 328 | dma_addr_t table_addr; | 315 | dma_addr_t table_addr; |
| 316 | struct radeon_bo *robj; | ||
| 317 | void *ptr; | ||
| 329 | unsigned num_gpu_pages; | 318 | unsigned num_gpu_pages; |
| 330 | unsigned num_cpu_pages; | 319 | unsigned num_cpu_pages; |
| 331 | unsigned table_size; | 320 | unsigned table_size; |
| 332 | union radeon_gart_table table; | ||
| 333 | struct page **pages; | 321 | struct page **pages; |
| 334 | dma_addr_t *pages_addr; | 322 | dma_addr_t *pages_addr; |
| 335 | bool *ttm_alloced; | 323 | bool *ttm_alloced; |
| @@ -340,6 +328,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev); | |||
| 340 | void radeon_gart_table_ram_free(struct radeon_device *rdev); | 328 | void radeon_gart_table_ram_free(struct radeon_device *rdev); |
| 341 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev); | 329 | int radeon_gart_table_vram_alloc(struct radeon_device *rdev); |
| 342 | void radeon_gart_table_vram_free(struct radeon_device *rdev); | 330 | void radeon_gart_table_vram_free(struct radeon_device *rdev); |
| 331 | int radeon_gart_table_vram_pin(struct radeon_device *rdev); | ||
| 332 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev); | ||
| 343 | int radeon_gart_init(struct radeon_device *rdev); | 333 | int radeon_gart_init(struct radeon_device *rdev); |
| 344 | void radeon_gart_fini(struct radeon_device *rdev); | 334 | void radeon_gart_fini(struct radeon_device *rdev); |
| 345 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | 335 | void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, |
| @@ -347,6 +337,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
| 347 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | 337 | int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, |
| 348 | int pages, struct page **pagelist, | 338 | int pages, struct page **pagelist, |
| 349 | dma_addr_t *dma_addr); | 339 | dma_addr_t *dma_addr); |
| 340 | void radeon_gart_restore(struct radeon_device *rdev); | ||
| 350 | 341 | ||
| 351 | 342 | ||
| 352 | /* | 343 | /* |
| @@ -437,25 +428,26 @@ union radeon_irq_stat_regs { | |||
| 437 | struct evergreen_irq_stat_regs evergreen; | 428 | struct evergreen_irq_stat_regs evergreen; |
| 438 | }; | 429 | }; |
| 439 | 430 | ||
| 431 | #define RADEON_MAX_HPD_PINS 6 | ||
| 432 | #define RADEON_MAX_CRTCS 6 | ||
| 433 | #define RADEON_MAX_HDMI_BLOCKS 2 | ||
| 434 | |||
| 440 | struct radeon_irq { | 435 | struct radeon_irq { |
| 441 | bool installed; | 436 | bool installed; |
| 442 | bool sw_int; | 437 | bool sw_int; |
| 443 | /* FIXME: use a define max crtc rather than hardcode it */ | 438 | bool crtc_vblank_int[RADEON_MAX_CRTCS]; |
| 444 | bool crtc_vblank_int[6]; | 439 | bool pflip[RADEON_MAX_CRTCS]; |
| 445 | bool pflip[6]; | ||
| 446 | wait_queue_head_t vblank_queue; | 440 | wait_queue_head_t vblank_queue; |
| 447 | /* FIXME: use defines for max hpd/dacs */ | 441 | bool hpd[RADEON_MAX_HPD_PINS]; |
| 448 | bool hpd[6]; | ||
| 449 | bool gui_idle; | 442 | bool gui_idle; |
| 450 | bool gui_idle_acked; | 443 | bool gui_idle_acked; |
| 451 | wait_queue_head_t idle_queue; | 444 | wait_queue_head_t idle_queue; |
| 452 | /* FIXME: use defines for max HDMI blocks */ | 445 | bool hdmi[RADEON_MAX_HDMI_BLOCKS]; |
| 453 | bool hdmi[2]; | ||
| 454 | spinlock_t sw_lock; | 446 | spinlock_t sw_lock; |
| 455 | int sw_refcount; | 447 | int sw_refcount; |
| 456 | union radeon_irq_stat_regs stat_regs; | 448 | union radeon_irq_stat_regs stat_regs; |
| 457 | spinlock_t pflip_lock[6]; | 449 | spinlock_t pflip_lock[RADEON_MAX_CRTCS]; |
| 458 | int pflip_refcount[6]; | 450 | int pflip_refcount[RADEON_MAX_CRTCS]; |
| 459 | }; | 451 | }; |
| 460 | 452 | ||
| 461 | int radeon_irq_kms_init(struct radeon_device *rdev); | 453 | int radeon_irq_kms_init(struct radeon_device *rdev); |
| @@ -533,7 +525,7 @@ struct r600_blit_cp_primitives { | |||
| 533 | void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr); | 525 | void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr); |
| 534 | void (*set_tex_resource)(struct radeon_device *rdev, | 526 | void (*set_tex_resource)(struct radeon_device *rdev, |
| 535 | int format, int w, int h, int pitch, | 527 | int format, int w, int h, int pitch, |
| 536 | u64 gpu_addr); | 528 | u64 gpu_addr, u32 size); |
| 537 | void (*set_scissors)(struct radeon_device *rdev, int x1, int y1, | 529 | void (*set_scissors)(struct radeon_device *rdev, int x1, int y1, |
| 538 | int x2, int y2); | 530 | int x2, int y2); |
| 539 | void (*draw_auto)(struct radeon_device *rdev); | 531 | void (*draw_auto)(struct radeon_device *rdev); |
| @@ -1143,10 +1135,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
| 1143 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1135 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
| 1144 | struct drm_file *filp); | 1136 | struct drm_file *filp); |
| 1145 | 1137 | ||
| 1146 | /* VRAM scratch page for HDP bug */ | 1138 | /* VRAM scratch page for HDP bug, default vram page */ |
| 1147 | struct r700_vram_scratch { | 1139 | struct r600_vram_scratch { |
| 1148 | struct radeon_bo *robj; | 1140 | struct radeon_bo *robj; |
| 1149 | volatile uint32_t *ptr; | 1141 | volatile uint32_t *ptr; |
| 1142 | u64 gpu_addr; | ||
| 1150 | }; | 1143 | }; |
| 1151 | 1144 | ||
| 1152 | /* | 1145 | /* |
| @@ -1218,7 +1211,7 @@ struct radeon_device { | |||
| 1218 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1211 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
| 1219 | const struct firmware *mc_fw; /* NI MC firmware */ | 1212 | const struct firmware *mc_fw; /* NI MC firmware */ |
| 1220 | struct r600_blit r600_blit; | 1213 | struct r600_blit r600_blit; |
| 1221 | struct r700_vram_scratch vram_scratch; | 1214 | struct r600_vram_scratch vram_scratch; |
| 1222 | int msi_enabled; /* msi enabled */ | 1215 | int msi_enabled; /* msi enabled */ |
| 1223 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1216 | struct r600_ih ih; /* r6/700 interrupt ring */ |
| 1224 | struct work_struct hotplug_work; | 1217 | struct work_struct hotplug_work; |
| @@ -1442,8 +1435,6 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v); | |||
| 1442 | /* AGP */ | 1435 | /* AGP */ |
| 1443 | extern int radeon_gpu_reset(struct radeon_device *rdev); | 1436 | extern int radeon_gpu_reset(struct radeon_device *rdev); |
| 1444 | extern void radeon_agp_disable(struct radeon_device *rdev); | 1437 | extern void radeon_agp_disable(struct radeon_device *rdev); |
| 1445 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | ||
| 1446 | extern void radeon_gart_restore(struct radeon_device *rdev); | ||
| 1447 | extern int radeon_modeset_init(struct radeon_device *rdev); | 1438 | extern int radeon_modeset_init(struct radeon_device *rdev); |
| 1448 | extern void radeon_modeset_fini(struct radeon_device *rdev); | 1439 | extern void radeon_modeset_fini(struct radeon_device *rdev); |
| 1449 | extern bool radeon_card_posted(struct radeon_device *rdev); | 1440 | extern bool radeon_card_posted(struct radeon_device *rdev); |
| @@ -1467,6 +1458,12 @@ extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | |||
| 1467 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | 1458 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); |
| 1468 | 1459 | ||
| 1469 | /* | 1460 | /* |
| 1461 | * R600 vram scratch functions | ||
| 1462 | */ | ||
| 1463 | int r600_vram_scratch_init(struct radeon_device *rdev); | ||
| 1464 | void r600_vram_scratch_fini(struct radeon_device *rdev); | ||
| 1465 | |||
| 1466 | /* | ||
| 1470 | * r600 functions used by radeon_encoder.c | 1467 | * r600 functions used by radeon_encoder.c |
| 1471 | */ | 1468 | */ |
| 1472 | extern void r600_hdmi_enable(struct drm_encoder *encoder); | 1469 | extern void r600_hdmi_enable(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index dec6cbe6a0a6..e7cb3ab09243 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -44,8 +44,6 @@ extern void | |||
| 44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | 44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, |
| 45 | struct drm_connector *drm_connector); | 45 | struct drm_connector *drm_connector); |
| 46 | 46 | ||
| 47 | bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); | ||
| 48 | |||
| 49 | void radeon_connector_hotplug(struct drm_connector *connector) | 47 | void radeon_connector_hotplug(struct drm_connector *connector) |
| 50 | { | 48 | { |
| 51 | struct drm_device *dev = connector->dev; | 49 | struct drm_device *dev = connector->dev; |
| @@ -432,55 +430,6 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
| 432 | return 0; | 430 | return 0; |
| 433 | } | 431 | } |
| 434 | 432 | ||
| 435 | /* | ||
| 436 | * Some integrated ATI Radeon chipset implementations (e. g. | ||
| 437 | * Asus M2A-VM HDMI) may indicate the availability of a DDC, | ||
| 438 | * even when there's no monitor connected. For these connectors | ||
| 439 | * following DDC probe extension will be applied: check also for the | ||
| 440 | * availability of EDID with at least a correct EDID header. Only then, | ||
| 441 | * DDC is assumed to be available. This prevents drm_get_edid() and | ||
| 442 | * drm_edid_block_valid() from periodically dumping data and kernel | ||
| 443 | * errors into the logs and onto the terminal. | ||
| 444 | */ | ||
| 445 | static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, | ||
| 446 | uint32_t supported_device, | ||
| 447 | int connector_type) | ||
| 448 | { | ||
| 449 | /* Asus M2A-VM HDMI board sends data to i2c bus even, | ||
| 450 | * if HDMI add-on card is not plugged in or HDMI is disabled in | ||
| 451 | * BIOS. Valid DDC can only be assumed, if also a valid EDID header | ||
| 452 | * can be retrieved via i2c bus during DDC probe */ | ||
| 453 | if ((dev->pdev->device == 0x791e) && | ||
| 454 | (dev->pdev->subsystem_vendor == 0x1043) && | ||
| 455 | (dev->pdev->subsystem_device == 0x826d)) { | ||
| 456 | if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
| 457 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
| 458 | return true; | ||
| 459 | } | ||
| 460 | /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus | ||
| 461 | * for a DVI connector that is not implemented */ | ||
| 462 | if ((dev->pdev->device == 0x796e) && | ||
| 463 | (dev->pdev->subsystem_vendor == 0x1019) && | ||
| 464 | (dev->pdev->subsystem_device == 0x2615)) { | ||
| 465 | if ((connector_type == DRM_MODE_CONNECTOR_DVID) && | ||
| 466 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | ||
| 467 | return true; | ||
| 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 | } | ||
| 479 | |||
| 480 | /* Default: no EDID header probe required for DDC probing */ | ||
| 481 | return false; | ||
| 482 | } | ||
| 483 | |||
| 484 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | 433 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, |
| 485 | struct drm_connector *connector) | 434 | struct drm_connector *connector) |
| 486 | { | 435 | { |
| @@ -721,8 +670,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
| 721 | ret = connector_status_disconnected; | 670 | ret = connector_status_disconnected; |
| 722 | 671 | ||
| 723 | if (radeon_connector->ddc_bus) | 672 | if (radeon_connector->ddc_bus) |
| 724 | dret = radeon_ddc_probe(radeon_connector, | 673 | dret = radeon_ddc_probe(radeon_connector); |
| 725 | radeon_connector->requires_extended_probe); | ||
| 726 | if (dret) { | 674 | if (dret) { |
| 727 | radeon_connector->detected_by_load = false; | 675 | radeon_connector->detected_by_load = false; |
| 728 | if (radeon_connector->edid) { | 676 | if (radeon_connector->edid) { |
| @@ -764,7 +712,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
| 764 | if (radeon_connector->dac_load_detect && encoder) { | 712 | if (radeon_connector->dac_load_detect && encoder) { |
| 765 | encoder_funcs = encoder->helper_private; | 713 | encoder_funcs = encoder->helper_private; |
| 766 | ret = encoder_funcs->detect(encoder, connector); | 714 | ret = encoder_funcs->detect(encoder, connector); |
| 767 | if (ret == connector_status_connected) | 715 | if (ret != connector_status_disconnected) |
| 768 | radeon_connector->detected_by_load = true; | 716 | radeon_connector->detected_by_load = true; |
| 769 | } | 717 | } |
| 770 | } | 718 | } |
| @@ -904,8 +852,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 904 | bool dret = false; | 852 | bool dret = false; |
| 905 | 853 | ||
| 906 | if (radeon_connector->ddc_bus) | 854 | if (radeon_connector->ddc_bus) |
| 907 | dret = radeon_ddc_probe(radeon_connector, | 855 | dret = radeon_ddc_probe(radeon_connector); |
| 908 | radeon_connector->requires_extended_probe); | ||
| 909 | if (dret) { | 856 | if (dret) { |
| 910 | radeon_connector->detected_by_load = false; | 857 | radeon_connector->detected_by_load = false; |
| 911 | if (radeon_connector->edid) { | 858 | if (radeon_connector->edid) { |
| @@ -1005,8 +952,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1005 | ret = encoder_funcs->detect(encoder, connector); | 952 | ret = encoder_funcs->detect(encoder, connector); |
| 1006 | if (ret == connector_status_connected) { | 953 | if (ret == connector_status_connected) { |
| 1007 | radeon_connector->use_digital = false; | 954 | radeon_connector->use_digital = false; |
| 1008 | radeon_connector->detected_by_load = true; | ||
| 1009 | } | 955 | } |
| 956 | if (ret != connector_status_disconnected) | ||
| 957 | radeon_connector->detected_by_load = true; | ||
| 1010 | } | 958 | } |
| 1011 | break; | 959 | break; |
| 1012 | } | 960 | } |
| @@ -1203,7 +1151,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 1203 | } | 1151 | } |
| 1204 | } else { | 1152 | } else { |
| 1205 | /* need to setup ddc on the bridge */ | 1153 | /* need to setup ddc on the bridge */ |
| 1206 | if (radeon_connector_encoder_is_dp_bridge(connector)) { | 1154 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != |
| 1155 | ENCODER_OBJECT_ID_NONE) { | ||
| 1207 | if (encoder) | 1156 | if (encoder) |
| 1208 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1157 | radeon_atom_ext_encoder_setup_ddc(encoder); |
| 1209 | } | 1158 | } |
| @@ -1213,13 +1162,12 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 1213 | return ret; | 1162 | return ret; |
| 1214 | } | 1163 | } |
| 1215 | 1164 | ||
| 1216 | bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) | 1165 | u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector) |
| 1217 | { | 1166 | { |
| 1218 | struct drm_mode_object *obj; | 1167 | struct drm_mode_object *obj; |
| 1219 | struct drm_encoder *encoder; | 1168 | struct drm_encoder *encoder; |
| 1220 | struct radeon_encoder *radeon_encoder; | 1169 | struct radeon_encoder *radeon_encoder; |
| 1221 | int i; | 1170 | int i; |
| 1222 | bool found = false; | ||
| 1223 | 1171 | ||
| 1224 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 1172 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
| 1225 | if (connector->encoder_ids[i] == 0) | 1173 | if (connector->encoder_ids[i] == 0) |
| @@ -1235,14 +1183,13 @@ bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) | |||
| 1235 | switch (radeon_encoder->encoder_id) { | 1183 | switch (radeon_encoder->encoder_id) { |
| 1236 | case ENCODER_OBJECT_ID_TRAVIS: | 1184 | case ENCODER_OBJECT_ID_TRAVIS: |
| 1237 | case ENCODER_OBJECT_ID_NUTMEG: | 1185 | case ENCODER_OBJECT_ID_NUTMEG: |
| 1238 | found = true; | 1186 | return radeon_encoder->encoder_id; |
| 1239 | break; | ||
| 1240 | default: | 1187 | default: |
| 1241 | break; | 1188 | break; |
| 1242 | } | 1189 | } |
| 1243 | } | 1190 | } |
| 1244 | 1191 | ||
| 1245 | return found; | 1192 | return ENCODER_OBJECT_ID_NONE; |
| 1246 | } | 1193 | } |
| 1247 | 1194 | ||
| 1248 | bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) | 1195 | bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) |
| @@ -1319,7 +1266,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1319 | if (!radeon_dig_connector->edp_on) | 1266 | if (!radeon_dig_connector->edp_on) |
| 1320 | atombios_set_edp_panel_power(connector, | 1267 | atombios_set_edp_panel_power(connector, |
| 1321 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1268 | ATOM_TRANSMITTER_ACTION_POWER_OFF); |
| 1322 | } else if (radeon_connector_encoder_is_dp_bridge(connector)) { | 1269 | } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != |
| 1270 | ENCODER_OBJECT_ID_NONE) { | ||
| 1323 | /* DP bridges are always DP */ | 1271 | /* DP bridges are always DP */ |
| 1324 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; | 1272 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
| 1325 | /* get the DPCD from the bridge */ | 1273 | /* get the DPCD from the bridge */ |
| @@ -1328,8 +1276,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1328 | if (encoder) { | 1276 | if (encoder) { |
| 1329 | /* setup ddc on the bridge */ | 1277 | /* setup ddc on the bridge */ |
| 1330 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1278 | radeon_atom_ext_encoder_setup_ddc(encoder); |
| 1331 | if (radeon_ddc_probe(radeon_connector, | 1279 | if (radeon_ddc_probe(radeon_connector)) /* try DDC */ |
| 1332 | radeon_connector->requires_extended_probe)) /* try DDC */ | ||
| 1333 | ret = connector_status_connected; | 1280 | ret = connector_status_connected; |
| 1334 | else if (radeon_connector->dac_load_detect) { /* try load detection */ | 1281 | else if (radeon_connector->dac_load_detect) { /* try load detection */ |
| 1335 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 1282 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
| @@ -1347,8 +1294,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1347 | if (radeon_dp_getdpcd(radeon_connector)) | 1294 | if (radeon_dp_getdpcd(radeon_connector)) |
| 1348 | ret = connector_status_connected; | 1295 | ret = connector_status_connected; |
| 1349 | } else { | 1296 | } else { |
| 1350 | if (radeon_ddc_probe(radeon_connector, | 1297 | if (radeon_ddc_probe(radeon_connector)) |
| 1351 | radeon_connector->requires_extended_probe)) | ||
| 1352 | ret = connector_status_connected; | 1298 | ret = connector_status_connected; |
| 1353 | } | 1299 | } |
| 1354 | } | 1300 | } |
| @@ -1493,9 +1439,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1493 | radeon_connector->shared_ddc = shared_ddc; | 1439 | radeon_connector->shared_ddc = shared_ddc; |
| 1494 | radeon_connector->connector_object_id = connector_object_id; | 1440 | radeon_connector->connector_object_id = connector_object_id; |
| 1495 | radeon_connector->hpd = *hpd; | 1441 | radeon_connector->hpd = *hpd; |
| 1496 | radeon_connector->requires_extended_probe = | 1442 | |
| 1497 | radeon_connector_needs_extended_probe(rdev, supported_device, | ||
| 1498 | connector_type); | ||
| 1499 | radeon_connector->router = *router; | 1443 | radeon_connector->router = *router; |
| 1500 | if (router->ddc_valid || router->cd_valid) { | 1444 | if (router->ddc_valid || router->cd_valid) { |
| 1501 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); | 1445 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
| @@ -1842,9 +1786,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1842 | radeon_connector->devices = supported_device; | 1786 | radeon_connector->devices = supported_device; |
| 1843 | radeon_connector->connector_object_id = connector_object_id; | 1787 | radeon_connector->connector_object_id = connector_object_id; |
| 1844 | radeon_connector->hpd = *hpd; | 1788 | radeon_connector->hpd = *hpd; |
| 1845 | radeon_connector->requires_extended_probe = | 1789 | |
| 1846 | radeon_connector_needs_extended_probe(rdev, supported_device, | ||
| 1847 | connector_type); | ||
| 1848 | switch (connector_type) { | 1790 | switch (connector_type) { |
| 1849 | case DRM_MODE_CONNECTOR_VGA: | 1791 | case DRM_MODE_CONNECTOR_VGA: |
| 1850 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1792 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 6adb3e58affd..a22d6e6a49a2 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -33,8 +33,6 @@ | |||
| 33 | #include "drm_crtc_helper.h" | 33 | #include "drm_crtc_helper.h" |
| 34 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
| 35 | 35 | ||
| 36 | static int radeon_ddc_dump(struct drm_connector *connector); | ||
| 37 | |||
| 38 | static void avivo_crtc_load_lut(struct drm_crtc *crtc) | 36 | static void avivo_crtc_load_lut(struct drm_crtc *crtc) |
| 39 | { | 37 | { |
| 40 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 38 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| @@ -669,7 +667,6 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
| 669 | static bool radeon_setup_enc_conn(struct drm_device *dev) | 667 | static bool radeon_setup_enc_conn(struct drm_device *dev) |
| 670 | { | 668 | { |
| 671 | struct radeon_device *rdev = dev->dev_private; | 669 | struct radeon_device *rdev = dev->dev_private; |
| 672 | struct drm_connector *drm_connector; | ||
| 673 | bool ret = false; | 670 | bool ret = false; |
| 674 | 671 | ||
| 675 | if (rdev->bios) { | 672 | if (rdev->bios) { |
| @@ -689,8 +686,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
| 689 | if (ret) { | 686 | if (ret) { |
| 690 | radeon_setup_encoder_clones(dev); | 687 | radeon_setup_encoder_clones(dev); |
| 691 | radeon_print_display_setup(dev); | 688 | radeon_print_display_setup(dev); |
| 692 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) | ||
| 693 | radeon_ddc_dump(drm_connector); | ||
| 694 | } | 689 | } |
| 695 | 690 | ||
| 696 | return ret; | 691 | return ret; |
| @@ -708,7 +703,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 708 | 703 | ||
| 709 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 704 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || |
| 710 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || | 705 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || |
| 711 | radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) { | 706 | (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != |
| 707 | ENCODER_OBJECT_ID_NONE)) { | ||
| 712 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 708 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
| 713 | 709 | ||
| 714 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || | 710 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || |
| @@ -743,34 +739,6 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 743 | return 0; | 739 | return 0; |
| 744 | } | 740 | } |
| 745 | 741 | ||
| 746 | static int radeon_ddc_dump(struct drm_connector *connector) | ||
| 747 | { | ||
| 748 | struct edid *edid; | ||
| 749 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 750 | int ret = 0; | ||
| 751 | |||
| 752 | /* on hw with routers, select right port */ | ||
| 753 | if (radeon_connector->router.ddc_valid) | ||
| 754 | radeon_router_select_ddc_port(radeon_connector); | ||
| 755 | |||
| 756 | if (!radeon_connector->ddc_bus) | ||
| 757 | return -1; | ||
| 758 | edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); | ||
| 759 | /* Log EDID retrieval status here. In particular with regard to | ||
| 760 | * connectors with requires_extended_probe flag set, that will prevent | ||
| 761 | * function radeon_dvi_detect() to fetch EDID on this connector, | ||
| 762 | * as long as there is no valid EDID header found */ | ||
| 763 | if (edid) { | ||
| 764 | DRM_INFO("Radeon display connector %s: Found valid EDID", | ||
| 765 | drm_get_connector_name(connector)); | ||
| 766 | kfree(edid); | ||
| 767 | } else { | ||
| 768 | DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", | ||
| 769 | drm_get_connector_name(connector)); | ||
| 770 | } | ||
| 771 | return ret; | ||
| 772 | } | ||
| 773 | |||
| 774 | /* avivo */ | 742 | /* avivo */ |
| 775 | static void avivo_get_fb_div(struct radeon_pll *pll, | 743 | static void avivo_get_fb_div(struct radeon_pll *pll, |
| 776 | u32 target_clock, | 744 | u32 target_clock, |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 969933833ccb..a0b35e909489 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -119,6 +119,7 @@ int radeon_audio = 0; | |||
| 119 | int radeon_disp_priority = 0; | 119 | int radeon_disp_priority = 0; |
| 120 | int radeon_hw_i2c = 0; | 120 | int radeon_hw_i2c = 0; |
| 121 | int radeon_pcie_gen2 = 0; | 121 | int radeon_pcie_gen2 = 0; |
| 122 | int radeon_msi = -1; | ||
| 122 | 123 | ||
| 123 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 124 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
| 124 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 125 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
| @@ -165,6 +166,9 @@ module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); | |||
| 165 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); | 166 | MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); |
| 166 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); | 167 | module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); |
| 167 | 168 | ||
| 169 | MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); | ||
| 170 | module_param_named(msi, radeon_msi, int, 0444); | ||
| 171 | |||
| 168 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) | 172 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) |
| 169 | { | 173 | { |
| 170 | drm_radeon_private_t *dev_priv = dev->dev_private; | 174 | drm_radeon_private_t *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index eb3f6dc6df83..06e413e6a920 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -29,12 +29,6 @@ | |||
| 29 | #include "radeon.h" | 29 | #include "radeon.h" |
| 30 | #include "atom.h" | 30 | #include "atom.h" |
| 31 | 31 | ||
| 32 | extern int atom_debug; | ||
| 33 | |||
| 34 | /* evil but including atombios.h is much worse */ | ||
| 35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
| 36 | struct drm_display_mode *mode); | ||
| 37 | |||
| 38 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | 32 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) |
| 39 | { | 33 | { |
| 40 | struct drm_device *dev = encoder->dev; | 34 | struct drm_device *dev = encoder->dev; |
| @@ -156,27 +150,6 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8 | |||
| 156 | return ret; | 150 | return ret; |
| 157 | } | 151 | } |
| 158 | 152 | ||
| 159 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
| 160 | { | ||
| 161 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 162 | switch (radeon_encoder->encoder_id) { | ||
| 163 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 164 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 165 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 166 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 167 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 168 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 169 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 170 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 171 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 172 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 173 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 174 | return true; | ||
| 175 | default: | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | void | 153 | void |
| 181 | radeon_link_encoder_connector(struct drm_device *dev) | 154 | radeon_link_encoder_connector(struct drm_device *dev) |
| 182 | { | 155 | { |
| @@ -229,23 +202,7 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
| 229 | return NULL; | 202 | return NULL; |
| 230 | } | 203 | } |
| 231 | 204 | ||
| 232 | static struct drm_connector * | 205 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) |
| 233 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 234 | { | ||
| 235 | struct drm_device *dev = encoder->dev; | ||
| 236 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 237 | struct drm_connector *connector; | ||
| 238 | struct radeon_connector *radeon_connector; | ||
| 239 | |||
| 240 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 241 | radeon_connector = to_radeon_connector(connector); | ||
| 242 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 243 | return connector; | ||
| 244 | } | ||
| 245 | return NULL; | ||
| 246 | } | ||
| 247 | |||
| 248 | struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) | ||
| 249 | { | 206 | { |
| 250 | struct drm_device *dev = encoder->dev; | 207 | struct drm_device *dev = encoder->dev; |
| 251 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 208 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| @@ -266,9 +223,9 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder | |||
| 266 | return NULL; | 223 | return NULL; |
| 267 | } | 224 | } |
| 268 | 225 | ||
| 269 | bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder) | 226 | u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) |
| 270 | { | 227 | { |
| 271 | struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder); | 228 | struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder); |
| 272 | 229 | ||
| 273 | if (other_encoder) { | 230 | if (other_encoder) { |
| 274 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); | 231 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); |
| @@ -332,2105 +289,3 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
| 332 | 289 | ||
| 333 | } | 290 | } |
| 334 | 291 | ||
| 335 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | ||
| 336 | struct drm_display_mode *mode, | ||
| 337 | struct drm_display_mode *adjusted_mode) | ||
| 338 | { | ||
| 339 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 340 | struct drm_device *dev = encoder->dev; | ||
| 341 | struct radeon_device *rdev = dev->dev_private; | ||
| 342 | |||
| 343 | /* set the active encoder to connector routing */ | ||
| 344 | radeon_encoder_set_active_device(encoder); | ||
| 345 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 346 | |||
| 347 | /* hw bug */ | ||
| 348 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 349 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | ||
| 350 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | ||
| 351 | |||
| 352 | /* get the native mode for LVDS */ | ||
| 353 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 354 | radeon_panel_mode_fixup(encoder, adjusted_mode); | ||
| 355 | |||
| 356 | /* get the native mode for TV */ | ||
| 357 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
| 358 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
| 359 | if (tv_dac) { | ||
| 360 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
| 361 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
| 362 | tv_dac->tv_std == TV_STD_PAL_M) | ||
| 363 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
| 364 | else | ||
| 365 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | if (ASIC_IS_DCE3(rdev) && | ||
| 370 | ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
| 371 | radeon_encoder_is_dp_bridge(encoder))) { | ||
| 372 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 373 | radeon_dp_set_link_config(connector, mode); | ||
| 374 | } | ||
| 375 | |||
| 376 | return true; | ||
| 377 | } | ||
| 378 | |||
| 379 | static void | ||
| 380 | atombios_dac_setup(struct drm_encoder *encoder, int action) | ||
| 381 | { | ||
| 382 | struct drm_device *dev = encoder->dev; | ||
| 383 | struct radeon_device *rdev = dev->dev_private; | ||
| 384 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 385 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | ||
| 386 | int index = 0; | ||
| 387 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
| 388 | |||
| 389 | memset(&args, 0, sizeof(args)); | ||
| 390 | |||
| 391 | switch (radeon_encoder->encoder_id) { | ||
| 392 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 393 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 394 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | ||
| 395 | break; | ||
| 396 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 397 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 398 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | ||
| 399 | break; | ||
| 400 | } | ||
| 401 | |||
| 402 | args.ucAction = action; | ||
| 403 | |||
| 404 | if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) | ||
| 405 | args.ucDacStandard = ATOM_DAC1_PS2; | ||
| 406 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 407 | args.ucDacStandard = ATOM_DAC1_CV; | ||
| 408 | else { | ||
| 409 | switch (dac_info->tv_std) { | ||
| 410 | case TV_STD_PAL: | ||
| 411 | case TV_STD_PAL_M: | ||
| 412 | case TV_STD_SCART_PAL: | ||
| 413 | case TV_STD_SECAM: | ||
| 414 | case TV_STD_PAL_CN: | ||
| 415 | args.ucDacStandard = ATOM_DAC1_PAL; | ||
| 416 | break; | ||
| 417 | case TV_STD_NTSC: | ||
| 418 | case TV_STD_NTSC_J: | ||
| 419 | case TV_STD_PAL_60: | ||
| 420 | default: | ||
| 421 | args.ucDacStandard = ATOM_DAC1_NTSC; | ||
| 422 | break; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 426 | |||
| 427 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 428 | |||
| 429 | } | ||
| 430 | |||
| 431 | static void | ||
| 432 | atombios_tv_setup(struct drm_encoder *encoder, int action) | ||
| 433 | { | ||
| 434 | struct drm_device *dev = encoder->dev; | ||
| 435 | struct radeon_device *rdev = dev->dev_private; | ||
| 436 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 437 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | ||
| 438 | int index = 0; | ||
| 439 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | ||
| 440 | |||
| 441 | memset(&args, 0, sizeof(args)); | ||
| 442 | |||
| 443 | index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); | ||
| 444 | |||
| 445 | args.sTVEncoder.ucAction = action; | ||
| 446 | |||
| 447 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 448 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | ||
| 449 | else { | ||
| 450 | switch (dac_info->tv_std) { | ||
| 451 | case TV_STD_NTSC: | ||
| 452 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
| 453 | break; | ||
| 454 | case TV_STD_PAL: | ||
| 455 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; | ||
| 456 | break; | ||
| 457 | case TV_STD_PAL_M: | ||
| 458 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; | ||
| 459 | break; | ||
| 460 | case TV_STD_PAL_60: | ||
| 461 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; | ||
| 462 | break; | ||
| 463 | case TV_STD_NTSC_J: | ||
| 464 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; | ||
| 465 | break; | ||
| 466 | case TV_STD_SCART_PAL: | ||
| 467 | args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ | ||
| 468 | break; | ||
| 469 | case TV_STD_SECAM: | ||
| 470 | args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; | ||
| 471 | break; | ||
| 472 | case TV_STD_PAL_CN: | ||
| 473 | args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; | ||
| 474 | break; | ||
| 475 | default: | ||
| 476 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 482 | |||
| 483 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 484 | |||
| 485 | } | ||
| 486 | |||
| 487 | union dvo_encoder_control { | ||
| 488 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; | ||
| 489 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; | ||
| 490 | DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; | ||
| 491 | }; | ||
| 492 | |||
| 493 | void | ||
| 494 | atombios_dvo_setup(struct drm_encoder *encoder, int action) | ||
| 495 | { | ||
| 496 | struct drm_device *dev = encoder->dev; | ||
| 497 | struct radeon_device *rdev = dev->dev_private; | ||
| 498 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 499 | union dvo_encoder_control args; | ||
| 500 | int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); | ||
| 501 | |||
| 502 | memset(&args, 0, sizeof(args)); | ||
| 503 | |||
| 504 | if (ASIC_IS_DCE3(rdev)) { | ||
| 505 | /* DCE3+ */ | ||
| 506 | args.dvo_v3.ucAction = action; | ||
| 507 | args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 508 | args.dvo_v3.ucDVOConfig = 0; /* XXX */ | ||
| 509 | } else if (ASIC_IS_DCE2(rdev)) { | ||
| 510 | /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */ | ||
| 511 | args.dvo.sDVOEncoder.ucAction = action; | ||
| 512 | args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 513 | /* DFP1, CRT1, TV1 depending on the type of port */ | ||
| 514 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | ||
| 515 | |||
| 516 | if (radeon_encoder->pixel_clock > 165000) | ||
| 517 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | ||
| 518 | } else { | ||
| 519 | /* R4xx, R5xx */ | ||
| 520 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | ||
| 521 | |||
| 522 | if (radeon_encoder->pixel_clock > 165000) | ||
| 523 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 524 | |||
| 525 | /*if (pScrn->rgbBits == 8)*/ | ||
| 526 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 527 | } | ||
| 528 | |||
| 529 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 530 | } | ||
| 531 | |||
| 532 | union lvds_encoder_control { | ||
| 533 | LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 534 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | ||
| 535 | }; | ||
| 536 | |||
| 537 | void | ||
| 538 | atombios_digital_setup(struct drm_encoder *encoder, int action) | ||
| 539 | { | ||
| 540 | struct drm_device *dev = encoder->dev; | ||
| 541 | struct radeon_device *rdev = dev->dev_private; | ||
| 542 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 543 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 544 | union lvds_encoder_control args; | ||
| 545 | int index = 0; | ||
| 546 | int hdmi_detected = 0; | ||
| 547 | uint8_t frev, crev; | ||
| 548 | |||
| 549 | if (!dig) | ||
| 550 | return; | ||
| 551 | |||
| 552 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
| 553 | hdmi_detected = 1; | ||
| 554 | |||
| 555 | memset(&args, 0, sizeof(args)); | ||
| 556 | |||
| 557 | switch (radeon_encoder->encoder_id) { | ||
| 558 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 559 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
| 560 | break; | ||
| 561 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 562 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 563 | index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); | ||
| 564 | break; | ||
| 565 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 566 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 567 | index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); | ||
| 568 | else | ||
| 569 | index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); | ||
| 570 | break; | ||
| 571 | } | ||
| 572 | |||
| 573 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 574 | return; | ||
| 575 | |||
| 576 | switch (frev) { | ||
| 577 | case 1: | ||
| 578 | case 2: | ||
| 579 | switch (crev) { | ||
| 580 | case 1: | ||
| 581 | args.v1.ucMisc = 0; | ||
| 582 | args.v1.ucAction = action; | ||
| 583 | if (hdmi_detected) | ||
| 584 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
| 585 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 586 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 587 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
| 588 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 589 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 590 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 591 | } else { | ||
| 592 | if (dig->linkb) | ||
| 593 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
| 594 | if (radeon_encoder->pixel_clock > 165000) | ||
| 595 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 596 | /*if (pScrn->rgbBits == 8) */ | ||
| 597 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | ||
| 598 | } | ||
| 599 | break; | ||
| 600 | case 2: | ||
| 601 | case 3: | ||
| 602 | args.v2.ucMisc = 0; | ||
| 603 | args.v2.ucAction = action; | ||
| 604 | if (crev == 3) { | ||
| 605 | if (dig->coherent_mode) | ||
| 606 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | ||
| 607 | } | ||
| 608 | if (hdmi_detected) | ||
| 609 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | ||
| 610 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 611 | args.v2.ucTruncate = 0; | ||
| 612 | args.v2.ucSpatial = 0; | ||
| 613 | args.v2.ucTemporal = 0; | ||
| 614 | args.v2.ucFRC = 0; | ||
| 615 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 616 | if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) | ||
| 617 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 618 | if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { | ||
| 619 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | ||
| 620 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 621 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | ||
| 622 | } | ||
| 623 | if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { | ||
| 624 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | ||
| 625 | if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) | ||
| 626 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | ||
| 627 | if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) | ||
| 628 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | ||
| 629 | } | ||
| 630 | } else { | ||
| 631 | if (dig->linkb) | ||
| 632 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | ||
| 633 | if (radeon_encoder->pixel_clock > 165000) | ||
| 634 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | ||
| 635 | } | ||
| 636 | break; | ||
| 637 | default: | ||
| 638 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 639 | break; | ||
| 640 | } | ||
| 641 | break; | ||
| 642 | default: | ||
| 643 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
| 644 | break; | ||
| 645 | } | ||
| 646 | |||
| 647 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 648 | } | ||
| 649 | |||
| 650 | int | ||
| 651 | atombios_get_encoder_mode(struct drm_encoder *encoder) | ||
| 652 | { | ||
| 653 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 654 | struct drm_device *dev = encoder->dev; | ||
| 655 | struct radeon_device *rdev = dev->dev_private; | ||
| 656 | struct drm_connector *connector; | ||
| 657 | struct radeon_connector *radeon_connector; | ||
| 658 | struct radeon_connector_atom_dig *dig_connector; | ||
| 659 | |||
| 660 | /* dp bridges are always DP */ | ||
| 661 | if (radeon_encoder_is_dp_bridge(encoder)) | ||
| 662 | return ATOM_ENCODER_MODE_DP; | ||
| 663 | |||
| 664 | /* DVO is always DVO */ | ||
| 665 | if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) | ||
| 666 | return ATOM_ENCODER_MODE_DVO; | ||
| 667 | |||
| 668 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 669 | /* if we don't have an active device yet, just use one of | ||
| 670 | * the connectors tied to the encoder. | ||
| 671 | */ | ||
| 672 | if (!connector) | ||
| 673 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 674 | radeon_connector = to_radeon_connector(connector); | ||
| 675 | |||
| 676 | switch (connector->connector_type) { | ||
| 677 | case DRM_MODE_CONNECTOR_DVII: | ||
| 678 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | ||
| 679 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 680 | /* fix me */ | ||
| 681 | if (ASIC_IS_DCE4(rdev)) | ||
| 682 | return ATOM_ENCODER_MODE_DVI; | ||
| 683 | else | ||
| 684 | return ATOM_ENCODER_MODE_HDMI; | ||
| 685 | } else if (radeon_connector->use_digital) | ||
| 686 | return ATOM_ENCODER_MODE_DVI; | ||
| 687 | else | ||
| 688 | return ATOM_ENCODER_MODE_CRT; | ||
| 689 | break; | ||
| 690 | case DRM_MODE_CONNECTOR_DVID: | ||
| 691 | case DRM_MODE_CONNECTOR_HDMIA: | ||
| 692 | default: | ||
| 693 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 694 | /* fix me */ | ||
| 695 | if (ASIC_IS_DCE4(rdev)) | ||
| 696 | return ATOM_ENCODER_MODE_DVI; | ||
| 697 | else | ||
| 698 | return ATOM_ENCODER_MODE_HDMI; | ||
| 699 | } else | ||
| 700 | return ATOM_ENCODER_MODE_DVI; | ||
| 701 | break; | ||
| 702 | case DRM_MODE_CONNECTOR_LVDS: | ||
| 703 | return ATOM_ENCODER_MODE_LVDS; | ||
| 704 | break; | ||
| 705 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
| 706 | dig_connector = radeon_connector->con_priv; | ||
| 707 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
| 708 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
| 709 | return ATOM_ENCODER_MODE_DP; | ||
| 710 | else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | ||
| 711 | /* fix me */ | ||
| 712 | if (ASIC_IS_DCE4(rdev)) | ||
| 713 | return ATOM_ENCODER_MODE_DVI; | ||
| 714 | else | ||
| 715 | return ATOM_ENCODER_MODE_HDMI; | ||
| 716 | } else | ||
| 717 | return ATOM_ENCODER_MODE_DVI; | ||
| 718 | break; | ||
| 719 | case DRM_MODE_CONNECTOR_eDP: | ||
| 720 | return ATOM_ENCODER_MODE_DP; | ||
| 721 | case DRM_MODE_CONNECTOR_DVIA: | ||
| 722 | case DRM_MODE_CONNECTOR_VGA: | ||
| 723 | return ATOM_ENCODER_MODE_CRT; | ||
| 724 | break; | ||
| 725 | case DRM_MODE_CONNECTOR_Composite: | ||
| 726 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
| 727 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
| 728 | /* fix me */ | ||
| 729 | return ATOM_ENCODER_MODE_TV; | ||
| 730 | /*return ATOM_ENCODER_MODE_CV;*/ | ||
| 731 | break; | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | /* | ||
| 736 | * DIG Encoder/Transmitter Setup | ||
| 737 | * | ||
| 738 | * DCE 3.0/3.1 | ||
| 739 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
| 740 | * Supports up to 3 digital outputs | ||
| 741 | * - 2 DIG encoder blocks. | ||
| 742 | * DIG1 can drive UNIPHY link A or link B | ||
| 743 | * DIG2 can drive UNIPHY link B or LVTMA | ||
| 744 | * | ||
| 745 | * DCE 3.2 | ||
| 746 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
| 747 | * Supports up to 5 digital outputs | ||
| 748 | * - 2 DIG encoder blocks. | ||
| 749 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 750 | * | ||
| 751 | * DCE 4.0/5.0 | ||
| 752 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
| 753 | * Supports up to 6 digital outputs | ||
| 754 | * - 6 DIG encoder blocks. | ||
| 755 | * - DIG to PHY mapping is hardcoded | ||
| 756 | * DIG1 drives UNIPHY0 link A, A+B | ||
| 757 | * DIG2 drives UNIPHY0 link B | ||
| 758 | * DIG3 drives UNIPHY1 link A, A+B | ||
| 759 | * DIG4 drives UNIPHY1 link B | ||
| 760 | * DIG5 drives UNIPHY2 link A, A+B | ||
| 761 | * DIG6 drives UNIPHY2 link B | ||
| 762 | * | ||
| 763 | * DCE 4.1 | ||
| 764 | * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). | ||
| 765 | * Supports up to 6 digital outputs | ||
| 766 | * - 2 DIG encoder blocks. | ||
| 767 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 768 | * | ||
| 769 | * Routing | ||
| 770 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
| 771 | * Examples: | ||
| 772 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
| 773 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
| 774 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
| 775 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
| 776 | */ | ||
| 777 | |||
| 778 | union dig_encoder_control { | ||
| 779 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 780 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
| 781 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
| 782 | DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; | ||
| 783 | }; | ||
| 784 | |||
| 785 | void | ||
| 786 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) | ||
| 787 | { | ||
| 788 | struct drm_device *dev = encoder->dev; | ||
| 789 | struct radeon_device *rdev = dev->dev_private; | ||
| 790 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 791 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 792 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 793 | union dig_encoder_control args; | ||
| 794 | int index = 0; | ||
| 795 | uint8_t frev, crev; | ||
| 796 | int dp_clock = 0; | ||
| 797 | int dp_lane_count = 0; | ||
| 798 | int hpd_id = RADEON_HPD_NONE; | ||
| 799 | int bpc = 8; | ||
| 800 | |||
| 801 | if (connector) { | ||
| 802 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 803 | struct radeon_connector_atom_dig *dig_connector = | ||
| 804 | radeon_connector->con_priv; | ||
| 805 | |||
| 806 | dp_clock = dig_connector->dp_clock; | ||
| 807 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 808 | hpd_id = radeon_connector->hpd.hpd; | ||
| 809 | bpc = connector->display_info.bpc; | ||
| 810 | } | ||
| 811 | |||
| 812 | /* no dig encoder assigned */ | ||
| 813 | if (dig->dig_encoder == -1) | ||
| 814 | return; | ||
| 815 | |||
| 816 | memset(&args, 0, sizeof(args)); | ||
| 817 | |||
| 818 | if (ASIC_IS_DCE4(rdev)) | ||
| 819 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); | ||
| 820 | else { | ||
| 821 | if (dig->dig_encoder) | ||
| 822 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
| 823 | else | ||
| 824 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
| 825 | } | ||
| 826 | |||
| 827 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 828 | return; | ||
| 829 | |||
| 830 | args.v1.ucAction = action; | ||
| 831 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 832 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) | ||
| 833 | args.v3.ucPanelMode = panel_mode; | ||
| 834 | else | ||
| 835 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 836 | |||
| 837 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | ||
| 838 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) | ||
| 839 | args.v1.ucLaneNum = dp_lane_count; | ||
| 840 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 841 | args.v1.ucLaneNum = 8; | ||
| 842 | else | ||
| 843 | args.v1.ucLaneNum = 4; | ||
| 844 | |||
| 845 | if (ASIC_IS_DCE5(rdev)) { | ||
| 846 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | ||
| 847 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) { | ||
| 848 | if (dp_clock == 270000) | ||
| 849 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | ||
| 850 | else if (dp_clock == 540000) | ||
| 851 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | ||
| 852 | } | ||
| 853 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | ||
| 854 | switch (bpc) { | ||
| 855 | case 0: | ||
| 856 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 857 | break; | ||
| 858 | case 6: | ||
| 859 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 860 | break; | ||
| 861 | case 8: | ||
| 862 | default: | ||
| 863 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 864 | break; | ||
| 865 | case 10: | ||
| 866 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 867 | break; | ||
| 868 | case 12: | ||
| 869 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 870 | break; | ||
| 871 | case 16: | ||
| 872 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 873 | break; | ||
| 874 | } | ||
| 875 | if (hpd_id == RADEON_HPD_NONE) | ||
| 876 | args.v4.ucHPD_ID = 0; | ||
| 877 | else | ||
| 878 | args.v4.ucHPD_ID = hpd_id + 1; | ||
| 879 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 880 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
| 881 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 882 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
| 883 | switch (bpc) { | ||
| 884 | case 0: | ||
| 885 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 886 | break; | ||
| 887 | case 6: | ||
| 888 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 889 | break; | ||
| 890 | case 8: | ||
| 891 | default: | ||
| 892 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 893 | break; | ||
| 894 | case 10: | ||
| 895 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 896 | break; | ||
| 897 | case 12: | ||
| 898 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 899 | break; | ||
| 900 | case 16: | ||
| 901 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 902 | break; | ||
| 903 | } | ||
| 904 | } else { | ||
| 905 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | ||
| 906 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 907 | switch (radeon_encoder->encoder_id) { | ||
| 908 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 909 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | ||
| 910 | break; | ||
| 911 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 912 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 913 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
| 914 | break; | ||
| 915 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 916 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | ||
| 917 | break; | ||
| 918 | } | ||
| 919 | if (dig->linkb) | ||
| 920 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
| 921 | else | ||
| 922 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
| 923 | } | ||
| 924 | |||
| 925 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 926 | |||
| 927 | } | ||
| 928 | |||
| 929 | union dig_transmitter_control { | ||
| 930 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | ||
| 931 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | ||
| 932 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
| 933 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; | ||
| 934 | }; | ||
| 935 | |||
| 936 | void | ||
| 937 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) | ||
| 938 | { | ||
| 939 | struct drm_device *dev = encoder->dev; | ||
| 940 | struct radeon_device *rdev = dev->dev_private; | ||
| 941 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 942 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 943 | struct drm_connector *connector; | ||
| 944 | union dig_transmitter_control args; | ||
| 945 | int index = 0; | ||
| 946 | uint8_t frev, crev; | ||
| 947 | bool is_dp = false; | ||
| 948 | int pll_id = 0; | ||
| 949 | int dp_clock = 0; | ||
| 950 | int dp_lane_count = 0; | ||
| 951 | int connector_object_id = 0; | ||
| 952 | int igp_lane_info = 0; | ||
| 953 | int dig_encoder = dig->dig_encoder; | ||
| 954 | |||
| 955 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 956 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 957 | /* just needed to avoid bailing in the encoder check. the encoder | ||
| 958 | * isn't used for init | ||
| 959 | */ | ||
| 960 | dig_encoder = 0; | ||
| 961 | } else | ||
| 962 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 963 | |||
| 964 | if (connector) { | ||
| 965 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 966 | struct radeon_connector_atom_dig *dig_connector = | ||
| 967 | radeon_connector->con_priv; | ||
| 968 | |||
| 969 | dp_clock = dig_connector->dp_clock; | ||
| 970 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 971 | connector_object_id = | ||
| 972 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 973 | igp_lane_info = dig_connector->igp_lane_info; | ||
| 974 | } | ||
| 975 | |||
| 976 | /* no dig encoder assigned */ | ||
| 977 | if (dig_encoder == -1) | ||
| 978 | return; | ||
| 979 | |||
| 980 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | ||
| 981 | is_dp = true; | ||
| 982 | |||
| 983 | memset(&args, 0, sizeof(args)); | ||
| 984 | |||
| 985 | switch (radeon_encoder->encoder_id) { | ||
| 986 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 987 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
| 988 | break; | ||
| 989 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 990 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 991 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 992 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
| 993 | break; | ||
| 994 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 995 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); | ||
| 996 | break; | ||
| 997 | } | ||
| 998 | |||
| 999 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1000 | return; | ||
| 1001 | |||
| 1002 | args.v1.ucAction = action; | ||
| 1003 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | ||
| 1004 | args.v1.usInitInfo = cpu_to_le16(connector_object_id); | ||
| 1005 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 1006 | args.v1.asMode.ucLaneSel = lane_num; | ||
| 1007 | args.v1.asMode.ucLaneSet = lane_set; | ||
| 1008 | } else { | ||
| 1009 | if (is_dp) | ||
| 1010 | args.v1.usPixelClock = | ||
| 1011 | cpu_to_le16(dp_clock / 10); | ||
| 1012 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 1013 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 1014 | else | ||
| 1015 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1016 | } | ||
| 1017 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1018 | if (is_dp) | ||
| 1019 | args.v3.ucLaneNum = dp_lane_count; | ||
| 1020 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 1021 | args.v3.ucLaneNum = 8; | ||
| 1022 | else | ||
| 1023 | args.v3.ucLaneNum = 4; | ||
| 1024 | |||
| 1025 | if (dig->linkb) | ||
| 1026 | args.v3.acConfig.ucLinkSel = 1; | ||
| 1027 | if (dig_encoder & 1) | ||
| 1028 | args.v3.acConfig.ucEncoderSel = 1; | ||
| 1029 | |||
| 1030 | /* Select the PLL for the PHY | ||
| 1031 | * DP PHY should be clocked from external src if there is | ||
| 1032 | * one. | ||
| 1033 | */ | ||
| 1034 | if (encoder->crtc) { | ||
| 1035 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1036 | pll_id = radeon_crtc->pll_id; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | if (ASIC_IS_DCE5(rdev)) { | ||
| 1040 | /* On DCE5 DCPLL usually generates the DP ref clock */ | ||
| 1041 | if (is_dp) { | ||
| 1042 | if (rdev->clock.dp_extclk) | ||
| 1043 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; | ||
| 1044 | else | ||
| 1045 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; | ||
| 1046 | } else | ||
| 1047 | args.v4.acConfig.ucRefClkSource = pll_id; | ||
| 1048 | } else { | ||
| 1049 | /* On DCE4, if there is an external clock, it generates the DP ref clock */ | ||
| 1050 | if (is_dp && rdev->clock.dp_extclk) | ||
| 1051 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
| 1052 | else | ||
| 1053 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | switch (radeon_encoder->encoder_id) { | ||
| 1057 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1058 | args.v3.acConfig.ucTransmitterSel = 0; | ||
| 1059 | break; | ||
| 1060 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1061 | args.v3.acConfig.ucTransmitterSel = 1; | ||
| 1062 | break; | ||
| 1063 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1064 | args.v3.acConfig.ucTransmitterSel = 2; | ||
| 1065 | break; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | if (is_dp) | ||
| 1069 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
| 1070 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 1071 | if (dig->coherent_mode) | ||
| 1072 | args.v3.acConfig.fCoherentMode = 1; | ||
| 1073 | if (radeon_encoder->pixel_clock > 165000) | ||
| 1074 | args.v3.acConfig.fDualLinkConnector = 1; | ||
| 1075 | } | ||
| 1076 | } else if (ASIC_IS_DCE32(rdev)) { | ||
| 1077 | args.v2.acConfig.ucEncoderSel = dig_encoder; | ||
| 1078 | if (dig->linkb) | ||
| 1079 | args.v2.acConfig.ucLinkSel = 1; | ||
| 1080 | |||
| 1081 | switch (radeon_encoder->encoder_id) { | ||
| 1082 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1083 | args.v2.acConfig.ucTransmitterSel = 0; | ||
| 1084 | break; | ||
| 1085 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1086 | args.v2.acConfig.ucTransmitterSel = 1; | ||
| 1087 | break; | ||
| 1088 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1089 | args.v2.acConfig.ucTransmitterSel = 2; | ||
| 1090 | break; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | if (is_dp) { | ||
| 1094 | args.v2.acConfig.fCoherentMode = 1; | ||
| 1095 | args.v2.acConfig.fDPConnector = 1; | ||
| 1096 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 1097 | if (dig->coherent_mode) | ||
| 1098 | args.v2.acConfig.fCoherentMode = 1; | ||
| 1099 | if (radeon_encoder->pixel_clock > 165000) | ||
| 1100 | args.v2.acConfig.fDualLinkConnector = 1; | ||
| 1101 | } | ||
| 1102 | } else { | ||
| 1103 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | ||
| 1104 | |||
| 1105 | if (dig_encoder) | ||
| 1106 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
| 1107 | else | ||
| 1108 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
| 1109 | |||
| 1110 | if ((rdev->flags & RADEON_IS_IGP) && | ||
| 1111 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | ||
| 1112 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | ||
| 1113 | if (igp_lane_info & 0x1) | ||
| 1114 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 1115 | else if (igp_lane_info & 0x2) | ||
| 1116 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | ||
| 1117 | else if (igp_lane_info & 0x4) | ||
| 1118 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | ||
| 1119 | else if (igp_lane_info & 0x8) | ||
| 1120 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | ||
| 1121 | } else { | ||
| 1122 | if (igp_lane_info & 0x3) | ||
| 1123 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | ||
| 1124 | else if (igp_lane_info & 0xc) | ||
| 1125 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | ||
| 1126 | } | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | if (dig->linkb) | ||
| 1130 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
| 1131 | else | ||
| 1132 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
| 1133 | |||
| 1134 | if (is_dp) | ||
| 1135 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
| 1136 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 1137 | if (dig->coherent_mode) | ||
| 1138 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
| 1139 | if (radeon_encoder->pixel_clock > 165000) | ||
| 1140 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
| 1141 | } | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | bool | ||
| 1148 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) | ||
| 1149 | { | ||
| 1150 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1151 | struct drm_device *dev = radeon_connector->base.dev; | ||
| 1152 | struct radeon_device *rdev = dev->dev_private; | ||
| 1153 | union dig_transmitter_control args; | ||
| 1154 | int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | ||
| 1155 | uint8_t frev, crev; | ||
| 1156 | |||
| 1157 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) | ||
| 1158 | goto done; | ||
| 1159 | |||
| 1160 | if (!ASIC_IS_DCE4(rdev)) | ||
| 1161 | goto done; | ||
| 1162 | |||
| 1163 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && | ||
| 1164 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | ||
| 1165 | goto done; | ||
| 1166 | |||
| 1167 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1168 | goto done; | ||
| 1169 | |||
| 1170 | memset(&args, 0, sizeof(args)); | ||
| 1171 | |||
| 1172 | args.v1.ucAction = action; | ||
| 1173 | |||
| 1174 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1175 | |||
| 1176 | /* wait for the panel to power up */ | ||
| 1177 | if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { | ||
| 1178 | int i; | ||
| 1179 | |||
| 1180 | for (i = 0; i < 300; i++) { | ||
| 1181 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
| 1182 | return true; | ||
| 1183 | mdelay(1); | ||
| 1184 | } | ||
| 1185 | return false; | ||
| 1186 | } | ||
| 1187 | done: | ||
| 1188 | return true; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | union external_encoder_control { | ||
| 1192 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
| 1193 | EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; | ||
| 1194 | }; | ||
| 1195 | |||
| 1196 | static void | ||
| 1197 | atombios_external_encoder_setup(struct drm_encoder *encoder, | ||
| 1198 | struct drm_encoder *ext_encoder, | ||
| 1199 | int action) | ||
| 1200 | { | ||
| 1201 | struct drm_device *dev = encoder->dev; | ||
| 1202 | struct radeon_device *rdev = dev->dev_private; | ||
| 1203 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1204 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | ||
| 1205 | union external_encoder_control args; | ||
| 1206 | struct drm_connector *connector; | ||
| 1207 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | ||
| 1208 | u8 frev, crev; | ||
| 1209 | int dp_clock = 0; | ||
| 1210 | int dp_lane_count = 0; | ||
| 1211 | int connector_object_id = 0; | ||
| 1212 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 1213 | int bpc = 8; | ||
| 1214 | |||
| 1215 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
| 1216 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 1217 | else | ||
| 1218 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 1219 | |||
| 1220 | if (connector) { | ||
| 1221 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1222 | struct radeon_connector_atom_dig *dig_connector = | ||
| 1223 | radeon_connector->con_priv; | ||
| 1224 | |||
| 1225 | dp_clock = dig_connector->dp_clock; | ||
| 1226 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 1227 | connector_object_id = | ||
| 1228 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 1229 | bpc = connector->display_info.bpc; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | memset(&args, 0, sizeof(args)); | ||
| 1233 | |||
| 1234 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1235 | return; | ||
| 1236 | |||
| 1237 | switch (frev) { | ||
| 1238 | case 1: | ||
| 1239 | /* no params on frev 1 */ | ||
| 1240 | break; | ||
| 1241 | case 2: | ||
| 1242 | switch (crev) { | ||
| 1243 | case 1: | ||
| 1244 | case 2: | ||
| 1245 | args.v1.sDigEncoder.ucAction = action; | ||
| 1246 | args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1247 | args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 1248 | |||
| 1249 | if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
| 1250 | if (dp_clock == 270000) | ||
| 1251 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 1252 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | ||
| 1253 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 1254 | args.v1.sDigEncoder.ucLaneNum = 8; | ||
| 1255 | else | ||
| 1256 | args.v1.sDigEncoder.ucLaneNum = 4; | ||
| 1257 | break; | ||
| 1258 | case 3: | ||
| 1259 | args.v3.sExtEncoder.ucAction = action; | ||
| 1260 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
| 1261 | args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); | ||
| 1262 | else | ||
| 1263 | args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
| 1264 | args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
| 1265 | |||
| 1266 | if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
| 1267 | if (dp_clock == 270000) | ||
| 1268 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | ||
| 1269 | else if (dp_clock == 540000) | ||
| 1270 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | ||
| 1271 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | ||
| 1272 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 1273 | args.v3.sExtEncoder.ucLaneNum = 8; | ||
| 1274 | else | ||
| 1275 | args.v3.sExtEncoder.ucLaneNum = 4; | ||
| 1276 | switch (ext_enum) { | ||
| 1277 | case GRAPH_OBJECT_ENUM_ID1: | ||
| 1278 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; | ||
| 1279 | break; | ||
| 1280 | case GRAPH_OBJECT_ENUM_ID2: | ||
| 1281 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; | ||
| 1282 | break; | ||
| 1283 | case GRAPH_OBJECT_ENUM_ID3: | ||
| 1284 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | ||
| 1285 | break; | ||
| 1286 | } | ||
| 1287 | switch (bpc) { | ||
| 1288 | case 0: | ||
| 1289 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
| 1290 | break; | ||
| 1291 | case 6: | ||
| 1292 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
| 1293 | break; | ||
| 1294 | case 8: | ||
| 1295 | default: | ||
| 1296 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
| 1297 | break; | ||
| 1298 | case 10: | ||
| 1299 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
| 1300 | break; | ||
| 1301 | case 12: | ||
| 1302 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
| 1303 | break; | ||
| 1304 | case 16: | ||
| 1305 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
| 1306 | break; | ||
| 1307 | } | ||
| 1308 | break; | ||
| 1309 | default: | ||
| 1310 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1311 | return; | ||
| 1312 | } | ||
| 1313 | break; | ||
| 1314 | default: | ||
| 1315 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1316 | return; | ||
| 1317 | } | ||
| 1318 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | static void | ||
| 1322 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | ||
| 1323 | { | ||
| 1324 | struct drm_device *dev = encoder->dev; | ||
| 1325 | struct radeon_device *rdev = dev->dev_private; | ||
| 1326 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1327 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1328 | ENABLE_YUV_PS_ALLOCATION args; | ||
| 1329 | int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); | ||
| 1330 | uint32_t temp, reg; | ||
| 1331 | |||
| 1332 | memset(&args, 0, sizeof(args)); | ||
| 1333 | |||
| 1334 | if (rdev->family >= CHIP_R600) | ||
| 1335 | reg = R600_BIOS_3_SCRATCH; | ||
| 1336 | else | ||
| 1337 | reg = RADEON_BIOS_3_SCRATCH; | ||
| 1338 | |||
| 1339 | /* XXX: fix up scratch reg handling */ | ||
| 1340 | temp = RREG32(reg); | ||
| 1341 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1342 | WREG32(reg, (ATOM_S3_TV1_ACTIVE | | ||
| 1343 | (radeon_crtc->crtc_id << 18))); | ||
| 1344 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1345 | WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); | ||
| 1346 | else | ||
| 1347 | WREG32(reg, 0); | ||
| 1348 | |||
| 1349 | if (enable) | ||
| 1350 | args.ucEnable = ATOM_ENABLE; | ||
| 1351 | args.ucCRTC = radeon_crtc->crtc_id; | ||
| 1352 | |||
| 1353 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1354 | |||
| 1355 | WREG32(reg, temp); | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | static void | ||
| 1359 | radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
| 1360 | { | ||
| 1361 | struct drm_device *dev = encoder->dev; | ||
| 1362 | struct radeon_device *rdev = dev->dev_private; | ||
| 1363 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1364 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 1365 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | ||
| 1366 | int index = 0; | ||
| 1367 | bool is_dig = false; | ||
| 1368 | bool is_dce5_dac = false; | ||
| 1369 | bool is_dce5_dvo = false; | ||
| 1370 | |||
| 1371 | memset(&args, 0, sizeof(args)); | ||
| 1372 | |||
| 1373 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | ||
| 1374 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | ||
| 1375 | radeon_encoder->active_device); | ||
| 1376 | switch (radeon_encoder->encoder_id) { | ||
| 1377 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1378 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1379 | index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); | ||
| 1380 | break; | ||
| 1381 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1382 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1383 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1384 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1385 | is_dig = true; | ||
| 1386 | break; | ||
| 1387 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1388 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1389 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
| 1390 | break; | ||
| 1391 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1392 | if (ASIC_IS_DCE5(rdev)) | ||
| 1393 | is_dce5_dvo = true; | ||
| 1394 | else if (ASIC_IS_DCE3(rdev)) | ||
| 1395 | is_dig = true; | ||
| 1396 | else | ||
| 1397 | index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); | ||
| 1398 | break; | ||
| 1399 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1400 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
| 1401 | break; | ||
| 1402 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1403 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1404 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
| 1405 | else | ||
| 1406 | index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); | ||
| 1407 | break; | ||
| 1408 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1409 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1410 | if (ASIC_IS_DCE5(rdev)) | ||
| 1411 | is_dce5_dac = true; | ||
| 1412 | else { | ||
| 1413 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1414 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
| 1415 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1416 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
| 1417 | else | ||
| 1418 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | ||
| 1419 | } | ||
| 1420 | break; | ||
| 1421 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1422 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1423 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1424 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | ||
| 1425 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1426 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | ||
| 1427 | else | ||
| 1428 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | ||
| 1429 | break; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | if (is_dig) { | ||
| 1433 | switch (mode) { | ||
| 1434 | case DRM_MODE_DPMS_ON: | ||
| 1435 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
| 1436 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | ||
| 1437 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1438 | else | ||
| 1439 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
| 1440 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | ||
| 1441 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1442 | |||
| 1443 | if (connector && | ||
| 1444 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
| 1445 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1446 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
| 1447 | radeon_connector->con_priv; | ||
| 1448 | atombios_set_edp_panel_power(connector, | ||
| 1449 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 1450 | radeon_dig_connector->edp_on = true; | ||
| 1451 | } | ||
| 1452 | if (ASIC_IS_DCE4(rdev)) | ||
| 1453 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
| 1454 | radeon_dp_link_train(encoder, connector); | ||
| 1455 | if (ASIC_IS_DCE4(rdev)) | ||
| 1456 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | ||
| 1457 | } | ||
| 1458 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1459 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | ||
| 1460 | break; | ||
| 1461 | case DRM_MODE_DPMS_STANDBY: | ||
| 1462 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1463 | case DRM_MODE_DPMS_OFF: | ||
| 1464 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1465 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | ||
| 1466 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1467 | |||
| 1468 | if (ASIC_IS_DCE4(rdev)) | ||
| 1469 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
| 1470 | if (connector && | ||
| 1471 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
| 1472 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1473 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
| 1474 | radeon_connector->con_priv; | ||
| 1475 | atombios_set_edp_panel_power(connector, | ||
| 1476 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
| 1477 | radeon_dig_connector->edp_on = false; | ||
| 1478 | } | ||
| 1479 | } | ||
| 1480 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 1481 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | ||
| 1482 | break; | ||
| 1483 | } | ||
| 1484 | } else if (is_dce5_dac) { | ||
| 1485 | switch (mode) { | ||
| 1486 | case DRM_MODE_DPMS_ON: | ||
| 1487 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
| 1488 | break; | ||
| 1489 | case DRM_MODE_DPMS_STANDBY: | ||
| 1490 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1491 | case DRM_MODE_DPMS_OFF: | ||
| 1492 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
| 1493 | break; | ||
| 1494 | } | ||
| 1495 | } else if (is_dce5_dvo) { | ||
| 1496 | switch (mode) { | ||
| 1497 | case DRM_MODE_DPMS_ON: | ||
| 1498 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
| 1499 | break; | ||
| 1500 | case DRM_MODE_DPMS_STANDBY: | ||
| 1501 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1502 | case DRM_MODE_DPMS_OFF: | ||
| 1503 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
| 1504 | break; | ||
| 1505 | } | ||
| 1506 | } else { | ||
| 1507 | switch (mode) { | ||
| 1508 | case DRM_MODE_DPMS_ON: | ||
| 1509 | args.ucAction = ATOM_ENABLE; | ||
| 1510 | /* workaround for DVOOutputControl on some RS690 systems */ | ||
| 1511 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { | ||
| 1512 | u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); | ||
| 1513 | WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); | ||
| 1514 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1515 | WREG32(RADEON_BIOS_3_SCRATCH, reg); | ||
| 1516 | } else | ||
| 1517 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1518 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 1519 | args.ucAction = ATOM_LCD_BLON; | ||
| 1520 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1521 | } | ||
| 1522 | break; | ||
| 1523 | case DRM_MODE_DPMS_STANDBY: | ||
| 1524 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1525 | case DRM_MODE_DPMS_OFF: | ||
| 1526 | args.ucAction = ATOM_DISABLE; | ||
| 1527 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1528 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 1529 | args.ucAction = ATOM_LCD_BLOFF; | ||
| 1530 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1531 | } | ||
| 1532 | break; | ||
| 1533 | } | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | if (ext_encoder) { | ||
| 1537 | switch (mode) { | ||
| 1538 | case DRM_MODE_DPMS_ON: | ||
| 1539 | default: | ||
| 1540 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1541 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1542 | EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); | ||
| 1543 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1544 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); | ||
| 1545 | } else | ||
| 1546 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1547 | break; | ||
| 1548 | case DRM_MODE_DPMS_STANDBY: | ||
| 1549 | case DRM_MODE_DPMS_SUSPEND: | ||
| 1550 | case DRM_MODE_DPMS_OFF: | ||
| 1551 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1552 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1553 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); | ||
| 1554 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1555 | EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); | ||
| 1556 | } else | ||
| 1557 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); | ||
| 1558 | break; | ||
| 1559 | } | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | ||
| 1563 | |||
| 1564 | } | ||
| 1565 | |||
| 1566 | union crtc_source_param { | ||
| 1567 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | ||
| 1568 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | ||
| 1569 | }; | ||
| 1570 | |||
| 1571 | static void | ||
| 1572 | atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | ||
| 1573 | { | ||
| 1574 | struct drm_device *dev = encoder->dev; | ||
| 1575 | struct radeon_device *rdev = dev->dev_private; | ||
| 1576 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1577 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1578 | union crtc_source_param args; | ||
| 1579 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | ||
| 1580 | uint8_t frev, crev; | ||
| 1581 | struct radeon_encoder_atom_dig *dig; | ||
| 1582 | |||
| 1583 | memset(&args, 0, sizeof(args)); | ||
| 1584 | |||
| 1585 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1586 | return; | ||
| 1587 | |||
| 1588 | switch (frev) { | ||
| 1589 | case 1: | ||
| 1590 | switch (crev) { | ||
| 1591 | case 1: | ||
| 1592 | default: | ||
| 1593 | if (ASIC_IS_AVIVO(rdev)) | ||
| 1594 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
| 1595 | else { | ||
| 1596 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) { | ||
| 1597 | args.v1.ucCRTC = radeon_crtc->crtc_id; | ||
| 1598 | } else { | ||
| 1599 | args.v1.ucCRTC = radeon_crtc->crtc_id << 2; | ||
| 1600 | } | ||
| 1601 | } | ||
| 1602 | switch (radeon_encoder->encoder_id) { | ||
| 1603 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1604 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1605 | args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; | ||
| 1606 | break; | ||
| 1607 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1608 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1609 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) | ||
| 1610 | args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; | ||
| 1611 | else | ||
| 1612 | args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; | ||
| 1613 | break; | ||
| 1614 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1615 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1616 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1617 | args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; | ||
| 1618 | break; | ||
| 1619 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1620 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1621 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1622 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
| 1623 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1624 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
| 1625 | else | ||
| 1626 | args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; | ||
| 1627 | break; | ||
| 1628 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1629 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1630 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1631 | args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; | ||
| 1632 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1633 | args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; | ||
| 1634 | else | ||
| 1635 | args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; | ||
| 1636 | break; | ||
| 1637 | } | ||
| 1638 | break; | ||
| 1639 | case 2: | ||
| 1640 | args.v2.ucCRTC = radeon_crtc->crtc_id; | ||
| 1641 | if (radeon_encoder_is_dp_bridge(encoder)) { | ||
| 1642 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1643 | |||
| 1644 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | ||
| 1645 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; | ||
| 1646 | else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) | ||
| 1647 | args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; | ||
| 1648 | else | ||
| 1649 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 1650 | } else | ||
| 1651 | args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
| 1652 | switch (radeon_encoder->encoder_id) { | ||
| 1653 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1654 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1655 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1656 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1657 | dig = radeon_encoder->enc_priv; | ||
| 1658 | switch (dig->dig_encoder) { | ||
| 1659 | case 0: | ||
| 1660 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
| 1661 | break; | ||
| 1662 | case 1: | ||
| 1663 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
| 1664 | break; | ||
| 1665 | case 2: | ||
| 1666 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
| 1667 | break; | ||
| 1668 | case 3: | ||
| 1669 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
| 1670 | break; | ||
| 1671 | case 4: | ||
| 1672 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
| 1673 | break; | ||
| 1674 | case 5: | ||
| 1675 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
| 1676 | break; | ||
| 1677 | } | ||
| 1678 | break; | ||
| 1679 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1680 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | ||
| 1681 | break; | ||
| 1682 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1683 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1684 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1685 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1686 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1687 | else | ||
| 1688 | args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; | ||
| 1689 | break; | ||
| 1690 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1691 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
| 1692 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1693 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | ||
| 1694 | args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; | ||
| 1695 | else | ||
| 1696 | args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; | ||
| 1697 | break; | ||
| 1698 | } | ||
| 1699 | break; | ||
| 1700 | } | ||
| 1701 | break; | ||
| 1702 | default: | ||
| 1703 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | ||
| 1704 | return; | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1708 | |||
| 1709 | /* update scratch regs with new routing */ | ||
| 1710 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | static void | ||
| 1714 | atombios_apply_encoder_quirks(struct drm_encoder *encoder, | ||
| 1715 | struct drm_display_mode *mode) | ||
| 1716 | { | ||
| 1717 | struct drm_device *dev = encoder->dev; | ||
| 1718 | struct radeon_device *rdev = dev->dev_private; | ||
| 1719 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1720 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1721 | |||
| 1722 | /* Funky macbooks */ | ||
| 1723 | if ((dev->pdev->device == 0x71C5) && | ||
| 1724 | (dev->pdev->subsystem_vendor == 0x106b) && | ||
| 1725 | (dev->pdev->subsystem_device == 0x0080)) { | ||
| 1726 | if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { | ||
| 1727 | uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL); | ||
| 1728 | |||
| 1729 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; | ||
| 1730 | lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; | ||
| 1731 | |||
| 1732 | WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); | ||
| 1733 | } | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | /* set scaler clears this on some chips */ | ||
| 1737 | if (ASIC_IS_AVIVO(rdev) && | ||
| 1738 | (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { | ||
| 1739 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1740 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1741 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1742 | EVERGREEN_INTERLEAVE_EN); | ||
| 1743 | else | ||
| 1744 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1745 | } else { | ||
| 1746 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 1747 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
| 1748 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
| 1749 | else | ||
| 1750 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
| 1751 | } | ||
| 1752 | } | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | ||
| 1756 | { | ||
| 1757 | struct drm_device *dev = encoder->dev; | ||
| 1758 | struct radeon_device *rdev = dev->dev_private; | ||
| 1759 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
| 1760 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1761 | struct drm_encoder *test_encoder; | ||
| 1762 | struct radeon_encoder_atom_dig *dig; | ||
| 1763 | uint32_t dig_enc_in_use = 0; | ||
| 1764 | |||
| 1765 | /* DCE4/5 */ | ||
| 1766 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1767 | dig = radeon_encoder->enc_priv; | ||
| 1768 | if (ASIC_IS_DCE41(rdev)) { | ||
| 1769 | /* ontario follows DCE4 */ | ||
| 1770 | if (rdev->family == CHIP_PALM) { | ||
| 1771 | if (dig->linkb) | ||
| 1772 | return 1; | ||
| 1773 | else | ||
| 1774 | return 0; | ||
| 1775 | } else | ||
| 1776 | /* llano follows DCE3.2 */ | ||
| 1777 | return radeon_crtc->crtc_id; | ||
| 1778 | } else { | ||
| 1779 | switch (radeon_encoder->encoder_id) { | ||
| 1780 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1781 | if (dig->linkb) | ||
| 1782 | return 1; | ||
| 1783 | else | ||
| 1784 | return 0; | ||
| 1785 | break; | ||
| 1786 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1787 | if (dig->linkb) | ||
| 1788 | return 3; | ||
| 1789 | else | ||
| 1790 | return 2; | ||
| 1791 | break; | ||
| 1792 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1793 | if (dig->linkb) | ||
| 1794 | return 5; | ||
| 1795 | else | ||
| 1796 | return 4; | ||
| 1797 | break; | ||
| 1798 | } | ||
| 1799 | } | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | /* on DCE32 and encoder can driver any block so just crtc id */ | ||
| 1803 | if (ASIC_IS_DCE32(rdev)) { | ||
| 1804 | return radeon_crtc->crtc_id; | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | /* on DCE3 - LVTMA can only be driven by DIGB */ | ||
| 1808 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
| 1809 | struct radeon_encoder *radeon_test_encoder; | ||
| 1810 | |||
| 1811 | if (encoder == test_encoder) | ||
| 1812 | continue; | ||
| 1813 | |||
| 1814 | if (!radeon_encoder_is_digital(test_encoder)) | ||
| 1815 | continue; | ||
| 1816 | |||
| 1817 | radeon_test_encoder = to_radeon_encoder(test_encoder); | ||
| 1818 | dig = radeon_test_encoder->enc_priv; | ||
| 1819 | |||
| 1820 | if (dig->dig_encoder >= 0) | ||
| 1821 | dig_enc_in_use |= (1 << dig->dig_encoder); | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { | ||
| 1825 | if (dig_enc_in_use & 0x2) | ||
| 1826 | DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); | ||
| 1827 | return 1; | ||
| 1828 | } | ||
| 1829 | if (!(dig_enc_in_use & 1)) | ||
| 1830 | return 0; | ||
| 1831 | return 1; | ||
| 1832 | } | ||
| 1833 | |||
| 1834 | /* This only needs to be called once at startup */ | ||
| 1835 | void | ||
| 1836 | radeon_atom_encoder_init(struct radeon_device *rdev) | ||
| 1837 | { | ||
| 1838 | struct drm_device *dev = rdev->ddev; | ||
| 1839 | struct drm_encoder *encoder; | ||
| 1840 | |||
| 1841 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 1842 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1843 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 1844 | |||
| 1845 | switch (radeon_encoder->encoder_id) { | ||
| 1846 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1847 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1848 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1849 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1850 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
| 1851 | break; | ||
| 1852 | default: | ||
| 1853 | break; | ||
| 1854 | } | ||
| 1855 | |||
| 1856 | if (ext_encoder && ASIC_IS_DCE41(rdev)) | ||
| 1857 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1858 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
| 1859 | } | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | static void | ||
| 1863 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | ||
| 1864 | struct drm_display_mode *mode, | ||
| 1865 | struct drm_display_mode *adjusted_mode) | ||
| 1866 | { | ||
| 1867 | struct drm_device *dev = encoder->dev; | ||
| 1868 | struct radeon_device *rdev = dev->dev_private; | ||
| 1869 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1870 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 1871 | |||
| 1872 | radeon_encoder->pixel_clock = adjusted_mode->clock; | ||
| 1873 | |||
| 1874 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | ||
| 1875 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | ||
| 1876 | atombios_yuv_setup(encoder, true); | ||
| 1877 | else | ||
| 1878 | atombios_yuv_setup(encoder, false); | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | switch (radeon_encoder->encoder_id) { | ||
| 1882 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 1883 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 1884 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 1885 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 1886 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); | ||
| 1887 | break; | ||
| 1888 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 1889 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1890 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1891 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 1892 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1893 | /* disable the transmitter */ | ||
| 1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1895 | /* setup and enable the encoder */ | ||
| 1896 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1897 | |||
| 1898 | /* enable the transmitter */ | ||
| 1899 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1900 | } else { | ||
| 1901 | /* disable the encoder and transmitter */ | ||
| 1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1903 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1904 | |||
| 1905 | /* setup and enable the encoder and transmitter */ | ||
| 1906 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1907 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1908 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1909 | } | ||
| 1910 | break; | ||
| 1911 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 1912 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 1913 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 1914 | atombios_dvo_setup(encoder, ATOM_ENABLE); | ||
| 1915 | break; | ||
| 1916 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 1917 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 1918 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 1919 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 1920 | atombios_dac_setup(encoder, ATOM_ENABLE); | ||
| 1921 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { | ||
| 1922 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
| 1923 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
| 1924 | else | ||
| 1925 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
| 1926 | } | ||
| 1927 | break; | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | if (ext_encoder) { | ||
| 1931 | if (ASIC_IS_DCE41(rdev)) | ||
| 1932 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1933 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1934 | else | ||
| 1935 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1936 | } | ||
| 1937 | |||
| 1938 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | ||
| 1939 | |||
| 1940 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | ||
| 1941 | r600_hdmi_enable(encoder); | ||
| 1942 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
| 1943 | } | ||
| 1944 | } | ||
| 1945 | |||
| 1946 | static bool | ||
| 1947 | atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 1948 | { | ||
| 1949 | struct drm_device *dev = encoder->dev; | ||
| 1950 | struct radeon_device *rdev = dev->dev_private; | ||
| 1951 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1952 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1953 | |||
| 1954 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | | ||
| 1955 | ATOM_DEVICE_CV_SUPPORT | | ||
| 1956 | ATOM_DEVICE_CRT_SUPPORT)) { | ||
| 1957 | DAC_LOAD_DETECTION_PS_ALLOCATION args; | ||
| 1958 | int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); | ||
| 1959 | uint8_t frev, crev; | ||
| 1960 | |||
| 1961 | memset(&args, 0, sizeof(args)); | ||
| 1962 | |||
| 1963 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
| 1964 | return false; | ||
| 1965 | |||
| 1966 | args.sDacload.ucMisc = 0; | ||
| 1967 | |||
| 1968 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || | ||
| 1969 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)) | ||
| 1970 | args.sDacload.ucDacType = ATOM_DAC_A; | ||
| 1971 | else | ||
| 1972 | args.sDacload.ucDacType = ATOM_DAC_B; | ||
| 1973 | |||
| 1974 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) | ||
| 1975 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); | ||
| 1976 | else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) | ||
| 1977 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); | ||
| 1978 | else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 1979 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); | ||
| 1980 | if (crev >= 3) | ||
| 1981 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
| 1982 | } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 1983 | args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); | ||
| 1984 | if (crev >= 3) | ||
| 1985 | args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 1989 | |||
| 1990 | return true; | ||
| 1991 | } else | ||
| 1992 | return false; | ||
| 1993 | } | ||
| 1994 | |||
| 1995 | static enum drm_connector_status | ||
| 1996 | radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 1997 | { | ||
| 1998 | struct drm_device *dev = encoder->dev; | ||
| 1999 | struct radeon_device *rdev = dev->dev_private; | ||
| 2000 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2001 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 2002 | uint32_t bios_0_scratch; | ||
| 2003 | |||
| 2004 | if (!atombios_dac_load_detect(encoder, connector)) { | ||
| 2005 | DRM_DEBUG_KMS("detect returned false \n"); | ||
| 2006 | return connector_status_unknown; | ||
| 2007 | } | ||
| 2008 | |||
| 2009 | if (rdev->family >= CHIP_R600) | ||
| 2010 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
| 2011 | else | ||
| 2012 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | ||
| 2013 | |||
| 2014 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
| 2015 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
| 2016 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
| 2017 | return connector_status_connected; | ||
| 2018 | } | ||
| 2019 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
| 2020 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
| 2021 | return connector_status_connected; | ||
| 2022 | } | ||
| 2023 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 2024 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
| 2025 | return connector_status_connected; | ||
| 2026 | } | ||
| 2027 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 2028 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
| 2029 | return connector_status_connected; /* CTV */ | ||
| 2030 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
| 2031 | return connector_status_connected; /* STV */ | ||
| 2032 | } | ||
| 2033 | return connector_status_disconnected; | ||
| 2034 | } | ||
| 2035 | |||
| 2036 | static enum drm_connector_status | ||
| 2037 | radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
| 2038 | { | ||
| 2039 | struct drm_device *dev = encoder->dev; | ||
| 2040 | struct radeon_device *rdev = dev->dev_private; | ||
| 2041 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2042 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 2043 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 2044 | u32 bios_0_scratch; | ||
| 2045 | |||
| 2046 | if (!ASIC_IS_DCE4(rdev)) | ||
| 2047 | return connector_status_unknown; | ||
| 2048 | |||
| 2049 | if (!ext_encoder) | ||
| 2050 | return connector_status_unknown; | ||
| 2051 | |||
| 2052 | if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0) | ||
| 2053 | return connector_status_unknown; | ||
| 2054 | |||
| 2055 | /* load detect on the dp bridge */ | ||
| 2056 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 2057 | EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION); | ||
| 2058 | |||
| 2059 | bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); | ||
| 2060 | |||
| 2061 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | ||
| 2062 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | ||
| 2063 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | ||
| 2064 | return connector_status_connected; | ||
| 2065 | } | ||
| 2066 | if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { | ||
| 2067 | if (bios_0_scratch & ATOM_S0_CRT2_MASK) | ||
| 2068 | return connector_status_connected; | ||
| 2069 | } | ||
| 2070 | if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { | ||
| 2071 | if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) | ||
| 2072 | return connector_status_connected; | ||
| 2073 | } | ||
| 2074 | if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { | ||
| 2075 | if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) | ||
| 2076 | return connector_status_connected; /* CTV */ | ||
| 2077 | else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) | ||
| 2078 | return connector_status_connected; /* STV */ | ||
| 2079 | } | ||
| 2080 | return connector_status_disconnected; | ||
| 2081 | } | ||
| 2082 | |||
| 2083 | void | ||
| 2084 | radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | ||
| 2085 | { | ||
| 2086 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 2087 | |||
| 2088 | if (ext_encoder) | ||
| 2089 | /* ddc_setup on the dp bridge */ | ||
| 2090 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 2091 | EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); | ||
| 2092 | |||
| 2093 | } | ||
| 2094 | |||
| 2095 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | ||
| 2096 | { | ||
| 2097 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2098 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 2099 | |||
| 2100 | if ((radeon_encoder->active_device & | ||
| 2101 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || | ||
| 2102 | radeon_encoder_is_dp_bridge(encoder)) { | ||
| 2103 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 2104 | if (dig) | ||
| 2105 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | ||
| 2106 | } | ||
| 2107 | |||
| 2108 | radeon_atom_output_lock(encoder, true); | ||
| 2109 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2110 | |||
| 2111 | if (connector) { | ||
| 2112 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 2113 | |||
| 2114 | /* select the clock/data port if it uses a router */ | ||
| 2115 | if (radeon_connector->router.cd_valid) | ||
| 2116 | radeon_router_select_cd_port(radeon_connector); | ||
| 2117 | |||
| 2118 | /* turn eDP panel on for mode set */ | ||
| 2119 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
| 2120 | atombios_set_edp_panel_power(connector, | ||
| 2121 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | /* this is needed for the pll/ss setup to work correctly in some cases */ | ||
| 2125 | atombios_set_encoder_crtc_source(encoder); | ||
| 2126 | } | ||
| 2127 | |||
| 2128 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | ||
| 2129 | { | ||
| 2130 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | ||
| 2131 | radeon_atom_output_lock(encoder, false); | ||
| 2132 | } | ||
| 2133 | |||
| 2134 | static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | ||
| 2135 | { | ||
| 2136 | struct drm_device *dev = encoder->dev; | ||
| 2137 | struct radeon_device *rdev = dev->dev_private; | ||
| 2138 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2139 | struct radeon_encoder_atom_dig *dig; | ||
| 2140 | |||
| 2141 | /* check for pre-DCE3 cards with shared encoders; | ||
| 2142 | * can't really use the links individually, so don't disable | ||
| 2143 | * the encoder if it's in use by another connector | ||
| 2144 | */ | ||
| 2145 | if (!ASIC_IS_DCE3(rdev)) { | ||
| 2146 | struct drm_encoder *other_encoder; | ||
| 2147 | struct radeon_encoder *other_radeon_encoder; | ||
| 2148 | |||
| 2149 | list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { | ||
| 2150 | other_radeon_encoder = to_radeon_encoder(other_encoder); | ||
| 2151 | if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && | ||
| 2152 | drm_helper_encoder_in_use(other_encoder)) | ||
| 2153 | goto disable_done; | ||
| 2154 | } | ||
| 2155 | } | ||
| 2156 | |||
| 2157 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2158 | |||
| 2159 | switch (radeon_encoder->encoder_id) { | ||
| 2160 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 2161 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 2162 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 2163 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 2164 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); | ||
| 2165 | break; | ||
| 2166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 2167 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 2168 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 2169 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 2170 | if (ASIC_IS_DCE4(rdev)) | ||
| 2171 | /* disable the transmitter */ | ||
| 2172 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2173 | else { | ||
| 2174 | /* disable the encoder and transmitter */ | ||
| 2175 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2176 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 2177 | } | ||
| 2178 | break; | ||
| 2179 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 2180 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 2181 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 2182 | atombios_dvo_setup(encoder, ATOM_DISABLE); | ||
| 2183 | break; | ||
| 2184 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 2185 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 2186 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 2187 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 2188 | atombios_dac_setup(encoder, ATOM_DISABLE); | ||
| 2189 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
| 2190 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
| 2191 | break; | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | disable_done: | ||
| 2195 | if (radeon_encoder_is_digital(encoder)) { | ||
| 2196 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | ||
| 2197 | r600_hdmi_disable(encoder); | ||
| 2198 | dig = radeon_encoder->enc_priv; | ||
| 2199 | dig->dig_encoder = -1; | ||
| 2200 | } | ||
| 2201 | radeon_encoder->active_device = 0; | ||
| 2202 | } | ||
| 2203 | |||
| 2204 | /* these are handled by the primary encoders */ | ||
| 2205 | static void radeon_atom_ext_prepare(struct drm_encoder *encoder) | ||
| 2206 | { | ||
| 2207 | |||
| 2208 | } | ||
| 2209 | |||
| 2210 | static void radeon_atom_ext_commit(struct drm_encoder *encoder) | ||
| 2211 | { | ||
| 2212 | |||
| 2213 | } | ||
| 2214 | |||
| 2215 | static void | ||
| 2216 | radeon_atom_ext_mode_set(struct drm_encoder *encoder, | ||
| 2217 | struct drm_display_mode *mode, | ||
| 2218 | struct drm_display_mode *adjusted_mode) | ||
| 2219 | { | ||
| 2220 | |||
| 2221 | } | ||
| 2222 | |||
| 2223 | static void radeon_atom_ext_disable(struct drm_encoder *encoder) | ||
| 2224 | { | ||
| 2225 | |||
| 2226 | } | ||
| 2227 | |||
| 2228 | static void | ||
| 2229 | radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) | ||
| 2230 | { | ||
| 2231 | |||
| 2232 | } | ||
| 2233 | |||
| 2234 | static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, | ||
| 2235 | struct drm_display_mode *mode, | ||
| 2236 | struct drm_display_mode *adjusted_mode) | ||
| 2237 | { | ||
| 2238 | return true; | ||
| 2239 | } | ||
| 2240 | |||
| 2241 | static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { | ||
| 2242 | .dpms = radeon_atom_ext_dpms, | ||
| 2243 | .mode_fixup = radeon_atom_ext_mode_fixup, | ||
| 2244 | .prepare = radeon_atom_ext_prepare, | ||
| 2245 | .mode_set = radeon_atom_ext_mode_set, | ||
| 2246 | .commit = radeon_atom_ext_commit, | ||
| 2247 | .disable = radeon_atom_ext_disable, | ||
| 2248 | /* no detect for TMDS/LVDS yet */ | ||
| 2249 | }; | ||
| 2250 | |||
| 2251 | static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { | ||
| 2252 | .dpms = radeon_atom_encoder_dpms, | ||
| 2253 | .mode_fixup = radeon_atom_mode_fixup, | ||
| 2254 | .prepare = radeon_atom_encoder_prepare, | ||
| 2255 | .mode_set = radeon_atom_encoder_mode_set, | ||
| 2256 | .commit = radeon_atom_encoder_commit, | ||
| 2257 | .disable = radeon_atom_encoder_disable, | ||
| 2258 | .detect = radeon_atom_dig_detect, | ||
| 2259 | }; | ||
| 2260 | |||
| 2261 | static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { | ||
| 2262 | .dpms = radeon_atom_encoder_dpms, | ||
| 2263 | .mode_fixup = radeon_atom_mode_fixup, | ||
| 2264 | .prepare = radeon_atom_encoder_prepare, | ||
| 2265 | .mode_set = radeon_atom_encoder_mode_set, | ||
| 2266 | .commit = radeon_atom_encoder_commit, | ||
| 2267 | .detect = radeon_atom_dac_detect, | ||
| 2268 | }; | ||
| 2269 | |||
| 2270 | void radeon_enc_destroy(struct drm_encoder *encoder) | ||
| 2271 | { | ||
| 2272 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 2273 | kfree(radeon_encoder->enc_priv); | ||
| 2274 | drm_encoder_cleanup(encoder); | ||
| 2275 | kfree(radeon_encoder); | ||
| 2276 | } | ||
| 2277 | |||
| 2278 | static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | ||
| 2279 | .destroy = radeon_enc_destroy, | ||
| 2280 | }; | ||
| 2281 | |||
| 2282 | struct radeon_encoder_atom_dac * | ||
| 2283 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | ||
| 2284 | { | ||
| 2285 | struct drm_device *dev = radeon_encoder->base.dev; | ||
| 2286 | struct radeon_device *rdev = dev->dev_private; | ||
| 2287 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | ||
| 2288 | |||
| 2289 | if (!dac) | ||
| 2290 | return NULL; | ||
| 2291 | |||
| 2292 | dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
| 2293 | return dac; | ||
| 2294 | } | ||
| 2295 | |||
| 2296 | struct radeon_encoder_atom_dig * | ||
| 2297 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | ||
| 2298 | { | ||
| 2299 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 2300 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | ||
| 2301 | |||
| 2302 | if (!dig) | ||
| 2303 | return NULL; | ||
| 2304 | |||
| 2305 | /* coherent mode by default */ | ||
| 2306 | dig->coherent_mode = true; | ||
| 2307 | dig->dig_encoder = -1; | ||
| 2308 | |||
| 2309 | if (encoder_enum == 2) | ||
| 2310 | dig->linkb = true; | ||
| 2311 | else | ||
| 2312 | dig->linkb = false; | ||
| 2313 | |||
| 2314 | return dig; | ||
| 2315 | } | ||
| 2316 | |||
| 2317 | void | ||
| 2318 | radeon_add_atom_encoder(struct drm_device *dev, | ||
| 2319 | uint32_t encoder_enum, | ||
| 2320 | uint32_t supported_device, | ||
| 2321 | u16 caps) | ||
| 2322 | { | ||
| 2323 | struct radeon_device *rdev = dev->dev_private; | ||
| 2324 | struct drm_encoder *encoder; | ||
| 2325 | struct radeon_encoder *radeon_encoder; | ||
| 2326 | |||
| 2327 | /* see if we already added it */ | ||
| 2328 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 2329 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 2330 | if (radeon_encoder->encoder_enum == encoder_enum) { | ||
| 2331 | radeon_encoder->devices |= supported_device; | ||
| 2332 | return; | ||
| 2333 | } | ||
| 2334 | |||
| 2335 | } | ||
| 2336 | |||
| 2337 | /* add a new one */ | ||
| 2338 | radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); | ||
| 2339 | if (!radeon_encoder) | ||
| 2340 | return; | ||
| 2341 | |||
| 2342 | encoder = &radeon_encoder->base; | ||
| 2343 | switch (rdev->num_crtc) { | ||
| 2344 | case 1: | ||
| 2345 | encoder->possible_crtcs = 0x1; | ||
| 2346 | break; | ||
| 2347 | case 2: | ||
| 2348 | default: | ||
| 2349 | encoder->possible_crtcs = 0x3; | ||
| 2350 | break; | ||
| 2351 | case 4: | ||
| 2352 | encoder->possible_crtcs = 0xf; | ||
| 2353 | break; | ||
| 2354 | case 6: | ||
| 2355 | encoder->possible_crtcs = 0x3f; | ||
| 2356 | break; | ||
| 2357 | } | ||
| 2358 | |||
| 2359 | radeon_encoder->enc_priv = NULL; | ||
| 2360 | |||
| 2361 | radeon_encoder->encoder_enum = encoder_enum; | ||
| 2362 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 2363 | radeon_encoder->devices = supported_device; | ||
| 2364 | radeon_encoder->rmx_type = RMX_OFF; | ||
| 2365 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | ||
| 2366 | radeon_encoder->is_ext_encoder = false; | ||
| 2367 | radeon_encoder->caps = caps; | ||
| 2368 | |||
| 2369 | switch (radeon_encoder->encoder_id) { | ||
| 2370 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 2371 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 2372 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 2373 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 2374 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 2375 | radeon_encoder->rmx_type = RMX_FULL; | ||
| 2376 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2377 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
| 2378 | } else { | ||
| 2379 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2380 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2381 | } | ||
| 2382 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
| 2383 | break; | ||
| 2384 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | ||
| 2385 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2386 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
| 2387 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
| 2388 | break; | ||
| 2389 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | ||
| 2390 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | ||
| 2391 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | ||
| 2392 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); | ||
| 2393 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
| 2394 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | ||
| 2395 | break; | ||
| 2396 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 2397 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 2398 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 2399 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 2400 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 2401 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 2402 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 2403 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
| 2404 | radeon_encoder->rmx_type = RMX_FULL; | ||
| 2405 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2406 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | ||
| 2407 | } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { | ||
| 2408 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2409 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2410 | } else { | ||
| 2411 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2412 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | ||
| 2413 | } | ||
| 2414 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | ||
| 2415 | break; | ||
| 2416 | case ENCODER_OBJECT_ID_SI170B: | ||
| 2417 | case ENCODER_OBJECT_ID_CH7303: | ||
| 2418 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: | ||
| 2419 | case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: | ||
| 2420 | case ENCODER_OBJECT_ID_TITFP513: | ||
| 2421 | case ENCODER_OBJECT_ID_VT1623: | ||
| 2422 | case ENCODER_OBJECT_ID_HDMI_SI1930: | ||
| 2423 | case ENCODER_OBJECT_ID_TRAVIS: | ||
| 2424 | case ENCODER_OBJECT_ID_NUTMEG: | ||
| 2425 | /* these are handled by the primary encoders */ | ||
| 2426 | radeon_encoder->is_ext_encoder = true; | ||
| 2427 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
| 2428 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); | ||
| 2429 | else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) | ||
| 2430 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | ||
| 2431 | else | ||
| 2432 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
| 2433 | drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); | ||
| 2434 | break; | ||
| 2435 | } | ||
| 2436 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index fdc3a9a54bf8..ba7ab79e12c1 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -49,27 +49,27 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev) | |||
| 49 | rdev->gart.table_size >> PAGE_SHIFT); | 49 | rdev->gart.table_size >> PAGE_SHIFT); |
| 50 | } | 50 | } |
| 51 | #endif | 51 | #endif |
| 52 | rdev->gart.table.ram.ptr = ptr; | 52 | rdev->gart.ptr = ptr; |
| 53 | memset((void *)rdev->gart.table.ram.ptr, 0, rdev->gart.table_size); | 53 | memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size); |
| 54 | return 0; | 54 | return 0; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) | 57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) |
| 58 | { | 58 | { |
| 59 | if (rdev->gart.table.ram.ptr == NULL) { | 59 | if (rdev->gart.ptr == NULL) { |
| 60 | return; | 60 | return; |
| 61 | } | 61 | } |
| 62 | #ifdef CONFIG_X86 | 62 | #ifdef CONFIG_X86 |
| 63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || | 63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || |
| 64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { | 64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { |
| 65 | set_memory_wb((unsigned long)rdev->gart.table.ram.ptr, | 65 | set_memory_wb((unsigned long)rdev->gart.ptr, |
| 66 | rdev->gart.table_size >> PAGE_SHIFT); | 66 | rdev->gart.table_size >> PAGE_SHIFT); |
| 67 | } | 67 | } |
| 68 | #endif | 68 | #endif |
| 69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, | 69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, |
| 70 | (void *)rdev->gart.table.ram.ptr, | 70 | (void *)rdev->gart.ptr, |
| 71 | rdev->gart.table_addr); | 71 | rdev->gart.table_addr); |
| 72 | rdev->gart.table.ram.ptr = NULL; | 72 | rdev->gart.ptr = NULL; |
| 73 | rdev->gart.table_addr = 0; | 73 | rdev->gart.table_addr = 0; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -77,10 +77,10 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
| 77 | { | 77 | { |
| 78 | int r; | 78 | int r; |
| 79 | 79 | ||
| 80 | if (rdev->gart.table.vram.robj == NULL) { | 80 | if (rdev->gart.robj == NULL) { |
| 81 | r = radeon_bo_create(rdev, rdev->gart.table_size, | 81 | r = radeon_bo_create(rdev, rdev->gart.table_size, |
| 82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
| 83 | &rdev->gart.table.vram.robj); | 83 | &rdev->gart.robj); |
| 84 | if (r) { | 84 | if (r) { |
| 85 | return r; | 85 | return r; |
| 86 | } | 86 | } |
| @@ -93,38 +93,46 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
| 93 | uint64_t gpu_addr; | 93 | uint64_t gpu_addr; |
| 94 | int r; | 94 | int r; |
| 95 | 95 | ||
| 96 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 96 | r = radeon_bo_reserve(rdev->gart.robj, false); |
| 97 | if (unlikely(r != 0)) | 97 | if (unlikely(r != 0)) |
| 98 | return r; | 98 | return r; |
| 99 | r = radeon_bo_pin(rdev->gart.table.vram.robj, | 99 | r = radeon_bo_pin(rdev->gart.robj, |
| 100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | 100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); |
| 101 | if (r) { | 101 | if (r) { |
| 102 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 102 | radeon_bo_unreserve(rdev->gart.robj); |
| 103 | return r; | 103 | return r; |
| 104 | } | 104 | } |
| 105 | r = radeon_bo_kmap(rdev->gart.table.vram.robj, | 105 | r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr); |
| 106 | (void **)&rdev->gart.table.vram.ptr); | ||
| 107 | if (r) | 106 | if (r) |
| 108 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 107 | radeon_bo_unpin(rdev->gart.robj); |
| 109 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 108 | radeon_bo_unreserve(rdev->gart.robj); |
| 110 | rdev->gart.table_addr = gpu_addr; | 109 | rdev->gart.table_addr = gpu_addr; |
| 111 | return r; | 110 | return r; |
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | 113 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev) |
| 115 | { | 114 | { |
| 116 | int r; | 115 | int r; |
| 117 | 116 | ||
| 118 | if (rdev->gart.table.vram.robj == NULL) { | 117 | if (rdev->gart.robj == NULL) { |
| 119 | return; | 118 | return; |
| 120 | } | 119 | } |
| 121 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 120 | r = radeon_bo_reserve(rdev->gart.robj, false); |
| 122 | if (likely(r == 0)) { | 121 | if (likely(r == 0)) { |
| 123 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | 122 | radeon_bo_kunmap(rdev->gart.robj); |
| 124 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 123 | radeon_bo_unpin(rdev->gart.robj); |
| 125 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 124 | radeon_bo_unreserve(rdev->gart.robj); |
| 125 | rdev->gart.ptr = NULL; | ||
| 126 | } | 126 | } |
| 127 | radeon_bo_unref(&rdev->gart.table.vram.robj); | 127 | } |
| 128 | |||
| 129 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | ||
| 130 | { | ||
| 131 | if (rdev->gart.robj == NULL) { | ||
| 132 | return; | ||
| 133 | } | ||
| 134 | radeon_gart_table_vram_unpin(rdev); | ||
| 135 | radeon_bo_unref(&rdev->gart.robj); | ||
| 128 | } | 136 | } |
| 129 | 137 | ||
| 130 | 138 | ||
| @@ -151,12 +159,14 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
| 151 | if (rdev->gart.pages[p]) { | 159 | if (rdev->gart.pages[p]) { |
| 152 | if (!rdev->gart.ttm_alloced[p]) | 160 | if (!rdev->gart.ttm_alloced[p]) |
| 153 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], | 161 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
| 154 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 162 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
| 155 | rdev->gart.pages[p] = NULL; | 163 | rdev->gart.pages[p] = NULL; |
| 156 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | 164 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; |
| 157 | page_base = rdev->gart.pages_addr[p]; | 165 | page_base = rdev->gart.pages_addr[p]; |
| 158 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 166 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| 159 | radeon_gart_set_page(rdev, t, page_base); | 167 | if (rdev->gart.ptr) { |
| 168 | radeon_gart_set_page(rdev, t, page_base); | ||
| 169 | } | ||
| 160 | page_base += RADEON_GPU_PAGE_SIZE; | 170 | page_base += RADEON_GPU_PAGE_SIZE; |
| 161 | } | 171 | } |
| 162 | } | 172 | } |
| @@ -199,10 +209,12 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
| 199 | } | 209 | } |
| 200 | } | 210 | } |
| 201 | rdev->gart.pages[p] = pagelist[i]; | 211 | rdev->gart.pages[p] = pagelist[i]; |
| 202 | page_base = rdev->gart.pages_addr[p]; | 212 | if (rdev->gart.ptr) { |
| 203 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 213 | page_base = rdev->gart.pages_addr[p]; |
| 204 | radeon_gart_set_page(rdev, t, page_base); | 214 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| 205 | page_base += RADEON_GPU_PAGE_SIZE; | 215 | radeon_gart_set_page(rdev, t, page_base); |
| 216 | page_base += RADEON_GPU_PAGE_SIZE; | ||
| 217 | } | ||
| 206 | } | 218 | } |
| 207 | } | 219 | } |
| 208 | mb(); | 220 | mb(); |
| @@ -215,6 +227,9 @@ void radeon_gart_restore(struct radeon_device *rdev) | |||
| 215 | int i, j, t; | 227 | int i, j, t; |
| 216 | u64 page_base; | 228 | u64 page_base; |
| 217 | 229 | ||
| 230 | if (!rdev->gart.ptr) { | ||
| 231 | return; | ||
| 232 | } | ||
| 218 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { | 233 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { |
| 219 | page_base = rdev->gart.pages_addr[i]; | 234 | page_base = rdev->gart.pages_addr[i]; |
| 220 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 235 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index e6d110ce2331..7bb1b079f480 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | * radeon_ddc_probe | 34 | * radeon_ddc_probe |
| 35 | * | 35 | * |
| 36 | */ | 36 | */ |
| 37 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) | 37 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
| 38 | { | 38 | { |
| 39 | u8 out = 0x0; | 39 | u8 out = 0x0; |
| 40 | u8 buf[8]; | 40 | u8 buf[8]; |
| @@ -49,15 +49,11 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e | |||
| 49 | { | 49 | { |
| 50 | .addr = 0x50, | 50 | .addr = 0x50, |
| 51 | .flags = I2C_M_RD, | 51 | .flags = I2C_M_RD, |
| 52 | .len = 1, | 52 | .len = 8, |
| 53 | .buf = buf, | 53 | .buf = buf, |
| 54 | } | 54 | } |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | /* Read 8 bytes from i2c for extended probe of EDID header */ | ||
| 58 | if (requires_extended_probe) | ||
| 59 | msgs[1].len = 8; | ||
| 60 | |||
| 61 | /* on hw with routers, select right port */ | 57 | /* on hw with routers, select right port */ |
| 62 | if (radeon_connector->router.ddc_valid) | 58 | if (radeon_connector->router.ddc_valid) |
| 63 | radeon_router_select_ddc_port(radeon_connector); | 59 | radeon_router_select_ddc_port(radeon_connector); |
| @@ -66,17 +62,15 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e | |||
| 66 | if (ret != 2) | 62 | if (ret != 2) |
| 67 | /* Couldn't find an accessible DDC on this connector */ | 63 | /* Couldn't find an accessible DDC on this connector */ |
| 68 | return false; | 64 | return false; |
| 69 | if (requires_extended_probe) { | 65 | /* Probe also for valid EDID header |
| 70 | /* Probe also for valid EDID header | 66 | * EDID header starts with: |
| 71 | * EDID header starts with: | 67 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
| 72 | * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. | 68 | * Only the first 6 bytes must be valid as |
| 73 | * Only the first 6 bytes must be valid as | 69 | * drm_edid_block_valid() can fix the last 2 bytes */ |
| 74 | * drm_edid_block_valid() can fix the last 2 bytes */ | 70 | if (drm_edid_header_is_valid(buf) < 6) { |
| 75 | if (drm_edid_header_is_valid(buf) < 6) { | 71 | /* Couldn't find an accessible EDID on this |
| 76 | /* Couldn't find an accessible EDID on this | 72 | * connector */ |
| 77 | * connector */ | 73 | return false; |
| 78 | return false; | ||
| 79 | } | ||
| 80 | } | 74 | } |
| 81 | return true; | 75 | return true; |
| 82 | } | 76 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 9ec830c77af0..8f86aeb26693 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -67,10 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
| 67 | /* Disable *all* interrupts */ | 67 | /* Disable *all* interrupts */ |
| 68 | rdev->irq.sw_int = false; | 68 | rdev->irq.sw_int = false; |
| 69 | rdev->irq.gui_idle = false; | 69 | rdev->irq.gui_idle = false; |
| 70 | for (i = 0; i < rdev->num_crtc; i++) | 70 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
| 71 | rdev->irq.crtc_vblank_int[i] = false; | ||
| 72 | for (i = 0; i < 6; i++) { | ||
| 73 | rdev->irq.hpd[i] = false; | 71 | rdev->irq.hpd[i] = false; |
| 72 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | ||
| 73 | rdev->irq.crtc_vblank_int[i] = false; | ||
| 74 | rdev->irq.pflip[i] = false; | 74 | rdev->irq.pflip[i] = false; |
| 75 | } | 75 | } |
| 76 | radeon_irq_set(rdev); | 76 | radeon_irq_set(rdev); |
| @@ -99,15 +99,55 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
| 99 | /* Disable *all* interrupts */ | 99 | /* Disable *all* interrupts */ |
| 100 | rdev->irq.sw_int = false; | 100 | rdev->irq.sw_int = false; |
| 101 | rdev->irq.gui_idle = false; | 101 | rdev->irq.gui_idle = false; |
| 102 | for (i = 0; i < rdev->num_crtc; i++) | 102 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
| 103 | rdev->irq.crtc_vblank_int[i] = false; | ||
| 104 | for (i = 0; i < 6; i++) { | ||
| 105 | rdev->irq.hpd[i] = false; | 103 | rdev->irq.hpd[i] = false; |
| 104 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | ||
| 105 | rdev->irq.crtc_vblank_int[i] = false; | ||
| 106 | rdev->irq.pflip[i] = false; | 106 | rdev->irq.pflip[i] = false; |
| 107 | } | 107 | } |
| 108 | radeon_irq_set(rdev); | 108 | radeon_irq_set(rdev); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static bool radeon_msi_ok(struct radeon_device *rdev) | ||
| 112 | { | ||
| 113 | /* RV370/RV380 was first asic with MSI support */ | ||
| 114 | if (rdev->family < CHIP_RV380) | ||
| 115 | return false; | ||
| 116 | |||
| 117 | /* MSIs don't work on AGP */ | ||
| 118 | if (rdev->flags & RADEON_IS_AGP) | ||
| 119 | return false; | ||
| 120 | |||
| 121 | /* force MSI on */ | ||
| 122 | if (radeon_msi == 1) | ||
| 123 | return true; | ||
| 124 | else if (radeon_msi == 0) | ||
| 125 | return false; | ||
| 126 | |||
| 127 | /* Quirks */ | ||
| 128 | /* HP RS690 only seems to work with MSIs. */ | ||
| 129 | if ((rdev->pdev->device == 0x791f) && | ||
| 130 | (rdev->pdev->subsystem_vendor == 0x103c) && | ||
| 131 | (rdev->pdev->subsystem_device == 0x30c2)) | ||
| 132 | return true; | ||
| 133 | |||
| 134 | /* Dell RS690 only seems to work with MSIs. */ | ||
| 135 | if ((rdev->pdev->device == 0x791f) && | ||
| 136 | (rdev->pdev->subsystem_vendor == 0x1028) && | ||
| 137 | (rdev->pdev->subsystem_device == 0x01fd)) | ||
| 138 | return true; | ||
| 139 | |||
| 140 | if (rdev->flags & RADEON_IS_IGP) { | ||
| 141 | /* APUs work fine with MSIs */ | ||
| 142 | if (rdev->family >= CHIP_PALM) | ||
| 143 | return true; | ||
| 144 | /* lots of IGPs have problems with MSIs */ | ||
| 145 | return false; | ||
| 146 | } | ||
| 147 | |||
| 148 | return true; | ||
| 149 | } | ||
| 150 | |||
| 111 | int radeon_irq_kms_init(struct radeon_device *rdev) | 151 | int radeon_irq_kms_init(struct radeon_device *rdev) |
| 112 | { | 152 | { |
| 113 | int i; | 153 | int i; |
| @@ -124,12 +164,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 124 | } | 164 | } |
| 125 | /* enable msi */ | 165 | /* enable msi */ |
| 126 | rdev->msi_enabled = 0; | 166 | rdev->msi_enabled = 0; |
| 127 | /* MSIs don't seem to work reliably on all IGP | 167 | |
| 128 | * chips. Disable MSI on them for now. | 168 | if (radeon_msi_ok(rdev)) { |
| 129 | */ | ||
| 130 | if ((rdev->family >= CHIP_RV380) && | ||
| 131 | ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) && | ||
| 132 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
| 133 | int ret = pci_enable_msi(rdev->pdev); | 169 | int ret = pci_enable_msi(rdev->pdev); |
| 134 | if (!ret) { | 170 | if (!ret) { |
| 135 | rdev->msi_enabled = 1; | 171 | rdev->msi_enabled = 1; |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ed0178f03235..2c2e75ef8a37 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -438,9 +438,6 @@ struct radeon_connector { | |||
| 438 | struct radeon_i2c_chan *ddc_bus; | 438 | struct radeon_i2c_chan *ddc_bus; |
| 439 | /* some systems have an hdmi and vga port with a shared ddc line */ | 439 | /* some systems have an hdmi and vga port with a shared ddc line */ |
| 440 | bool shared_ddc; | 440 | bool shared_ddc; |
| 441 | /* for some Radeon chip families we apply an additional EDID header | ||
| 442 | check as part of the DDC probe */ | ||
| 443 | bool requires_extended_probe; | ||
| 444 | bool use_digital; | 441 | bool use_digital; |
| 445 | /* we need to mind the EDID between detect | 442 | /* we need to mind the EDID between detect |
| 446 | and get modes due to analog/digital/tvencoder */ | 443 | and get modes due to analog/digital/tvencoder */ |
| @@ -459,6 +456,8 @@ struct radeon_framebuffer { | |||
| 459 | struct drm_gem_object *obj; | 456 | struct drm_gem_object *obj; |
| 460 | }; | 457 | }; |
| 461 | 458 | ||
| 459 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ | ||
| 460 | ((em) == ATOM_ENCODER_MODE_DP_MST)) | ||
| 462 | 461 | ||
| 463 | extern enum radeon_tv_std | 462 | extern enum radeon_tv_std |
| 464 | radeon_combios_get_tv_info(struct radeon_device *rdev); | 463 | radeon_combios_get_tv_info(struct radeon_device *rdev); |
| @@ -468,8 +467,8 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); | |||
| 468 | extern struct drm_connector * | 467 | extern struct drm_connector * |
| 469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | 468 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); |
| 470 | 469 | ||
| 471 | extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder); | 470 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); |
| 472 | extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); | 471 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
| 473 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); | 472 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); |
| 474 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); | 473 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); |
| 475 | 474 | ||
| @@ -489,7 +488,7 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | |||
| 489 | int action, uint8_t lane_num, | 488 | int action, uint8_t lane_num, |
| 490 | uint8_t lane_set); | 489 | uint8_t lane_set); |
| 491 | extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); | 490 | extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); |
| 492 | extern struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder); | 491 | extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder); |
| 493 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | 492 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |
| 494 | u8 write_byte, u8 *read_byte); | 493 | u8 write_byte, u8 *read_byte); |
| 495 | 494 | ||
| @@ -519,8 +518,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, | |||
| 519 | u8 val); | 518 | u8 val); |
| 520 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); | 519 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
| 521 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); | 520 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
| 522 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, | 521 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
| 523 | bool requires_extended_probe); | ||
| 524 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); | 522 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
| 525 | 523 | ||
| 526 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); | 524 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 89a6e1ecea8d..06b90c87f8f3 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
| @@ -77,7 +77,7 @@ int rs400_gart_init(struct radeon_device *rdev) | |||
| 77 | { | 77 | { |
| 78 | int r; | 78 | int r; |
| 79 | 79 | ||
| 80 | if (rdev->gart.table.ram.ptr) { | 80 | if (rdev->gart.ptr) { |
| 81 | WARN(1, "RS400 GART already initialized\n"); | 81 | WARN(1, "RS400 GART already initialized\n"); |
| 82 | return 0; | 82 | return 0; |
| 83 | } | 83 | } |
| @@ -212,6 +212,7 @@ void rs400_gart_fini(struct radeon_device *rdev) | |||
| 212 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 212 | int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
| 213 | { | 213 | { |
| 214 | uint32_t entry; | 214 | uint32_t entry; |
| 215 | u32 *gtt = rdev->gart.ptr; | ||
| 215 | 216 | ||
| 216 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 217 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
| 217 | return -EINVAL; | 218 | return -EINVAL; |
| @@ -221,7 +222,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | |||
| 221 | ((upper_32_bits(addr) & 0xff) << 4) | | 222 | ((upper_32_bits(addr) & 0xff) << 4) | |
| 222 | RS400_PTE_WRITEABLE | RS400_PTE_READABLE; | 223 | RS400_PTE_WRITEABLE | RS400_PTE_READABLE; |
| 223 | entry = cpu_to_le32(entry); | 224 | entry = cpu_to_le32(entry); |
| 224 | rdev->gart.table.ram.ptr[i] = entry; | 225 | gtt[i] = entry; |
| 225 | return 0; | 226 | return 0; |
| 226 | } | 227 | } |
| 227 | 228 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 9320dd6404f6..481b99e89f65 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -287,6 +287,7 @@ void rs600_hpd_init(struct radeon_device *rdev) | |||
| 287 | default: | 287 | default: |
| 288 | break; | 288 | break; |
| 289 | } | 289 | } |
| 290 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
| 290 | } | 291 | } |
| 291 | if (rdev->irq.installed) | 292 | if (rdev->irq.installed) |
| 292 | rs600_irq_set(rdev); | 293 | rs600_irq_set(rdev); |
| @@ -413,7 +414,7 @@ int rs600_gart_init(struct radeon_device *rdev) | |||
| 413 | { | 414 | { |
| 414 | int r; | 415 | int r; |
| 415 | 416 | ||
| 416 | if (rdev->gart.table.vram.robj) { | 417 | if (rdev->gart.robj) { |
| 417 | WARN(1, "RS600 GART already initialized\n"); | 418 | WARN(1, "RS600 GART already initialized\n"); |
| 418 | return 0; | 419 | return 0; |
| 419 | } | 420 | } |
| @@ -431,7 +432,7 @@ static int rs600_gart_enable(struct radeon_device *rdev) | |||
| 431 | u32 tmp; | 432 | u32 tmp; |
| 432 | int r, i; | 433 | int r, i; |
| 433 | 434 | ||
| 434 | if (rdev->gart.table.vram.robj == NULL) { | 435 | if (rdev->gart.robj == NULL) { |
| 435 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 436 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 436 | return -EINVAL; | 437 | return -EINVAL; |
| 437 | } | 438 | } |
| @@ -494,20 +495,12 @@ static int rs600_gart_enable(struct radeon_device *rdev) | |||
| 494 | void rs600_gart_disable(struct radeon_device *rdev) | 495 | void rs600_gart_disable(struct radeon_device *rdev) |
| 495 | { | 496 | { |
| 496 | u32 tmp; | 497 | u32 tmp; |
| 497 | int r; | ||
| 498 | 498 | ||
| 499 | /* FIXME: disable out of gart access */ | 499 | /* FIXME: disable out of gart access */ |
| 500 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); | 500 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); |
| 501 | tmp = RREG32_MC(R_000009_MC_CNTL1); | 501 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
| 502 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); | 502 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); |
| 503 | if (rdev->gart.table.vram.robj) { | 503 | radeon_gart_table_vram_unpin(rdev); |
| 504 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 505 | if (r == 0) { | ||
| 506 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 507 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 508 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 509 | } | ||
| 510 | } | ||
| 511 | } | 504 | } |
| 512 | 505 | ||
| 513 | void rs600_gart_fini(struct radeon_device *rdev) | 506 | void rs600_gart_fini(struct radeon_device *rdev) |
| @@ -525,7 +518,7 @@ void rs600_gart_fini(struct radeon_device *rdev) | |||
| 525 | 518 | ||
| 526 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 519 | int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
| 527 | { | 520 | { |
| 528 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 521 | void __iomem *ptr = (void *)rdev->gart.ptr; |
| 529 | 522 | ||
| 530 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | 523 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
| 531 | return -EINVAL; | 524 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 87cc1feee3ac..a983f410ab89 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -124,7 +124,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
| 124 | u32 tmp; | 124 | u32 tmp; |
| 125 | int r, i; | 125 | int r, i; |
| 126 | 126 | ||
| 127 | if (rdev->gart.table.vram.robj == NULL) { | 127 | if (rdev->gart.robj == NULL) { |
| 128 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | 128 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
| 129 | return -EINVAL; | 129 | return -EINVAL; |
| 130 | } | 130 | } |
| @@ -171,7 +171,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
| 171 | void rv770_pcie_gart_disable(struct radeon_device *rdev) | 171 | void rv770_pcie_gart_disable(struct radeon_device *rdev) |
| 172 | { | 172 | { |
| 173 | u32 tmp; | 173 | u32 tmp; |
| 174 | int i, r; | 174 | int i; |
| 175 | 175 | ||
| 176 | /* Disable all tables */ | 176 | /* Disable all tables */ |
| 177 | for (i = 0; i < 7; i++) | 177 | for (i = 0; i < 7; i++) |
| @@ -191,14 +191,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) | |||
| 191 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 191 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
| 192 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 192 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
| 193 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 193 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
| 194 | if (rdev->gart.table.vram.robj) { | 194 | radeon_gart_table_vram_unpin(rdev); |
| 195 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
| 196 | if (likely(r == 0)) { | ||
| 197 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
| 198 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
| 199 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | 195 | } |
| 203 | 196 | ||
| 204 | void rv770_pcie_gart_fini(struct radeon_device *rdev) | 197 | void rv770_pcie_gart_fini(struct radeon_device *rdev) |
| @@ -282,7 +275,7 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
| 282 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 275 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
| 283 | rdev->mc.vram_end >> 12); | 276 | rdev->mc.vram_end >> 12); |
| 284 | } | 277 | } |
| 285 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 278 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
| 286 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 279 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
| 287 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 280 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
| 288 | WREG32(MC_VM_FB_LOCATION, tmp); | 281 | WREG32(MC_VM_FB_LOCATION, tmp); |
| @@ -959,54 +952,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 959 | 952 | ||
| 960 | } | 953 | } |
| 961 | 954 | ||
| 962 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
| 963 | { | ||
| 964 | int r; | ||
| 965 | u64 gpu_addr; | ||
| 966 | |||
| 967 | if (rdev->vram_scratch.robj == NULL) { | ||
| 968 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
| 969 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
| 970 | &rdev->vram_scratch.robj); | ||
| 971 | if (r) { | ||
| 972 | return r; | ||
| 973 | } | ||
| 974 | } | ||
| 975 | |||
| 976 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 977 | if (unlikely(r != 0)) | ||
| 978 | return r; | ||
| 979 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
| 980 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
| 981 | if (r) { | ||
| 982 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 983 | return r; | ||
| 984 | } | ||
| 985 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
| 986 | (void **)&rdev->vram_scratch.ptr); | ||
| 987 | if (r) | ||
| 988 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 989 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 990 | |||
| 991 | return r; | ||
| 992 | } | ||
| 993 | |||
| 994 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
| 995 | { | ||
| 996 | int r; | ||
| 997 | |||
| 998 | if (rdev->vram_scratch.robj == NULL) { | ||
| 999 | return; | ||
| 1000 | } | ||
| 1001 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 1002 | if (likely(r == 0)) { | ||
| 1003 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
| 1004 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 1005 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 1006 | } | ||
| 1007 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 955 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
| 1011 | { | 956 | { |
| 1012 | u64 size_bf, size_af; | 957 | u64 size_bf, size_af; |
| @@ -1106,6 +1051,10 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 1106 | } | 1051 | } |
| 1107 | } | 1052 | } |
| 1108 | 1053 | ||
| 1054 | r = r600_vram_scratch_init(rdev); | ||
| 1055 | if (r) | ||
| 1056 | return r; | ||
| 1057 | |||
| 1109 | rv770_mc_program(rdev); | 1058 | rv770_mc_program(rdev); |
| 1110 | if (rdev->flags & RADEON_IS_AGP) { | 1059 | if (rdev->flags & RADEON_IS_AGP) { |
| 1111 | rv770_agp_enable(rdev); | 1060 | rv770_agp_enable(rdev); |
| @@ -1114,9 +1063,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 1114 | if (r) | 1063 | if (r) |
| 1115 | return r; | 1064 | return r; |
| 1116 | } | 1065 | } |
| 1117 | r = rv770_vram_scratch_init(rdev); | 1066 | |
| 1118 | if (r) | ||
| 1119 | return r; | ||
| 1120 | rv770_gpu_init(rdev); | 1067 | rv770_gpu_init(rdev); |
| 1121 | r = r600_blit_init(rdev); | 1068 | r = r600_blit_init(rdev); |
| 1122 | if (r) { | 1069 | if (r) { |
| @@ -1316,7 +1263,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
| 1316 | radeon_ib_pool_fini(rdev); | 1263 | radeon_ib_pool_fini(rdev); |
| 1317 | radeon_irq_kms_fini(rdev); | 1264 | radeon_irq_kms_fini(rdev); |
| 1318 | rv770_pcie_gart_fini(rdev); | 1265 | rv770_pcie_gart_fini(rdev); |
| 1319 | rv770_vram_scratch_fini(rdev); | 1266 | r600_vram_scratch_fini(rdev); |
| 1320 | radeon_gem_fini(rdev); | 1267 | radeon_gem_fini(rdev); |
| 1321 | radeon_fence_driver_fini(rdev); | 1268 | radeon_fence_driver_fini(rdev); |
| 1322 | radeon_agp_fini(rdev); | 1269 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 1805b8c2a948..dff8fc767152 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -104,6 +104,9 @@ | |||
| 104 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ | 104 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ |
| 105 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ | 105 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ |
| 106 | struct drm_vmw_present_readback_arg) | 106 | struct drm_vmw_present_readback_arg) |
| 107 | #define DRM_IOCTL_VMW_UPDATE_LAYOUT \ | ||
| 108 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \ | ||
| 109 | struct drm_vmw_update_layout_arg) | ||
| 107 | 110 | ||
| 108 | /** | 111 | /** |
| 109 | * The core DRM version of this macro doesn't account for | 112 | * The core DRM version of this macro doesn't account for |
| @@ -166,6 +169,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = { | |||
| 166 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, | 169 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, |
| 167 | vmw_present_readback_ioctl, | 170 | vmw_present_readback_ioctl, |
| 168 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | 171 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), |
| 172 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, | ||
| 173 | vmw_kms_update_layout_ioctl, | ||
| 174 | DRM_MASTER | DRM_UNLOCKED), | ||
| 169 | }; | 175 | }; |
| 170 | 176 | ||
| 171 | static struct pci_device_id vmw_pci_id_list[] = { | 177 | static struct pci_device_id vmw_pci_id_list[] = { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 30589d0aecd9..8cca91a93bde 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -40,9 +40,9 @@ | |||
| 40 | #include "ttm/ttm_module.h" | 40 | #include "ttm/ttm_module.h" |
| 41 | #include "vmwgfx_fence.h" | 41 | #include "vmwgfx_fence.h" |
| 42 | 42 | ||
| 43 | #define VMWGFX_DRIVER_DATE "20111008" | 43 | #define VMWGFX_DRIVER_DATE "20111025" |
| 44 | #define VMWGFX_DRIVER_MAJOR 2 | 44 | #define VMWGFX_DRIVER_MAJOR 2 |
| 45 | #define VMWGFX_DRIVER_MINOR 2 | 45 | #define VMWGFX_DRIVER_MINOR 3 |
| 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
| 47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 | 47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 |
| 48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
| @@ -633,6 +633,8 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
| 633 | struct drm_vmw_fence_rep __user *user_fence_rep, | 633 | struct drm_vmw_fence_rep __user *user_fence_rep, |
| 634 | struct drm_vmw_rect *clips, | 634 | struct drm_vmw_rect *clips, |
| 635 | uint32_t num_clips); | 635 | uint32_t num_clips); |
| 636 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | ||
| 637 | struct drm_file *file_priv); | ||
| 636 | 638 | ||
| 637 | /** | 639 | /** |
| 638 | * Overlay control - vmwgfx_overlay.c | 640 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8b14dfd513a1..03daefa73397 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -111,6 +111,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 111 | if (!ret) { | 111 | if (!ret) { |
| 112 | if (!surface->snooper.image) { | 112 | if (!surface->snooper.image) { |
| 113 | DRM_ERROR("surface not suitable for cursor\n"); | 113 | DRM_ERROR("surface not suitable for cursor\n"); |
| 114 | vmw_surface_unreference(&surface); | ||
| 114 | return -EINVAL; | 115 | return -EINVAL; |
| 115 | } | 116 | } |
| 116 | } else { | 117 | } else { |
| @@ -176,7 +177,9 @@ err_unreserve: | |||
| 176 | return 0; | 177 | return 0; |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 179 | vmw_cursor_update_position(dev_priv, true, du->cursor_x, du->cursor_y); | 180 | vmw_cursor_update_position(dev_priv, true, |
| 181 | du->cursor_x + du->hotspot_x, | ||
| 182 | du->cursor_y + du->hotspot_y); | ||
| 180 | 183 | ||
| 181 | return 0; | 184 | return 0; |
| 182 | } | 185 | } |
| @@ -191,7 +194,8 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 191 | du->cursor_y = y + crtc->y; | 194 | du->cursor_y = y + crtc->y; |
| 192 | 195 | ||
| 193 | vmw_cursor_update_position(dev_priv, shown, | 196 | vmw_cursor_update_position(dev_priv, shown, |
| 194 | du->cursor_x, du->cursor_y); | 197 | du->cursor_x + du->hotspot_x, |
| 198 | du->cursor_y + du->hotspot_y); | ||
| 195 | 199 | ||
| 196 | return 0; | 200 | return 0; |
| 197 | } | 201 | } |
| @@ -212,7 +216,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
| 212 | SVGA3dCmdHeader header; | 216 | SVGA3dCmdHeader header; |
| 213 | SVGA3dCmdSurfaceDMA dma; | 217 | SVGA3dCmdSurfaceDMA dma; |
| 214 | } *cmd; | 218 | } *cmd; |
| 215 | int ret; | 219 | int i, ret; |
| 216 | 220 | ||
| 217 | cmd = container_of(header, struct vmw_dma_cmd, header); | 221 | cmd = container_of(header, struct vmw_dma_cmd, header); |
| 218 | 222 | ||
| @@ -234,16 +238,19 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
| 234 | box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) / | 238 | box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) / |
| 235 | sizeof(SVGA3dCopyBox); | 239 | sizeof(SVGA3dCopyBox); |
| 236 | 240 | ||
| 237 | if (cmd->dma.guest.pitch != (64 * 4) || | 241 | if (cmd->dma.guest.ptr.offset % PAGE_SIZE || |
| 238 | cmd->dma.guest.ptr.offset % PAGE_SIZE || | ||
| 239 | box->x != 0 || box->y != 0 || box->z != 0 || | 242 | box->x != 0 || box->y != 0 || box->z != 0 || |
| 240 | box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || | 243 | box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || |
| 241 | box->w != 64 || box->h != 64 || box->d != 1 || | 244 | box->d != 1 || box_count != 1) { |
| 242 | box_count != 1) { | ||
| 243 | /* TODO handle none page aligned offsets */ | 245 | /* TODO handle none page aligned offsets */ |
| 244 | /* TODO handle partial uploads and pitch != 256 */ | 246 | /* TODO handle more dst & src != 0 */ |
| 245 | /* TODO handle more then one copy (size != 64) */ | 247 | /* TODO handle more then one copy */ |
| 246 | DRM_ERROR("lazy programmer, can't handle weird stuff\n"); | 248 | DRM_ERROR("Cant snoop dma request for cursor!\n"); |
| 249 | DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n", | ||
| 250 | box->srcx, box->srcy, box->srcz, | ||
| 251 | box->x, box->y, box->z, | ||
| 252 | box->w, box->h, box->d, box_count, | ||
| 253 | cmd->dma.guest.ptr.offset); | ||
| 247 | return; | 254 | return; |
| 248 | } | 255 | } |
| 249 | 256 | ||
| @@ -262,7 +269,16 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, | |||
| 262 | 269 | ||
| 263 | virtual = ttm_kmap_obj_virtual(&map, &dummy); | 270 | virtual = ttm_kmap_obj_virtual(&map, &dummy); |
| 264 | 271 | ||
| 265 | memcpy(srf->snooper.image, virtual, 64*64*4); | 272 | if (box->w == 64 && cmd->dma.guest.pitch == 64*4) { |
| 273 | memcpy(srf->snooper.image, virtual, 64*64*4); | ||
| 274 | } else { | ||
| 275 | /* Image is unsigned pointer. */ | ||
| 276 | for (i = 0; i < box->h; i++) | ||
| 277 | memcpy(srf->snooper.image + i * 64, | ||
| 278 | virtual + i * cmd->dma.guest.pitch, | ||
| 279 | box->w * 4); | ||
| 280 | } | ||
| 281 | |||
| 266 | srf->snooper.age++; | 282 | srf->snooper.age++; |
| 267 | 283 | ||
| 268 | /* we can't call this function from this function since execbuf has | 284 | /* we can't call this function from this function since execbuf has |
| @@ -994,7 +1010,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, | |||
| 994 | required_size = mode_cmd->pitch * mode_cmd->height; | 1010 | required_size = mode_cmd->pitch * mode_cmd->height; |
| 995 | if (unlikely(required_size > (u64) dev_priv->vram_size)) { | 1011 | if (unlikely(required_size > (u64) dev_priv->vram_size)) { |
| 996 | DRM_ERROR("VRAM size is too small for requested mode.\n"); | 1012 | DRM_ERROR("VRAM size is too small for requested mode.\n"); |
| 997 | return NULL; | 1013 | return ERR_PTR(-ENOMEM); |
| 998 | } | 1014 | } |
| 999 | 1015 | ||
| 1000 | /* | 1016 | /* |
| @@ -1517,6 +1533,8 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
| 1517 | du->pref_width = rects[du->unit].w; | 1533 | du->pref_width = rects[du->unit].w; |
| 1518 | du->pref_height = rects[du->unit].h; | 1534 | du->pref_height = rects[du->unit].h; |
| 1519 | du->pref_active = true; | 1535 | du->pref_active = true; |
| 1536 | du->gui_x = rects[du->unit].x; | ||
| 1537 | du->gui_y = rects[du->unit].y; | ||
| 1520 | } else { | 1538 | } else { |
| 1521 | du->pref_width = 800; | 1539 | du->pref_width = 800; |
| 1522 | du->pref_height = 600; | 1540 | du->pref_height = 600; |
| @@ -1572,12 +1590,14 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) | |||
| 1572 | uint32_t num_displays; | 1590 | uint32_t num_displays; |
| 1573 | struct drm_device *dev = connector->dev; | 1591 | struct drm_device *dev = connector->dev; |
| 1574 | struct vmw_private *dev_priv = vmw_priv(dev); | 1592 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1593 | struct vmw_display_unit *du = vmw_connector_to_du(connector); | ||
| 1575 | 1594 | ||
| 1576 | mutex_lock(&dev_priv->hw_mutex); | 1595 | mutex_lock(&dev_priv->hw_mutex); |
| 1577 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); | 1596 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); |
| 1578 | mutex_unlock(&dev_priv->hw_mutex); | 1597 | mutex_unlock(&dev_priv->hw_mutex); |
| 1579 | 1598 | ||
| 1580 | return ((vmw_connector_to_du(connector)->unit < num_displays) ? | 1599 | return ((vmw_connector_to_du(connector)->unit < num_displays && |
| 1600 | du->pref_active) ? | ||
| 1581 | connector_status_connected : connector_status_disconnected); | 1601 | connector_status_connected : connector_status_disconnected); |
| 1582 | } | 1602 | } |
| 1583 | 1603 | ||
| @@ -1658,6 +1678,28 @@ static struct drm_display_mode vmw_kms_connector_builtin[] = { | |||
| 1658 | { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, | 1678 | { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, |
| 1659 | }; | 1679 | }; |
| 1660 | 1680 | ||
| 1681 | /** | ||
| 1682 | * vmw_guess_mode_timing - Provide fake timings for a | ||
| 1683 | * 60Hz vrefresh mode. | ||
| 1684 | * | ||
| 1685 | * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay | ||
| 1686 | * members filled in. | ||
| 1687 | */ | ||
| 1688 | static void vmw_guess_mode_timing(struct drm_display_mode *mode) | ||
| 1689 | { | ||
| 1690 | mode->hsync_start = mode->hdisplay + 50; | ||
| 1691 | mode->hsync_end = mode->hsync_start + 50; | ||
| 1692 | mode->htotal = mode->hsync_end + 50; | ||
| 1693 | |||
| 1694 | mode->vsync_start = mode->vdisplay + 50; | ||
| 1695 | mode->vsync_end = mode->vsync_start + 50; | ||
| 1696 | mode->vtotal = mode->vsync_end + 50; | ||
| 1697 | |||
| 1698 | mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6; | ||
| 1699 | mode->vrefresh = drm_mode_vrefresh(mode); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | |||
| 1661 | int vmw_du_connector_fill_modes(struct drm_connector *connector, | 1703 | int vmw_du_connector_fill_modes(struct drm_connector *connector, |
| 1662 | uint32_t max_width, uint32_t max_height) | 1704 | uint32_t max_width, uint32_t max_height) |
| 1663 | { | 1705 | { |
| @@ -1680,18 +1722,23 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 1680 | return 0; | 1722 | return 0; |
| 1681 | mode->hdisplay = du->pref_width; | 1723 | mode->hdisplay = du->pref_width; |
| 1682 | mode->vdisplay = du->pref_height; | 1724 | mode->vdisplay = du->pref_height; |
| 1683 | mode->vrefresh = drm_mode_vrefresh(mode); | 1725 | vmw_guess_mode_timing(mode); |
| 1726 | |||
| 1684 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, | 1727 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, |
| 1685 | mode->vdisplay)) { | 1728 | mode->vdisplay)) { |
| 1686 | drm_mode_probed_add(connector, mode); | 1729 | drm_mode_probed_add(connector, mode); |
| 1730 | } else { | ||
| 1731 | drm_mode_destroy(dev, mode); | ||
| 1732 | mode = NULL; | ||
| 1733 | } | ||
| 1687 | 1734 | ||
| 1688 | if (du->pref_mode) { | 1735 | if (du->pref_mode) { |
| 1689 | list_del_init(&du->pref_mode->head); | 1736 | list_del_init(&du->pref_mode->head); |
| 1690 | drm_mode_destroy(dev, du->pref_mode); | 1737 | drm_mode_destroy(dev, du->pref_mode); |
| 1691 | } | ||
| 1692 | |||
| 1693 | du->pref_mode = mode; | ||
| 1694 | } | 1738 | } |
| 1739 | |||
| 1740 | /* mode might be null here, this is intended */ | ||
| 1741 | du->pref_mode = mode; | ||
| 1695 | } | 1742 | } |
| 1696 | 1743 | ||
| 1697 | for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { | 1744 | for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { |
| @@ -1712,6 +1759,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 1712 | drm_mode_probed_add(connector, mode); | 1759 | drm_mode_probed_add(connector, mode); |
| 1713 | } | 1760 | } |
| 1714 | 1761 | ||
| 1762 | /* Move the prefered mode first, help apps pick the right mode. */ | ||
| 1763 | if (du->pref_mode) | ||
| 1764 | list_move(&du->pref_mode->head, &connector->probed_modes); | ||
| 1765 | |||
| 1715 | drm_mode_connector_list_update(connector); | 1766 | drm_mode_connector_list_update(connector); |
| 1716 | 1767 | ||
| 1717 | return 1; | 1768 | return 1; |
| @@ -1723,3 +1774,63 @@ int vmw_du_connector_set_property(struct drm_connector *connector, | |||
| 1723 | { | 1774 | { |
| 1724 | return 0; | 1775 | return 0; |
| 1725 | } | 1776 | } |
| 1777 | |||
| 1778 | |||
| 1779 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | ||
| 1780 | struct drm_file *file_priv) | ||
| 1781 | { | ||
| 1782 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
| 1783 | struct drm_vmw_update_layout_arg *arg = | ||
| 1784 | (struct drm_vmw_update_layout_arg *)data; | ||
| 1785 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
| 1786 | void __user *user_rects; | ||
| 1787 | struct drm_vmw_rect *rects; | ||
| 1788 | unsigned rects_size; | ||
| 1789 | int ret; | ||
| 1790 | int i; | ||
| 1791 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
| 1792 | |||
| 1793 | ret = ttm_read_lock(&vmaster->lock, true); | ||
| 1794 | if (unlikely(ret != 0)) | ||
| 1795 | return ret; | ||
| 1796 | |||
| 1797 | if (!arg->num_outputs) { | ||
| 1798 | struct drm_vmw_rect def_rect = {0, 0, 800, 600}; | ||
| 1799 | vmw_du_update_layout(dev_priv, 1, &def_rect); | ||
| 1800 | goto out_unlock; | ||
| 1801 | } | ||
| 1802 | |||
| 1803 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); | ||
| 1804 | rects = kzalloc(rects_size, GFP_KERNEL); | ||
| 1805 | if (unlikely(!rects)) { | ||
| 1806 | ret = -ENOMEM; | ||
| 1807 | goto out_unlock; | ||
| 1808 | } | ||
| 1809 | |||
| 1810 | user_rects = (void __user *)(unsigned long)arg->rects; | ||
| 1811 | ret = copy_from_user(rects, user_rects, rects_size); | ||
| 1812 | if (unlikely(ret != 0)) { | ||
| 1813 | DRM_ERROR("Failed to get rects.\n"); | ||
| 1814 | ret = -EFAULT; | ||
| 1815 | goto out_free; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | for (i = 0; i < arg->num_outputs; ++i) { | ||
| 1819 | if (rects->x < 0 || | ||
| 1820 | rects->y < 0 || | ||
| 1821 | rects->x + rects->w > mode_config->max_width || | ||
| 1822 | rects->y + rects->h > mode_config->max_height) { | ||
| 1823 | DRM_ERROR("Invalid GUI layout.\n"); | ||
| 1824 | ret = -EINVAL; | ||
| 1825 | goto out_free; | ||
| 1826 | } | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | vmw_du_update_layout(dev_priv, arg->num_outputs, rects); | ||
| 1830 | |||
| 1831 | out_free: | ||
| 1832 | kfree(rects); | ||
| 1833 | out_unlock: | ||
| 1834 | ttm_read_unlock(&vmaster->lock); | ||
| 1835 | return ret; | ||
| 1836 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index db0b901f8c3f..af8e6e5bd964 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
| @@ -96,6 +96,13 @@ struct vmw_display_unit { | |||
| 96 | unsigned pref_height; | 96 | unsigned pref_height; |
| 97 | bool pref_active; | 97 | bool pref_active; |
| 98 | struct drm_display_mode *pref_mode; | 98 | struct drm_display_mode *pref_mode; |
| 99 | |||
| 100 | /* | ||
| 101 | * Gui positioning | ||
| 102 | */ | ||
| 103 | int gui_x; | ||
| 104 | int gui_y; | ||
| 105 | bool is_implicit; | ||
| 99 | }; | 106 | }; |
| 100 | 107 | ||
| 101 | #define vmw_crtc_to_du(x) \ | 108 | #define vmw_crtc_to_du(x) \ |
| @@ -126,8 +133,7 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
| 126 | int vmw_du_connector_set_property(struct drm_connector *connector, | 133 | int vmw_du_connector_set_property(struct drm_connector *connector, |
| 127 | struct drm_property *property, | 134 | struct drm_property *property, |
| 128 | uint64_t val); | 135 | uint64_t val); |
| 129 | int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | 136 | |
| 130 | struct drm_vmw_rect *rects); | ||
| 131 | 137 | ||
| 132 | /* | 138 | /* |
| 133 | * Legacy display unit functions - vmwgfx_ldu.c | 139 | * Legacy display unit functions - vmwgfx_ldu.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 92f56bc594eb..90c5e3928491 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
| @@ -337,13 +337,14 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 337 | ldu->base.pref_width = 800; | 337 | ldu->base.pref_width = 800; |
| 338 | ldu->base.pref_height = 600; | 338 | ldu->base.pref_height = 600; |
| 339 | ldu->base.pref_mode = NULL; | 339 | ldu->base.pref_mode = NULL; |
| 340 | ldu->base.is_implicit = true; | ||
| 340 | 341 | ||
| 341 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 342 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
| 342 | DRM_MODE_CONNECTOR_LVDS); | 343 | DRM_MODE_CONNECTOR_VIRTUAL); |
| 343 | connector->status = vmw_du_connector_detect(connector, true); | 344 | connector->status = vmw_du_connector_detect(connector, true); |
| 344 | 345 | ||
| 345 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, | 346 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, |
| 346 | DRM_MODE_ENCODER_LVDS); | 347 | DRM_MODE_ENCODER_VIRTUAL); |
| 347 | drm_mode_connector_attach_encoder(connector, encoder); | 348 | drm_mode_connector_attach_encoder(connector, encoder); |
| 348 | encoder->possible_crtcs = (1 << unit); | 349 | encoder->possible_crtcs = (1 << unit); |
| 349 | encoder->possible_clones = 0; | 350 | encoder->possible_clones = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 477b2a9eb3c2..4defdcf1c72e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
| @@ -36,12 +36,9 @@ | |||
| 36 | container_of(x, struct vmw_screen_object_unit, base.connector) | 36 | container_of(x, struct vmw_screen_object_unit, base.connector) |
| 37 | 37 | ||
| 38 | struct vmw_screen_object_display { | 38 | struct vmw_screen_object_display { |
| 39 | struct list_head active; | 39 | unsigned num_implicit; |
| 40 | 40 | ||
| 41 | unsigned num_active; | 41 | struct vmw_framebuffer *implicit_fb; |
| 42 | unsigned last_num_active; | ||
| 43 | |||
| 44 | struct vmw_framebuffer *fb; | ||
| 45 | }; | 42 | }; |
| 46 | 43 | ||
| 47 | /** | 44 | /** |
| @@ -54,13 +51,11 @@ struct vmw_screen_object_unit { | |||
| 54 | struct vmw_dma_buffer *buffer; /**< Backing store buffer */ | 51 | struct vmw_dma_buffer *buffer; /**< Backing store buffer */ |
| 55 | 52 | ||
| 56 | bool defined; | 53 | bool defined; |
| 57 | 54 | bool active_implicit; | |
| 58 | struct list_head active; | ||
| 59 | }; | 55 | }; |
| 60 | 56 | ||
| 61 | static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) | 57 | static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) |
| 62 | { | 58 | { |
| 63 | list_del_init(&sou->active); | ||
| 64 | vmw_display_unit_cleanup(&sou->base); | 59 | vmw_display_unit_cleanup(&sou->base); |
| 65 | kfree(sou); | 60 | kfree(sou); |
| 66 | } | 61 | } |
| @@ -75,58 +70,31 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc) | |||
| 75 | vmw_sou_destroy(vmw_crtc_to_sou(crtc)); | 70 | vmw_sou_destroy(vmw_crtc_to_sou(crtc)); |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | static int vmw_sou_del_active(struct vmw_private *vmw_priv, | 73 | static void vmw_sou_del_active(struct vmw_private *vmw_priv, |
| 79 | struct vmw_screen_object_unit *sou) | 74 | struct vmw_screen_object_unit *sou) |
| 80 | { | 75 | { |
| 81 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; | 76 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; |
| 82 | if (list_empty(&sou->active)) | ||
| 83 | return 0; | ||
| 84 | 77 | ||
| 85 | /* Must init otherwise list_empty(&sou->active) will not work. */ | 78 | if (sou->active_implicit) { |
| 86 | list_del_init(&sou->active); | 79 | if (--(ld->num_implicit) == 0) |
| 87 | if (--(ld->num_active) == 0) { | 80 | ld->implicit_fb = NULL; |
| 88 | BUG_ON(!ld->fb); | 81 | sou->active_implicit = false; |
| 89 | if (ld->fb->unpin) | ||
| 90 | ld->fb->unpin(ld->fb); | ||
| 91 | ld->fb = NULL; | ||
| 92 | } | 82 | } |
| 93 | |||
| 94 | return 0; | ||
| 95 | } | 83 | } |
| 96 | 84 | ||
| 97 | static int vmw_sou_add_active(struct vmw_private *vmw_priv, | 85 | static void vmw_sou_add_active(struct vmw_private *vmw_priv, |
| 98 | struct vmw_screen_object_unit *sou, | 86 | struct vmw_screen_object_unit *sou, |
| 99 | struct vmw_framebuffer *vfb) | 87 | struct vmw_framebuffer *vfb) |
| 100 | { | 88 | { |
| 101 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; | 89 | struct vmw_screen_object_display *ld = vmw_priv->sou_priv; |
| 102 | struct vmw_screen_object_unit *entry; | ||
| 103 | struct list_head *at; | ||
| 104 | |||
| 105 | BUG_ON(!ld->num_active && ld->fb); | ||
| 106 | if (vfb != ld->fb) { | ||
| 107 | if (ld->fb && ld->fb->unpin) | ||
| 108 | ld->fb->unpin(ld->fb); | ||
| 109 | if (vfb->pin) | ||
| 110 | vfb->pin(vfb); | ||
| 111 | ld->fb = vfb; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (!list_empty(&sou->active)) | ||
| 115 | return 0; | ||
| 116 | 90 | ||
| 117 | at = &ld->active; | 91 | BUG_ON(!ld->num_implicit && ld->implicit_fb); |
| 118 | list_for_each_entry(entry, &ld->active, active) { | ||
| 119 | if (entry->base.unit > sou->base.unit) | ||
| 120 | break; | ||
| 121 | 92 | ||
| 122 | at = &entry->active; | 93 | if (!sou->active_implicit && sou->base.is_implicit) { |
| 94 | ld->implicit_fb = vfb; | ||
| 95 | sou->active_implicit = true; | ||
| 96 | ld->num_implicit++; | ||
| 123 | } | 97 | } |
| 124 | |||
| 125 | list_add(&sou->active, at); | ||
| 126 | |||
| 127 | ld->num_active++; | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | } | 98 | } |
| 131 | 99 | ||
| 132 | /** | 100 | /** |
| @@ -164,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, | |||
| 164 | (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0); | 132 | (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0); |
| 165 | cmd->obj.size.width = mode->hdisplay; | 133 | cmd->obj.size.width = mode->hdisplay; |
| 166 | cmd->obj.size.height = mode->vdisplay; | 134 | cmd->obj.size.height = mode->vdisplay; |
| 167 | cmd->obj.root.x = x; | 135 | if (sou->base.is_implicit) { |
| 168 | cmd->obj.root.y = y; | 136 | cmd->obj.root.x = x; |
| 137 | cmd->obj.root.y = y; | ||
| 138 | } else { | ||
| 139 | cmd->obj.root.x = sou->base.gui_x; | ||
| 140 | cmd->obj.root.y = sou->base.gui_y; | ||
| 141 | } | ||
| 169 | 142 | ||
| 170 | /* Ok to assume that buffer is pinned in vram */ | 143 | /* Ok to assume that buffer is pinned in vram */ |
| 171 | vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); | 144 | vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); |
| @@ -312,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) | |||
| 312 | } | 285 | } |
| 313 | 286 | ||
| 314 | /* sou only supports one fb active at the time */ | 287 | /* sou only supports one fb active at the time */ |
| 315 | if (dev_priv->sou_priv->fb && vfb && | 288 | if (sou->base.is_implicit && |
| 316 | !(dev_priv->sou_priv->num_active == 1 && | 289 | dev_priv->sou_priv->implicit_fb && vfb && |
| 317 | !list_empty(&sou->active)) && | 290 | !(dev_priv->sou_priv->num_implicit == 1 && |
| 318 | dev_priv->sou_priv->fb != vfb) { | 291 | sou->active_implicit) && |
| 292 | dev_priv->sou_priv->implicit_fb != vfb) { | ||
| 319 | DRM_ERROR("Multiple framebuffers not supported\n"); | 293 | DRM_ERROR("Multiple framebuffers not supported\n"); |
| 320 | return -EINVAL; | 294 | return -EINVAL; |
| 321 | } | 295 | } |
| @@ -471,19 +445,20 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 471 | encoder = &sou->base.encoder; | 445 | encoder = &sou->base.encoder; |
| 472 | connector = &sou->base.connector; | 446 | connector = &sou->base.connector; |
| 473 | 447 | ||
| 474 | INIT_LIST_HEAD(&sou->active); | 448 | sou->active_implicit = false; |
| 475 | 449 | ||
| 476 | sou->base.pref_active = (unit == 0); | 450 | sou->base.pref_active = (unit == 0); |
| 477 | sou->base.pref_width = 800; | 451 | sou->base.pref_width = 800; |
| 478 | sou->base.pref_height = 600; | 452 | sou->base.pref_height = 600; |
| 479 | sou->base.pref_mode = NULL; | 453 | sou->base.pref_mode = NULL; |
| 454 | sou->base.is_implicit = true; | ||
| 480 | 455 | ||
| 481 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 456 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
| 482 | DRM_MODE_CONNECTOR_LVDS); | 457 | DRM_MODE_CONNECTOR_VIRTUAL); |
| 483 | connector->status = vmw_du_connector_detect(connector, true); | 458 | connector->status = vmw_du_connector_detect(connector, true); |
| 484 | 459 | ||
| 485 | drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs, | 460 | drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs, |
| 486 | DRM_MODE_ENCODER_LVDS); | 461 | DRM_MODE_ENCODER_VIRTUAL); |
| 487 | drm_mode_connector_attach_encoder(connector, encoder); | 462 | drm_mode_connector_attach_encoder(connector, encoder); |
| 488 | encoder->possible_crtcs = (1 << unit); | 463 | encoder->possible_crtcs = (1 << unit); |
| 489 | encoder->possible_clones = 0; | 464 | encoder->possible_clones = 0; |
| @@ -520,10 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv) | |||
| 520 | if (unlikely(!dev_priv->sou_priv)) | 495 | if (unlikely(!dev_priv->sou_priv)) |
| 521 | goto err_no_mem; | 496 | goto err_no_mem; |
| 522 | 497 | ||
| 523 | INIT_LIST_HEAD(&dev_priv->sou_priv->active); | 498 | dev_priv->sou_priv->num_implicit = 0; |
| 524 | dev_priv->sou_priv->num_active = 0; | 499 | dev_priv->sou_priv->implicit_fb = NULL; |
| 525 | dev_priv->sou_priv->last_num_active = 0; | ||
| 526 | dev_priv->sou_priv->fb = NULL; | ||
| 527 | 500 | ||
| 528 | ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); | 501 | ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); |
| 529 | if (unlikely(ret != 0)) | 502 | if (unlikely(ret != 0)) |
| @@ -558,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv) | |||
| 558 | 531 | ||
| 559 | drm_vblank_cleanup(dev); | 532 | drm_vblank_cleanup(dev); |
| 560 | 533 | ||
| 561 | if (!list_empty(&dev_priv->sou_priv->active)) | ||
| 562 | DRM_ERROR("Still have active outputs when unloading driver"); | ||
| 563 | |||
| 564 | kfree(dev_priv->sou_priv); | 534 | kfree(dev_priv->sou_priv); |
| 565 | 535 | ||
| 566 | return 0; | 536 | return 0; |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 0d2f727e96be..93df2d72750b 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | 72 | ||
| 73 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 | 73 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 |
| 74 | 74 | ||
| 75 | #define DP_EDP_CONFIGURATION_CAP 0x00d | ||
| 75 | #define DP_TRAINING_AUX_RD_INTERVAL 0x00e | 76 | #define DP_TRAINING_AUX_RD_INTERVAL 0x00e |
| 76 | 77 | ||
| 77 | #define DP_PSR_SUPPORT 0x070 | 78 | #define DP_PSR_SUPPORT 0x070 |
| @@ -159,6 +160,8 @@ | |||
| 159 | # define DP_CP_IRQ (1 << 2) | 160 | # define DP_CP_IRQ (1 << 2) |
| 160 | # define DP_SINK_SPECIFIC_IRQ (1 << 6) | 161 | # define DP_SINK_SPECIFIC_IRQ (1 << 6) |
| 161 | 162 | ||
| 163 | #define DP_EDP_CONFIGURATION_SET 0x10a | ||
| 164 | |||
| 162 | #define DP_LANE0_1_STATUS 0x202 | 165 | #define DP_LANE0_1_STATUS 0x202 |
| 163 | #define DP_LANE2_3_STATUS 0x203 | 166 | #define DP_LANE2_3_STATUS 0x203 |
| 164 | # define DP_LANE_CR_DONE (1 << 0) | 167 | # define DP_LANE_CR_DONE (1 << 0) |
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index c4961ea50a49..d30bedfeb7ef 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
| @@ -120,11 +120,12 @@ struct drm_mode_crtc { | |||
| 120 | struct drm_mode_modeinfo mode; | 120 | struct drm_mode_modeinfo mode; |
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | #define DRM_MODE_ENCODER_NONE 0 | 123 | #define DRM_MODE_ENCODER_NONE 0 |
| 124 | #define DRM_MODE_ENCODER_DAC 1 | 124 | #define DRM_MODE_ENCODER_DAC 1 |
| 125 | #define DRM_MODE_ENCODER_TMDS 2 | 125 | #define DRM_MODE_ENCODER_TMDS 2 |
| 126 | #define DRM_MODE_ENCODER_LVDS 3 | 126 | #define DRM_MODE_ENCODER_LVDS 3 |
| 127 | #define DRM_MODE_ENCODER_TVDAC 4 | 127 | #define DRM_MODE_ENCODER_TVDAC 4 |
| 128 | #define DRM_MODE_ENCODER_VIRTUAL 5 | ||
| 128 | 129 | ||
| 129 | struct drm_mode_get_encoder { | 130 | struct drm_mode_get_encoder { |
| 130 | __u32 encoder_id; | 131 | __u32 encoder_id; |
| @@ -162,6 +163,7 @@ struct drm_mode_get_encoder { | |||
| 162 | #define DRM_MODE_CONNECTOR_HDMIB 12 | 163 | #define DRM_MODE_CONNECTOR_HDMIB 12 |
| 163 | #define DRM_MODE_CONNECTOR_TV 13 | 164 | #define DRM_MODE_CONNECTOR_TV 13 |
| 164 | #define DRM_MODE_CONNECTOR_eDP 14 | 165 | #define DRM_MODE_CONNECTOR_eDP 14 |
| 166 | #define DRM_MODE_CONNECTOR_VIRTUAL 15 | ||
| 165 | 167 | ||
| 166 | struct drm_mode_get_connector { | 168 | struct drm_mode_get_connector { |
| 167 | 169 | ||
diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h index cd7cd8162ed6..bcb0912afe7a 100644 --- a/include/drm/vmwgfx_drm.h +++ b/include/drm/vmwgfx_drm.h | |||
| @@ -54,7 +54,7 @@ | |||
| 54 | #define DRM_VMW_FENCE_EVENT 17 | 54 | #define DRM_VMW_FENCE_EVENT 17 |
| 55 | #define DRM_VMW_PRESENT 18 | 55 | #define DRM_VMW_PRESENT 18 |
| 56 | #define DRM_VMW_PRESENT_READBACK 19 | 56 | #define DRM_VMW_PRESENT_READBACK 19 |
| 57 | 57 | #define DRM_VMW_UPDATE_LAYOUT 20 | |
| 58 | 58 | ||
| 59 | /*************************************************************************/ | 59 | /*************************************************************************/ |
| 60 | /** | 60 | /** |
| @@ -552,31 +552,6 @@ struct drm_vmw_get_3d_cap_arg { | |||
| 552 | 552 | ||
| 553 | /*************************************************************************/ | 553 | /*************************************************************************/ |
| 554 | /** | 554 | /** |
| 555 | * DRM_VMW_UPDATE_LAYOUT - Update layout | ||
| 556 | * | ||
| 557 | * Updates the preferred modes and connection status for connectors. The | ||
| 558 | * command conisits of one drm_vmw_update_layout_arg pointing out a array | ||
| 559 | * of num_outputs drm_vmw_rect's. | ||
| 560 | */ | ||
| 561 | |||
| 562 | /** | ||
| 563 | * struct drm_vmw_update_layout_arg | ||
| 564 | * | ||
| 565 | * @num_outputs: number of active | ||
| 566 | * @rects: pointer to array of drm_vmw_rect | ||
| 567 | * | ||
| 568 | * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. | ||
| 569 | */ | ||
| 570 | |||
| 571 | struct drm_vmw_update_layout_arg { | ||
| 572 | uint32_t num_outputs; | ||
| 573 | uint32_t pad64; | ||
| 574 | uint64_t rects; | ||
| 575 | }; | ||
| 576 | |||
| 577 | |||
| 578 | /*************************************************************************/ | ||
| 579 | /** | ||
| 580 | * DRM_VMW_FENCE_WAIT | 555 | * DRM_VMW_FENCE_WAIT |
| 581 | * | 556 | * |
| 582 | * Waits for a fence object to signal. The wait is interruptible, so that | 557 | * Waits for a fence object to signal. The wait is interruptible, so that |
| @@ -788,4 +763,28 @@ struct drm_vmw_present_readback_arg { | |||
| 788 | uint64_t clips_ptr; | 763 | uint64_t clips_ptr; |
| 789 | uint64_t fence_rep; | 764 | uint64_t fence_rep; |
| 790 | }; | 765 | }; |
| 766 | |||
| 767 | /*************************************************************************/ | ||
| 768 | /** | ||
| 769 | * DRM_VMW_UPDATE_LAYOUT - Update layout | ||
| 770 | * | ||
| 771 | * Updates the preferred modes and connection status for connectors. The | ||
| 772 | * command consists of one drm_vmw_update_layout_arg pointing to an array | ||
| 773 | * of num_outputs drm_vmw_rect's. | ||
| 774 | */ | ||
| 775 | |||
| 776 | /** | ||
| 777 | * struct drm_vmw_update_layout_arg | ||
| 778 | * | ||
| 779 | * @num_outputs: number of active connectors | ||
| 780 | * @rects: pointer to array of drm_vmw_rect cast to an uint64_t | ||
| 781 | * | ||
| 782 | * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. | ||
| 783 | */ | ||
| 784 | struct drm_vmw_update_layout_arg { | ||
| 785 | uint32_t num_outputs; | ||
| 786 | uint32_t pad64; | ||
| 787 | uint64_t rects; | ||
| 788 | }; | ||
| 789 | |||
| 791 | #endif | 790 | #endif |
