diff options
24 files changed, 2657 insertions, 323 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index b5713eedd6e1..feb52eee4314 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
| @@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \ | |||
| 49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
| 50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
| 51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
| 52 | r600_blit_kms.o radeon_pm.o | 52 | r600_blit_kms.o radeon_pm.o atombios_dp.o |
| 53 | 53 | ||
| 54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
| 55 | 55 | ||
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d67c42555ab9..6578d19dff93 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
| @@ -263,10 +263,10 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
| 263 | case ATOM_ARG_FB: | 263 | case ATOM_ARG_FB: |
| 264 | idx = U8(*ptr); | 264 | idx = U8(*ptr); |
| 265 | (*ptr)++; | 265 | (*ptr)++; |
| 266 | val = gctx->scratch[((gctx->fb_base + idx) / 4)]; | ||
| 266 | if (print) | 267 | if (print) |
| 267 | DEBUG("FB[0x%02X]", idx); | 268 | DEBUG("FB[0x%02X]", idx); |
| 268 | printk(KERN_INFO "FB access is not implemented.\n"); | 269 | break; |
| 269 | return 0; | ||
| 270 | case ATOM_ARG_IMM: | 270 | case ATOM_ARG_IMM: |
| 271 | switch (align) { | 271 | switch (align) { |
| 272 | case ATOM_SRC_DWORD: | 272 | case ATOM_SRC_DWORD: |
| @@ -488,9 +488,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
| 488 | case ATOM_ARG_FB: | 488 | case ATOM_ARG_FB: |
| 489 | idx = U8(*ptr); | 489 | idx = U8(*ptr); |
| 490 | (*ptr)++; | 490 | (*ptr)++; |
| 491 | gctx->scratch[((gctx->fb_base + idx) / 4)] = val; | ||
| 491 | DEBUG("FB[0x%02X]", idx); | 492 | DEBUG("FB[0x%02X]", idx); |
| 492 | printk(KERN_INFO "FB access is not implemented.\n"); | 493 | break; |
| 493 | return; | ||
| 494 | case ATOM_ARG_PLL: | 494 | case ATOM_ARG_PLL: |
| 495 | idx = U8(*ptr); | 495 | idx = U8(*ptr); |
| 496 | (*ptr)++; | 496 | (*ptr)++; |
| @@ -1214,3 +1214,28 @@ void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | |||
| 1214 | *crev = CU8(idx + 3); | 1214 | *crev = CU8(idx + 3); |
| 1215 | return; | 1215 | return; |
| 1216 | } | 1216 | } |
| 1217 | |||
| 1218 | int atom_allocate_fb_scratch(struct atom_context *ctx) | ||
| 1219 | { | ||
| 1220 | int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); | ||
| 1221 | uint16_t data_offset; | ||
| 1222 | int usage_bytes; | ||
| 1223 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; | ||
| 1224 | |||
| 1225 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | ||
| 1226 | |||
| 1227 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); | ||
| 1228 | |||
| 1229 | DRM_DEBUG("atom firmware requested %08x %dkb\n", | ||
| 1230 | firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, | ||
| 1231 | firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); | ||
| 1232 | |||
| 1233 | usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; | ||
| 1234 | if (usage_bytes == 0) | ||
| 1235 | usage_bytes = 20 * 1024; | ||
| 1236 | /* allocate some scratch memory */ | ||
| 1237 | ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); | ||
| 1238 | if (!ctx->scratch) | ||
| 1239 | return -ENOMEM; | ||
| 1240 | return 0; | ||
| 1241 | } | ||
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index e6eb38f2bcae..6671848e5ea1 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
| @@ -132,6 +132,7 @@ struct atom_context { | |||
| 132 | uint8_t shift; | 132 | uint8_t shift; |
| 133 | int cs_equal, cs_above; | 133 | int cs_equal, cs_above; |
| 134 | int io_mode; | 134 | int io_mode; |
| 135 | uint32_t *scratch; | ||
| 135 | }; | 136 | }; |
| 136 | 137 | ||
| 137 | extern int atom_debug; | 138 | extern int atom_debug; |
| @@ -142,6 +143,7 @@ int atom_asic_init(struct atom_context *); | |||
| 142 | void atom_destroy(struct atom_context *); | 143 | void atom_destroy(struct atom_context *); |
| 143 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); | 144 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); |
| 144 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); | 145 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); |
| 146 | int atom_allocate_fb_scratch(struct atom_context *ctx); | ||
| 145 | #include "atom-types.h" | 147 | #include "atom-types.h" |
| 146 | #include "atombios.h" | 148 | #include "atombios.h" |
| 147 | #include "ObjectID.h" | 149 | #include "ObjectID.h" |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index c11ddddfb3b6..e83927644de4 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
| @@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD { | |||
| 2680 | typedef struct _ATOM_HPD_INT_RECORD { | 2680 | typedef struct _ATOM_HPD_INT_RECORD { |
| 2681 | ATOM_COMMON_RECORD_HEADER sheader; | 2681 | ATOM_COMMON_RECORD_HEADER sheader; |
| 2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ | 2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ |
| 2683 | UCHAR ucPluggged_PinState; | 2683 | UCHAR ucPlugged_PinState; |
| 2684 | } ATOM_HPD_INT_RECORD; | 2684 | } ATOM_HPD_INT_RECORD; |
| 2685 | 2685 | ||
| 2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { | 2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c new file mode 100644 index 000000000000..0d63c4436e7c --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -0,0 +1,790 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2007-8 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 "radeon_drm.h" | ||
| 28 | #include "radeon.h" | ||
| 29 | |||
| 30 | #include "atom.h" | ||
| 31 | #include "atom-bits.h" | ||
| 32 | #include "drm_dp_helper.h" | ||
| 33 | |||
| 34 | /* move these to drm_dp_helper.c/h */ | ||
| 35 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
| 36 | #define DP_LINK_STATUS_SIZE 6 | ||
| 37 | #define DP_DPCD_SIZE 8 | ||
| 38 | |||
| 39 | static char *voltage_names[] = { | ||
| 40 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
| 41 | }; | ||
| 42 | static char *pre_emph_names[] = { | ||
| 43 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const int dp_clocks[] = { | ||
| 47 | 54000, /* 1 lane, 1.62 Ghz */ | ||
| 48 | 90000, /* 1 lane, 2.70 Ghz */ | ||
| 49 | 108000, /* 2 lane, 1.62 Ghz */ | ||
| 50 | 180000, /* 2 lane, 2.70 Ghz */ | ||
| 51 | 216000, /* 4 lane, 1.62 Ghz */ | ||
| 52 | 360000, /* 4 lane, 2.70 Ghz */ | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int); | ||
| 56 | |||
| 57 | /* common helper functions */ | ||
| 58 | static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
| 59 | { | ||
| 60 | int i; | ||
| 61 | u8 max_link_bw; | ||
| 62 | u8 max_lane_count; | ||
| 63 | |||
| 64 | if (!dpcd) | ||
| 65 | return 0; | ||
| 66 | |||
| 67 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
| 68 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
| 69 | |||
| 70 | switch (max_link_bw) { | ||
| 71 | case DP_LINK_BW_1_62: | ||
| 72 | default: | ||
| 73 | for (i = 0; i < num_dp_clocks; i++) { | ||
| 74 | if (i % 2) | ||
| 75 | continue; | ||
| 76 | switch (max_lane_count) { | ||
| 77 | case 1: | ||
| 78 | if (i > 1) | ||
| 79 | return 0; | ||
| 80 | break; | ||
| 81 | case 2: | ||
| 82 | if (i > 3) | ||
| 83 | return 0; | ||
| 84 | break; | ||
| 85 | case 4: | ||
| 86 | default: | ||
| 87 | break; | ||
| 88 | } | ||
| 89 | if (dp_clocks[i] > mode_clock) { | ||
| 90 | if (i < 2) | ||
| 91 | return 1; | ||
| 92 | else if (i < 4) | ||
| 93 | return 2; | ||
| 94 | else | ||
| 95 | return 4; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | break; | ||
| 99 | case DP_LINK_BW_2_7: | ||
| 100 | for (i = 0; i < num_dp_clocks; i++) { | ||
| 101 | switch (max_lane_count) { | ||
| 102 | case 1: | ||
| 103 | if (i > 1) | ||
| 104 | return 0; | ||
| 105 | break; | ||
| 106 | case 2: | ||
| 107 | if (i > 3) | ||
| 108 | return 0; | ||
| 109 | break; | ||
| 110 | case 4: | ||
| 111 | default: | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | if (dp_clocks[i] > mode_clock) { | ||
| 115 | if (i < 2) | ||
| 116 | return 1; | ||
| 117 | else if (i < 4) | ||
| 118 | return 2; | ||
| 119 | else | ||
| 120 | return 4; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | break; | ||
| 124 | } | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
| 130 | { | ||
| 131 | int i; | ||
| 132 | u8 max_link_bw; | ||
| 133 | u8 max_lane_count; | ||
| 134 | |||
| 135 | if (!dpcd) | ||
| 136 | return 0; | ||
| 137 | |||
| 138 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
| 139 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
| 140 | |||
| 141 | switch (max_link_bw) { | ||
| 142 | case DP_LINK_BW_1_62: | ||
| 143 | default: | ||
| 144 | for (i = 0; i < num_dp_clocks; i++) { | ||
| 145 | if (i % 2) | ||
| 146 | continue; | ||
| 147 | switch (max_lane_count) { | ||
| 148 | case 1: | ||
| 149 | if (i > 1) | ||
| 150 | return 0; | ||
| 151 | break; | ||
| 152 | case 2: | ||
| 153 | if (i > 3) | ||
| 154 | return 0; | ||
| 155 | break; | ||
| 156 | case 4: | ||
| 157 | default: | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | if (dp_clocks[i] > mode_clock) | ||
| 161 | return 162000; | ||
| 162 | } | ||
| 163 | break; | ||
| 164 | case DP_LINK_BW_2_7: | ||
| 165 | for (i = 0; i < num_dp_clocks; i++) { | ||
| 166 | switch (max_lane_count) { | ||
| 167 | case 1: | ||
| 168 | if (i > 1) | ||
| 169 | return 0; | ||
| 170 | break; | ||
| 171 | case 2: | ||
| 172 | if (i > 3) | ||
| 173 | return 0; | ||
| 174 | break; | ||
| 175 | case 4: | ||
| 176 | default: | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | if (dp_clocks[i] > mode_clock) | ||
| 180 | return (i % 2) ? 270000 : 162000; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
| 188 | { | ||
| 189 | int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
| 190 | int bw = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
| 191 | |||
| 192 | if ((lanes == 0) || (bw == 0)) | ||
| 193 | return MODE_CLOCK_HIGH; | ||
| 194 | |||
| 195 | return MODE_OK; | ||
| 196 | } | ||
| 197 | |||
| 198 | static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) | ||
| 199 | { | ||
| 200 | return link_status[r - DP_LANE0_1_STATUS]; | ||
| 201 | } | ||
| 202 | |||
| 203 | static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], | ||
| 204 | int lane) | ||
| 205 | { | ||
| 206 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
| 207 | int s = (lane & 1) * 4; | ||
| 208 | u8 l = dp_link_status(link_status, i); | ||
| 209 | return (l >> s) & 0xf; | ||
| 210 | } | ||
| 211 | |||
| 212 | static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
| 213 | int lane_count) | ||
| 214 | { | ||
| 215 | int lane; | ||
| 216 | u8 lane_status; | ||
| 217 | |||
| 218 | for (lane = 0; lane < lane_count; lane++) { | ||
| 219 | lane_status = dp_get_lane_status(link_status, lane); | ||
| 220 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
| 221 | return false; | ||
| 222 | } | ||
| 223 | return true; | ||
| 224 | } | ||
| 225 | |||
| 226 | static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
| 227 | int lane_count) | ||
| 228 | { | ||
| 229 | u8 lane_align; | ||
| 230 | u8 lane_status; | ||
| 231 | int lane; | ||
| 232 | |||
| 233 | lane_align = dp_link_status(link_status, | ||
| 234 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
| 235 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
| 236 | return false; | ||
| 237 | for (lane = 0; lane < lane_count; lane++) { | ||
| 238 | lane_status = dp_get_lane_status(link_status, lane); | ||
| 239 | if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) | ||
| 240 | return false; | ||
| 241 | } | ||
| 242 | return true; | ||
| 243 | } | ||
| 244 | |||
| 245 | static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
| 246 | int lane) | ||
| 247 | |||
| 248 | { | ||
| 249 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
| 250 | int s = ((lane & 1) ? | ||
| 251 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
| 252 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
| 253 | u8 l = dp_link_status(link_status, i); | ||
| 254 | |||
| 255 | return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
| 256 | } | ||
| 257 | |||
| 258 | static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
| 259 | int lane) | ||
| 260 | { | ||
| 261 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
| 262 | int s = ((lane & 1) ? | ||
| 263 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
| 264 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
| 265 | u8 l = dp_link_status(link_status, i); | ||
| 266 | |||
| 267 | return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
| 268 | } | ||
| 269 | |||
| 270 | /* XXX fix me -- chip specific */ | ||
| 271 | #define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 | ||
| 272 | static u8 dp_pre_emphasis_max(u8 voltage_swing) | ||
| 273 | { | ||
| 274 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
| 275 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
| 276 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
| 277 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
| 278 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
| 279 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
| 280 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
| 281 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
| 282 | default: | ||
| 283 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | ||
| 288 | int lane_count, | ||
| 289 | u8 train_set[4]) | ||
| 290 | { | ||
| 291 | u8 v = 0; | ||
| 292 | u8 p = 0; | ||
| 293 | int lane; | ||
| 294 | |||
| 295 | for (lane = 0; lane < lane_count; lane++) { | ||
| 296 | u8 this_v = dp_get_adjust_request_voltage(link_status, lane); | ||
| 297 | u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); | ||
| 298 | |||
| 299 | DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n", | ||
| 300 | lane, | ||
| 301 | voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
| 302 | pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
| 303 | |||
| 304 | if (this_v > v) | ||
| 305 | v = this_v; | ||
| 306 | if (this_p > p) | ||
| 307 | p = this_p; | ||
| 308 | } | ||
| 309 | |||
| 310 | if (v >= DP_VOLTAGE_MAX) | ||
| 311 | v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
| 312 | |||
| 313 | if (p >= dp_pre_emphasis_max(v)) | ||
| 314 | p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
| 315 | |||
| 316 | DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n", | ||
| 317 | voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
| 318 | pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
| 319 | |||
| 320 | for (lane = 0; lane < 4; lane++) | ||
| 321 | train_set[lane] = v | p; | ||
| 322 | } | ||
| 323 | |||
| 324 | |||
| 325 | /* radeon aux chan functions */ | ||
| 326 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | ||
| 327 | int num_bytes, u8 *read_byte, | ||
| 328 | u8 read_buf_len, u8 delay) | ||
| 329 | { | ||
| 330 | struct drm_device *dev = chan->dev; | ||
| 331 | struct radeon_device *rdev = dev->dev_private; | ||
| 332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | ||
| 333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | ||
| 334 | unsigned char *base; | ||
| 335 | |||
| 336 | memset(&args, 0, sizeof(args)); | ||
| 337 | |||
| 338 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | ||
| 339 | |||
| 340 | memcpy(base, req_bytes, num_bytes); | ||
| 341 | |||
| 342 | args.lpAuxRequest = 0; | ||
| 343 | args.lpDataOut = 16; | ||
| 344 | args.ucDataOutLen = 0; | ||
| 345 | args.ucChannelID = chan->rec.i2c_id; | ||
| 346 | args.ucDelay = delay / 10; | ||
| 347 | |||
| 348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 349 | |||
| 350 | if (args.ucReplyStatus) { | ||
| 351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | ||
| 352 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | ||
| 353 | chan->rec.i2c_id, args.ucReplyStatus); | ||
| 354 | return false; | ||
| 355 | } | ||
| 356 | |||
| 357 | if (args.ucDataOutLen && read_byte && read_buf_len) { | ||
| 358 | if (read_buf_len < args.ucDataOutLen) { | ||
| 359 | DRM_ERROR("Buffer to small for return answer %d %d\n", | ||
| 360 | read_buf_len, args.ucDataOutLen); | ||
| 361 | return false; | ||
| 362 | } | ||
| 363 | { | ||
| 364 | int len = min(read_buf_len, args.ucDataOutLen); | ||
| 365 | memcpy(read_byte, base + 16, len); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | return true; | ||
| 369 | } | ||
| 370 | |||
| 371 | bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address, | ||
| 372 | uint8_t send_bytes, uint8_t *send) | ||
| 373 | { | ||
| 374 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 375 | u8 msg[20]; | ||
| 376 | u8 msg_len, dp_msg_len; | ||
| 377 | bool ret; | ||
| 378 | |||
| 379 | dp_msg_len = 4; | ||
| 380 | msg[0] = address; | ||
| 381 | msg[1] = address >> 8; | ||
| 382 | msg[2] = AUX_NATIVE_WRITE << 4; | ||
| 383 | dp_msg_len += send_bytes; | ||
| 384 | msg[3] = (dp_msg_len << 4) | (send_bytes - 1); | ||
| 385 | |||
| 386 | if (send_bytes > 16) | ||
| 387 | return false; | ||
| 388 | |||
| 389 | memcpy(&msg[4], send, send_bytes); | ||
| 390 | msg_len = 4 + send_bytes; | ||
| 391 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0); | ||
| 392 | return ret; | ||
| 393 | } | ||
| 394 | |||
| 395 | bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address, | ||
| 396 | uint8_t delay, uint8_t expected_bytes, | ||
| 397 | uint8_t *read_p) | ||
| 398 | { | ||
| 399 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 400 | u8 msg[20]; | ||
| 401 | u8 msg_len, dp_msg_len; | ||
| 402 | bool ret = false; | ||
| 403 | msg_len = 4; | ||
| 404 | dp_msg_len = 4; | ||
| 405 | msg[0] = address; | ||
| 406 | msg[1] = address >> 8; | ||
| 407 | msg[2] = AUX_NATIVE_READ << 4; | ||
| 408 | msg[3] = (dp_msg_len) << 4; | ||
| 409 | msg[3] |= expected_bytes - 1; | ||
| 410 | |||
| 411 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay); | ||
| 412 | return ret; | ||
| 413 | } | ||
| 414 | |||
| 415 | /* radeon dp functions */ | ||
| 416 | static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock, | ||
| 417 | uint8_t ucconfig, uint8_t lane_num) | ||
| 418 | { | ||
| 419 | DP_ENCODER_SERVICE_PARAMETERS args; | ||
| 420 | int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); | ||
| 421 | |||
| 422 | memset(&args, 0, sizeof(args)); | ||
| 423 | args.ucLinkClock = dp_clock / 10; | ||
| 424 | args.ucConfig = ucconfig; | ||
| 425 | args.ucAction = action; | ||
| 426 | args.ucLaneNum = lane_num; | ||
| 427 | args.ucStatus = 0; | ||
| 428 | |||
| 429 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
| 430 | return args.ucStatus; | ||
| 431 | } | ||
| 432 | |||
| 433 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) | ||
| 434 | { | ||
| 435 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 436 | struct drm_device *dev = radeon_connector->base.dev; | ||
| 437 | struct radeon_device *rdev = dev->dev_private; | ||
| 438 | |||
| 439 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, | ||
| 440 | dig_connector->dp_i2c_bus->rec.i2c_id, 0); | ||
| 441 | } | ||
| 442 | |||
| 443 | bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | ||
| 444 | { | ||
| 445 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 446 | u8 msg[25]; | ||
| 447 | int ret; | ||
| 448 | |||
| 449 | ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg); | ||
| 450 | if (ret) { | ||
| 451 | memcpy(dig_connector->dpcd, msg, 8); | ||
| 452 | { | ||
| 453 | int i; | ||
| 454 | DRM_DEBUG("DPCD: "); | ||
| 455 | for (i = 0; i < 8; i++) | ||
| 456 | DRM_DEBUG("%02x ", msg[i]); | ||
| 457 | DRM_DEBUG("\n"); | ||
| 458 | } | ||
| 459 | return true; | ||
| 460 | } | ||
| 461 | dig_connector->dpcd[0] = 0; | ||
| 462 | return false; | ||
| 463 | } | ||
| 464 | |||
| 465 | void radeon_dp_set_link_config(struct drm_connector *connector, | ||
| 466 | struct drm_display_mode *mode) | ||
| 467 | { | ||
| 468 | struct radeon_connector *radeon_connector; | ||
| 469 | struct radeon_connector_atom_dig *dig_connector; | ||
| 470 | |||
| 471 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
| 472 | return; | ||
| 473 | |||
| 474 | radeon_connector = to_radeon_connector(connector); | ||
| 475 | if (!radeon_connector->con_priv) | ||
| 476 | return; | ||
| 477 | dig_connector = radeon_connector->con_priv; | ||
| 478 | |||
| 479 | dig_connector->dp_clock = | ||
| 480 | dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
| 481 | dig_connector->dp_lane_count = | ||
| 482 | dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
| 483 | } | ||
| 484 | |||
| 485 | int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
| 486 | struct drm_display_mode *mode) | ||
| 487 | { | ||
| 488 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 489 | |||
| 490 | return dp_mode_valid(dig_connector->dpcd, mode->clock); | ||
| 491 | } | ||
| 492 | |||
| 493 | static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector, | ||
| 494 | u8 link_status[DP_LINK_STATUS_SIZE]) | ||
| 495 | { | ||
| 496 | int ret; | ||
| 497 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100, | ||
| 498 | DP_LINK_STATUS_SIZE, link_status); | ||
| 499 | if (!ret) { | ||
| 500 | DRM_ERROR("displayport link status failed\n"); | ||
| 501 | return false; | ||
| 502 | } | ||
| 503 | |||
| 504 | DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n", | ||
| 505 | link_status[0], link_status[1], link_status[2], | ||
| 506 | link_status[3], link_status[4], link_status[5]); | ||
| 507 | return true; | ||
| 508 | } | ||
| 509 | |||
| 510 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) | ||
| 511 | { | ||
| 512 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 513 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
| 514 | |||
| 515 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
| 516 | return false; | ||
| 517 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) | ||
| 518 | return false; | ||
| 519 | return true; | ||
| 520 | } | ||
| 521 | |||
| 522 | static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state) | ||
| 523 | { | ||
| 524 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 525 | |||
| 526 | if (dig_connector->dpcd[0] >= 0x11) { | ||
| 527 | radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1, | ||
| 528 | &power_state); | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread) | ||
| 533 | { | ||
| 534 | radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1, | ||
| 535 | &downspread); | ||
| 536 | } | ||
| 537 | |||
| 538 | static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector, | ||
| 539 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
| 540 | { | ||
| 541 | radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2, | ||
| 542 | link_configuration); | ||
| 543 | } | ||
| 544 | |||
| 545 | static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector, | ||
| 546 | struct drm_encoder *encoder, | ||
| 547 | u8 train_set[4]) | ||
| 548 | { | ||
| 549 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
| 550 | int i; | ||
| 551 | |||
| 552 | for (i = 0; i < dig_connector->dp_lane_count; i++) | ||
| 553 | atombios_dig_transmitter_setup(encoder, | ||
| 554 | ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, | ||
| 555 | i, train_set[i]); | ||
| 556 | |||
| 557 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET, | ||
| 558 | dig_connector->dp_lane_count, train_set); | ||
| 559 | } | ||
| 560 | |||
| 561 | static void dp_set_training(struct radeon_connector *radeon_connector, | ||
| 562 | u8 training) | ||
| 563 | { | ||
| 564 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET, | ||
| 565 | 1, &training); | ||
| 566 | } | ||
| 567 | |||
| 568 | void dp_link_train(struct drm_encoder *encoder, | ||
| 569 | struct drm_connector *connector) | ||
| 570 | { | ||
| 571 | struct drm_device *dev = encoder->dev; | ||
| 572 | struct radeon_device *rdev = dev->dev_private; | ||
| 573 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 574 | struct radeon_encoder_atom_dig *dig; | ||
| 575 | struct radeon_connector *radeon_connector; | ||
| 576 | struct radeon_connector_atom_dig *dig_connector; | ||
| 577 | int enc_id = 0; | ||
| 578 | bool clock_recovery, channel_eq; | ||
| 579 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
| 580 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
| 581 | u8 tries, voltage; | ||
| 582 | u8 train_set[4]; | ||
| 583 | int i; | ||
| 584 | |||
| 585 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
| 586 | return; | ||
| 587 | |||
| 588 | if (!radeon_encoder->enc_priv) | ||
| 589 | return; | ||
| 590 | dig = radeon_encoder->enc_priv; | ||
| 591 | |||
| 592 | radeon_connector = to_radeon_connector(connector); | ||
| 593 | if (!radeon_connector->con_priv) | ||
| 594 | return; | ||
| 595 | dig_connector = radeon_connector->con_priv; | ||
| 596 | |||
| 597 | if (ASIC_IS_DCE32(rdev)) { | ||
| 598 | if (dig->dig_block) | ||
| 599 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | ||
| 600 | else | ||
| 601 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | ||
| 602 | if (dig_connector->linkb) | ||
| 603 | enc_id |= ATOM_DP_CONFIG_LINK_B; | ||
| 604 | else | ||
| 605 | enc_id |= ATOM_DP_CONFIG_LINK_A; | ||
| 606 | } else { | ||
| 607 | if (dig_connector->linkb) | ||
| 608 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B; | ||
| 609 | else | ||
| 610 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A; | ||
| 611 | } | ||
| 612 | |||
| 613 | memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
| 614 | if (dig_connector->dp_clock == 270000) | ||
| 615 | link_configuration[0] = DP_LINK_BW_2_7; | ||
| 616 | else | ||
| 617 | link_configuration[0] = DP_LINK_BW_1_62; | ||
| 618 | link_configuration[1] = dig_connector->dp_lane_count; | ||
| 619 | if (dig_connector->dpcd[0] >= 0x11) | ||
| 620 | link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
| 621 | |||
| 622 | /* power up the sink */ | ||
| 623 | dp_set_power(radeon_connector, DP_SET_POWER_D0); | ||
| 624 | /* disable the training pattern on the sink */ | ||
| 625 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
| 626 | /* set link bw and lanes on the sink */ | ||
| 627 | dp_set_link_bw_lanes(radeon_connector, link_configuration); | ||
| 628 | /* disable downspread on the sink */ | ||
| 629 | dp_set_downspread(radeon_connector, 0); | ||
| 630 | /* start training on the source */ | ||
| 631 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, | ||
| 632 | dig_connector->dp_clock, enc_id, 0); | ||
| 633 | /* set training pattern 1 on the source */ | ||
| 634 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
| 635 | dig_connector->dp_clock, enc_id, 0); | ||
| 636 | |||
| 637 | /* set initial vs/emph */ | ||
| 638 | memset(train_set, 0, 4); | ||
| 639 | udelay(400); | ||
| 640 | /* set training pattern 1 on the sink */ | ||
| 641 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1); | ||
| 642 | |||
| 643 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
| 644 | |||
| 645 | /* clock recovery loop */ | ||
| 646 | clock_recovery = false; | ||
| 647 | tries = 0; | ||
| 648 | voltage = 0xff; | ||
| 649 | for (;;) { | ||
| 650 | udelay(100); | ||
| 651 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
| 652 | break; | ||
| 653 | |||
| 654 | if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) { | ||
| 655 | clock_recovery = true; | ||
| 656 | break; | ||
| 657 | } | ||
| 658 | |||
| 659 | for (i = 0; i < dig_connector->dp_lane_count; i++) { | ||
| 660 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
| 661 | break; | ||
| 662 | } | ||
| 663 | if (i == dig_connector->dp_lane_count) { | ||
| 664 | DRM_ERROR("clock recovery reached max voltage\n"); | ||
| 665 | break; | ||
| 666 | } | ||
| 667 | |||
| 668 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
| 669 | ++tries; | ||
| 670 | if (tries == 5) { | ||
| 671 | DRM_ERROR("clock recovery tried 5 times\n"); | ||
| 672 | break; | ||
| 673 | } | ||
| 674 | } else | ||
| 675 | tries = 0; | ||
| 676 | |||
| 677 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
| 678 | |||
| 679 | /* Compute new train_set as requested by sink */ | ||
| 680 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
| 681 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
| 682 | } | ||
| 683 | if (!clock_recovery) | ||
| 684 | DRM_ERROR("clock recovery failed\n"); | ||
| 685 | else | ||
| 686 | DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n", | ||
| 687 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
| 688 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> | ||
| 689 | DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
| 690 | |||
| 691 | |||
| 692 | /* set training pattern 2 on the sink */ | ||
| 693 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); | ||
| 694 | /* set training pattern 2 on the source */ | ||
| 695 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
| 696 | dig_connector->dp_clock, enc_id, 1); | ||
| 697 | |||
| 698 | /* channel equalization loop */ | ||
| 699 | tries = 0; | ||
| 700 | channel_eq = false; | ||
| 701 | for (;;) { | ||
| 702 | udelay(400); | ||
| 703 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
| 704 | break; | ||
| 705 | |||
| 706 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) { | ||
| 707 | channel_eq = true; | ||
| 708 | break; | ||
| 709 | } | ||
| 710 | |||
| 711 | /* Try 5 times */ | ||
| 712 | if (tries > 5) { | ||
| 713 | DRM_ERROR("channel eq failed: 5 tries\n"); | ||
| 714 | break; | ||
| 715 | } | ||
| 716 | |||
| 717 | /* Compute new train_set as requested by sink */ | ||
| 718 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
| 719 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
| 720 | |||
| 721 | tries++; | ||
| 722 | } | ||
| 723 | |||
| 724 | if (!channel_eq) | ||
| 725 | DRM_ERROR("channel eq failed\n"); | ||
| 726 | else | ||
| 727 | DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n", | ||
| 728 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
| 729 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) | ||
| 730 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
| 731 | |||
| 732 | /* disable the training pattern on the sink */ | ||
| 733 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
| 734 | |||
| 735 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, | ||
| 736 | dig_connector->dp_clock, enc_id, 0); | ||
| 737 | } | ||
| 738 | |||
| 739 | int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
| 740 | uint8_t write_byte, uint8_t *read_byte) | ||
| 741 | { | ||
| 742 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
| 743 | struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; | ||
| 744 | int ret = 0; | ||
| 745 | uint16_t address = algo_data->address; | ||
| 746 | uint8_t msg[5]; | ||
| 747 | uint8_t reply[2]; | ||
| 748 | int msg_len, dp_msg_len; | ||
| 749 | int reply_bytes; | ||
| 750 | |||
| 751 | /* Set up the command byte */ | ||
| 752 | if (mode & MODE_I2C_READ) | ||
| 753 | msg[2] = AUX_I2C_READ << 4; | ||
| 754 | else | ||
| 755 | msg[2] = AUX_I2C_WRITE << 4; | ||
| 756 | |||
| 757 | if (!(mode & MODE_I2C_STOP)) | ||
| 758 | msg[2] |= AUX_I2C_MOT << 4; | ||
| 759 | |||
| 760 | msg[0] = address; | ||
| 761 | msg[1] = address >> 8; | ||
| 762 | |||
| 763 | reply_bytes = 1; | ||
| 764 | |||
| 765 | msg_len = 4; | ||
| 766 | dp_msg_len = 3; | ||
| 767 | switch (mode) { | ||
| 768 | case MODE_I2C_WRITE: | ||
| 769 | msg[4] = write_byte; | ||
| 770 | msg_len++; | ||
| 771 | dp_msg_len += 2; | ||
| 772 | break; | ||
| 773 | case MODE_I2C_READ: | ||
| 774 | dp_msg_len += 1; | ||
| 775 | break; | ||
| 776 | default: | ||
| 777 | break; | ||
| 778 | } | ||
| 779 | |||
| 780 | msg[3] = (dp_msg_len) << 4; | ||
| 781 | ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0); | ||
| 782 | |||
| 783 | if (ret) { | ||
| 784 | if (read_byte) | ||
| 785 | *read_byte = reply[0]; | ||
| 786 | return reply_bytes; | ||
| 787 | } | ||
| 788 | return -EREMOTEIO; | ||
| 789 | } | ||
| 790 | |||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 109096802e66..b7baf16c11d7 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -65,6 +65,95 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
| 65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
| 66 | */ | 66 | */ |
| 67 | 67 | ||
| 68 | /* hpd for digital panel detect/disconnect */ | ||
| 69 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
| 70 | { | ||
| 71 | bool connected = false; | ||
| 72 | |||
| 73 | switch (hpd) { | ||
| 74 | case RADEON_HPD_1: | ||
| 75 | if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE) | ||
| 76 | connected = true; | ||
| 77 | break; | ||
| 78 | case RADEON_HPD_2: | ||
| 79 | if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE) | ||
| 80 | connected = true; | ||
| 81 | break; | ||
| 82 | default: | ||
| 83 | break; | ||
| 84 | } | ||
| 85 | return connected; | ||
| 86 | } | ||
| 87 | |||
| 88 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
| 89 | enum radeon_hpd_id hpd) | ||
| 90 | { | ||
| 91 | u32 tmp; | ||
| 92 | bool connected = r100_hpd_sense(rdev, hpd); | ||
| 93 | |||
| 94 | switch (hpd) { | ||
| 95 | case RADEON_HPD_1: | ||
| 96 | tmp = RREG32(RADEON_FP_GEN_CNTL); | ||
| 97 | if (connected) | ||
| 98 | tmp &= ~RADEON_FP_DETECT_INT_POL; | ||
| 99 | else | ||
| 100 | tmp |= RADEON_FP_DETECT_INT_POL; | ||
| 101 | WREG32(RADEON_FP_GEN_CNTL, tmp); | ||
| 102 | break; | ||
| 103 | case RADEON_HPD_2: | ||
| 104 | tmp = RREG32(RADEON_FP2_GEN_CNTL); | ||
| 105 | if (connected) | ||
| 106 | tmp &= ~RADEON_FP2_DETECT_INT_POL; | ||
| 107 | else | ||
| 108 | tmp |= RADEON_FP2_DETECT_INT_POL; | ||
| 109 | WREG32(RADEON_FP2_GEN_CNTL, tmp); | ||
| 110 | break; | ||
| 111 | default: | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | void r100_hpd_init(struct radeon_device *rdev) | ||
| 117 | { | ||
| 118 | struct drm_device *dev = rdev->ddev; | ||
| 119 | struct drm_connector *connector; | ||
| 120 | |||
| 121 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 123 | switch (radeon_connector->hpd.hpd) { | ||
| 124 | case RADEON_HPD_1: | ||
| 125 | rdev->irq.hpd[0] = true; | ||
| 126 | break; | ||
| 127 | case RADEON_HPD_2: | ||
| 128 | rdev->irq.hpd[1] = true; | ||
| 129 | break; | ||
| 130 | default: | ||
| 131 | break; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | r100_irq_set(rdev); | ||
| 135 | } | ||
| 136 | |||
| 137 | void r100_hpd_fini(struct radeon_device *rdev) | ||
| 138 | { | ||
| 139 | struct drm_device *dev = rdev->ddev; | ||
| 140 | struct drm_connector *connector; | ||
| 141 | |||
| 142 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 143 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 144 | switch (radeon_connector->hpd.hpd) { | ||
| 145 | case RADEON_HPD_1: | ||
| 146 | rdev->irq.hpd[0] = false; | ||
| 147 | break; | ||
| 148 | case RADEON_HPD_2: | ||
| 149 | rdev->irq.hpd[1] = false; | ||
| 150 | break; | ||
| 151 | default: | ||
| 152 | break; | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 68 | /* | 157 | /* |
| 69 | * PCI GART | 158 | * PCI GART |
| 70 | */ | 159 | */ |
| @@ -163,6 +252,12 @@ int r100_irq_set(struct radeon_device *rdev) | |||
| 163 | if (rdev->irq.crtc_vblank_int[1]) { | 252 | if (rdev->irq.crtc_vblank_int[1]) { |
| 164 | tmp |= RADEON_CRTC2_VBLANK_MASK; | 253 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
| 165 | } | 254 | } |
| 255 | if (rdev->irq.hpd[0]) { | ||
| 256 | tmp |= RADEON_FP_DETECT_MASK; | ||
| 257 | } | ||
| 258 | if (rdev->irq.hpd[1]) { | ||
| 259 | tmp |= RADEON_FP2_DETECT_MASK; | ||
| 260 | } | ||
| 166 | WREG32(RADEON_GEN_INT_CNTL, tmp); | 261 | WREG32(RADEON_GEN_INT_CNTL, tmp); |
| 167 | return 0; | 262 | return 0; |
| 168 | } | 263 | } |
| @@ -181,8 +276,9 @@ void r100_irq_disable(struct radeon_device *rdev) | |||
| 181 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | 276 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
| 182 | { | 277 | { |
| 183 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | 278 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
| 184 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | 279 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
| 185 | RADEON_CRTC2_VBLANK_STAT; | 280 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
| 281 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; | ||
| 186 | 282 | ||
| 187 | if (irqs) { | 283 | if (irqs) { |
| 188 | WREG32(RADEON_GEN_INT_STATUS, irqs); | 284 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
| @@ -193,6 +289,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
| 193 | int r100_irq_process(struct radeon_device *rdev) | 289 | int r100_irq_process(struct radeon_device *rdev) |
| 194 | { | 290 | { |
| 195 | uint32_t status, msi_rearm; | 291 | uint32_t status, msi_rearm; |
| 292 | bool queue_hotplug = false; | ||
| 196 | 293 | ||
| 197 | status = r100_irq_ack(rdev); | 294 | status = r100_irq_ack(rdev); |
| 198 | if (!status) { | 295 | if (!status) { |
| @@ -213,8 +310,18 @@ int r100_irq_process(struct radeon_device *rdev) | |||
| 213 | if (status & RADEON_CRTC2_VBLANK_STAT) { | 310 | if (status & RADEON_CRTC2_VBLANK_STAT) { |
| 214 | drm_handle_vblank(rdev->ddev, 1); | 311 | drm_handle_vblank(rdev->ddev, 1); |
| 215 | } | 312 | } |
| 313 | if (status & RADEON_FP_DETECT_STAT) { | ||
| 314 | queue_hotplug = true; | ||
| 315 | DRM_DEBUG("HPD1\n"); | ||
| 316 | } | ||
| 317 | if (status & RADEON_FP2_DETECT_STAT) { | ||
| 318 | queue_hotplug = true; | ||
| 319 | DRM_DEBUG("HPD2\n"); | ||
| 320 | } | ||
| 216 | status = r100_irq_ack(rdev); | 321 | status = r100_irq_ack(rdev); |
| 217 | } | 322 | } |
| 323 | if (queue_hotplug) | ||
| 324 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
| 218 | if (rdev->msi_enabled) { | 325 | if (rdev->msi_enabled) { |
| 219 | switch (rdev->family) { | 326 | switch (rdev->family) { |
| 220 | case CHIP_RS400: | 327 | case CHIP_RS400: |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 7baa73955563..74ad89bdf2b5 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
| @@ -716,6 +716,8 @@ | |||
| 716 | 716 | ||
| 717 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 | 717 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 |
| 718 | 718 | ||
| 719 | #define AVIVO_DC_GPIO_HPD_A 0x7e94 | ||
| 720 | |||
| 719 | #define AVIVO_GPIO_0 0x7e30 | 721 | #define AVIVO_GPIO_0 0x7e30 |
| 720 | #define AVIVO_GPIO_1 0x7e40 | 722 | #define AVIVO_GPIO_1 0x7e40 |
| 721 | #define AVIVO_GPIO_2 0x7e50 | 723 | #define AVIVO_GPIO_2 0x7e50 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 94e7fd2f59e9..250ec3fe1a16 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -74,6 +74,281 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
| 74 | void r600_gpu_init(struct radeon_device *rdev); | 74 | void r600_gpu_init(struct radeon_device *rdev); |
| 75 | void r600_fini(struct radeon_device *rdev); | 75 | void r600_fini(struct radeon_device *rdev); |
| 76 | 76 | ||
| 77 | /* hpd for digital panel detect/disconnect */ | ||
| 78 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
| 79 | { | ||
| 80 | bool connected = false; | ||
| 81 | |||
| 82 | if (ASIC_IS_DCE3(rdev)) { | ||
| 83 | switch (hpd) { | ||
| 84 | case RADEON_HPD_1: | ||
| 85 | if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) | ||
| 86 | connected = true; | ||
| 87 | break; | ||
| 88 | case RADEON_HPD_2: | ||
| 89 | if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) | ||
| 90 | connected = true; | ||
| 91 | break; | ||
| 92 | case RADEON_HPD_3: | ||
| 93 | if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) | ||
| 94 | connected = true; | ||
| 95 | break; | ||
| 96 | case RADEON_HPD_4: | ||
| 97 | if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) | ||
| 98 | connected = true; | ||
| 99 | break; | ||
| 100 | /* DCE 3.2 */ | ||
| 101 | case RADEON_HPD_5: | ||
| 102 | if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) | ||
| 103 | connected = true; | ||
| 104 | break; | ||
| 105 | case RADEON_HPD_6: | ||
| 106 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | ||
| 107 | connected = true; | ||
| 108 | break; | ||
| 109 | default: | ||
| 110 | break; | ||
| 111 | } | ||
| 112 | } else { | ||
| 113 | switch (hpd) { | ||
| 114 | case RADEON_HPD_1: | ||
| 115 | if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
| 116 | connected = true; | ||
| 117 | break; | ||
| 118 | case RADEON_HPD_2: | ||
| 119 | if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
| 120 | connected = true; | ||
| 121 | break; | ||
| 122 | case RADEON_HPD_3: | ||
| 123 | if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
| 124 | connected = true; | ||
| 125 | break; | ||
| 126 | default: | ||
| 127 | break; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | return connected; | ||
| 131 | } | ||
| 132 | |||
| 133 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
| 134 | enum radeon_hpd_id hpd) | ||
| 135 | { | ||
| 136 | u32 tmp; | ||
| 137 | bool connected = r600_hpd_sense(rdev, hpd); | ||
| 138 | |||
| 139 | if (ASIC_IS_DCE3(rdev)) { | ||
| 140 | switch (hpd) { | ||
| 141 | case RADEON_HPD_1: | ||
| 142 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
| 143 | if (connected) | ||
| 144 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 145 | else | ||
| 146 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 147 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
| 148 | break; | ||
| 149 | case RADEON_HPD_2: | ||
| 150 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
| 151 | if (connected) | ||
| 152 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 153 | else | ||
| 154 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 155 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
| 156 | break; | ||
| 157 | case RADEON_HPD_3: | ||
| 158 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
| 159 | if (connected) | ||
| 160 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 161 | else | ||
| 162 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 163 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
| 164 | break; | ||
| 165 | case RADEON_HPD_4: | ||
| 166 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
| 167 | if (connected) | ||
| 168 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 169 | else | ||
| 170 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 171 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
| 172 | break; | ||
| 173 | case RADEON_HPD_5: | ||
| 174 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
| 175 | if (connected) | ||
| 176 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 177 | else | ||
| 178 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 179 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
| 180 | break; | ||
| 181 | /* DCE 3.2 */ | ||
| 182 | case RADEON_HPD_6: | ||
| 183 | tmp = RREG32(DC_HPD6_INT_CONTROL); | ||
| 184 | if (connected) | ||
| 185 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
| 186 | else | ||
| 187 | tmp |= DC_HPDx_INT_POLARITY; | ||
| 188 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
| 189 | break; | ||
| 190 | default: | ||
| 191 | break; | ||
| 192 | } | ||
| 193 | } else { | ||
| 194 | switch (hpd) { | ||
| 195 | case RADEON_HPD_1: | ||
| 196 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
| 197 | if (connected) | ||
| 198 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 199 | else | ||
| 200 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 201 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
| 202 | break; | ||
| 203 | case RADEON_HPD_2: | ||
| 204 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
| 205 | if (connected) | ||
| 206 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 207 | else | ||
| 208 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 209 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
| 210 | break; | ||
| 211 | case RADEON_HPD_3: | ||
| 212 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
| 213 | if (connected) | ||
| 214 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 215 | else | ||
| 216 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 217 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
| 218 | break; | ||
| 219 | default: | ||
| 220 | break; | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | void r600_hpd_init(struct radeon_device *rdev) | ||
| 226 | { | ||
| 227 | struct drm_device *dev = rdev->ddev; | ||
| 228 | struct drm_connector *connector; | ||
| 229 | |||
| 230 | if (ASIC_IS_DCE3(rdev)) { | ||
| 231 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
| 232 | if (ASIC_IS_DCE32(rdev)) | ||
| 233 | tmp |= DC_HPDx_EN; | ||
| 234 | |||
| 235 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 236 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 237 | switch (radeon_connector->hpd.hpd) { | ||
| 238 | case RADEON_HPD_1: | ||
| 239 | WREG32(DC_HPD1_CONTROL, tmp); | ||
| 240 | rdev->irq.hpd[0] = true; | ||
| 241 | break; | ||
| 242 | case RADEON_HPD_2: | ||
| 243 | WREG32(DC_HPD2_CONTROL, tmp); | ||
| 244 | rdev->irq.hpd[1] = true; | ||
| 245 | break; | ||
| 246 | case RADEON_HPD_3: | ||
| 247 | WREG32(DC_HPD3_CONTROL, tmp); | ||
| 248 | rdev->irq.hpd[2] = true; | ||
| 249 | break; | ||
| 250 | case RADEON_HPD_4: | ||
| 251 | WREG32(DC_HPD4_CONTROL, tmp); | ||
| 252 | rdev->irq.hpd[3] = true; | ||
| 253 | break; | ||
| 254 | /* DCE 3.2 */ | ||
| 255 | case RADEON_HPD_5: | ||
| 256 | WREG32(DC_HPD5_CONTROL, tmp); | ||
| 257 | rdev->irq.hpd[4] = true; | ||
| 258 | break; | ||
| 259 | case RADEON_HPD_6: | ||
| 260 | WREG32(DC_HPD6_CONTROL, tmp); | ||
| 261 | rdev->irq.hpd[5] = true; | ||
| 262 | break; | ||
| 263 | default: | ||
| 264 | break; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | } else { | ||
| 268 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 269 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 270 | switch (radeon_connector->hpd.hpd) { | ||
| 271 | case RADEON_HPD_1: | ||
| 272 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
| 273 | rdev->irq.hpd[0] = true; | ||
| 274 | break; | ||
| 275 | case RADEON_HPD_2: | ||
| 276 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
| 277 | rdev->irq.hpd[1] = true; | ||
| 278 | break; | ||
| 279 | case RADEON_HPD_3: | ||
| 280 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
| 281 | rdev->irq.hpd[2] = true; | ||
| 282 | break; | ||
| 283 | default: | ||
| 284 | break; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | r600_irq_set(rdev); | ||
| 289 | } | ||
| 290 | |||
| 291 | void r600_hpd_fini(struct radeon_device *rdev) | ||
| 292 | { | ||
| 293 | struct drm_device *dev = rdev->ddev; | ||
| 294 | struct drm_connector *connector; | ||
| 295 | |||
| 296 | if (ASIC_IS_DCE3(rdev)) { | ||
| 297 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 298 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 299 | switch (radeon_connector->hpd.hpd) { | ||
| 300 | case RADEON_HPD_1: | ||
| 301 | WREG32(DC_HPD1_CONTROL, 0); | ||
| 302 | rdev->irq.hpd[0] = false; | ||
| 303 | break; | ||
| 304 | case RADEON_HPD_2: | ||
| 305 | WREG32(DC_HPD2_CONTROL, 0); | ||
| 306 | rdev->irq.hpd[1] = false; | ||
| 307 | break; | ||
| 308 | case RADEON_HPD_3: | ||
| 309 | WREG32(DC_HPD3_CONTROL, 0); | ||
| 310 | rdev->irq.hpd[2] = false; | ||
| 311 | break; | ||
| 312 | case RADEON_HPD_4: | ||
| 313 | WREG32(DC_HPD4_CONTROL, 0); | ||
| 314 | rdev->irq.hpd[3] = false; | ||
| 315 | break; | ||
| 316 | /* DCE 3.2 */ | ||
| 317 | case RADEON_HPD_5: | ||
| 318 | WREG32(DC_HPD5_CONTROL, 0); | ||
| 319 | rdev->irq.hpd[4] = false; | ||
| 320 | break; | ||
| 321 | case RADEON_HPD_6: | ||
| 322 | WREG32(DC_HPD6_CONTROL, 0); | ||
| 323 | rdev->irq.hpd[5] = false; | ||
| 324 | break; | ||
| 325 | default: | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | } | ||
| 329 | } else { | ||
| 330 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 331 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 332 | switch (radeon_connector->hpd.hpd) { | ||
| 333 | case RADEON_HPD_1: | ||
| 334 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); | ||
| 335 | rdev->irq.hpd[0] = false; | ||
| 336 | break; | ||
| 337 | case RADEON_HPD_2: | ||
| 338 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); | ||
| 339 | rdev->irq.hpd[1] = false; | ||
| 340 | break; | ||
| 341 | case RADEON_HPD_3: | ||
| 342 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); | ||
| 343 | rdev->irq.hpd[2] = false; | ||
| 344 | break; | ||
| 345 | default: | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 77 | /* | 352 | /* |
| 78 | * R600 PCIE GART | 353 | * R600 PCIE GART |
| 79 | */ | 354 | */ |
| @@ -2060,6 +2335,42 @@ static void r600_disable_interrupts(struct radeon_device *rdev) | |||
| 2060 | rdev->ih.rptr = 0; | 2335 | rdev->ih.rptr = 0; |
| 2061 | } | 2336 | } |
| 2062 | 2337 | ||
| 2338 | static void r600_disable_interrupt_state(struct radeon_device *rdev) | ||
| 2339 | { | ||
| 2340 | u32 tmp; | ||
| 2341 | |||
| 2342 | WREG32(CP_INT_CNTL, 0); | ||
| 2343 | WREG32(GRBM_INT_CNTL, 0); | ||
| 2344 | WREG32(DxMODE_INT_MASK, 0); | ||
| 2345 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2346 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | ||
| 2347 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | ||
| 2348 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2349 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
| 2350 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2351 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
| 2352 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2353 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
| 2354 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2355 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
| 2356 | if (ASIC_IS_DCE32(rdev)) { | ||
| 2357 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2358 | WREG32(DC_HPD5_INT_CONTROL, 0); | ||
| 2359 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
| 2360 | WREG32(DC_HPD6_INT_CONTROL, 0); | ||
| 2361 | } | ||
| 2362 | } else { | ||
| 2363 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | ||
| 2364 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | ||
| 2365 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 2366 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); | ||
| 2367 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 2368 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); | ||
| 2369 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
| 2370 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); | ||
| 2371 | } | ||
| 2372 | } | ||
| 2373 | |||
| 2063 | int r600_irq_init(struct radeon_device *rdev) | 2374 | int r600_irq_init(struct radeon_device *rdev) |
| 2064 | { | 2375 | { |
| 2065 | int ret = 0; | 2376 | int ret = 0; |
| @@ -2122,9 +2433,7 @@ int r600_irq_init(struct radeon_device *rdev) | |||
| 2122 | WREG32(IH_CNTL, ih_cntl); | 2433 | WREG32(IH_CNTL, ih_cntl); |
| 2123 | 2434 | ||
| 2124 | /* force the active interrupt state to all disabled */ | 2435 | /* force the active interrupt state to all disabled */ |
| 2125 | WREG32(CP_INT_CNTL, 0); | 2436 | r600_disable_interrupt_state(rdev); |
| 2126 | WREG32(GRBM_INT_CNTL, 0); | ||
| 2127 | WREG32(DxMODE_INT_MASK, 0); | ||
| 2128 | 2437 | ||
| 2129 | /* enable irqs */ | 2438 | /* enable irqs */ |
| 2130 | r600_enable_interrupts(rdev); | 2439 | r600_enable_interrupts(rdev); |
| @@ -2141,13 +2450,29 @@ void r600_irq_fini(struct radeon_device *rdev) | |||
| 2141 | 2450 | ||
| 2142 | int r600_irq_set(struct radeon_device *rdev) | 2451 | int r600_irq_set(struct radeon_device *rdev) |
| 2143 | { | 2452 | { |
| 2144 | uint32_t cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 2453 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
| 2145 | uint32_t mode_int = 0; | 2454 | u32 mode_int = 0; |
| 2455 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | ||
| 2146 | 2456 | ||
| 2147 | /* don't enable anything if the ih is disabled */ | 2457 | /* don't enable anything if the ih is disabled */ |
| 2148 | if (!rdev->ih.enabled) | 2458 | if (!rdev->ih.enabled) |
| 2149 | return 0; | 2459 | return 0; |
| 2150 | 2460 | ||
| 2461 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2462 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2463 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2464 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2465 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2466 | if (ASIC_IS_DCE32(rdev)) { | ||
| 2467 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2468 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2469 | } | ||
| 2470 | } else { | ||
| 2471 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2472 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2473 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
| 2474 | } | ||
| 2475 | |||
| 2151 | if (rdev->irq.sw_int) { | 2476 | if (rdev->irq.sw_int) { |
| 2152 | DRM_DEBUG("r600_irq_set: sw int\n"); | 2477 | DRM_DEBUG("r600_irq_set: sw int\n"); |
| 2153 | cp_int_cntl |= RB_INT_ENABLE; | 2478 | cp_int_cntl |= RB_INT_ENABLE; |
| @@ -2160,39 +2485,137 @@ int r600_irq_set(struct radeon_device *rdev) | |||
| 2160 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 2485 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
| 2161 | mode_int |= D2MODE_VBLANK_INT_MASK; | 2486 | mode_int |= D2MODE_VBLANK_INT_MASK; |
| 2162 | } | 2487 | } |
| 2488 | if (rdev->irq.hpd[0]) { | ||
| 2489 | DRM_DEBUG("r600_irq_set: hpd 1\n"); | ||
| 2490 | hpd1 |= DC_HPDx_INT_EN; | ||
| 2491 | } | ||
| 2492 | if (rdev->irq.hpd[1]) { | ||
| 2493 | DRM_DEBUG("r600_irq_set: hpd 2\n"); | ||
| 2494 | hpd2 |= DC_HPDx_INT_EN; | ||
| 2495 | } | ||
| 2496 | if (rdev->irq.hpd[2]) { | ||
| 2497 | DRM_DEBUG("r600_irq_set: hpd 3\n"); | ||
| 2498 | hpd3 |= DC_HPDx_INT_EN; | ||
| 2499 | } | ||
| 2500 | if (rdev->irq.hpd[3]) { | ||
| 2501 | DRM_DEBUG("r600_irq_set: hpd 4\n"); | ||
| 2502 | hpd4 |= DC_HPDx_INT_EN; | ||
| 2503 | } | ||
| 2504 | if (rdev->irq.hpd[4]) { | ||
| 2505 | DRM_DEBUG("r600_irq_set: hpd 5\n"); | ||
| 2506 | hpd5 |= DC_HPDx_INT_EN; | ||
| 2507 | } | ||
| 2508 | if (rdev->irq.hpd[5]) { | ||
| 2509 | DRM_DEBUG("r600_irq_set: hpd 6\n"); | ||
| 2510 | hpd6 |= DC_HPDx_INT_EN; | ||
| 2511 | } | ||
| 2163 | 2512 | ||
| 2164 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2513 | WREG32(CP_INT_CNTL, cp_int_cntl); |
| 2165 | WREG32(DxMODE_INT_MASK, mode_int); | 2514 | WREG32(DxMODE_INT_MASK, mode_int); |
| 2515 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2516 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | ||
| 2517 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | ||
| 2518 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | ||
| 2519 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | ||
| 2520 | if (ASIC_IS_DCE32(rdev)) { | ||
| 2521 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | ||
| 2522 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | ||
| 2523 | } | ||
| 2524 | } else { | ||
| 2525 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
| 2526 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
| 2527 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); | ||
| 2528 | } | ||
| 2166 | 2529 | ||
| 2167 | return 0; | 2530 | return 0; |
| 2168 | } | 2531 | } |
| 2169 | 2532 | ||
| 2170 | static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int) | 2533 | static inline void r600_irq_ack(struct radeon_device *rdev, |
| 2534 | u32 *disp_int, | ||
| 2535 | u32 *disp_int_cont, | ||
| 2536 | u32 *disp_int_cont2) | ||
| 2171 | { | 2537 | { |
| 2538 | u32 tmp; | ||
| 2539 | |||
| 2540 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2541 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
| 2542 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | ||
| 2543 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | ||
| 2544 | } else { | ||
| 2545 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
| 2546 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | ||
| 2547 | *disp_int_cont2 = 0; | ||
| 2548 | } | ||
| 2172 | 2549 | ||
| 2173 | if (disp_int & LB_D1_VBLANK_INTERRUPT) | 2550 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) |
| 2174 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 2551 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
| 2175 | if (disp_int & LB_D1_VLINE_INTERRUPT) | 2552 | if (*disp_int & LB_D1_VLINE_INTERRUPT) |
| 2176 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 2553 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
| 2177 | if (disp_int & LB_D2_VBLANK_INTERRUPT) | 2554 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) |
| 2178 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 2555 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
| 2179 | if (disp_int & LB_D2_VLINE_INTERRUPT) | 2556 | if (*disp_int & LB_D2_VLINE_INTERRUPT) |
| 2180 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 2557 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
| 2181 | 2558 | if (*disp_int & DC_HPD1_INTERRUPT) { | |
| 2559 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2560 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
| 2561 | tmp |= DC_HPDx_INT_ACK; | ||
| 2562 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
| 2563 | } else { | ||
| 2564 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
| 2565 | tmp |= DC_HPDx_INT_ACK; | ||
| 2566 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
| 2567 | } | ||
| 2568 | } | ||
| 2569 | if (*disp_int & DC_HPD2_INTERRUPT) { | ||
| 2570 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2571 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
| 2572 | tmp |= DC_HPDx_INT_ACK; | ||
| 2573 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
| 2574 | } else { | ||
| 2575 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
| 2576 | tmp |= DC_HPDx_INT_ACK; | ||
| 2577 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
| 2578 | } | ||
| 2579 | } | ||
| 2580 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | ||
| 2581 | if (ASIC_IS_DCE3(rdev)) { | ||
| 2582 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
| 2583 | tmp |= DC_HPDx_INT_ACK; | ||
| 2584 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
| 2585 | } else { | ||
| 2586 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
| 2587 | tmp |= DC_HPDx_INT_ACK; | ||
| 2588 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
| 2589 | } | ||
| 2590 | } | ||
| 2591 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | ||
| 2592 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
| 2593 | tmp |= DC_HPDx_INT_ACK; | ||
| 2594 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
| 2595 | } | ||
| 2596 | if (ASIC_IS_DCE32(rdev)) { | ||
| 2597 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
| 2598 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
| 2599 | tmp |= DC_HPDx_INT_ACK; | ||
| 2600 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
| 2601 | } | ||
| 2602 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
| 2603 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
| 2604 | tmp |= DC_HPDx_INT_ACK; | ||
| 2605 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
| 2606 | } | ||
| 2607 | } | ||
| 2182 | } | 2608 | } |
| 2183 | 2609 | ||
| 2184 | void r600_irq_disable(struct radeon_device *rdev) | 2610 | void r600_irq_disable(struct radeon_device *rdev) |
| 2185 | { | 2611 | { |
| 2186 | u32 disp_int; | 2612 | u32 disp_int, disp_int_cont, disp_int_cont2; |
| 2187 | 2613 | ||
| 2188 | r600_disable_interrupts(rdev); | 2614 | r600_disable_interrupts(rdev); |
| 2189 | /* Wait and acknowledge irq */ | 2615 | /* Wait and acknowledge irq */ |
| 2190 | mdelay(1); | 2616 | mdelay(1); |
| 2191 | if (ASIC_IS_DCE3(rdev)) | 2617 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); |
| 2192 | disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 2618 | r600_disable_interrupt_state(rdev); |
| 2193 | else | ||
| 2194 | disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
| 2195 | r600_irq_ack(rdev, disp_int); | ||
| 2196 | } | 2619 | } |
| 2197 | 2620 | ||
| 2198 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | 2621 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) |
| @@ -2249,8 +2672,9 @@ int r600_irq_process(struct radeon_device *rdev) | |||
| 2249 | u32 rptr = rdev->ih.rptr; | 2672 | u32 rptr = rdev->ih.rptr; |
| 2250 | u32 src_id, src_data; | 2673 | u32 src_id, src_data; |
| 2251 | u32 last_entry = rdev->ih.ring_size - 16; | 2674 | u32 last_entry = rdev->ih.ring_size - 16; |
| 2252 | u32 ring_index, disp_int; | 2675 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; |
| 2253 | unsigned long flags; | 2676 | unsigned long flags; |
| 2677 | bool queue_hotplug = false; | ||
| 2254 | 2678 | ||
| 2255 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2679 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
| 2256 | 2680 | ||
| @@ -2267,11 +2691,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
| 2267 | 2691 | ||
| 2268 | restart_ih: | 2692 | restart_ih: |
| 2269 | /* display interrupts */ | 2693 | /* display interrupts */ |
| 2270 | if (ASIC_IS_DCE3(rdev)) | 2694 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); |
| 2271 | disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
| 2272 | else | ||
| 2273 | disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
| 2274 | r600_irq_ack(rdev, disp_int); | ||
| 2275 | 2695 | ||
| 2276 | rdev->ih.wptr = wptr; | 2696 | rdev->ih.wptr = wptr; |
| 2277 | while (rptr != wptr) { | 2697 | while (rptr != wptr) { |
| @@ -2321,6 +2741,55 @@ restart_ih: | |||
| 2321 | break; | 2741 | break; |
| 2322 | } | 2742 | } |
| 2323 | break; | 2743 | break; |
| 2744 | case 19: /* HPD/DAC hotplug */ | ||
| 2745 | switch (src_data) { | ||
| 2746 | case 0: | ||
| 2747 | if (disp_int & DC_HPD1_INTERRUPT) { | ||
| 2748 | disp_int &= ~DC_HPD1_INTERRUPT; | ||
| 2749 | queue_hotplug = true; | ||
| 2750 | DRM_DEBUG("IH: HPD1\n"); | ||
| 2751 | } | ||
| 2752 | break; | ||
| 2753 | case 1: | ||
| 2754 | if (disp_int & DC_HPD2_INTERRUPT) { | ||
| 2755 | disp_int &= ~DC_HPD2_INTERRUPT; | ||
| 2756 | queue_hotplug = true; | ||
| 2757 | DRM_DEBUG("IH: HPD2\n"); | ||
| 2758 | } | ||
| 2759 | break; | ||
| 2760 | case 4: | ||
| 2761 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | ||
| 2762 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | ||
| 2763 | queue_hotplug = true; | ||
| 2764 | DRM_DEBUG("IH: HPD3\n"); | ||
| 2765 | } | ||
| 2766 | break; | ||
| 2767 | case 5: | ||
| 2768 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | ||
| 2769 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | ||
| 2770 | queue_hotplug = true; | ||
| 2771 | DRM_DEBUG("IH: HPD4\n"); | ||
| 2772 | } | ||
| 2773 | break; | ||
| 2774 | case 10: | ||
| 2775 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
| 2776 | disp_int_cont &= ~DC_HPD5_INTERRUPT; | ||
| 2777 | queue_hotplug = true; | ||
| 2778 | DRM_DEBUG("IH: HPD5\n"); | ||
| 2779 | } | ||
| 2780 | break; | ||
| 2781 | case 12: | ||
| 2782 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
| 2783 | disp_int_cont &= ~DC_HPD6_INTERRUPT; | ||
| 2784 | queue_hotplug = true; | ||
| 2785 | DRM_DEBUG("IH: HPD6\n"); | ||
| 2786 | } | ||
| 2787 | break; | ||
| 2788 | default: | ||
| 2789 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
| 2790 | break; | ||
| 2791 | } | ||
| 2792 | break; | ||
| 2324 | case 176: /* CP_INT in ring buffer */ | 2793 | case 176: /* CP_INT in ring buffer */ |
| 2325 | case 177: /* CP_INT in IB1 */ | 2794 | case 177: /* CP_INT in IB1 */ |
| 2326 | case 178: /* CP_INT in IB2 */ | 2795 | case 178: /* CP_INT in IB2 */ |
| @@ -2345,6 +2814,8 @@ restart_ih: | |||
| 2345 | wptr = r600_get_ih_wptr(rdev); | 2814 | wptr = r600_get_ih_wptr(rdev); |
| 2346 | if (wptr != rdev->ih.wptr) | 2815 | if (wptr != rdev->ih.wptr) |
| 2347 | goto restart_ih; | 2816 | goto restart_ih; |
| 2817 | if (queue_hotplug) | ||
| 2818 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
| 2348 | rdev->ih.rptr = rptr; | 2819 | rdev->ih.rptr = rptr; |
| 2349 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 2820 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
| 2350 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 2821 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 61ccde5637d7..05894edadab4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -558,6 +558,7 @@ | |||
| 558 | # define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) | 558 | # define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) |
| 559 | # define DC_I2C_SW_DONE_INTERRUPT (1 << 20) | 559 | # define DC_I2C_SW_DONE_INTERRUPT (1 << 20) |
| 560 | # define DC_I2C_HW_DONE_INTERRUPT (1 << 21) | 560 | # define DC_I2C_HW_DONE_INTERRUPT (1 << 21) |
| 561 | #define DISP_INTERRUPT_STATUS_CONTINUE 0x7ee8 | ||
| 561 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 | 562 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 |
| 562 | # define DC_HPD4_INTERRUPT (1 << 14) | 563 | # define DC_HPD4_INTERRUPT (1 << 14) |
| 563 | # define DC_HPD4_RX_INTERRUPT (1 << 15) | 564 | # define DC_HPD4_RX_INTERRUPT (1 << 15) |
| @@ -590,6 +591,18 @@ | |||
| 590 | # define DC_HPD6_INTERRUPT (1 << 21) | 591 | # define DC_HPD6_INTERRUPT (1 << 21) |
| 591 | # define DC_HPD6_RX_INTERRUPT (1 << 22) | 592 | # define DC_HPD6_RX_INTERRUPT (1 << 22) |
| 592 | 593 | ||
| 594 | #define DACA_AUTO_DETECT_CONTROL 0x7828 | ||
| 595 | #define DACB_AUTO_DETECT_CONTROL 0x7a28 | ||
| 596 | #define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028 | ||
| 597 | #define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128 | ||
| 598 | # define DACx_AUTODETECT_MODE(x) ((x) << 0) | ||
| 599 | # define DACx_AUTODETECT_MODE_NONE 0 | ||
| 600 | # define DACx_AUTODETECT_MODE_CONNECT 1 | ||
| 601 | # define DACx_AUTODETECT_MODE_DISCONNECT 2 | ||
| 602 | # define DACx_AUTODETECT_FRAME_TIME_COUNTER(x) ((x) << 8) | ||
| 603 | /* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */ | ||
| 604 | # define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16) | ||
| 605 | |||
| 593 | #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 | 606 | #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 |
| 594 | #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 | 607 | #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 |
| 595 | #define DACA_AUTODETECT_INT_CONTROL 0x7838 | 608 | #define DACA_AUTODETECT_INT_CONTROL 0x7838 |
| @@ -597,23 +610,62 @@ | |||
| 597 | # define DACx_AUTODETECT_ACK (1 << 0) | 610 | # define DACx_AUTODETECT_ACK (1 << 0) |
| 598 | # define DACx_AUTODETECT_INT_ENABLE (1 << 16) | 611 | # define DACx_AUTODETECT_INT_ENABLE (1 << 16) |
| 599 | 612 | ||
| 613 | #define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00 | ||
| 614 | #define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10 | ||
| 615 | #define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24 | ||
| 616 | # define DC_HOT_PLUG_DETECTx_EN (1 << 0) | ||
| 617 | |||
| 618 | #define DC_HOT_PLUG_DETECT1_INT_STATUS 0x7d04 | ||
| 619 | #define DC_HOT_PLUG_DETECT2_INT_STATUS 0x7d14 | ||
| 620 | #define DC_HOT_PLUG_DETECT3_INT_STATUS 0x7d28 | ||
| 621 | # define DC_HOT_PLUG_DETECTx_INT_STATUS (1 << 0) | ||
| 622 | # define DC_HOT_PLUG_DETECTx_SENSE (1 << 1) | ||
| 623 | |||
| 624 | /* DCE 3.0 */ | ||
| 625 | #define DC_HPD1_INT_STATUS 0x7d00 | ||
| 626 | #define DC_HPD2_INT_STATUS 0x7d0c | ||
| 627 | #define DC_HPD3_INT_STATUS 0x7d18 | ||
| 628 | #define DC_HPD4_INT_STATUS 0x7d24 | ||
| 629 | /* DCE 3.2 */ | ||
| 630 | #define DC_HPD5_INT_STATUS 0x7dc0 | ||
| 631 | #define DC_HPD6_INT_STATUS 0x7df4 | ||
| 632 | # define DC_HPDx_INT_STATUS (1 << 0) | ||
| 633 | # define DC_HPDx_SENSE (1 << 1) | ||
| 634 | # define DC_HPDx_RX_INT_STATUS (1 << 8) | ||
| 635 | |||
| 600 | #define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 | 636 | #define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 |
| 601 | #define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 | 637 | #define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 |
| 602 | #define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c | 638 | #define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c |
| 603 | # define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) | 639 | # define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) |
| 604 | # define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) | 640 | # define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) |
| 605 | # define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) | 641 | # define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) |
| 606 | /* DCE 3.2 */ | 642 | /* DCE 3.0 */ |
| 607 | #define DC_HPD1_INT_CONTROL 0x7d04 | 643 | #define DC_HPD1_INT_CONTROL 0x7d04 |
| 608 | #define DC_HPD2_INT_CONTROL 0x7d10 | 644 | #define DC_HPD2_INT_CONTROL 0x7d10 |
| 609 | #define DC_HPD3_INT_CONTROL 0x7d1c | 645 | #define DC_HPD3_INT_CONTROL 0x7d1c |
| 610 | #define DC_HPD4_INT_CONTROL 0x7d28 | 646 | #define DC_HPD4_INT_CONTROL 0x7d28 |
| 647 | /* DCE 3.2 */ | ||
| 648 | #define DC_HPD5_INT_CONTROL 0x7dc4 | ||
| 649 | #define DC_HPD6_INT_CONTROL 0x7df8 | ||
| 611 | # define DC_HPDx_INT_ACK (1 << 0) | 650 | # define DC_HPDx_INT_ACK (1 << 0) |
| 612 | # define DC_HPDx_INT_POLARITY (1 << 8) | 651 | # define DC_HPDx_INT_POLARITY (1 << 8) |
| 613 | # define DC_HPDx_INT_EN (1 << 16) | 652 | # define DC_HPDx_INT_EN (1 << 16) |
| 614 | # define DC_HPDx_RX_INT_ACK (1 << 20) | 653 | # define DC_HPDx_RX_INT_ACK (1 << 20) |
| 615 | # define DC_HPDx_RX_INT_EN (1 << 24) | 654 | # define DC_HPDx_RX_INT_EN (1 << 24) |
| 616 | 655 | ||
| 656 | /* DCE 3.0 */ | ||
| 657 | #define DC_HPD1_CONTROL 0x7d08 | ||
| 658 | #define DC_HPD2_CONTROL 0x7d14 | ||
| 659 | #define DC_HPD3_CONTROL 0x7d20 | ||
| 660 | #define DC_HPD4_CONTROL 0x7d2c | ||
| 661 | /* DCE 3.2 */ | ||
| 662 | #define DC_HPD5_CONTROL 0x7dc8 | ||
| 663 | #define DC_HPD6_CONTROL 0x7dfc | ||
| 664 | # define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) | ||
| 665 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | ||
| 666 | /* DCE 3.2 */ | ||
| 667 | # define DC_HPDx_EN (1 << 28) | ||
| 668 | |||
| 617 | /* | 669 | /* |
| 618 | * PM4 | 670 | * PM4 |
| 619 | */ | 671 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f3deb4982b2d..a15cf9ceb9a7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -339,6 +339,8 @@ struct radeon_irq { | |||
| 339 | bool sw_int; | 339 | bool sw_int; |
| 340 | /* FIXME: use a define max crtc rather than hardcode it */ | 340 | /* FIXME: use a define max crtc rather than hardcode it */ |
| 341 | bool crtc_vblank_int[2]; | 341 | bool crtc_vblank_int[2]; |
| 342 | /* FIXME: use defines for max hpd/dacs */ | ||
| 343 | bool hpd[6]; | ||
| 342 | spinlock_t sw_lock; | 344 | spinlock_t sw_lock; |
| 343 | int sw_refcount; | 345 | int sw_refcount; |
| 344 | }; | 346 | }; |
| @@ -647,6 +649,10 @@ struct radeon_asic { | |||
| 647 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); | 649 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); |
| 648 | void (*bandwidth_update)(struct radeon_device *rdev); | 650 | void (*bandwidth_update)(struct radeon_device *rdev); |
| 649 | void (*hdp_flush)(struct radeon_device *rdev); | 651 | void (*hdp_flush)(struct radeon_device *rdev); |
| 652 | void (*hpd_init)(struct radeon_device *rdev); | ||
| 653 | void (*hpd_fini)(struct radeon_device *rdev); | ||
| 654 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
| 655 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
| 650 | }; | 656 | }; |
| 651 | 657 | ||
| 652 | /* | 658 | /* |
| @@ -803,6 +809,8 @@ struct radeon_device { | |||
| 803 | struct r600_blit r600_blit; | 809 | struct r600_blit r600_blit; |
| 804 | int msi_enabled; /* msi enabled */ | 810 | int msi_enabled; /* msi enabled */ |
| 805 | struct r600_ih ih; /* r6/700 interrupt ring */ | 811 | struct r600_ih ih; /* r6/700 interrupt ring */ |
| 812 | struct workqueue_struct *wq; | ||
| 813 | struct work_struct hotplug_work; | ||
| 806 | }; | 814 | }; |
| 807 | 815 | ||
| 808 | int radeon_device_init(struct radeon_device *rdev, | 816 | int radeon_device_init(struct radeon_device *rdev, |
| @@ -986,6 +994,10 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
| 986 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) | 994 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) |
| 987 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) | 995 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) |
| 988 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) | 996 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) |
| 997 | #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) | ||
| 998 | #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) | ||
| 999 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) | ||
| 1000 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) | ||
| 989 | 1001 | ||
| 990 | /* Common functions */ | 1002 | /* Common functions */ |
| 991 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | 1003 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 755f50555c3d..636116bedcb4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -77,6 +77,11 @@ void r100_bandwidth_update(struct radeon_device *rdev); | |||
| 77 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 77 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
| 78 | int r100_ring_test(struct radeon_device *rdev); | 78 | int r100_ring_test(struct radeon_device *rdev); |
| 79 | void r100_hdp_flush(struct radeon_device *rdev); | 79 | void r100_hdp_flush(struct radeon_device *rdev); |
| 80 | void r100_hpd_init(struct radeon_device *rdev); | ||
| 81 | void r100_hpd_fini(struct radeon_device *rdev); | ||
| 82 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
| 83 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
| 84 | enum radeon_hpd_id hpd); | ||
| 80 | 85 | ||
| 81 | static struct radeon_asic r100_asic = { | 86 | static struct radeon_asic r100_asic = { |
| 82 | .init = &r100_init, | 87 | .init = &r100_init, |
| @@ -109,6 +114,10 @@ static struct radeon_asic r100_asic = { | |||
| 109 | .clear_surface_reg = r100_clear_surface_reg, | 114 | .clear_surface_reg = r100_clear_surface_reg, |
| 110 | .bandwidth_update = &r100_bandwidth_update, | 115 | .bandwidth_update = &r100_bandwidth_update, |
| 111 | .hdp_flush = &r100_hdp_flush, | 116 | .hdp_flush = &r100_hdp_flush, |
| 117 | .hpd_init = &r100_hpd_init, | ||
| 118 | .hpd_fini = &r100_hpd_fini, | ||
| 119 | .hpd_sense = &r100_hpd_sense, | ||
| 120 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
| 112 | }; | 121 | }; |
| 113 | 122 | ||
| 114 | 123 | ||
| @@ -165,6 +174,10 @@ static struct radeon_asic r300_asic = { | |||
| 165 | .clear_surface_reg = r100_clear_surface_reg, | 174 | .clear_surface_reg = r100_clear_surface_reg, |
| 166 | .bandwidth_update = &r100_bandwidth_update, | 175 | .bandwidth_update = &r100_bandwidth_update, |
| 167 | .hdp_flush = &r100_hdp_flush, | 176 | .hdp_flush = &r100_hdp_flush, |
| 177 | .hpd_init = &r100_hpd_init, | ||
| 178 | .hpd_fini = &r100_hpd_fini, | ||
| 179 | .hpd_sense = &r100_hpd_sense, | ||
| 180 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
| 168 | }; | 181 | }; |
| 169 | 182 | ||
| 170 | /* | 183 | /* |
| @@ -205,6 +218,10 @@ static struct radeon_asic r420_asic = { | |||
| 205 | .clear_surface_reg = r100_clear_surface_reg, | 218 | .clear_surface_reg = r100_clear_surface_reg, |
| 206 | .bandwidth_update = &r100_bandwidth_update, | 219 | .bandwidth_update = &r100_bandwidth_update, |
| 207 | .hdp_flush = &r100_hdp_flush, | 220 | .hdp_flush = &r100_hdp_flush, |
| 221 | .hpd_init = &r100_hpd_init, | ||
| 222 | .hpd_fini = &r100_hpd_fini, | ||
| 223 | .hpd_sense = &r100_hpd_sense, | ||
| 224 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
| 208 | }; | 225 | }; |
| 209 | 226 | ||
| 210 | 227 | ||
| @@ -250,6 +267,10 @@ static struct radeon_asic rs400_asic = { | |||
| 250 | .clear_surface_reg = r100_clear_surface_reg, | 267 | .clear_surface_reg = r100_clear_surface_reg, |
| 251 | .bandwidth_update = &r100_bandwidth_update, | 268 | .bandwidth_update = &r100_bandwidth_update, |
| 252 | .hdp_flush = &r100_hdp_flush, | 269 | .hdp_flush = &r100_hdp_flush, |
| 270 | .hpd_init = &r100_hpd_init, | ||
| 271 | .hpd_fini = &r100_hpd_fini, | ||
| 272 | .hpd_sense = &r100_hpd_sense, | ||
| 273 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
| 253 | }; | 274 | }; |
| 254 | 275 | ||
| 255 | 276 | ||
| @@ -268,6 +289,12 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
| 268 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 289 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 269 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 290 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 270 | void rs600_bandwidth_update(struct radeon_device *rdev); | 291 | void rs600_bandwidth_update(struct radeon_device *rdev); |
| 292 | void rs600_hpd_init(struct radeon_device *rdev); | ||
| 293 | void rs600_hpd_fini(struct radeon_device *rdev); | ||
| 294 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
| 295 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
| 296 | enum radeon_hpd_id hpd); | ||
| 297 | |||
| 271 | static struct radeon_asic rs600_asic = { | 298 | static struct radeon_asic rs600_asic = { |
| 272 | .init = &rs600_init, | 299 | .init = &rs600_init, |
| 273 | .fini = &rs600_fini, | 300 | .fini = &rs600_fini, |
| @@ -297,6 +324,10 @@ static struct radeon_asic rs600_asic = { | |||
| 297 | .set_clock_gating = &radeon_atom_set_clock_gating, | 324 | .set_clock_gating = &radeon_atom_set_clock_gating, |
| 298 | .bandwidth_update = &rs600_bandwidth_update, | 325 | .bandwidth_update = &rs600_bandwidth_update, |
| 299 | .hdp_flush = &r100_hdp_flush, | 326 | .hdp_flush = &r100_hdp_flush, |
| 327 | .hpd_init = &rs600_hpd_init, | ||
| 328 | .hpd_fini = &rs600_hpd_fini, | ||
| 329 | .hpd_sense = &rs600_hpd_sense, | ||
| 330 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
| 300 | }; | 331 | }; |
| 301 | 332 | ||
| 302 | 333 | ||
| @@ -341,6 +372,10 @@ static struct radeon_asic rs690_asic = { | |||
| 341 | .clear_surface_reg = r100_clear_surface_reg, | 372 | .clear_surface_reg = r100_clear_surface_reg, |
| 342 | .bandwidth_update = &rs690_bandwidth_update, | 373 | .bandwidth_update = &rs690_bandwidth_update, |
| 343 | .hdp_flush = &r100_hdp_flush, | 374 | .hdp_flush = &r100_hdp_flush, |
| 375 | .hpd_init = &rs600_hpd_init, | ||
| 376 | .hpd_fini = &rs600_hpd_fini, | ||
| 377 | .hpd_sense = &rs600_hpd_sense, | ||
| 378 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
| 344 | }; | 379 | }; |
| 345 | 380 | ||
| 346 | 381 | ||
| @@ -389,6 +424,10 @@ static struct radeon_asic rv515_asic = { | |||
| 389 | .clear_surface_reg = r100_clear_surface_reg, | 424 | .clear_surface_reg = r100_clear_surface_reg, |
| 390 | .bandwidth_update = &rv515_bandwidth_update, | 425 | .bandwidth_update = &rv515_bandwidth_update, |
| 391 | .hdp_flush = &r100_hdp_flush, | 426 | .hdp_flush = &r100_hdp_flush, |
| 427 | .hpd_init = &rs600_hpd_init, | ||
| 428 | .hpd_fini = &rs600_hpd_fini, | ||
| 429 | .hpd_sense = &rs600_hpd_sense, | ||
| 430 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
| 392 | }; | 431 | }; |
| 393 | 432 | ||
| 394 | 433 | ||
| @@ -428,6 +467,10 @@ static struct radeon_asic r520_asic = { | |||
| 428 | .clear_surface_reg = r100_clear_surface_reg, | 467 | .clear_surface_reg = r100_clear_surface_reg, |
| 429 | .bandwidth_update = &rv515_bandwidth_update, | 468 | .bandwidth_update = &rv515_bandwidth_update, |
| 430 | .hdp_flush = &r100_hdp_flush, | 469 | .hdp_flush = &r100_hdp_flush, |
| 470 | .hpd_init = &rs600_hpd_init, | ||
| 471 | .hpd_fini = &rs600_hpd_fini, | ||
| 472 | .hpd_sense = &rs600_hpd_sense, | ||
| 473 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
| 431 | }; | 474 | }; |
| 432 | 475 | ||
| 433 | /* | 476 | /* |
| @@ -465,6 +508,11 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
| 465 | uint64_t src_offset, uint64_t dst_offset, | 508 | uint64_t src_offset, uint64_t dst_offset, |
| 466 | unsigned num_pages, struct radeon_fence *fence); | 509 | unsigned num_pages, struct radeon_fence *fence); |
| 467 | void r600_hdp_flush(struct radeon_device *rdev); | 510 | void r600_hdp_flush(struct radeon_device *rdev); |
| 511 | void r600_hpd_init(struct radeon_device *rdev); | ||
| 512 | void r600_hpd_fini(struct radeon_device *rdev); | ||
| 513 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
| 514 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
| 515 | enum radeon_hpd_id hpd); | ||
| 468 | 516 | ||
| 469 | static struct radeon_asic r600_asic = { | 517 | static struct radeon_asic r600_asic = { |
| 470 | .init = &r600_init, | 518 | .init = &r600_init, |
| @@ -496,6 +544,10 @@ static struct radeon_asic r600_asic = { | |||
| 496 | .clear_surface_reg = r600_clear_surface_reg, | 544 | .clear_surface_reg = r600_clear_surface_reg, |
| 497 | .bandwidth_update = &rv515_bandwidth_update, | 545 | .bandwidth_update = &rv515_bandwidth_update, |
| 498 | .hdp_flush = &r600_hdp_flush, | 546 | .hdp_flush = &r600_hdp_flush, |
| 547 | .hpd_init = &r600_hpd_init, | ||
| 548 | .hpd_fini = &r600_hpd_fini, | ||
| 549 | .hpd_sense = &r600_hpd_sense, | ||
| 550 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
| 499 | }; | 551 | }; |
| 500 | 552 | ||
| 501 | /* | 553 | /* |
| @@ -537,6 +589,10 @@ static struct radeon_asic rv770_asic = { | |||
| 537 | .clear_surface_reg = r600_clear_surface_reg, | 589 | .clear_surface_reg = r600_clear_surface_reg, |
| 538 | .bandwidth_update = &rv515_bandwidth_update, | 590 | .bandwidth_update = &rv515_bandwidth_update, |
| 539 | .hdp_flush = &r600_hdp_flush, | 591 | .hdp_flush = &r600_hdp_flush, |
| 592 | .hpd_init = &r600_hpd_init, | ||
| 593 | .hpd_fini = &r600_hpd_fini, | ||
| 594 | .hpd_sense = &r600_hpd_sense, | ||
| 595 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
| 540 | }; | 596 | }; |
| 541 | 597 | ||
| 542 | #endif | 598 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5e414102c875..d7b0feb7d47f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -47,7 +47,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 47 | int connector_type, | 47 | int connector_type, |
| 48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
| 49 | bool linkb, uint32_t igp_lane_info, | 49 | bool linkb, uint32_t igp_lane_info, |
| 50 | uint16_t connector_object_id); | 50 | uint16_t connector_object_id, |
| 51 | struct radeon_hpd *hpd); | ||
| 51 | 52 | ||
| 52 | /* from radeon_legacy_encoder.c */ | 53 | /* from radeon_legacy_encoder.c */ |
| 53 | extern void | 54 | extern void |
| @@ -60,12 +61,11 @@ union atom_supported_devices { | |||
| 60 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 61 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 63 | static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | 64 | static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
| 64 | *dev, uint8_t id) | 65 | uint8_t id) |
| 65 | { | 66 | { |
| 66 | struct radeon_device *rdev = dev->dev_private; | ||
| 67 | struct atom_context *ctx = rdev->mode_info.atom_context; | 67 | struct atom_context *ctx = rdev->mode_info.atom_context; |
| 68 | ATOM_GPIO_I2C_ASSIGMENT gpio; | 68 | ATOM_GPIO_I2C_ASSIGMENT *gpio; |
| 69 | struct radeon_i2c_bus_rec i2c; | 69 | struct radeon_i2c_bus_rec i2c; |
| 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); | 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
| 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; | 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; |
| @@ -78,34 +78,116 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | |||
| 78 | 78 | ||
| 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
| 80 | 80 | ||
| 81 | gpio = i2c_info->asGPIO_Info[id]; | 81 | gpio = &i2c_info->asGPIO_Info[id]; |
| 82 | 82 | ||
| 83 | i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; | 83 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
| 84 | i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; | 84 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
| 85 | i2c.en_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; | 85 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
| 86 | i2c.en_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; | 86 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; |
| 87 | i2c.y_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; | 87 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; |
| 88 | i2c.y_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; | 88 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; |
| 89 | i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; | 89 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; |
| 90 | i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; | 90 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; |
| 91 | i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); | 91 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); |
| 92 | i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); | 92 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); |
| 93 | i2c.en_clk_mask = (1 << gpio.ucClkEnShift); | 93 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); |
| 94 | i2c.en_data_mask = (1 << gpio.ucDataEnShift); | 94 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); |
| 95 | i2c.y_clk_mask = (1 << gpio.ucClkY_Shift); | 95 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); |
| 96 | i2c.y_data_mask = (1 << gpio.ucDataY_Shift); | 96 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); |
| 97 | i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); | 97 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); |
| 98 | i2c.a_data_mask = (1 << gpio.ucDataA_Shift); | 98 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); |
| 99 | |||
| 100 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
| 101 | i2c.hw_capable = true; | ||
| 102 | else | ||
| 103 | i2c.hw_capable = false; | ||
| 104 | |||
| 105 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
| 106 | i2c.mm_i2c = true; | ||
| 107 | else | ||
| 108 | i2c.mm_i2c = false; | ||
| 109 | |||
| 110 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
| 111 | |||
| 99 | i2c.valid = true; | 112 | i2c.valid = true; |
| 100 | 113 | ||
| 101 | return i2c; | 114 | return i2c; |
| 102 | } | 115 | } |
| 103 | 116 | ||
| 117 | static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, | ||
| 118 | u8 id) | ||
| 119 | { | ||
| 120 | struct atom_context *ctx = rdev->mode_info.atom_context; | ||
| 121 | struct radeon_gpio_rec gpio; | ||
| 122 | int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); | ||
| 123 | struct _ATOM_GPIO_PIN_LUT *gpio_info; | ||
| 124 | ATOM_GPIO_PIN_ASSIGNMENT *pin; | ||
| 125 | u16 data_offset, size; | ||
| 126 | int i, num_indices; | ||
| 127 | |||
| 128 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); | ||
| 129 | gpio.valid = false; | ||
| 130 | |||
| 131 | atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); | ||
| 132 | |||
| 133 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | ||
| 134 | |||
| 135 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | ||
| 136 | |||
| 137 | for (i = 0; i < num_indices; i++) { | ||
| 138 | pin = &gpio_info->asGPIO_Pin[i]; | ||
| 139 | if (id == pin->ucGPIO_ID) { | ||
| 140 | gpio.id = pin->ucGPIO_ID; | ||
| 141 | gpio.reg = pin->usGpioPin_AIndex * 4; | ||
| 142 | gpio.mask = (1 << pin->ucGpioPinBitShift); | ||
| 143 | gpio.valid = true; | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | return gpio; | ||
| 149 | } | ||
| 150 | |||
| 151 | static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, | ||
| 152 | struct radeon_gpio_rec *gpio) | ||
| 153 | { | ||
| 154 | struct radeon_hpd hpd; | ||
| 155 | hpd.gpio = *gpio; | ||
| 156 | if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { | ||
| 157 | switch(gpio->mask) { | ||
| 158 | case (1 << 0): | ||
| 159 | hpd.hpd = RADEON_HPD_1; | ||
| 160 | break; | ||
| 161 | case (1 << 8): | ||
| 162 | hpd.hpd = RADEON_HPD_2; | ||
| 163 | break; | ||
| 164 | case (1 << 16): | ||
| 165 | hpd.hpd = RADEON_HPD_3; | ||
| 166 | break; | ||
| 167 | case (1 << 24): | ||
| 168 | hpd.hpd = RADEON_HPD_4; | ||
| 169 | break; | ||
| 170 | case (1 << 26): | ||
| 171 | hpd.hpd = RADEON_HPD_5; | ||
| 172 | break; | ||
| 173 | case (1 << 28): | ||
| 174 | hpd.hpd = RADEON_HPD_6; | ||
| 175 | break; | ||
| 176 | default: | ||
| 177 | hpd.hpd = RADEON_HPD_NONE; | ||
| 178 | break; | ||
| 179 | } | ||
| 180 | } else | ||
| 181 | hpd.hpd = RADEON_HPD_NONE; | ||
| 182 | return hpd; | ||
| 183 | } | ||
| 184 | |||
| 104 | static bool radeon_atom_apply_quirks(struct drm_device *dev, | 185 | static bool radeon_atom_apply_quirks(struct drm_device *dev, |
| 105 | uint32_t supported_device, | 186 | uint32_t supported_device, |
| 106 | int *connector_type, | 187 | int *connector_type, |
| 107 | struct radeon_i2c_bus_rec *i2c_bus, | 188 | struct radeon_i2c_bus_rec *i2c_bus, |
| 108 | uint16_t *line_mux) | 189 | uint16_t *line_mux, |
| 190 | struct radeon_hpd *hpd) | ||
| 109 | { | 191 | { |
| 110 | 192 | ||
| 111 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ | 193 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
| @@ -266,16 +348,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 266 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 348 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 267 | struct atom_context *ctx = mode_info->atom_context; | 349 | struct atom_context *ctx = mode_info->atom_context; |
| 268 | int index = GetIndexIntoMasterTable(DATA, Object_Header); | 350 | int index = GetIndexIntoMasterTable(DATA, Object_Header); |
| 269 | uint16_t size, data_offset; | 351 | u16 size, data_offset; |
| 270 | uint8_t frev, crev, line_mux = 0; | 352 | u8 frev, crev; |
| 271 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; | 353 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
| 272 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; | 354 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
| 273 | ATOM_OBJECT_HEADER *obj_header; | 355 | ATOM_OBJECT_HEADER *obj_header; |
| 274 | int i, j, path_size, device_support; | 356 | int i, j, path_size, device_support; |
| 275 | int connector_type; | 357 | int connector_type; |
| 276 | uint16_t igp_lane_info, conn_id, connector_object_id; | 358 | u16 igp_lane_info, conn_id, connector_object_id; |
| 277 | bool linkb; | 359 | bool linkb; |
| 278 | struct radeon_i2c_bus_rec ddc_bus; | 360 | struct radeon_i2c_bus_rec ddc_bus; |
| 361 | struct radeon_gpio_rec gpio; | ||
| 362 | struct radeon_hpd hpd; | ||
| 279 | 363 | ||
| 280 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 364 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
| 281 | 365 | ||
| @@ -302,7 +386,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 302 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 386 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
| 303 | path_size += le16_to_cpu(path->usSize); | 387 | path_size += le16_to_cpu(path->usSize); |
| 304 | linkb = false; | 388 | linkb = false; |
| 305 | |||
| 306 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 389 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
| 307 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 390 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
| 308 | 391 | ||
| @@ -403,10 +486,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 403 | } | 486 | } |
| 404 | } | 487 | } |
| 405 | 488 | ||
| 406 | /* look up gpio for ddc */ | 489 | /* look up gpio for ddc, hpd */ |
| 407 | if ((le16_to_cpu(path->usDeviceTag) & | 490 | if ((le16_to_cpu(path->usDeviceTag) & |
| 408 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 491 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { |
| 409 | == 0) { | ||
| 410 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { | 492 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { |
| 411 | if (le16_to_cpu(path->usConnObjectId) == | 493 | if (le16_to_cpu(path->usConnObjectId) == |
| 412 | le16_to_cpu(con_obj->asObjects[j]. | 494 | le16_to_cpu(con_obj->asObjects[j]. |
| @@ -420,21 +502,31 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 420 | asObjects[j]. | 502 | asObjects[j]. |
| 421 | usRecordOffset)); | 503 | usRecordOffset)); |
| 422 | ATOM_I2C_RECORD *i2c_record; | 504 | ATOM_I2C_RECORD *i2c_record; |
| 505 | ATOM_HPD_INT_RECORD *hpd_record; | ||
| 506 | hpd.hpd = RADEON_HPD_NONE; | ||
| 423 | 507 | ||
| 424 | while (record->ucRecordType > 0 | 508 | while (record->ucRecordType > 0 |
| 425 | && record-> | 509 | && record-> |
| 426 | ucRecordType <= | 510 | ucRecordType <= |
| 427 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | 511 | ATOM_MAX_OBJECT_RECORD_NUMBER) { |
| 428 | switch (record-> | 512 | switch (record->ucRecordType) { |
| 429 | ucRecordType) { | ||
| 430 | case ATOM_I2C_RECORD_TYPE: | 513 | case ATOM_I2C_RECORD_TYPE: |
| 431 | i2c_record = | 514 | i2c_record = |
| 432 | (ATOM_I2C_RECORD | 515 | (ATOM_I2C_RECORD *) |
| 433 | *) record; | 516 | record; |
| 434 | line_mux = | 517 | ddc_bus = radeon_lookup_i2c_gpio(rdev, |
| 435 | i2c_record-> | 518 | i2c_record-> |
| 436 | sucI2cId. | 519 | sucI2cId. |
| 437 | bfI2C_LineMux; | 520 | bfI2C_LineMux); |
| 521 | break; | ||
| 522 | case ATOM_HPD_INT_RECORD_TYPE: | ||
| 523 | hpd_record = | ||
| 524 | (ATOM_HPD_INT_RECORD *) | ||
| 525 | record; | ||
| 526 | gpio = radeon_lookup_gpio(rdev, | ||
| 527 | hpd_record->ucHPDIntGPIOID); | ||
| 528 | hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
| 529 | hpd.plugged_state = hpd_record->ucPlugged_PinState; | ||
| 438 | break; | 530 | break; |
| 439 | } | 531 | } |
| 440 | record = | 532 | record = |
| @@ -447,24 +539,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 447 | break; | 539 | break; |
| 448 | } | 540 | } |
| 449 | } | 541 | } |
| 450 | } else | 542 | } else { |
| 451 | line_mux = 0; | 543 | hpd.hpd = RADEON_HPD_NONE; |
| 452 | |||
| 453 | if ((le16_to_cpu(path->usDeviceTag) == | ||
| 454 | ATOM_DEVICE_TV1_SUPPORT) | ||
| 455 | || (le16_to_cpu(path->usDeviceTag) == | ||
| 456 | ATOM_DEVICE_TV2_SUPPORT) | ||
| 457 | || (le16_to_cpu(path->usDeviceTag) == | ||
| 458 | ATOM_DEVICE_CV_SUPPORT)) | ||
| 459 | ddc_bus.valid = false; | 544 | ddc_bus.valid = false; |
| 460 | else | 545 | } |
| 461 | ddc_bus = radeon_lookup_gpio(dev, line_mux); | ||
| 462 | 546 | ||
| 463 | conn_id = le16_to_cpu(path->usConnObjectId); | 547 | conn_id = le16_to_cpu(path->usConnObjectId); |
| 464 | 548 | ||
| 465 | if (!radeon_atom_apply_quirks | 549 | if (!radeon_atom_apply_quirks |
| 466 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, | 550 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, |
| 467 | &ddc_bus, &conn_id)) | 551 | &ddc_bus, &conn_id, &hpd)) |
| 468 | continue; | 552 | continue; |
| 469 | 553 | ||
| 470 | radeon_add_atom_connector(dev, | 554 | radeon_add_atom_connector(dev, |
| @@ -473,7 +557,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 473 | usDeviceTag), | 557 | usDeviceTag), |
| 474 | connector_type, &ddc_bus, | 558 | connector_type, &ddc_bus, |
| 475 | linkb, igp_lane_info, | 559 | linkb, igp_lane_info, |
| 476 | connector_object_id); | 560 | connector_object_id, |
| 561 | &hpd); | ||
| 477 | 562 | ||
| 478 | } | 563 | } |
| 479 | } | 564 | } |
| @@ -528,6 +613,7 @@ struct bios_connector { | |||
| 528 | uint16_t devices; | 613 | uint16_t devices; |
| 529 | int connector_type; | 614 | int connector_type; |
| 530 | struct radeon_i2c_bus_rec ddc_bus; | 615 | struct radeon_i2c_bus_rec ddc_bus; |
| 616 | struct radeon_hpd hpd; | ||
| 531 | }; | 617 | }; |
| 532 | 618 | ||
| 533 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct | 619 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct |
| @@ -543,7 +629,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 543 | uint16_t device_support; | 629 | uint16_t device_support; |
| 544 | uint8_t dac; | 630 | uint8_t dac; |
| 545 | union atom_supported_devices *supported_devices; | 631 | union atom_supported_devices *supported_devices; |
| 546 | int i, j; | 632 | int i, j, max_device; |
| 547 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; | 633 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
| 548 | 634 | ||
| 549 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 635 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
| @@ -553,7 +639,12 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 553 | 639 | ||
| 554 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); | 640 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); |
| 555 | 641 | ||
| 556 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 642 | if (frev > 1) |
| 643 | max_device = ATOM_MAX_SUPPORTED_DEVICE; | ||
| 644 | else | ||
| 645 | max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; | ||
| 646 | |||
| 647 | for (i = 0; i < max_device; i++) { | ||
| 557 | ATOM_CONNECTOR_INFO_I2C ci = | 648 | ATOM_CONNECTOR_INFO_I2C ci = |
| 558 | supported_devices->info.asConnInfo[i]; | 649 | supported_devices->info.asConnInfo[i]; |
| 559 | 650 | ||
| @@ -608,8 +699,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 608 | bios_connectors[i].line_mux = 52; | 699 | bios_connectors[i].line_mux = 52; |
| 609 | } else | 700 | } else |
| 610 | bios_connectors[i].ddc_bus = | 701 | bios_connectors[i].ddc_bus = |
| 611 | radeon_lookup_gpio(dev, | 702 | radeon_lookup_i2c_gpio(rdev, |
| 612 | bios_connectors[i].line_mux); | 703 | bios_connectors[i].line_mux); |
| 704 | |||
| 705 | if ((crev > 1) && (frev > 1)) { | ||
| 706 | u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; | ||
| 707 | switch (isb) { | ||
| 708 | case 0x4: | ||
| 709 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
| 710 | break; | ||
| 711 | case 0xa: | ||
| 712 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
| 713 | break; | ||
| 714 | default: | ||
| 715 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | } else { | ||
| 719 | if (i == ATOM_DEVICE_DFP1_INDEX) | ||
| 720 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
| 721 | else if (i == ATOM_DEVICE_DFP2_INDEX) | ||
| 722 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
| 723 | else | ||
| 724 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
| 725 | } | ||
| 613 | 726 | ||
| 614 | /* Always set the connector type to VGA for CRT1/CRT2. if they are | 727 | /* Always set the connector type to VGA for CRT1/CRT2. if they are |
| 615 | * shared with a DVI port, we'll pick up the DVI connector when we | 728 | * shared with a DVI port, we'll pick up the DVI connector when we |
| @@ -621,7 +734,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 621 | 734 | ||
| 622 | if (!radeon_atom_apply_quirks | 735 | if (!radeon_atom_apply_quirks |
| 623 | (dev, (1 << i), &bios_connectors[i].connector_type, | 736 | (dev, (1 << i), &bios_connectors[i].connector_type, |
| 624 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) | 737 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, |
| 738 | &bios_connectors[i].hpd)) | ||
| 625 | continue; | 739 | continue; |
| 626 | 740 | ||
| 627 | bios_connectors[i].valid = true; | 741 | bios_connectors[i].valid = true; |
| @@ -643,9 +757,9 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 643 | } | 757 | } |
| 644 | 758 | ||
| 645 | /* combine shared connectors */ | 759 | /* combine shared connectors */ |
| 646 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 760 | for (i = 0; i < max_device; i++) { |
| 647 | if (bios_connectors[i].valid) { | 761 | if (bios_connectors[i].valid) { |
| 648 | for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { | 762 | for (j = 0; j < max_device; j++) { |
| 649 | if (bios_connectors[j].valid && (i != j)) { | 763 | if (bios_connectors[j].valid && (i != j)) { |
| 650 | if (bios_connectors[i].line_mux == | 764 | if (bios_connectors[i].line_mux == |
| 651 | bios_connectors[j].line_mux) { | 765 | bios_connectors[j].line_mux) { |
| @@ -669,6 +783,10 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 669 | bios_connectors[i]. | 783 | bios_connectors[i]. |
| 670 | connector_type = | 784 | connector_type = |
| 671 | DRM_MODE_CONNECTOR_DVII; | 785 | DRM_MODE_CONNECTOR_DVII; |
| 786 | if (bios_connectors[j].devices & | ||
| 787 | (ATOM_DEVICE_DFP_SUPPORT)) | ||
| 788 | bios_connectors[i].hpd = | ||
| 789 | bios_connectors[j].hpd; | ||
| 672 | bios_connectors[j]. | 790 | bios_connectors[j]. |
| 673 | valid = false; | 791 | valid = false; |
| 674 | } | 792 | } |
| @@ -679,7 +797,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 679 | } | 797 | } |
| 680 | 798 | ||
| 681 | /* add the connectors */ | 799 | /* add the connectors */ |
| 682 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 800 | for (i = 0; i < max_device; i++) { |
| 683 | if (bios_connectors[i].valid) { | 801 | if (bios_connectors[i].valid) { |
| 684 | uint16_t connector_object_id = | 802 | uint16_t connector_object_id = |
| 685 | atombios_get_connector_object_id(dev, | 803 | atombios_get_connector_object_id(dev, |
| @@ -692,7 +810,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 692 | connector_type, | 810 | connector_type, |
| 693 | &bios_connectors[i].ddc_bus, | 811 | &bios_connectors[i].ddc_bus, |
| 694 | false, 0, | 812 | false, 0, |
| 695 | connector_object_id); | 813 | connector_object_id, |
| 814 | &bios_connectors[i].hpd); | ||
| 696 | } | 815 | } |
| 697 | } | 816 | } |
| 698 | 817 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 14d3555e4afe..c5021a3445de 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -50,7 +50,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 50 | uint32_t supported_device, | 50 | uint32_t supported_device, |
| 51 | int connector_type, | 51 | int connector_type, |
| 52 | struct radeon_i2c_bus_rec *i2c_bus, | 52 | struct radeon_i2c_bus_rec *i2c_bus, |
| 53 | uint16_t connector_object_id); | 53 | uint16_t connector_object_id, |
| 54 | struct radeon_hpd *hpd); | ||
| 54 | 55 | ||
| 55 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
| 56 | extern void | 57 | extern void |
| @@ -442,29 +443,39 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, | |||
| 442 | 443 | ||
| 443 | } | 444 | } |
| 444 | 445 | ||
| 445 | struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) | 446 | static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, |
| 447 | int ddc_line) | ||
| 446 | { | 448 | { |
| 447 | struct radeon_i2c_bus_rec i2c; | 449 | struct radeon_i2c_bus_rec i2c; |
| 448 | 450 | ||
| 449 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | 451 | if (ddc_line == RADEON_GPIOPAD_MASK) { |
| 450 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | 452 | i2c.mask_clk_reg = RADEON_GPIOPAD_MASK; |
| 451 | i2c.a_clk_mask = RADEON_GPIO_A_1; | 453 | i2c.mask_data_reg = RADEON_GPIOPAD_MASK; |
| 452 | i2c.a_data_mask = RADEON_GPIO_A_0; | 454 | i2c.a_clk_reg = RADEON_GPIOPAD_A; |
| 453 | i2c.en_clk_mask = RADEON_GPIO_EN_1; | 455 | i2c.a_data_reg = RADEON_GPIOPAD_A; |
| 454 | i2c.en_data_mask = RADEON_GPIO_EN_0; | 456 | i2c.en_clk_reg = RADEON_GPIOPAD_EN; |
| 455 | i2c.y_clk_mask = RADEON_GPIO_Y_1; | 457 | i2c.en_data_reg = RADEON_GPIOPAD_EN; |
| 456 | i2c.y_data_mask = RADEON_GPIO_Y_0; | 458 | i2c.y_clk_reg = RADEON_GPIOPAD_Y; |
| 457 | if ((ddc_line == RADEON_LCD_GPIO_MASK) || | 459 | i2c.y_data_reg = RADEON_GPIOPAD_Y; |
| 458 | (ddc_line == RADEON_MDGPIO_EN_REG)) { | 460 | } else if (ddc_line == RADEON_MDGPIO_MASK) { |
| 459 | i2c.mask_clk_reg = ddc_line; | 461 | i2c.mask_clk_reg = RADEON_MDGPIO_MASK; |
| 460 | i2c.mask_data_reg = ddc_line; | 462 | i2c.mask_data_reg = RADEON_MDGPIO_MASK; |
| 461 | i2c.a_clk_reg = ddc_line; | 463 | i2c.a_clk_reg = RADEON_MDGPIO_A; |
| 462 | i2c.a_data_reg = ddc_line; | 464 | i2c.a_data_reg = RADEON_MDGPIO_A; |
| 463 | i2c.en_clk_reg = ddc_line; | 465 | i2c.en_clk_reg = RADEON_MDGPIO_EN; |
| 464 | i2c.en_data_reg = ddc_line; | 466 | i2c.en_data_reg = RADEON_MDGPIO_EN; |
| 465 | i2c.y_clk_reg = ddc_line + 4; | 467 | i2c.y_clk_reg = RADEON_MDGPIO_Y; |
| 466 | i2c.y_data_reg = ddc_line + 4; | 468 | i2c.y_data_reg = RADEON_MDGPIO_Y; |
| 467 | } else { | 469 | } else { |
| 470 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | ||
| 471 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | ||
| 472 | i2c.a_clk_mask = RADEON_GPIO_A_1; | ||
| 473 | i2c.a_data_mask = RADEON_GPIO_A_0; | ||
| 474 | i2c.en_clk_mask = RADEON_GPIO_EN_1; | ||
| 475 | i2c.en_data_mask = RADEON_GPIO_EN_0; | ||
| 476 | i2c.y_clk_mask = RADEON_GPIO_Y_1; | ||
| 477 | i2c.y_data_mask = RADEON_GPIO_Y_0; | ||
| 478 | |||
| 468 | i2c.mask_clk_reg = ddc_line; | 479 | i2c.mask_clk_reg = ddc_line; |
| 469 | i2c.mask_data_reg = ddc_line; | 480 | i2c.mask_data_reg = ddc_line; |
| 470 | i2c.a_clk_reg = ddc_line; | 481 | i2c.a_clk_reg = ddc_line; |
| @@ -475,6 +486,28 @@ struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) | |||
| 475 | i2c.y_data_reg = ddc_line; | 486 | i2c.y_data_reg = ddc_line; |
| 476 | } | 487 | } |
| 477 | 488 | ||
| 489 | if (rdev->family < CHIP_R200) | ||
| 490 | i2c.hw_capable = false; | ||
| 491 | else { | ||
| 492 | switch (ddc_line) { | ||
| 493 | case RADEON_GPIO_VGA_DDC: | ||
| 494 | case RADEON_GPIO_DVI_DDC: | ||
| 495 | i2c.hw_capable = true; | ||
| 496 | break; | ||
| 497 | case RADEON_GPIO_MONID: | ||
| 498 | /* hw i2c on RADEON_GPIO_MONID doesn't seem to work | ||
| 499 | * reliably on some pre-r4xx hardware; not sure why. | ||
| 500 | */ | ||
| 501 | i2c.hw_capable = false; | ||
| 502 | break; | ||
| 503 | default: | ||
| 504 | i2c.hw_capable = false; | ||
| 505 | break; | ||
| 506 | } | ||
| 507 | } | ||
| 508 | i2c.mm_i2c = false; | ||
| 509 | i2c.i2c_id = 0; | ||
| 510 | |||
| 478 | if (ddc_line) | 511 | if (ddc_line) |
| 479 | i2c.valid = true; | 512 | i2c.valid = true; |
| 480 | else | 513 | else |
| @@ -1077,7 +1110,7 @@ bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, | |||
| 1077 | struct radeon_i2c_bus_rec i2c_bus; | 1110 | struct radeon_i2c_bus_rec i2c_bus; |
| 1078 | 1111 | ||
| 1079 | /* default for macs */ | 1112 | /* default for macs */ |
| 1080 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1113 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1081 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1114 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
| 1082 | 1115 | ||
| 1083 | /* XXX some macs have duallink chips */ | 1116 | /* XXX some macs have duallink chips */ |
| @@ -1153,23 +1186,23 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder | |||
| 1153 | gpio = RBIOS8(offset + 4 + 3); | 1186 | gpio = RBIOS8(offset + 4 + 3); |
| 1154 | switch (gpio) { | 1187 | switch (gpio) { |
| 1155 | case DDC_MONID: | 1188 | case DDC_MONID: |
| 1156 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1189 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1157 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1190 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
| 1158 | break; | 1191 | break; |
| 1159 | case DDC_DVI: | 1192 | case DDC_DVI: |
| 1160 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1193 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1161 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1194 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
| 1162 | break; | 1195 | break; |
| 1163 | case DDC_VGA: | 1196 | case DDC_VGA: |
| 1164 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1197 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1165 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1198 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
| 1166 | break; | 1199 | break; |
| 1167 | case DDC_CRT2: | 1200 | case DDC_CRT2: |
| 1168 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | 1201 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ |
| 1169 | if (rdev->family >= CHIP_R300) | 1202 | if (rdev->family >= CHIP_R300) |
| 1170 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1203 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1171 | else | 1204 | else |
| 1172 | i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1205 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
| 1173 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | 1206 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); |
| 1174 | break; | 1207 | break; |
| 1175 | case DDC_LCD: /* MM i2c */ | 1208 | case DDC_LCD: /* MM i2c */ |
| @@ -1194,6 +1227,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1194 | { | 1227 | { |
| 1195 | struct radeon_device *rdev = dev->dev_private; | 1228 | struct radeon_device *rdev = dev->dev_private; |
| 1196 | struct radeon_i2c_bus_rec ddc_i2c; | 1229 | struct radeon_i2c_bus_rec ddc_i2c; |
| 1230 | struct radeon_hpd hpd; | ||
| 1197 | 1231 | ||
| 1198 | rdev->mode_info.connector_table = radeon_connector_table; | 1232 | rdev->mode_info.connector_table = radeon_connector_table; |
| 1199 | if (rdev->mode_info.connector_table == CT_NONE) { | 1233 | if (rdev->mode_info.connector_table == CT_NONE) { |
| @@ -1254,7 +1288,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1254 | /* these are the most common settings */ | 1288 | /* these are the most common settings */ |
| 1255 | if (rdev->flags & RADEON_SINGLE_CRTC) { | 1289 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
| 1256 | /* VGA - primary dac */ | 1290 | /* VGA - primary dac */ |
| 1257 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1291 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1292 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1258 | radeon_add_legacy_encoder(dev, | 1293 | radeon_add_legacy_encoder(dev, |
| 1259 | radeon_get_encoder_id(dev, | 1294 | radeon_get_encoder_id(dev, |
| 1260 | ATOM_DEVICE_CRT1_SUPPORT, | 1295 | ATOM_DEVICE_CRT1_SUPPORT, |
| @@ -1264,10 +1299,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1264 | ATOM_DEVICE_CRT1_SUPPORT, | 1299 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1265 | DRM_MODE_CONNECTOR_VGA, | 1300 | DRM_MODE_CONNECTOR_VGA, |
| 1266 | &ddc_i2c, | 1301 | &ddc_i2c, |
| 1267 | CONNECTOR_OBJECT_ID_VGA); | 1302 | CONNECTOR_OBJECT_ID_VGA, |
| 1303 | &hpd); | ||
| 1268 | } else if (rdev->flags & RADEON_IS_MOBILITY) { | 1304 | } else if (rdev->flags & RADEON_IS_MOBILITY) { |
| 1269 | /* LVDS */ | 1305 | /* LVDS */ |
| 1270 | ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); | 1306 | ddc_i2c = combios_setup_i2c_bus(rdev, 0); |
| 1307 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1271 | radeon_add_legacy_encoder(dev, | 1308 | radeon_add_legacy_encoder(dev, |
| 1272 | radeon_get_encoder_id(dev, | 1309 | radeon_get_encoder_id(dev, |
| 1273 | ATOM_DEVICE_LCD1_SUPPORT, | 1310 | ATOM_DEVICE_LCD1_SUPPORT, |
| @@ -1277,10 +1314,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1277 | ATOM_DEVICE_LCD1_SUPPORT, | 1314 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1278 | DRM_MODE_CONNECTOR_LVDS, | 1315 | DRM_MODE_CONNECTOR_LVDS, |
| 1279 | &ddc_i2c, | 1316 | &ddc_i2c, |
| 1280 | CONNECTOR_OBJECT_ID_LVDS); | 1317 | CONNECTOR_OBJECT_ID_LVDS, |
| 1318 | &hpd); | ||
| 1281 | 1319 | ||
| 1282 | /* VGA - primary dac */ | 1320 | /* VGA - primary dac */ |
| 1283 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1321 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1322 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1284 | radeon_add_legacy_encoder(dev, | 1323 | radeon_add_legacy_encoder(dev, |
| 1285 | radeon_get_encoder_id(dev, | 1324 | radeon_get_encoder_id(dev, |
| 1286 | ATOM_DEVICE_CRT1_SUPPORT, | 1325 | ATOM_DEVICE_CRT1_SUPPORT, |
| @@ -1290,10 +1329,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1290 | ATOM_DEVICE_CRT1_SUPPORT, | 1329 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1291 | DRM_MODE_CONNECTOR_VGA, | 1330 | DRM_MODE_CONNECTOR_VGA, |
| 1292 | &ddc_i2c, | 1331 | &ddc_i2c, |
| 1293 | CONNECTOR_OBJECT_ID_VGA); | 1332 | CONNECTOR_OBJECT_ID_VGA, |
| 1333 | &hpd); | ||
| 1294 | } else { | 1334 | } else { |
| 1295 | /* DVI-I - tv dac, int tmds */ | 1335 | /* DVI-I - tv dac, int tmds */ |
| 1296 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1336 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1337 | hpd.hpd = RADEON_HPD_1; | ||
| 1297 | radeon_add_legacy_encoder(dev, | 1338 | radeon_add_legacy_encoder(dev, |
| 1298 | radeon_get_encoder_id(dev, | 1339 | radeon_get_encoder_id(dev, |
| 1299 | ATOM_DEVICE_DFP1_SUPPORT, | 1340 | ATOM_DEVICE_DFP1_SUPPORT, |
| @@ -1309,10 +1350,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1309 | ATOM_DEVICE_CRT2_SUPPORT, | 1350 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1310 | DRM_MODE_CONNECTOR_DVII, | 1351 | DRM_MODE_CONNECTOR_DVII, |
| 1311 | &ddc_i2c, | 1352 | &ddc_i2c, |
| 1312 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1353 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
| 1354 | &hpd); | ||
| 1313 | 1355 | ||
| 1314 | /* VGA - primary dac */ | 1356 | /* VGA - primary dac */ |
| 1315 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1357 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1358 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1316 | radeon_add_legacy_encoder(dev, | 1359 | radeon_add_legacy_encoder(dev, |
| 1317 | radeon_get_encoder_id(dev, | 1360 | radeon_get_encoder_id(dev, |
| 1318 | ATOM_DEVICE_CRT1_SUPPORT, | 1361 | ATOM_DEVICE_CRT1_SUPPORT, |
| @@ -1322,11 +1365,14 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1322 | ATOM_DEVICE_CRT1_SUPPORT, | 1365 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1323 | DRM_MODE_CONNECTOR_VGA, | 1366 | DRM_MODE_CONNECTOR_VGA, |
| 1324 | &ddc_i2c, | 1367 | &ddc_i2c, |
| 1325 | CONNECTOR_OBJECT_ID_VGA); | 1368 | CONNECTOR_OBJECT_ID_VGA, |
| 1369 | &hpd); | ||
| 1326 | } | 1370 | } |
| 1327 | 1371 | ||
| 1328 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { | 1372 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { |
| 1329 | /* TV - tv dac */ | 1373 | /* TV - tv dac */ |
| 1374 | ddc_i2c.valid = false; | ||
| 1375 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1330 | radeon_add_legacy_encoder(dev, | 1376 | radeon_add_legacy_encoder(dev, |
| 1331 | radeon_get_encoder_id(dev, | 1377 | radeon_get_encoder_id(dev, |
| 1332 | ATOM_DEVICE_TV1_SUPPORT, | 1378 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1336,14 +1382,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1336 | ATOM_DEVICE_TV1_SUPPORT, | 1382 | ATOM_DEVICE_TV1_SUPPORT, |
| 1337 | DRM_MODE_CONNECTOR_SVIDEO, | 1383 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1338 | &ddc_i2c, | 1384 | &ddc_i2c, |
| 1339 | CONNECTOR_OBJECT_ID_SVIDEO); | 1385 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1386 | &hpd); | ||
| 1340 | } | 1387 | } |
| 1341 | break; | 1388 | break; |
| 1342 | case CT_IBOOK: | 1389 | case CT_IBOOK: |
| 1343 | DRM_INFO("Connector Table: %d (ibook)\n", | 1390 | DRM_INFO("Connector Table: %d (ibook)\n", |
| 1344 | rdev->mode_info.connector_table); | 1391 | rdev->mode_info.connector_table); |
| 1345 | /* LVDS */ | 1392 | /* LVDS */ |
| 1346 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1393 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1394 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1347 | radeon_add_legacy_encoder(dev, | 1395 | radeon_add_legacy_encoder(dev, |
| 1348 | radeon_get_encoder_id(dev, | 1396 | radeon_get_encoder_id(dev, |
| 1349 | ATOM_DEVICE_LCD1_SUPPORT, | 1397 | ATOM_DEVICE_LCD1_SUPPORT, |
| @@ -1351,9 +1399,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1351 | ATOM_DEVICE_LCD1_SUPPORT); | 1399 | ATOM_DEVICE_LCD1_SUPPORT); |
| 1352 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1400 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
| 1353 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1401 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
| 1354 | CONNECTOR_OBJECT_ID_LVDS); | 1402 | CONNECTOR_OBJECT_ID_LVDS, |
| 1403 | &hpd); | ||
| 1355 | /* VGA - TV DAC */ | 1404 | /* VGA - TV DAC */ |
| 1356 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1405 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1406 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1357 | radeon_add_legacy_encoder(dev, | 1407 | radeon_add_legacy_encoder(dev, |
| 1358 | radeon_get_encoder_id(dev, | 1408 | radeon_get_encoder_id(dev, |
| 1359 | ATOM_DEVICE_CRT2_SUPPORT, | 1409 | ATOM_DEVICE_CRT2_SUPPORT, |
| @@ -1361,8 +1411,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1361 | ATOM_DEVICE_CRT2_SUPPORT); | 1411 | ATOM_DEVICE_CRT2_SUPPORT); |
| 1362 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1412 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
| 1363 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1413 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
| 1364 | CONNECTOR_OBJECT_ID_VGA); | 1414 | CONNECTOR_OBJECT_ID_VGA, |
| 1415 | &hpd); | ||
| 1365 | /* TV - TV DAC */ | 1416 | /* TV - TV DAC */ |
| 1417 | ddc_i2c.valid = false; | ||
| 1418 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1366 | radeon_add_legacy_encoder(dev, | 1419 | radeon_add_legacy_encoder(dev, |
| 1367 | radeon_get_encoder_id(dev, | 1420 | radeon_get_encoder_id(dev, |
| 1368 | ATOM_DEVICE_TV1_SUPPORT, | 1421 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1371,13 +1424,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1371 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1424 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1372 | DRM_MODE_CONNECTOR_SVIDEO, | 1425 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1373 | &ddc_i2c, | 1426 | &ddc_i2c, |
| 1374 | CONNECTOR_OBJECT_ID_SVIDEO); | 1427 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1428 | &hpd); | ||
| 1375 | break; | 1429 | break; |
| 1376 | case CT_POWERBOOK_EXTERNAL: | 1430 | case CT_POWERBOOK_EXTERNAL: |
| 1377 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", | 1431 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", |
| 1378 | rdev->mode_info.connector_table); | 1432 | rdev->mode_info.connector_table); |
| 1379 | /* LVDS */ | 1433 | /* LVDS */ |
| 1380 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1434 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1435 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1381 | radeon_add_legacy_encoder(dev, | 1436 | radeon_add_legacy_encoder(dev, |
| 1382 | radeon_get_encoder_id(dev, | 1437 | radeon_get_encoder_id(dev, |
| 1383 | ATOM_DEVICE_LCD1_SUPPORT, | 1438 | ATOM_DEVICE_LCD1_SUPPORT, |
| @@ -1385,9 +1440,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1385 | ATOM_DEVICE_LCD1_SUPPORT); | 1440 | ATOM_DEVICE_LCD1_SUPPORT); |
| 1386 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1441 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
| 1387 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1442 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
| 1388 | CONNECTOR_OBJECT_ID_LVDS); | 1443 | CONNECTOR_OBJECT_ID_LVDS, |
| 1444 | &hpd); | ||
| 1389 | /* DVI-I - primary dac, ext tmds */ | 1445 | /* DVI-I - primary dac, ext tmds */ |
| 1390 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1446 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1447 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
| 1391 | radeon_add_legacy_encoder(dev, | 1448 | radeon_add_legacy_encoder(dev, |
| 1392 | radeon_get_encoder_id(dev, | 1449 | radeon_get_encoder_id(dev, |
| 1393 | ATOM_DEVICE_DFP2_SUPPORT, | 1450 | ATOM_DEVICE_DFP2_SUPPORT, |
| @@ -1403,8 +1460,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1403 | ATOM_DEVICE_DFP2_SUPPORT | | 1460 | ATOM_DEVICE_DFP2_SUPPORT | |
| 1404 | ATOM_DEVICE_CRT1_SUPPORT, | 1461 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1405 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1462 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
| 1406 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I); | 1463 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, |
| 1464 | &hpd); | ||
| 1407 | /* TV - TV DAC */ | 1465 | /* TV - TV DAC */ |
| 1466 | ddc_i2c.valid = false; | ||
| 1467 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1408 | radeon_add_legacy_encoder(dev, | 1468 | radeon_add_legacy_encoder(dev, |
| 1409 | radeon_get_encoder_id(dev, | 1469 | radeon_get_encoder_id(dev, |
| 1410 | ATOM_DEVICE_TV1_SUPPORT, | 1470 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1413,13 +1473,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1413 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1473 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1414 | DRM_MODE_CONNECTOR_SVIDEO, | 1474 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1415 | &ddc_i2c, | 1475 | &ddc_i2c, |
| 1416 | CONNECTOR_OBJECT_ID_SVIDEO); | 1476 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1477 | &hpd); | ||
| 1417 | break; | 1478 | break; |
| 1418 | case CT_POWERBOOK_INTERNAL: | 1479 | case CT_POWERBOOK_INTERNAL: |
| 1419 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", | 1480 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", |
| 1420 | rdev->mode_info.connector_table); | 1481 | rdev->mode_info.connector_table); |
| 1421 | /* LVDS */ | 1482 | /* LVDS */ |
| 1422 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1483 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1484 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1423 | radeon_add_legacy_encoder(dev, | 1485 | radeon_add_legacy_encoder(dev, |
| 1424 | radeon_get_encoder_id(dev, | 1486 | radeon_get_encoder_id(dev, |
| 1425 | ATOM_DEVICE_LCD1_SUPPORT, | 1487 | ATOM_DEVICE_LCD1_SUPPORT, |
| @@ -1427,9 +1489,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1427 | ATOM_DEVICE_LCD1_SUPPORT); | 1489 | ATOM_DEVICE_LCD1_SUPPORT); |
| 1428 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1490 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
| 1429 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1491 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
| 1430 | CONNECTOR_OBJECT_ID_LVDS); | 1492 | CONNECTOR_OBJECT_ID_LVDS, |
| 1493 | &hpd); | ||
| 1431 | /* DVI-I - primary dac, int tmds */ | 1494 | /* DVI-I - primary dac, int tmds */ |
| 1432 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1495 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1496 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
| 1433 | radeon_add_legacy_encoder(dev, | 1497 | radeon_add_legacy_encoder(dev, |
| 1434 | radeon_get_encoder_id(dev, | 1498 | radeon_get_encoder_id(dev, |
| 1435 | ATOM_DEVICE_DFP1_SUPPORT, | 1499 | ATOM_DEVICE_DFP1_SUPPORT, |
| @@ -1444,8 +1508,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1444 | ATOM_DEVICE_DFP1_SUPPORT | | 1508 | ATOM_DEVICE_DFP1_SUPPORT | |
| 1445 | ATOM_DEVICE_CRT1_SUPPORT, | 1509 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1446 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1510 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
| 1447 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1511 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
| 1512 | &hpd); | ||
| 1448 | /* TV - TV DAC */ | 1513 | /* TV - TV DAC */ |
| 1514 | ddc_i2c.valid = false; | ||
| 1515 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1449 | radeon_add_legacy_encoder(dev, | 1516 | radeon_add_legacy_encoder(dev, |
| 1450 | radeon_get_encoder_id(dev, | 1517 | radeon_get_encoder_id(dev, |
| 1451 | ATOM_DEVICE_TV1_SUPPORT, | 1518 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1454,13 +1521,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1454 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1521 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1455 | DRM_MODE_CONNECTOR_SVIDEO, | 1522 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1456 | &ddc_i2c, | 1523 | &ddc_i2c, |
| 1457 | CONNECTOR_OBJECT_ID_SVIDEO); | 1524 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1525 | &hpd); | ||
| 1458 | break; | 1526 | break; |
| 1459 | case CT_POWERBOOK_VGA: | 1527 | case CT_POWERBOOK_VGA: |
| 1460 | DRM_INFO("Connector Table: %d (powerbook vga)\n", | 1528 | DRM_INFO("Connector Table: %d (powerbook vga)\n", |
| 1461 | rdev->mode_info.connector_table); | 1529 | rdev->mode_info.connector_table); |
| 1462 | /* LVDS */ | 1530 | /* LVDS */ |
| 1463 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1531 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1532 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1464 | radeon_add_legacy_encoder(dev, | 1533 | radeon_add_legacy_encoder(dev, |
| 1465 | radeon_get_encoder_id(dev, | 1534 | radeon_get_encoder_id(dev, |
| 1466 | ATOM_DEVICE_LCD1_SUPPORT, | 1535 | ATOM_DEVICE_LCD1_SUPPORT, |
| @@ -1468,9 +1537,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1468 | ATOM_DEVICE_LCD1_SUPPORT); | 1537 | ATOM_DEVICE_LCD1_SUPPORT); |
| 1469 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1538 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
| 1470 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, | 1539 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
| 1471 | CONNECTOR_OBJECT_ID_LVDS); | 1540 | CONNECTOR_OBJECT_ID_LVDS, |
| 1541 | &hpd); | ||
| 1472 | /* VGA - primary dac */ | 1542 | /* VGA - primary dac */ |
| 1473 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1543 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1544 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1474 | radeon_add_legacy_encoder(dev, | 1545 | radeon_add_legacy_encoder(dev, |
| 1475 | radeon_get_encoder_id(dev, | 1546 | radeon_get_encoder_id(dev, |
| 1476 | ATOM_DEVICE_CRT1_SUPPORT, | 1547 | ATOM_DEVICE_CRT1_SUPPORT, |
| @@ -1478,8 +1549,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1478 | ATOM_DEVICE_CRT1_SUPPORT); | 1549 | ATOM_DEVICE_CRT1_SUPPORT); |
| 1479 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, | 1550 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, |
| 1480 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1551 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
| 1481 | CONNECTOR_OBJECT_ID_VGA); | 1552 | CONNECTOR_OBJECT_ID_VGA, |
| 1553 | &hpd); | ||
| 1482 | /* TV - TV DAC */ | 1554 | /* TV - TV DAC */ |
| 1555 | ddc_i2c.valid = false; | ||
| 1556 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1483 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
| 1484 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_id(dev, |
| 1485 | ATOM_DEVICE_TV1_SUPPORT, | 1559 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1488,13 +1562,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1488 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1562 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1489 | DRM_MODE_CONNECTOR_SVIDEO, | 1563 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1490 | &ddc_i2c, | 1564 | &ddc_i2c, |
| 1491 | CONNECTOR_OBJECT_ID_SVIDEO); | 1565 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1566 | &hpd); | ||
| 1492 | break; | 1567 | break; |
| 1493 | case CT_MINI_EXTERNAL: | 1568 | case CT_MINI_EXTERNAL: |
| 1494 | DRM_INFO("Connector Table: %d (mini external tmds)\n", | 1569 | DRM_INFO("Connector Table: %d (mini external tmds)\n", |
| 1495 | rdev->mode_info.connector_table); | 1570 | rdev->mode_info.connector_table); |
| 1496 | /* DVI-I - tv dac, ext tmds */ | 1571 | /* DVI-I - tv dac, ext tmds */ |
| 1497 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1572 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
| 1573 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
| 1498 | radeon_add_legacy_encoder(dev, | 1574 | radeon_add_legacy_encoder(dev, |
| 1499 | radeon_get_encoder_id(dev, | 1575 | radeon_get_encoder_id(dev, |
| 1500 | ATOM_DEVICE_DFP2_SUPPORT, | 1576 | ATOM_DEVICE_DFP2_SUPPORT, |
| @@ -1510,8 +1586,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1510 | ATOM_DEVICE_DFP2_SUPPORT | | 1586 | ATOM_DEVICE_DFP2_SUPPORT | |
| 1511 | ATOM_DEVICE_CRT2_SUPPORT, | 1587 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1512 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1588 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
| 1513 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1589 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
| 1590 | &hpd); | ||
| 1514 | /* TV - TV DAC */ | 1591 | /* TV - TV DAC */ |
| 1592 | ddc_i2c.valid = false; | ||
| 1593 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1515 | radeon_add_legacy_encoder(dev, | 1594 | radeon_add_legacy_encoder(dev, |
| 1516 | radeon_get_encoder_id(dev, | 1595 | radeon_get_encoder_id(dev, |
| 1517 | ATOM_DEVICE_TV1_SUPPORT, | 1596 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1520,13 +1599,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1520 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1599 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
| 1521 | DRM_MODE_CONNECTOR_SVIDEO, | 1600 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1522 | &ddc_i2c, | 1601 | &ddc_i2c, |
| 1523 | CONNECTOR_OBJECT_ID_SVIDEO); | 1602 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1603 | &hpd); | ||
| 1524 | break; | 1604 | break; |
| 1525 | case CT_MINI_INTERNAL: | 1605 | case CT_MINI_INTERNAL: |
| 1526 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", | 1606 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", |
| 1527 | rdev->mode_info.connector_table); | 1607 | rdev->mode_info.connector_table); |
| 1528 | /* DVI-I - tv dac, int tmds */ | 1608 | /* DVI-I - tv dac, int tmds */ |
| 1529 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1609 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
| 1610 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
| 1530 | radeon_add_legacy_encoder(dev, | 1611 | radeon_add_legacy_encoder(dev, |
| 1531 | radeon_get_encoder_id(dev, | 1612 | radeon_get_encoder_id(dev, |
| 1532 | ATOM_DEVICE_DFP1_SUPPORT, | 1613 | ATOM_DEVICE_DFP1_SUPPORT, |
| @@ -1541,8 +1622,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1541 | ATOM_DEVICE_DFP1_SUPPORT | | 1622 | ATOM_DEVICE_DFP1_SUPPORT | |
| 1542 | ATOM_DEVICE_CRT2_SUPPORT, | 1623 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1543 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | 1624 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
| 1544 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 1625 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
| 1626 | &hpd); | ||
| 1545 | /* TV - TV DAC */ | 1627 | /* TV - TV DAC */ |
| 1628 | ddc_i2c.valid = false; | ||
| 1629 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1546 | radeon_add_legacy_encoder(dev, | 1630 | radeon_add_legacy_encoder(dev, |
| 1547 | radeon_get_encoder_id(dev, | 1631 | radeon_get_encoder_id(dev, |
| 1548 | ATOM_DEVICE_TV1_SUPPORT, | 1632 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1551,13 +1635,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1551 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1635 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
| 1552 | DRM_MODE_CONNECTOR_SVIDEO, | 1636 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1553 | &ddc_i2c, | 1637 | &ddc_i2c, |
| 1554 | CONNECTOR_OBJECT_ID_SVIDEO); | 1638 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1639 | &hpd); | ||
| 1555 | break; | 1640 | break; |
| 1556 | case CT_IMAC_G5_ISIGHT: | 1641 | case CT_IMAC_G5_ISIGHT: |
| 1557 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", | 1642 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", |
| 1558 | rdev->mode_info.connector_table); | 1643 | rdev->mode_info.connector_table); |
| 1559 | /* DVI-D - int tmds */ | 1644 | /* DVI-D - int tmds */ |
| 1560 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1645 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1646 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
| 1561 | radeon_add_legacy_encoder(dev, | 1647 | radeon_add_legacy_encoder(dev, |
| 1562 | radeon_get_encoder_id(dev, | 1648 | radeon_get_encoder_id(dev, |
| 1563 | ATOM_DEVICE_DFP1_SUPPORT, | 1649 | ATOM_DEVICE_DFP1_SUPPORT, |
| @@ -1565,9 +1651,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1565 | ATOM_DEVICE_DFP1_SUPPORT); | 1651 | ATOM_DEVICE_DFP1_SUPPORT); |
| 1566 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, | 1652 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, |
| 1567 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c, | 1653 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c, |
| 1568 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); | 1654 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, |
| 1655 | &hpd); | ||
| 1569 | /* VGA - tv dac */ | 1656 | /* VGA - tv dac */ |
| 1570 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1657 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1658 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1571 | radeon_add_legacy_encoder(dev, | 1659 | radeon_add_legacy_encoder(dev, |
| 1572 | radeon_get_encoder_id(dev, | 1660 | radeon_get_encoder_id(dev, |
| 1573 | ATOM_DEVICE_CRT2_SUPPORT, | 1661 | ATOM_DEVICE_CRT2_SUPPORT, |
| @@ -1575,8 +1663,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1575 | ATOM_DEVICE_CRT2_SUPPORT); | 1663 | ATOM_DEVICE_CRT2_SUPPORT); |
| 1576 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1664 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
| 1577 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1665 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
| 1578 | CONNECTOR_OBJECT_ID_VGA); | 1666 | CONNECTOR_OBJECT_ID_VGA, |
| 1667 | &hpd); | ||
| 1579 | /* TV - TV DAC */ | 1668 | /* TV - TV DAC */ |
| 1669 | ddc_i2c.valid = false; | ||
| 1670 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1580 | radeon_add_legacy_encoder(dev, | 1671 | radeon_add_legacy_encoder(dev, |
| 1581 | radeon_get_encoder_id(dev, | 1672 | radeon_get_encoder_id(dev, |
| 1582 | ATOM_DEVICE_TV1_SUPPORT, | 1673 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1585,13 +1676,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1585 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1676 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1586 | DRM_MODE_CONNECTOR_SVIDEO, | 1677 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1587 | &ddc_i2c, | 1678 | &ddc_i2c, |
| 1588 | CONNECTOR_OBJECT_ID_SVIDEO); | 1679 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1680 | &hpd); | ||
| 1589 | break; | 1681 | break; |
| 1590 | case CT_EMAC: | 1682 | case CT_EMAC: |
| 1591 | DRM_INFO("Connector Table: %d (emac)\n", | 1683 | DRM_INFO("Connector Table: %d (emac)\n", |
| 1592 | rdev->mode_info.connector_table); | 1684 | rdev->mode_info.connector_table); |
| 1593 | /* VGA - primary dac */ | 1685 | /* VGA - primary dac */ |
| 1594 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1686 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1687 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1595 | radeon_add_legacy_encoder(dev, | 1688 | radeon_add_legacy_encoder(dev, |
| 1596 | radeon_get_encoder_id(dev, | 1689 | radeon_get_encoder_id(dev, |
| 1597 | ATOM_DEVICE_CRT1_SUPPORT, | 1690 | ATOM_DEVICE_CRT1_SUPPORT, |
| @@ -1599,9 +1692,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1599 | ATOM_DEVICE_CRT1_SUPPORT); | 1692 | ATOM_DEVICE_CRT1_SUPPORT); |
| 1600 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, | 1693 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, |
| 1601 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1694 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
| 1602 | CONNECTOR_OBJECT_ID_VGA); | 1695 | CONNECTOR_OBJECT_ID_VGA, |
| 1696 | &hpd); | ||
| 1603 | /* VGA - tv dac */ | 1697 | /* VGA - tv dac */ |
| 1604 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1698 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
| 1699 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1605 | radeon_add_legacy_encoder(dev, | 1700 | radeon_add_legacy_encoder(dev, |
| 1606 | radeon_get_encoder_id(dev, | 1701 | radeon_get_encoder_id(dev, |
| 1607 | ATOM_DEVICE_CRT2_SUPPORT, | 1702 | ATOM_DEVICE_CRT2_SUPPORT, |
| @@ -1609,8 +1704,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1609 | ATOM_DEVICE_CRT2_SUPPORT); | 1704 | ATOM_DEVICE_CRT2_SUPPORT); |
| 1610 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1705 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
| 1611 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | 1706 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
| 1612 | CONNECTOR_OBJECT_ID_VGA); | 1707 | CONNECTOR_OBJECT_ID_VGA, |
| 1708 | &hpd); | ||
| 1613 | /* TV - TV DAC */ | 1709 | /* TV - TV DAC */ |
| 1710 | ddc_i2c.valid = false; | ||
| 1711 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1614 | radeon_add_legacy_encoder(dev, | 1712 | radeon_add_legacy_encoder(dev, |
| 1615 | radeon_get_encoder_id(dev, | 1713 | radeon_get_encoder_id(dev, |
| 1616 | ATOM_DEVICE_TV1_SUPPORT, | 1714 | ATOM_DEVICE_TV1_SUPPORT, |
| @@ -1619,7 +1717,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1619 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1717 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
| 1620 | DRM_MODE_CONNECTOR_SVIDEO, | 1718 | DRM_MODE_CONNECTOR_SVIDEO, |
| 1621 | &ddc_i2c, | 1719 | &ddc_i2c, |
| 1622 | CONNECTOR_OBJECT_ID_SVIDEO); | 1720 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 1721 | &hpd); | ||
| 1623 | break; | 1722 | break; |
| 1624 | default: | 1723 | default: |
| 1625 | DRM_INFO("Connector table: %d (invalid)\n", | 1724 | DRM_INFO("Connector table: %d (invalid)\n", |
| @@ -1636,7 +1735,8 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
| 1636 | int bios_index, | 1735 | int bios_index, |
| 1637 | enum radeon_combios_connector | 1736 | enum radeon_combios_connector |
| 1638 | *legacy_connector, | 1737 | *legacy_connector, |
| 1639 | struct radeon_i2c_bus_rec *ddc_i2c) | 1738 | struct radeon_i2c_bus_rec *ddc_i2c, |
| 1739 | struct radeon_hpd *hpd) | ||
| 1640 | { | 1740 | { |
| 1641 | struct radeon_device *rdev = dev->dev_private; | 1741 | struct radeon_device *rdev = dev->dev_private; |
| 1642 | 1742 | ||
| @@ -1644,11 +1744,11 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
| 1644 | if ((rdev->family == CHIP_RS400 || | 1744 | if ((rdev->family == CHIP_RS400 || |
| 1645 | rdev->family == CHIP_RS480) && | 1745 | rdev->family == CHIP_RS480) && |
| 1646 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | 1746 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) |
| 1647 | *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1747 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1648 | else if ((rdev->family == CHIP_RS400 || | 1748 | else if ((rdev->family == CHIP_RS400 || |
| 1649 | rdev->family == CHIP_RS480) && | 1749 | rdev->family == CHIP_RS480) && |
| 1650 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { | 1750 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { |
| 1651 | ddc_i2c->valid = true; | 1751 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK); |
| 1652 | ddc_i2c->mask_clk_mask = (0x20 << 8); | 1752 | ddc_i2c->mask_clk_mask = (0x20 << 8); |
| 1653 | ddc_i2c->mask_data_mask = 0x80; | 1753 | ddc_i2c->mask_data_mask = 0x80; |
| 1654 | ddc_i2c->a_clk_mask = (0x20 << 8); | 1754 | ddc_i2c->a_clk_mask = (0x20 << 8); |
| @@ -1657,20 +1757,12 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
| 1657 | ddc_i2c->en_data_mask = 0x80; | 1757 | ddc_i2c->en_data_mask = 0x80; |
| 1658 | ddc_i2c->y_clk_mask = (0x20 << 8); | 1758 | ddc_i2c->y_clk_mask = (0x20 << 8); |
| 1659 | ddc_i2c->y_data_mask = 0x80; | 1759 | ddc_i2c->y_data_mask = 0x80; |
| 1660 | ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK; | ||
| 1661 | ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK; | ||
| 1662 | ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A; | ||
| 1663 | ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; | ||
| 1664 | ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN; | ||
| 1665 | ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN; | ||
| 1666 | ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y; | ||
| 1667 | ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y; | ||
| 1668 | } | 1760 | } |
| 1669 | 1761 | ||
| 1670 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | 1762 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ |
| 1671 | if ((rdev->family >= CHIP_R300) && | 1763 | if ((rdev->family >= CHIP_R300) && |
| 1672 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | 1764 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) |
| 1673 | *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1765 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1674 | 1766 | ||
| 1675 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, | 1767 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, |
| 1676 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ | 1768 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ |
| @@ -1768,6 +1860,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1768 | enum radeon_combios_connector connector; | 1860 | enum radeon_combios_connector connector; |
| 1769 | int i = 0; | 1861 | int i = 0; |
| 1770 | struct radeon_i2c_bus_rec ddc_i2c; | 1862 | struct radeon_i2c_bus_rec ddc_i2c; |
| 1863 | struct radeon_hpd hpd; | ||
| 1771 | 1864 | ||
| 1772 | if (rdev->bios == NULL) | 1865 | if (rdev->bios == NULL) |
| 1773 | return false; | 1866 | return false; |
| @@ -1788,26 +1881,40 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1788 | switch (ddc_type) { | 1881 | switch (ddc_type) { |
| 1789 | case DDC_MONID: | 1882 | case DDC_MONID: |
| 1790 | ddc_i2c = | 1883 | ddc_i2c = |
| 1791 | combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1884 | combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
| 1792 | break; | 1885 | break; |
| 1793 | case DDC_DVI: | 1886 | case DDC_DVI: |
| 1794 | ddc_i2c = | 1887 | ddc_i2c = |
| 1795 | combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1888 | combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 1796 | break; | 1889 | break; |
| 1797 | case DDC_VGA: | 1890 | case DDC_VGA: |
| 1798 | ddc_i2c = | 1891 | ddc_i2c = |
| 1799 | combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1892 | combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 1800 | break; | 1893 | break; |
| 1801 | case DDC_CRT2: | 1894 | case DDC_CRT2: |
| 1802 | ddc_i2c = | 1895 | ddc_i2c = |
| 1803 | combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1896 | combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
| 1897 | break; | ||
| 1898 | default: | ||
| 1899 | break; | ||
| 1900 | } | ||
| 1901 | |||
| 1902 | switch (connector) { | ||
| 1903 | case CONNECTOR_PROPRIETARY_LEGACY: | ||
| 1904 | case CONNECTOR_DVI_I_LEGACY: | ||
| 1905 | case CONNECTOR_DVI_D_LEGACY: | ||
| 1906 | if ((tmp >> 4) & 0x1) | ||
| 1907 | hpd.hpd = RADEON_HPD_2; | ||
| 1908 | else | ||
| 1909 | hpd.hpd = RADEON_HPD_1; | ||
| 1804 | break; | 1910 | break; |
| 1805 | default: | 1911 | default: |
| 1912 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1806 | break; | 1913 | break; |
| 1807 | } | 1914 | } |
| 1808 | 1915 | ||
| 1809 | if (!radeon_apply_legacy_quirks(dev, i, &connector, | 1916 | if (!radeon_apply_legacy_quirks(dev, i, &connector, |
| 1810 | &ddc_i2c)) | 1917 | &ddc_i2c, &hpd)) |
| 1811 | continue; | 1918 | continue; |
| 1812 | 1919 | ||
| 1813 | switch (connector) { | 1920 | switch (connector) { |
| @@ -1824,7 +1931,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1824 | legacy_connector_convert | 1931 | legacy_connector_convert |
| 1825 | [connector], | 1932 | [connector], |
| 1826 | &ddc_i2c, | 1933 | &ddc_i2c, |
| 1827 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); | 1934 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, |
| 1935 | &hpd); | ||
| 1828 | break; | 1936 | break; |
| 1829 | case CONNECTOR_CRT_LEGACY: | 1937 | case CONNECTOR_CRT_LEGACY: |
| 1830 | if (tmp & 0x1) { | 1938 | if (tmp & 0x1) { |
| @@ -1850,7 +1958,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1850 | legacy_connector_convert | 1958 | legacy_connector_convert |
| 1851 | [connector], | 1959 | [connector], |
| 1852 | &ddc_i2c, | 1960 | &ddc_i2c, |
| 1853 | CONNECTOR_OBJECT_ID_VGA); | 1961 | CONNECTOR_OBJECT_ID_VGA, |
| 1962 | &hpd); | ||
| 1854 | break; | 1963 | break; |
| 1855 | case CONNECTOR_DVI_I_LEGACY: | 1964 | case CONNECTOR_DVI_I_LEGACY: |
| 1856 | devices = 0; | 1965 | devices = 0; |
| @@ -1896,7 +2005,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1896 | legacy_connector_convert | 2005 | legacy_connector_convert |
| 1897 | [connector], | 2006 | [connector], |
| 1898 | &ddc_i2c, | 2007 | &ddc_i2c, |
| 1899 | connector_object_id); | 2008 | connector_object_id, |
| 2009 | &hpd); | ||
| 1900 | break; | 2010 | break; |
| 1901 | case CONNECTOR_DVI_D_LEGACY: | 2011 | case CONNECTOR_DVI_D_LEGACY: |
| 1902 | if ((tmp >> 4) & 0x1) { | 2012 | if ((tmp >> 4) & 0x1) { |
| @@ -1914,7 +2024,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1914 | legacy_connector_convert | 2024 | legacy_connector_convert |
| 1915 | [connector], | 2025 | [connector], |
| 1916 | &ddc_i2c, | 2026 | &ddc_i2c, |
| 1917 | connector_object_id); | 2027 | connector_object_id, |
| 2028 | &hpd); | ||
| 1918 | break; | 2029 | break; |
| 1919 | case CONNECTOR_CTV_LEGACY: | 2030 | case CONNECTOR_CTV_LEGACY: |
| 1920 | case CONNECTOR_STV_LEGACY: | 2031 | case CONNECTOR_STV_LEGACY: |
| @@ -1929,7 +2040,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1929 | legacy_connector_convert | 2040 | legacy_connector_convert |
| 1930 | [connector], | 2041 | [connector], |
| 1931 | &ddc_i2c, | 2042 | &ddc_i2c, |
| 1932 | CONNECTOR_OBJECT_ID_SVIDEO); | 2043 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 2044 | &hpd); | ||
| 1933 | break; | 2045 | break; |
| 1934 | default: | 2046 | default: |
| 1935 | DRM_ERROR("Unknown connector type: %d\n", | 2047 | DRM_ERROR("Unknown connector type: %d\n", |
| @@ -1955,14 +2067,16 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1955 | 0), | 2067 | 0), |
| 1956 | ATOM_DEVICE_DFP1_SUPPORT); | 2068 | ATOM_DEVICE_DFP1_SUPPORT); |
| 1957 | 2069 | ||
| 1958 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 2070 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
| 2071 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1959 | radeon_add_legacy_connector(dev, | 2072 | radeon_add_legacy_connector(dev, |
| 1960 | 0, | 2073 | 0, |
| 1961 | ATOM_DEVICE_CRT1_SUPPORT | | 2074 | ATOM_DEVICE_CRT1_SUPPORT | |
| 1962 | ATOM_DEVICE_DFP1_SUPPORT, | 2075 | ATOM_DEVICE_DFP1_SUPPORT, |
| 1963 | DRM_MODE_CONNECTOR_DVII, | 2076 | DRM_MODE_CONNECTOR_DVII, |
| 1964 | &ddc_i2c, | 2077 | &ddc_i2c, |
| 1965 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); | 2078 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, |
| 2079 | &hpd); | ||
| 1966 | } else { | 2080 | } else { |
| 1967 | uint16_t crt_info = | 2081 | uint16_t crt_info = |
| 1968 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 2082 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
| @@ -1973,13 +2087,15 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 1973 | ATOM_DEVICE_CRT1_SUPPORT, | 2087 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1974 | 1), | 2088 | 1), |
| 1975 | ATOM_DEVICE_CRT1_SUPPORT); | 2089 | ATOM_DEVICE_CRT1_SUPPORT); |
| 1976 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 2090 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
| 2091 | hpd.hpd = RADEON_HPD_NONE; | ||
| 1977 | radeon_add_legacy_connector(dev, | 2092 | radeon_add_legacy_connector(dev, |
| 1978 | 0, | 2093 | 0, |
| 1979 | ATOM_DEVICE_CRT1_SUPPORT, | 2094 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1980 | DRM_MODE_CONNECTOR_VGA, | 2095 | DRM_MODE_CONNECTOR_VGA, |
| 1981 | &ddc_i2c, | 2096 | &ddc_i2c, |
| 1982 | CONNECTOR_OBJECT_ID_VGA); | 2097 | CONNECTOR_OBJECT_ID_VGA, |
| 2098 | &hpd); | ||
| 1983 | } else { | 2099 | } else { |
| 1984 | DRM_DEBUG("No connector info found\n"); | 2100 | DRM_DEBUG("No connector info found\n"); |
| 1985 | return false; | 2101 | return false; |
| @@ -2007,27 +2123,27 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2007 | case DDC_MONID: | 2123 | case DDC_MONID: |
| 2008 | ddc_i2c = | 2124 | ddc_i2c = |
| 2009 | combios_setup_i2c_bus | 2125 | combios_setup_i2c_bus |
| 2010 | (RADEON_GPIO_MONID); | 2126 | (rdev, RADEON_GPIO_MONID); |
| 2011 | break; | 2127 | break; |
| 2012 | case DDC_DVI: | 2128 | case DDC_DVI: |
| 2013 | ddc_i2c = | 2129 | ddc_i2c = |
| 2014 | combios_setup_i2c_bus | 2130 | combios_setup_i2c_bus |
| 2015 | (RADEON_GPIO_DVI_DDC); | 2131 | (rdev, RADEON_GPIO_DVI_DDC); |
| 2016 | break; | 2132 | break; |
| 2017 | case DDC_VGA: | 2133 | case DDC_VGA: |
| 2018 | ddc_i2c = | 2134 | ddc_i2c = |
| 2019 | combios_setup_i2c_bus | 2135 | combios_setup_i2c_bus |
| 2020 | (RADEON_GPIO_VGA_DDC); | 2136 | (rdev, RADEON_GPIO_VGA_DDC); |
| 2021 | break; | 2137 | break; |
| 2022 | case DDC_CRT2: | 2138 | case DDC_CRT2: |
| 2023 | ddc_i2c = | 2139 | ddc_i2c = |
| 2024 | combios_setup_i2c_bus | 2140 | combios_setup_i2c_bus |
| 2025 | (RADEON_GPIO_CRT2_DDC); | 2141 | (rdev, RADEON_GPIO_CRT2_DDC); |
| 2026 | break; | 2142 | break; |
| 2027 | case DDC_LCD: | 2143 | case DDC_LCD: |
| 2028 | ddc_i2c = | 2144 | ddc_i2c = |
| 2029 | combios_setup_i2c_bus | 2145 | combios_setup_i2c_bus |
| 2030 | (RADEON_LCD_GPIO_MASK); | 2146 | (rdev, RADEON_GPIOPAD_MASK); |
| 2031 | ddc_i2c.mask_clk_mask = | 2147 | ddc_i2c.mask_clk_mask = |
| 2032 | RBIOS32(lcd_ddc_info + 3); | 2148 | RBIOS32(lcd_ddc_info + 3); |
| 2033 | ddc_i2c.mask_data_mask = | 2149 | ddc_i2c.mask_data_mask = |
| @@ -2048,7 +2164,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2048 | case DDC_GPIO: | 2164 | case DDC_GPIO: |
| 2049 | ddc_i2c = | 2165 | ddc_i2c = |
| 2050 | combios_setup_i2c_bus | 2166 | combios_setup_i2c_bus |
| 2051 | (RADEON_MDGPIO_EN_REG); | 2167 | (rdev, RADEON_MDGPIO_MASK); |
| 2052 | ddc_i2c.mask_clk_mask = | 2168 | ddc_i2c.mask_clk_mask = |
| 2053 | RBIOS32(lcd_ddc_info + 3); | 2169 | RBIOS32(lcd_ddc_info + 3); |
| 2054 | ddc_i2c.mask_data_mask = | 2170 | ddc_i2c.mask_data_mask = |
| @@ -2074,12 +2190,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2074 | } else | 2190 | } else |
| 2075 | ddc_i2c.valid = false; | 2191 | ddc_i2c.valid = false; |
| 2076 | 2192 | ||
| 2193 | hpd.hpd = RADEON_HPD_NONE; | ||
| 2077 | radeon_add_legacy_connector(dev, | 2194 | radeon_add_legacy_connector(dev, |
| 2078 | 5, | 2195 | 5, |
| 2079 | ATOM_DEVICE_LCD1_SUPPORT, | 2196 | ATOM_DEVICE_LCD1_SUPPORT, |
| 2080 | DRM_MODE_CONNECTOR_LVDS, | 2197 | DRM_MODE_CONNECTOR_LVDS, |
| 2081 | &ddc_i2c, | 2198 | &ddc_i2c, |
| 2082 | CONNECTOR_OBJECT_ID_LVDS); | 2199 | CONNECTOR_OBJECT_ID_LVDS, |
| 2200 | &hpd); | ||
| 2083 | } | 2201 | } |
| 2084 | } | 2202 | } |
| 2085 | 2203 | ||
| @@ -2090,6 +2208,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2090 | if (tv_info) { | 2208 | if (tv_info) { |
| 2091 | if (RBIOS8(tv_info + 6) == 'T') { | 2209 | if (RBIOS8(tv_info + 6) == 'T') { |
| 2092 | if (radeon_apply_legacy_tv_quirks(dev)) { | 2210 | if (radeon_apply_legacy_tv_quirks(dev)) { |
| 2211 | hpd.hpd = RADEON_HPD_NONE; | ||
| 2093 | radeon_add_legacy_encoder(dev, | 2212 | radeon_add_legacy_encoder(dev, |
| 2094 | radeon_get_encoder_id | 2213 | radeon_get_encoder_id |
| 2095 | (dev, | 2214 | (dev, |
| @@ -2100,7 +2219,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2100 | ATOM_DEVICE_TV1_SUPPORT, | 2219 | ATOM_DEVICE_TV1_SUPPORT, |
| 2101 | DRM_MODE_CONNECTOR_SVIDEO, | 2220 | DRM_MODE_CONNECTOR_SVIDEO, |
| 2102 | &ddc_i2c, | 2221 | &ddc_i2c, |
| 2103 | CONNECTOR_OBJECT_ID_SVIDEO); | 2222 | CONNECTOR_OBJECT_ID_SVIDEO, |
| 2223 | &hpd); | ||
| 2104 | } | 2224 | } |
| 2105 | } | 2225 | } |
| 2106 | } | 2226 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 7ab3c501b4dd..cfa2ebb259fe 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -40,6 +40,26 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
| 40 | struct drm_encoder *encoder, | 40 | struct drm_encoder *encoder, |
| 41 | bool connected); | 41 | bool connected); |
| 42 | 42 | ||
| 43 | void radeon_connector_hotplug(struct drm_connector *connector) | ||
| 44 | { | ||
| 45 | struct drm_device *dev = connector->dev; | ||
| 46 | struct radeon_device *rdev = dev->dev_private; | ||
| 47 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 48 | |||
| 49 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
| 50 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
| 51 | |||
| 52 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
| 53 | if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
| 54 | if (radeon_dp_needs_link_train(radeon_connector)) { | ||
| 55 | if (connector->encoder) | ||
| 56 | dp_link_train(connector->encoder, connector); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | } | ||
| 62 | |||
| 43 | static void radeon_property_change_mode(struct drm_encoder *encoder) | 63 | static void radeon_property_change_mode(struct drm_encoder *encoder) |
| 44 | { | 64 | { |
| 45 | struct drm_crtc *crtc = encoder->crtc; | 65 | struct drm_crtc *crtc = encoder->crtc; |
| @@ -896,6 +916,91 @@ struct drm_connector_funcs radeon_dvi_connector_funcs = { | |||
| 896 | .force = radeon_dvi_force, | 916 | .force = radeon_dvi_force, |
| 897 | }; | 917 | }; |
| 898 | 918 | ||
| 919 | static void radeon_dp_connector_destroy(struct drm_connector *connector) | ||
| 920 | { | ||
| 921 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 922 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
| 923 | |||
| 924 | if (radeon_connector->ddc_bus) | ||
| 925 | radeon_i2c_destroy(radeon_connector->ddc_bus); | ||
| 926 | if (radeon_connector->edid) | ||
| 927 | kfree(radeon_connector->edid); | ||
| 928 | if (radeon_dig_connector->dp_i2c_bus) | ||
| 929 | radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); | ||
| 930 | kfree(radeon_connector->con_priv); | ||
| 931 | drm_sysfs_connector_remove(connector); | ||
| 932 | drm_connector_cleanup(connector); | ||
| 933 | kfree(connector); | ||
| 934 | } | ||
| 935 | |||
| 936 | static int radeon_dp_get_modes(struct drm_connector *connector) | ||
| 937 | { | ||
| 938 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 939 | int ret; | ||
| 940 | |||
| 941 | ret = radeon_ddc_get_modes(radeon_connector); | ||
| 942 | return ret; | ||
| 943 | } | ||
| 944 | |||
| 945 | static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) | ||
| 946 | { | ||
| 947 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 948 | enum drm_connector_status ret = connector_status_disconnected; | ||
| 949 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
| 950 | u8 sink_type; | ||
| 951 | |||
| 952 | if (radeon_connector->edid) { | ||
| 953 | kfree(radeon_connector->edid); | ||
| 954 | radeon_connector->edid = NULL; | ||
| 955 | } | ||
| 956 | |||
| 957 | sink_type = radeon_dp_getsinktype(radeon_connector); | ||
| 958 | if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
| 959 | if (radeon_dp_getdpcd(radeon_connector)) { | ||
| 960 | radeon_dig_connector->dp_sink_type = sink_type; | ||
| 961 | ret = connector_status_connected; | ||
| 962 | } | ||
| 963 | } else { | ||
| 964 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
| 965 | if (radeon_ddc_probe(radeon_connector)) { | ||
| 966 | radeon_dig_connector->dp_sink_type = sink_type; | ||
| 967 | ret = connector_status_connected; | ||
| 968 | } | ||
| 969 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
| 970 | } | ||
| 971 | |||
| 972 | return ret; | ||
| 973 | } | ||
| 974 | |||
| 975 | static int radeon_dp_mode_valid(struct drm_connector *connector, | ||
| 976 | struct drm_display_mode *mode) | ||
| 977 | { | ||
| 978 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
| 980 | |||
| 981 | /* XXX check mode bandwidth */ | ||
| 982 | |||
| 983 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | ||
| 984 | return radeon_dp_mode_valid_helper(radeon_connector, mode); | ||
| 985 | else | ||
| 986 | return MODE_OK; | ||
| 987 | } | ||
| 988 | |||
| 989 | struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { | ||
| 990 | .get_modes = radeon_dp_get_modes, | ||
| 991 | .mode_valid = radeon_dp_mode_valid, | ||
| 992 | .best_encoder = radeon_dvi_encoder, | ||
| 993 | }; | ||
| 994 | |||
| 995 | struct drm_connector_funcs radeon_dp_connector_funcs = { | ||
| 996 | .dpms = drm_helper_connector_dpms, | ||
| 997 | .detect = radeon_dp_detect, | ||
| 998 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
| 999 | .set_property = radeon_connector_set_property, | ||
| 1000 | .destroy = radeon_dp_connector_destroy, | ||
| 1001 | .force = radeon_dvi_force, | ||
| 1002 | }; | ||
| 1003 | |||
| 899 | void | 1004 | void |
| 900 | radeon_add_atom_connector(struct drm_device *dev, | 1005 | radeon_add_atom_connector(struct drm_device *dev, |
| 901 | uint32_t connector_id, | 1006 | uint32_t connector_id, |
| @@ -904,7 +1009,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 904 | struct radeon_i2c_bus_rec *i2c_bus, | 1009 | struct radeon_i2c_bus_rec *i2c_bus, |
| 905 | bool linkb, | 1010 | bool linkb, |
| 906 | uint32_t igp_lane_info, | 1011 | uint32_t igp_lane_info, |
| 907 | uint16_t connector_object_id) | 1012 | uint16_t connector_object_id, |
| 1013 | struct radeon_hpd *hpd) | ||
| 908 | { | 1014 | { |
| 909 | struct radeon_device *rdev = dev->dev_private; | 1015 | struct radeon_device *rdev = dev->dev_private; |
| 910 | struct drm_connector *connector; | 1016 | struct drm_connector *connector; |
| @@ -944,6 +1050,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 944 | radeon_connector->devices = supported_device; | 1050 | radeon_connector->devices = supported_device; |
| 945 | radeon_connector->shared_ddc = shared_ddc; | 1051 | radeon_connector->shared_ddc = shared_ddc; |
| 946 | radeon_connector->connector_object_id = connector_object_id; | 1052 | radeon_connector->connector_object_id = connector_object_id; |
| 1053 | radeon_connector->hpd = *hpd; | ||
| 947 | switch (connector_type) { | 1054 | switch (connector_type) { |
| 948 | case DRM_MODE_CONNECTOR_VGA: | 1055 | case DRM_MODE_CONNECTOR_VGA: |
| 949 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1056 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
| @@ -1030,10 +1137,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1030 | radeon_dig_connector->linkb = linkb; | 1137 | radeon_dig_connector->linkb = linkb; |
| 1031 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1138 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 1032 | radeon_connector->con_priv = radeon_dig_connector; | 1139 | radeon_connector->con_priv = radeon_dig_connector; |
| 1033 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1140 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
| 1034 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 1141 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); |
| 1035 | if (ret) | 1142 | if (ret) |
| 1036 | goto failed; | 1143 | goto failed; |
| 1144 | /* add DP i2c bus */ | ||
| 1145 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | ||
| 1037 | if (i2c_bus->valid) { | 1146 | if (i2c_bus->valid) { |
| 1038 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | 1147 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
| 1039 | if (!radeon_connector->ddc_bus) | 1148 | if (!radeon_connector->ddc_bus) |
| @@ -1099,7 +1208,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1099 | uint32_t supported_device, | 1208 | uint32_t supported_device, |
| 1100 | int connector_type, | 1209 | int connector_type, |
| 1101 | struct radeon_i2c_bus_rec *i2c_bus, | 1210 | struct radeon_i2c_bus_rec *i2c_bus, |
| 1102 | uint16_t connector_object_id) | 1211 | uint16_t connector_object_id, |
| 1212 | struct radeon_hpd *hpd) | ||
| 1103 | { | 1213 | { |
| 1104 | struct radeon_device *rdev = dev->dev_private; | 1214 | struct radeon_device *rdev = dev->dev_private; |
| 1105 | struct drm_connector *connector; | 1215 | struct drm_connector *connector; |
| @@ -1129,6 +1239,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1129 | radeon_connector->connector_id = connector_id; | 1239 | radeon_connector->connector_id = connector_id; |
| 1130 | radeon_connector->devices = supported_device; | 1240 | radeon_connector->devices = supported_device; |
| 1131 | radeon_connector->connector_object_id = connector_object_id; | 1241 | radeon_connector->connector_object_id = connector_object_id; |
| 1242 | radeon_connector->hpd = *hpd; | ||
| 1132 | switch (connector_type) { | 1243 | switch (connector_type) { |
| 1133 | case DRM_MODE_CONNECTOR_VGA: | 1244 | case DRM_MODE_CONNECTOR_VGA: |
| 1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1245 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a014ba4cc97c..7e55647f118e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -481,11 +481,13 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
| 481 | 481 | ||
| 482 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | 482 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
| 483 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 483 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
| 484 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | ||
| 484 | return 0; | 485 | return 0; |
| 485 | } | 486 | } |
| 486 | 487 | ||
| 487 | void radeon_atombios_fini(struct radeon_device *rdev) | 488 | void radeon_atombios_fini(struct radeon_device *rdev) |
| 488 | { | 489 | { |
| 490 | kfree(rdev->mode_info.atom_context->scratch); | ||
| 489 | kfree(rdev->mode_info.atom_context); | 491 | kfree(rdev->mode_info.atom_context); |
| 490 | kfree(rdev->mode_info.atom_card_info); | 492 | kfree(rdev->mode_info.atom_card_info); |
| 491 | } | 493 | } |
| @@ -568,6 +570,11 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 568 | rwlock_init(&rdev->fence_drv.lock); | 570 | rwlock_init(&rdev->fence_drv.lock); |
| 569 | INIT_LIST_HEAD(&rdev->gem.objects); | 571 | INIT_LIST_HEAD(&rdev->gem.objects); |
| 570 | 572 | ||
| 573 | /* setup workqueue */ | ||
| 574 | rdev->wq = create_workqueue("radeon"); | ||
| 575 | if (rdev->wq == NULL) | ||
| 576 | return -ENOMEM; | ||
| 577 | |||
| 571 | /* Set asic functions */ | 578 | /* Set asic functions */ |
| 572 | r = radeon_asic_init(rdev); | 579 | r = radeon_asic_init(rdev); |
| 573 | if (r) { | 580 | if (r) { |
| @@ -641,6 +648,7 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
| 641 | DRM_INFO("radeon: finishing device.\n"); | 648 | DRM_INFO("radeon: finishing device.\n"); |
| 642 | rdev->shutdown = true; | 649 | rdev->shutdown = true; |
| 643 | radeon_fini(rdev); | 650 | radeon_fini(rdev); |
| 651 | destroy_workqueue(rdev->wq); | ||
| 644 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 652 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
| 645 | iounmap(rdev->rmmio); | 653 | iounmap(rdev->rmmio); |
| 646 | rdev->rmmio = NULL; | 654 | rdev->rmmio = NULL; |
| @@ -687,6 +695,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
| 687 | radeon_save_bios_scratch_regs(rdev); | 695 | radeon_save_bios_scratch_regs(rdev); |
| 688 | 696 | ||
| 689 | radeon_suspend(rdev); | 697 | radeon_suspend(rdev); |
| 698 | radeon_hpd_fini(rdev); | ||
| 690 | /* evict remaining vram memory */ | 699 | /* evict remaining vram memory */ |
| 691 | radeon_bo_evict_vram(rdev); | 700 | radeon_bo_evict_vram(rdev); |
| 692 | 701 | ||
| @@ -721,6 +730,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
| 721 | fb_set_suspend(rdev->fbdev_info, 0); | 730 | fb_set_suspend(rdev->fbdev_info, 0); |
| 722 | release_console_sem(); | 731 | release_console_sem(); |
| 723 | 732 | ||
| 733 | /* reset hpd state */ | ||
| 734 | radeon_hpd_init(rdev); | ||
| 724 | /* blat the mode back in */ | 735 | /* blat the mode back in */ |
| 725 | drm_helper_resume_force_mode(dev); | 736 | drm_helper_resume_force_mode(dev); |
| 726 | return 0; | 737 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 62b02372cb09..c115f2e442eb 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -250,6 +250,16 @@ static const char *connector_names[13] = { | |||
| 250 | "HDMI-B", | 250 | "HDMI-B", |
| 251 | }; | 251 | }; |
| 252 | 252 | ||
| 253 | static const char *hpd_names[7] = { | ||
| 254 | "NONE", | ||
| 255 | "HPD1", | ||
| 256 | "HPD2", | ||
| 257 | "HPD3", | ||
| 258 | "HPD4", | ||
| 259 | "HPD5", | ||
| 260 | "HPD6", | ||
| 261 | }; | ||
| 262 | |||
| 253 | static void radeon_print_display_setup(struct drm_device *dev) | 263 | static void radeon_print_display_setup(struct drm_device *dev) |
| 254 | { | 264 | { |
| 255 | struct drm_connector *connector; | 265 | struct drm_connector *connector; |
| @@ -264,6 +274,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
| 264 | radeon_connector = to_radeon_connector(connector); | 274 | radeon_connector = to_radeon_connector(connector); |
| 265 | DRM_INFO("Connector %d:\n", i); | 275 | DRM_INFO("Connector %d:\n", i); |
| 266 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); | 276 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); |
| 277 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
| 278 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); | ||
| 267 | if (radeon_connector->ddc_bus) | 279 | if (radeon_connector->ddc_bus) |
| 268 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 280 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
| 269 | radeon_connector->ddc_bus->rec.mask_clk_reg, | 281 | radeon_connector->ddc_bus->rec.mask_clk_reg, |
| @@ -337,6 +349,11 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 337 | { | 349 | { |
| 338 | int ret = 0; | 350 | int ret = 0; |
| 339 | 351 | ||
| 352 | if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
| 353 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | ||
| 354 | if (dig->dp_i2c_bus) | ||
| 355 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | ||
| 356 | } | ||
| 340 | if (!radeon_connector->ddc_bus) | 357 | if (!radeon_connector->ddc_bus) |
| 341 | return -1; | 358 | return -1; |
| 342 | if (!radeon_connector->edid) { | 359 | if (!radeon_connector->edid) { |
| @@ -724,6 +741,8 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
| 724 | if (!ret) { | 741 | if (!ret) { |
| 725 | return ret; | 742 | return ret; |
| 726 | } | 743 | } |
| 744 | /* initialize hpd */ | ||
| 745 | radeon_hpd_init(rdev); | ||
| 727 | drm_helper_initial_config(rdev->ddev); | 746 | drm_helper_initial_config(rdev->ddev); |
| 728 | return 0; | 747 | return 0; |
| 729 | } | 748 | } |
| @@ -731,6 +750,7 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
| 731 | void radeon_modeset_fini(struct radeon_device *rdev) | 750 | void radeon_modeset_fini(struct radeon_device *rdev) |
| 732 | { | 751 | { |
| 733 | if (rdev->mode_info.mode_config_initialized) { | 752 | if (rdev->mode_info.mode_config_initialized) { |
| 753 | radeon_hpd_fini(rdev); | ||
| 734 | drm_mode_config_cleanup(rdev->ddev); | 754 | drm_mode_config_cleanup(rdev->ddev); |
| 735 | rdev->mode_info.mode_config_initialized = false; | 755 | rdev->mode_info.mode_config_initialized = false; |
| 736 | } | 756 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 291f6dd3683c..b4f23ec93201 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -250,6 +250,12 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
| 250 | } | 250 | } |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | if (ASIC_IS_DCE3(rdev) && | ||
| 254 | (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { | ||
| 255 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 256 | radeon_dp_set_link_config(connector, mode); | ||
| 257 | } | ||
| 258 | |||
| 253 | return true; | 259 | return true; |
| 254 | } | 260 | } |
| 255 | 261 | ||
| @@ -554,6 +560,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 554 | { | 560 | { |
| 555 | struct drm_connector *connector; | 561 | struct drm_connector *connector; |
| 556 | struct radeon_connector *radeon_connector; | 562 | struct radeon_connector *radeon_connector; |
| 563 | struct radeon_connector_atom_dig *radeon_dig_connector; | ||
| 557 | 564 | ||
| 558 | connector = radeon_get_connector_for_encoder(encoder); | 565 | connector = radeon_get_connector_for_encoder(encoder); |
| 559 | if (!connector) | 566 | if (!connector) |
| @@ -583,10 +590,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 583 | return ATOM_ENCODER_MODE_LVDS; | 590 | return ATOM_ENCODER_MODE_LVDS; |
| 584 | break; | 591 | break; |
| 585 | case DRM_MODE_CONNECTOR_DisplayPort: | 592 | case DRM_MODE_CONNECTOR_DisplayPort: |
| 586 | /*if (radeon_output->MonType == MT_DP) | 593 | radeon_dig_connector = radeon_connector->con_priv; |
| 587 | return ATOM_ENCODER_MODE_DP; | 594 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) |
| 588 | else*/ | 595 | return ATOM_ENCODER_MODE_DP; |
| 589 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 596 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
| 590 | return ATOM_ENCODER_MODE_HDMI; | 597 | return ATOM_ENCODER_MODE_HDMI; |
| 591 | else | 598 | else |
| 592 | return ATOM_ENCODER_MODE_DVI; | 599 | return ATOM_ENCODER_MODE_DVI; |
| @@ -605,6 +612,30 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 605 | } | 612 | } |
| 606 | } | 613 | } |
| 607 | 614 | ||
| 615 | /* | ||
| 616 | * DIG Encoder/Transmitter Setup | ||
| 617 | * | ||
| 618 | * DCE 3.0/3.1 | ||
| 619 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
| 620 | * Supports up to 3 digital outputs | ||
| 621 | * - 2 DIG encoder blocks. | ||
| 622 | * DIG1 can drive UNIPHY link A or link B | ||
| 623 | * DIG2 can drive UNIPHY link B or LVTMA | ||
| 624 | * | ||
| 625 | * DCE 3.2 | ||
| 626 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
| 627 | * Supports up to 5 digital outputs | ||
| 628 | * - 2 DIG encoder blocks. | ||
| 629 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
| 630 | * | ||
| 631 | * Routing | ||
| 632 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
| 633 | * Examples: | ||
| 634 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
| 635 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
| 636 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
| 637 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
| 638 | */ | ||
| 608 | static void | 639 | static void |
| 609 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 640 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
| 610 | { | 641 | { |
| @@ -646,10 +677,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 646 | } else { | 677 | } else { |
| 647 | switch (radeon_encoder->encoder_id) { | 678 | switch (radeon_encoder->encoder_id) { |
| 648 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 679 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 649 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 680 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
| 681 | * not already in use | ||
| 682 | */ | ||
| 683 | if (dig_connector->linkb) | ||
| 684 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
| 685 | else | ||
| 686 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
| 650 | num = 1; | 687 | num = 1; |
| 651 | break; | 688 | break; |
| 652 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 689 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 690 | /* Only dig2 encoder can drive LVTMA */ | ||
| 653 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 691 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); |
| 654 | num = 2; | 692 | num = 2; |
| 655 | break; | 693 | break; |
| @@ -684,18 +722,21 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 684 | } | 722 | } |
| 685 | } | 723 | } |
| 686 | 724 | ||
| 687 | if (radeon_encoder->pixel_clock > 165000) { | 725 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); |
| 688 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; | 726 | |
| 727 | if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
| 728 | if (dig_connector->dp_clock == 270000) | ||
| 729 | args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
| 730 | args.ucLaneNum = dig_connector->dp_lane_count; | ||
| 731 | } else if (radeon_encoder->pixel_clock > 165000) | ||
| 689 | args.ucLaneNum = 8; | 732 | args.ucLaneNum = 8; |
| 690 | } else { | 733 | else |
| 691 | if (dig_connector->linkb) | ||
| 692 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
| 693 | else | ||
| 694 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
| 695 | args.ucLaneNum = 4; | 734 | args.ucLaneNum = 4; |
| 696 | } | ||
| 697 | 735 | ||
| 698 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | 736 | if (dig_connector->linkb) |
| 737 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
| 738 | else | ||
| 739 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
| 699 | 740 | ||
| 700 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 741 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 701 | 742 | ||
| @@ -706,8 +747,8 @@ union dig_transmitter_control { | |||
| 706 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 747 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
| 707 | }; | 748 | }; |
| 708 | 749 | ||
| 709 | static void | 750 | void |
| 710 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | 751 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
| 711 | { | 752 | { |
| 712 | struct drm_device *dev = encoder->dev; | 753 | struct drm_device *dev = encoder->dev; |
| 713 | struct radeon_device *rdev = dev->dev_private; | 754 | struct radeon_device *rdev = dev->dev_private; |
| @@ -719,6 +760,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 719 | struct drm_connector *connector; | 760 | struct drm_connector *connector; |
| 720 | struct radeon_connector *radeon_connector; | 761 | struct radeon_connector *radeon_connector; |
| 721 | struct radeon_connector_atom_dig *dig_connector; | 762 | struct radeon_connector_atom_dig *dig_connector; |
| 763 | bool is_dp = false; | ||
| 722 | 764 | ||
| 723 | connector = radeon_get_connector_for_encoder(encoder); | 765 | connector = radeon_get_connector_for_encoder(encoder); |
| 724 | if (!connector) | 766 | if (!connector) |
| @@ -736,6 +778,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 736 | 778 | ||
| 737 | dig_connector = radeon_connector->con_priv; | 779 | dig_connector = radeon_connector->con_priv; |
| 738 | 780 | ||
| 781 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | ||
| 782 | is_dp = true; | ||
| 783 | |||
| 739 | memset(&args, 0, sizeof(args)); | 784 | memset(&args, 0, sizeof(args)); |
| 740 | 785 | ||
| 741 | if (ASIC_IS_DCE32(rdev)) | 786 | if (ASIC_IS_DCE32(rdev)) |
| @@ -756,17 +801,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 756 | args.v1.ucAction = action; | 801 | args.v1.ucAction = action; |
| 757 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 802 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
| 758 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 803 | args.v1.usInitInfo = radeon_connector->connector_object_id; |
| 804 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
| 805 | args.v1.asMode.ucLaneSel = lane_num; | ||
| 806 | args.v1.asMode.ucLaneSet = lane_set; | ||
| 759 | } else { | 807 | } else { |
| 760 | if (radeon_encoder->pixel_clock > 165000) | 808 | if (is_dp) |
| 809 | args.v1.usPixelClock = | ||
| 810 | cpu_to_le16(dig_connector->dp_clock / 10); | ||
| 811 | else if (radeon_encoder->pixel_clock > 165000) | ||
| 761 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 812 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 762 | else | 813 | else |
| 763 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 814 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| 764 | } | 815 | } |
| 765 | if (ASIC_IS_DCE32(rdev)) { | 816 | if (ASIC_IS_DCE32(rdev)) { |
| 766 | if (radeon_encoder->pixel_clock > 165000) | ||
| 767 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
| 768 | if (dig->dig_block) | 817 | if (dig->dig_block) |
| 769 | args.v2.acConfig.ucEncoderSel = 1; | 818 | args.v2.acConfig.ucEncoderSel = 1; |
| 819 | if (dig_connector->linkb) | ||
| 820 | args.v2.acConfig.ucLinkSel = 1; | ||
| 770 | 821 | ||
| 771 | switch (radeon_encoder->encoder_id) { | 822 | switch (radeon_encoder->encoder_id) { |
| 772 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 823 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| @@ -783,7 +834,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 783 | break; | 834 | break; |
| 784 | } | 835 | } |
| 785 | 836 | ||
| 786 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 837 | if (is_dp) |
| 838 | args.v2.acConfig.fCoherentMode = 1; | ||
| 839 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 787 | if (dig->coherent_mode) | 840 | if (dig->coherent_mode) |
| 788 | args.v2.acConfig.fCoherentMode = 1; | 841 | args.v2.acConfig.fCoherentMode = 1; |
| 789 | } | 842 | } |
| @@ -792,17 +845,20 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 792 | 845 | ||
| 793 | switch (radeon_encoder->encoder_id) { | 846 | switch (radeon_encoder->encoder_id) { |
| 794 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 847 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 795 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | 848 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
| 849 | * not already in use | ||
| 850 | */ | ||
| 851 | if (dig_connector->linkb) | ||
| 852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
| 853 | else | ||
| 854 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
| 796 | if (rdev->flags & RADEON_IS_IGP) { | 855 | if (rdev->flags & RADEON_IS_IGP) { |
| 797 | if (radeon_encoder->pixel_clock > 165000) { | 856 | if (radeon_encoder->pixel_clock > 165000) { |
| 798 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
| 799 | ATOM_TRANSMITTER_CONFIG_LINKA_B); | ||
| 800 | if (dig_connector->igp_lane_info & 0x3) | 857 | if (dig_connector->igp_lane_info & 0x3) |
| 801 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
| 802 | else if (dig_connector->igp_lane_info & 0xc) | 859 | else if (dig_connector->igp_lane_info & 0xc) |
| 803 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 860 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
| 804 | } else { | 861 | } else { |
| 805 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
| 806 | if (dig_connector->igp_lane_info & 0x1) | 862 | if (dig_connector->igp_lane_info & 0x1) |
| 807 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 863 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
| 808 | else if (dig_connector->igp_lane_info & 0x2) | 864 | else if (dig_connector->igp_lane_info & 0x2) |
| @@ -812,35 +868,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
| 812 | else if (dig_connector->igp_lane_info & 0x8) | 868 | else if (dig_connector->igp_lane_info & 0x8) |
| 813 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 869 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
| 814 | } | 870 | } |
| 815 | } else { | ||
| 816 | if (radeon_encoder->pixel_clock > 165000) | ||
| 817 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
| 818 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
| 819 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
| 820 | else { | ||
| 821 | if (dig_connector->linkb) | ||
| 822 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 823 | else | ||
| 824 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 825 | } | ||
| 826 | } | 871 | } |
| 827 | break; | 872 | break; |
| 828 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 873 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 874 | /* Only dig2 encoder can drive LVTMA */ | ||
| 829 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | 875 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; |
| 830 | if (radeon_encoder->pixel_clock > 165000) | ||
| 831 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
| 832 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
| 833 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
| 834 | else { | ||
| 835 | if (dig_connector->linkb) | ||
| 836 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 837 | else | ||
| 838 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
| 839 | } | ||
| 840 | break; | 876 | break; |
| 841 | } | 877 | } |
| 842 | 878 | ||
| 843 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 879 | if (radeon_encoder->pixel_clock > 165000) |
| 880 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
| 881 | |||
| 882 | if (dig_connector->linkb) | ||
| 883 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
| 884 | else | ||
| 885 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
| 886 | |||
| 887 | if (is_dp) | ||
| 888 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
| 889 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 844 | if (dig->coherent_mode) | 890 | if (dig->coherent_mode) |
| 845 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 891 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
| 846 | } | 892 | } |
| @@ -950,12 +996,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 950 | if (is_dig) { | 996 | if (is_dig) { |
| 951 | switch (mode) { | 997 | switch (mode) { |
| 952 | case DRM_MODE_DPMS_ON: | 998 | case DRM_MODE_DPMS_ON: |
| 953 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT); | 999 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1000 | { | ||
| 1001 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1002 | dp_link_train(encoder, connector); | ||
| 1003 | } | ||
| 954 | break; | 1004 | break; |
| 955 | case DRM_MODE_DPMS_STANDBY: | 1005 | case DRM_MODE_DPMS_STANDBY: |
| 956 | case DRM_MODE_DPMS_SUSPEND: | 1006 | case DRM_MODE_DPMS_SUSPEND: |
| 957 | case DRM_MODE_DPMS_OFF: | 1007 | case DRM_MODE_DPMS_OFF: |
| 958 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT); | 1008 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
| 959 | break; | 1009 | break; |
| 960 | } | 1010 | } |
| 961 | } else { | 1011 | } else { |
| @@ -1057,13 +1107,33 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
| 1057 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1107 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
| 1058 | else | 1108 | else |
| 1059 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1109 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
| 1060 | } else | 1110 | } else { |
| 1061 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1111 | struct drm_connector *connector; |
| 1112 | struct radeon_connector *radeon_connector; | ||
| 1113 | struct radeon_connector_atom_dig *dig_connector; | ||
| 1114 | |||
| 1115 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 1116 | if (!connector) | ||
| 1117 | return; | ||
| 1118 | radeon_connector = to_radeon_connector(connector); | ||
| 1119 | if (!radeon_connector->con_priv) | ||
| 1120 | return; | ||
| 1121 | dig_connector = radeon_connector->con_priv; | ||
| 1122 | |||
| 1123 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
| 1124 | * not already in use | ||
| 1125 | */ | ||
| 1126 | if (dig_connector->linkb) | ||
| 1127 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
| 1128 | else | ||
| 1129 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
| 1130 | } | ||
| 1062 | break; | 1131 | break; |
| 1063 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1132 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
| 1064 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1133 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
| 1065 | break; | 1134 | break; |
| 1066 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1135 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 1136 | /* Only dig2 encoder can drive LVTMA */ | ||
| 1067 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1137 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
| 1068 | break; | 1138 | break; |
| 1069 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1139 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
| @@ -1136,11 +1206,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1136 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1206 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1137 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1207 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
| 1138 | 1208 | ||
| 1139 | if (radeon_encoder->enc_priv) { | 1209 | if (radeon_encoder->active_device & |
| 1140 | struct radeon_encoder_atom_dig *dig; | 1210 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { |
| 1211 | if (radeon_encoder->enc_priv) { | ||
| 1212 | struct radeon_encoder_atom_dig *dig; | ||
| 1141 | 1213 | ||
| 1142 | dig = radeon_encoder->enc_priv; | 1214 | dig = radeon_encoder->enc_priv; |
| 1143 | dig->dig_block = radeon_crtc->crtc_id; | 1215 | dig->dig_block = radeon_crtc->crtc_id; |
| 1216 | } | ||
| 1144 | } | 1217 | } |
| 1145 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1218 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
| 1146 | 1219 | ||
| @@ -1166,14 +1239,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1239 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 1167 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1240 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 1168 | /* disable the encoder and transmitter */ | 1241 | /* disable the encoder and transmitter */ |
| 1169 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1242 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
| 1170 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1243 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); |
| 1171 | 1244 | ||
| 1172 | /* setup and enable the encoder and transmitter */ | 1245 | /* setup and enable the encoder and transmitter */ |
| 1173 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1246 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); |
| 1174 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); | 1247 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
| 1175 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); | 1248 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
| 1176 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 1249 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1177 | break; | 1250 | break; |
| 1178 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1251 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
| 1179 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1252 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 6c645fb4dad8..da3da1e89d00 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -69,13 +69,15 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
| 69 | * holds the i2c port in a bad state - switch hw i2c away before | 69 | * holds the i2c port in a bad state - switch hw i2c away before |
| 70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake | 70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake |
| 71 | */ | 71 | */ |
| 72 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { | 72 | if (rec->hw_capable) { |
| 73 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { | 73 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { |
| 74 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 74 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { |
| 75 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | 75 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
| 76 | } else { | 76 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); |
| 77 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 77 | } else { |
| 78 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | 78 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
| 79 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | ||
| 80 | } | ||
| 79 | } | 81 | } |
| 80 | } | 82 | } |
| 81 | 83 | ||
| @@ -86,6 +88,12 @@ void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
| 86 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; | 88 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; |
| 87 | WREG32(rec->a_data_reg, temp); | 89 | WREG32(rec->a_data_reg, temp); |
| 88 | 90 | ||
| 91 | /* set the pins to input */ | ||
| 92 | temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; | ||
| 93 | WREG32(rec->en_clk_reg, temp); | ||
| 94 | |||
| 95 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; | ||
| 96 | WREG32(rec->en_data_reg, temp); | ||
| 89 | 97 | ||
| 90 | /* mask the gpio pins for software use */ | 98 | /* mask the gpio pins for software use */ |
| 91 | temp = RREG32(rec->mask_clk_reg); | 99 | temp = RREG32(rec->mask_clk_reg); |
| @@ -172,20 +180,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 172 | return NULL; | 180 | return NULL; |
| 173 | 181 | ||
| 174 | i2c->adapter.owner = THIS_MODULE; | 182 | i2c->adapter.owner = THIS_MODULE; |
| 175 | i2c->adapter.algo_data = &i2c->algo; | ||
| 176 | i2c->dev = dev; | 183 | i2c->dev = dev; |
| 177 | i2c->algo.setsda = set_data; | 184 | i2c_set_adapdata(&i2c->adapter, i2c); |
| 178 | i2c->algo.setscl = set_clock; | 185 | i2c->adapter.algo_data = &i2c->algo.bit; |
| 179 | i2c->algo.getsda = get_data; | 186 | i2c->algo.bit.setsda = set_data; |
| 180 | i2c->algo.getscl = get_clock; | 187 | i2c->algo.bit.setscl = set_clock; |
| 181 | i2c->algo.udelay = 20; | 188 | i2c->algo.bit.getsda = get_data; |
| 189 | i2c->algo.bit.getscl = get_clock; | ||
| 190 | i2c->algo.bit.udelay = 20; | ||
| 182 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | 191 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always |
| 183 | * make this, 2 jiffies is a lot more reliable */ | 192 | * make this, 2 jiffies is a lot more reliable */ |
| 184 | i2c->algo.timeout = 2; | 193 | i2c->algo.bit.timeout = 2; |
| 185 | i2c->algo.data = i2c; | 194 | i2c->algo.bit.data = i2c; |
| 186 | i2c->rec = *rec; | 195 | i2c->rec = *rec; |
| 187 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
| 188 | |||
| 189 | ret = i2c_bit_add_bus(&i2c->adapter); | 196 | ret = i2c_bit_add_bus(&i2c->adapter); |
| 190 | if (ret) { | 197 | if (ret) { |
| 191 | DRM_INFO("Failed to register i2c %s\n", name); | 198 | DRM_INFO("Failed to register i2c %s\n", name); |
| @@ -199,6 +206,38 @@ out_free: | |||
| 199 | 206 | ||
| 200 | } | 207 | } |
| 201 | 208 | ||
| 209 | struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
| 210 | struct radeon_i2c_bus_rec *rec, | ||
| 211 | const char *name) | ||
| 212 | { | ||
| 213 | struct radeon_i2c_chan *i2c; | ||
| 214 | int ret; | ||
| 215 | |||
| 216 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | ||
| 217 | if (i2c == NULL) | ||
| 218 | return NULL; | ||
| 219 | |||
| 220 | i2c->rec = *rec; | ||
| 221 | i2c->adapter.owner = THIS_MODULE; | ||
| 222 | i2c->dev = dev; | ||
| 223 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
| 224 | i2c->adapter.algo_data = &i2c->algo.dp; | ||
| 225 | i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; | ||
| 226 | i2c->algo.dp.address = 0; | ||
| 227 | ret = i2c_dp_aux_add_bus(&i2c->adapter); | ||
| 228 | if (ret) { | ||
| 229 | DRM_INFO("Failed to register i2c %s\n", name); | ||
| 230 | goto out_free; | ||
| 231 | } | ||
| 232 | |||
| 233 | return i2c; | ||
| 234 | out_free: | ||
| 235 | kfree(i2c); | ||
| 236 | return NULL; | ||
| 237 | |||
| 238 | } | ||
| 239 | |||
| 240 | |||
| 202 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | 241 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) |
| 203 | { | 242 | { |
| 204 | if (!i2c) | 243 | if (!i2c) |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 26789970c5cf..9223296fe37b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
| 39 | return radeon_irq_process(rdev); | 39 | return radeon_irq_process(rdev); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /* | ||
| 43 | * Handle hotplug events outside the interrupt handler proper. | ||
| 44 | */ | ||
| 45 | static void radeon_hotplug_work_func(struct work_struct *work) | ||
| 46 | { | ||
| 47 | struct radeon_device *rdev = container_of(work, struct radeon_device, | ||
| 48 | hotplug_work); | ||
| 49 | struct drm_device *dev = rdev->ddev; | ||
| 50 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
| 51 | struct drm_connector *connector; | ||
| 52 | |||
| 53 | if (mode_config->num_connector) { | ||
| 54 | list_for_each_entry(connector, &mode_config->connector_list, head) | ||
| 55 | radeon_connector_hotplug(connector); | ||
| 56 | } | ||
| 57 | /* Just fire off a uevent and let userspace tell us what to do */ | ||
| 58 | drm_sysfs_hotplug_event(dev); | ||
| 59 | } | ||
| 60 | |||
| 42 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | 61 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
| 43 | { | 62 | { |
| 44 | struct radeon_device *rdev = dev->dev_private; | 63 | struct radeon_device *rdev = dev->dev_private; |
| 45 | unsigned i; | 64 | unsigned i; |
| 46 | 65 | ||
| 66 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | ||
| 67 | |||
| 47 | /* Disable *all* interrupts */ | 68 | /* Disable *all* interrupts */ |
| 48 | rdev->irq.sw_int = false; | 69 | rdev->irq.sw_int = false; |
| 49 | for (i = 0; i < 2; i++) { | 70 | for (i = 0; i < 2; i++) { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 135693d5437e..15ec7ca18a95 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <drm_crtc.h> | 33 | #include <drm_crtc.h> |
| 34 | #include <drm_mode.h> | 34 | #include <drm_mode.h> |
| 35 | #include <drm_edid.h> | 35 | #include <drm_edid.h> |
| 36 | #include <drm_dp_helper.h> | ||
| 36 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
| 37 | #include <linux/i2c-id.h> | 38 | #include <linux/i2c-id.h> |
| 38 | #include <linux/i2c-algo-bit.h> | 39 | #include <linux/i2c-algo-bit.h> |
| @@ -105,6 +106,13 @@ enum radeon_tv_std { | |||
| 105 | */ | 106 | */ |
| 106 | struct radeon_i2c_bus_rec { | 107 | struct radeon_i2c_bus_rec { |
| 107 | bool valid; | 108 | bool valid; |
| 109 | /* id used by atom */ | ||
| 110 | uint8_t i2c_id; | ||
| 111 | /* can be used with hw i2c engine */ | ||
| 112 | bool hw_capable; | ||
| 113 | /* uses multi-media i2c engine */ | ||
| 114 | bool mm_i2c; | ||
| 115 | /* regs and bits */ | ||
| 108 | uint32_t mask_clk_reg; | 116 | uint32_t mask_clk_reg; |
| 109 | uint32_t mask_data_reg; | 117 | uint32_t mask_data_reg; |
| 110 | uint32_t a_clk_reg; | 118 | uint32_t a_clk_reg; |
| @@ -164,9 +172,12 @@ struct radeon_pll { | |||
| 164 | }; | 172 | }; |
| 165 | 173 | ||
| 166 | struct radeon_i2c_chan { | 174 | struct radeon_i2c_chan { |
| 167 | struct drm_device *dev; | ||
| 168 | struct i2c_adapter adapter; | 175 | struct i2c_adapter adapter; |
| 169 | struct i2c_algo_bit_data algo; | 176 | struct drm_device *dev; |
| 177 | union { | ||
| 178 | struct i2c_algo_dp_aux_data dp; | ||
| 179 | struct i2c_algo_bit_data bit; | ||
| 180 | } algo; | ||
| 170 | struct radeon_i2c_bus_rec rec; | 181 | struct radeon_i2c_bus_rec rec; |
| 171 | }; | 182 | }; |
| 172 | 183 | ||
| @@ -328,6 +339,35 @@ struct radeon_encoder { | |||
| 328 | struct radeon_connector_atom_dig { | 339 | struct radeon_connector_atom_dig { |
| 329 | uint32_t igp_lane_info; | 340 | uint32_t igp_lane_info; |
| 330 | bool linkb; | 341 | bool linkb; |
| 342 | /* displayport */ | ||
| 343 | struct radeon_i2c_chan *dp_i2c_bus; | ||
| 344 | u8 dpcd[8]; | ||
| 345 | u8 dp_sink_type; | ||
| 346 | int dp_clock; | ||
| 347 | int dp_lane_count; | ||
| 348 | }; | ||
| 349 | |||
| 350 | struct radeon_gpio_rec { | ||
| 351 | bool valid; | ||
| 352 | u8 id; | ||
| 353 | u32 reg; | ||
| 354 | u32 mask; | ||
| 355 | }; | ||
| 356 | |||
| 357 | enum radeon_hpd_id { | ||
| 358 | RADEON_HPD_NONE = 0, | ||
| 359 | RADEON_HPD_1, | ||
| 360 | RADEON_HPD_2, | ||
| 361 | RADEON_HPD_3, | ||
| 362 | RADEON_HPD_4, | ||
| 363 | RADEON_HPD_5, | ||
| 364 | RADEON_HPD_6, | ||
| 365 | }; | ||
| 366 | |||
| 367 | struct radeon_hpd { | ||
| 368 | enum radeon_hpd_id hpd; | ||
| 369 | u8 plugged_state; | ||
| 370 | struct radeon_gpio_rec gpio; | ||
| 331 | }; | 371 | }; |
| 332 | 372 | ||
| 333 | struct radeon_connector { | 373 | struct radeon_connector { |
| @@ -344,6 +384,7 @@ struct radeon_connector { | |||
| 344 | void *con_priv; | 384 | void *con_priv; |
| 345 | bool dac_load_detect; | 385 | bool dac_load_detect; |
| 346 | uint16_t connector_object_id; | 386 | uint16_t connector_object_id; |
| 387 | struct radeon_hpd hpd; | ||
| 347 | }; | 388 | }; |
| 348 | 389 | ||
| 349 | struct radeon_framebuffer { | 390 | struct radeon_framebuffer { |
| @@ -351,6 +392,25 @@ struct radeon_framebuffer { | |||
| 351 | struct drm_gem_object *obj; | 392 | struct drm_gem_object *obj; |
| 352 | }; | 393 | }; |
| 353 | 394 | ||
| 395 | extern void radeon_connector_hotplug(struct drm_connector *connector); | ||
| 396 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | ||
| 397 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
| 398 | struct drm_display_mode *mode); | ||
| 399 | extern void radeon_dp_set_link_config(struct drm_connector *connector, | ||
| 400 | struct drm_display_mode *mode); | ||
| 401 | extern void dp_link_train(struct drm_encoder *encoder, | ||
| 402 | struct drm_connector *connector); | ||
| 403 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | ||
| 404 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | ||
| 405 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | ||
| 406 | int action, uint8_t lane_num, | ||
| 407 | uint8_t lane_set); | ||
| 408 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
| 409 | uint8_t write_byte, uint8_t *read_byte); | ||
| 410 | |||
| 411 | extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
| 412 | struct radeon_i2c_bus_rec *rec, | ||
| 413 | const char *name); | ||
| 354 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 414 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
| 355 | struct radeon_i2c_bus_rec *rec, | 415 | struct radeon_i2c_bus_rec *rec, |
| 356 | const char *name); | 416 | const char *name); |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index c4c41c8d908c..6d0a009dd4a1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
| @@ -887,6 +887,7 @@ | |||
| 887 | # define RADEON_FP_PANEL_FORMAT (1 << 3) | 887 | # define RADEON_FP_PANEL_FORMAT (1 << 3) |
| 888 | # define RADEON_FP_EN_TMDS (1 << 7) | 888 | # define RADEON_FP_EN_TMDS (1 << 7) |
| 889 | # define RADEON_FP_DETECT_SENSE (1 << 8) | 889 | # define RADEON_FP_DETECT_SENSE (1 << 8) |
| 890 | # define RADEON_FP_DETECT_INT_POL (1 << 9) | ||
| 890 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) | 891 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) |
| 891 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) | 892 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) |
| 892 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) | 893 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) |
| @@ -894,6 +895,7 @@ | |||
| 894 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) | 895 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) |
| 895 | # define RADEON_FP_SEL_CRTC1 (0 << 13) | 896 | # define RADEON_FP_SEL_CRTC1 (0 << 13) |
| 896 | # define RADEON_FP_SEL_CRTC2 (1 << 13) | 897 | # define RADEON_FP_SEL_CRTC2 (1 << 13) |
| 898 | # define R300_HPD_SEL(x) ((x) << 13) | ||
| 897 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) | 899 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) |
| 898 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) | 900 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) |
| 899 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) | 901 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) |
| @@ -909,6 +911,7 @@ | |||
| 909 | # define RADEON_FP2_ON (1 << 2) | 911 | # define RADEON_FP2_ON (1 << 2) |
| 910 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) | 912 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) |
| 911 | # define RADEON_FP2_DETECT_SENSE (1 << 8) | 913 | # define RADEON_FP2_DETECT_SENSE (1 << 8) |
| 914 | # define RADEON_FP2_DETECT_INT_POL (1 << 9) | ||
| 912 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) | 915 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) |
| 913 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) | 916 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) |
| 914 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) | 917 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) |
| @@ -988,14 +991,20 @@ | |||
| 988 | 991 | ||
| 989 | #define RADEON_GEN_INT_CNTL 0x0040 | 992 | #define RADEON_GEN_INT_CNTL 0x0040 |
| 990 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 993 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
| 994 | # define RADEON_FP_DETECT_MASK (1 << 4) | ||
| 991 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 995 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
| 996 | # define RADEON_FP2_DETECT_MASK (1 << 10) | ||
| 992 | # define RADEON_SW_INT_ENABLE (1 << 25) | 997 | # define RADEON_SW_INT_ENABLE (1 << 25) |
| 993 | #define RADEON_GEN_INT_STATUS 0x0044 | 998 | #define RADEON_GEN_INT_STATUS 0x0044 |
| 994 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) | 999 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
| 995 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) | 1000 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
| 996 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) | 1001 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
| 1002 | # define RADEON_FP_DETECT_STAT (1 << 4) | ||
| 1003 | # define RADEON_FP_DETECT_STAT_ACK (1 << 4) | ||
| 997 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) | 1004 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) |
| 998 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | 1005 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) |
| 1006 | # define RADEON_FP2_DETECT_STAT (1 << 10) | ||
| 1007 | # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) | ||
| 999 | # define RADEON_SW_INT_FIRE (1 << 26) | 1008 | # define RADEON_SW_INT_FIRE (1 << 26) |
| 1000 | # define RADEON_SW_INT_TEST (1 << 25) | 1009 | # define RADEON_SW_INT_TEST (1 << 25) |
| 1001 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 1010 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
| @@ -1148,16 +1157,16 @@ | |||
| 1148 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) | 1157 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) |
| 1149 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) | 1158 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) |
| 1150 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) | 1159 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) |
| 1160 | |||
| 1151 | #define RADEON_GPIOPAD_MASK 0x0198 | 1161 | #define RADEON_GPIOPAD_MASK 0x0198 |
| 1152 | #define RADEON_GPIOPAD_A 0x019c | 1162 | #define RADEON_GPIOPAD_A 0x019c |
| 1153 | #define RADEON_GPIOPAD_EN 0x01a0 | 1163 | #define RADEON_GPIOPAD_EN 0x01a0 |
| 1154 | #define RADEON_GPIOPAD_Y 0x01a4 | 1164 | #define RADEON_GPIOPAD_Y 0x01a4 |
| 1155 | #define RADEON_LCD_GPIO_MASK 0x01a0 | 1165 | #define RADEON_MDGPIO_MASK 0x01a8 |
| 1156 | #define RADEON_LCD_GPIO_Y_REG 0x01a4 | 1166 | #define RADEON_MDGPIO_A 0x01ac |
| 1157 | #define RADEON_MDGPIO_A_REG 0x01ac | 1167 | #define RADEON_MDGPIO_EN 0x01b0 |
| 1158 | #define RADEON_MDGPIO_EN_REG 0x01b0 | 1168 | #define RADEON_MDGPIO_Y 0x01b4 |
| 1159 | #define RADEON_MDGPIO_MASK 0x0198 | 1169 | |
| 1160 | #define RADEON_MDGPIO_Y_REG 0x01b4 | ||
| 1161 | #define RADEON_MEM_ADDR_CONFIG 0x0148 | 1170 | #define RADEON_MEM_ADDR_CONFIG 0x0148 |
| 1162 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ | 1171 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ |
| 1163 | #define RADEON_MEM_CNTL 0x0140 | 1172 | #define RADEON_MEM_CNTL 0x0140 |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 84b26376027d..fd5ab01f6ad1 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -60,6 +60,107 @@ int rs600_mc_init(struct radeon_device *rdev) | |||
| 60 | return r; | 60 | return r; |
| 61 | return 0; | 61 | return 0; |
| 62 | } | 62 | } |
| 63 | |||
| 64 | /* hpd for digital panel detect/disconnect */ | ||
| 65 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
| 66 | { | ||
| 67 | u32 tmp; | ||
| 68 | bool connected = false; | ||
| 69 | |||
| 70 | switch (hpd) { | ||
| 71 | case RADEON_HPD_1: | ||
| 72 | tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS); | ||
| 73 | if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp)) | ||
| 74 | connected = true; | ||
| 75 | break; | ||
| 76 | case RADEON_HPD_2: | ||
| 77 | tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS); | ||
| 78 | if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp)) | ||
| 79 | connected = true; | ||
| 80 | break; | ||
| 81 | default: | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | return connected; | ||
| 85 | } | ||
| 86 | |||
| 87 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
| 88 | enum radeon_hpd_id hpd) | ||
| 89 | { | ||
| 90 | u32 tmp; | ||
| 91 | bool connected = rs600_hpd_sense(rdev, hpd); | ||
| 92 | |||
| 93 | switch (hpd) { | ||
| 94 | case RADEON_HPD_1: | ||
| 95 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
| 96 | if (connected) | ||
| 97 | tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
| 98 | else | ||
| 99 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
| 100 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
| 101 | break; | ||
| 102 | case RADEON_HPD_2: | ||
| 103 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
| 104 | if (connected) | ||
| 105 | tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
| 106 | else | ||
| 107 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
| 108 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
| 109 | break; | ||
| 110 | default: | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | void rs600_hpd_init(struct radeon_device *rdev) | ||
| 116 | { | ||
| 117 | struct drm_device *dev = rdev->ddev; | ||
| 118 | struct drm_connector *connector; | ||
| 119 | |||
| 120 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 121 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 122 | switch (radeon_connector->hpd.hpd) { | ||
| 123 | case RADEON_HPD_1: | ||
| 124 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
| 125 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); | ||
| 126 | rdev->irq.hpd[0] = true; | ||
| 127 | break; | ||
| 128 | case RADEON_HPD_2: | ||
| 129 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
| 130 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); | ||
| 131 | rdev->irq.hpd[1] = true; | ||
| 132 | break; | ||
| 133 | default: | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | rs600_irq_set(rdev); | ||
| 138 | } | ||
| 139 | |||
| 140 | void rs600_hpd_fini(struct radeon_device *rdev) | ||
| 141 | { | ||
| 142 | struct drm_device *dev = rdev->ddev; | ||
| 143 | struct drm_connector *connector; | ||
| 144 | |||
| 145 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 146 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 147 | switch (radeon_connector->hpd.hpd) { | ||
| 148 | case RADEON_HPD_1: | ||
| 149 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
| 150 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); | ||
| 151 | rdev->irq.hpd[0] = false; | ||
| 152 | break; | ||
| 153 | case RADEON_HPD_2: | ||
| 154 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
| 155 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); | ||
| 156 | rdev->irq.hpd[1] = false; | ||
| 157 | break; | ||
| 158 | default: | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 63 | /* | 164 | /* |
| 64 | * GART. | 165 | * GART. |
| 65 | */ | 166 | */ |
| @@ -209,6 +310,10 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
| 209 | { | 310 | { |
| 210 | uint32_t tmp = 0; | 311 | uint32_t tmp = 0; |
| 211 | uint32_t mode_int = 0; | 312 | uint32_t mode_int = 0; |
| 313 | u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) & | ||
| 314 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
| 315 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | ||
| 316 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
| 212 | 317 | ||
| 213 | if (rdev->irq.sw_int) { | 318 | if (rdev->irq.sw_int) { |
| 214 | tmp |= S_000040_SW_INT_EN(1); | 319 | tmp |= S_000040_SW_INT_EN(1); |
| @@ -219,8 +324,16 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
| 219 | if (rdev->irq.crtc_vblank_int[1]) { | 324 | if (rdev->irq.crtc_vblank_int[1]) { |
| 220 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 325 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
| 221 | } | 326 | } |
| 327 | if (rdev->irq.hpd[0]) { | ||
| 328 | hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
| 329 | } | ||
| 330 | if (rdev->irq.hpd[1]) { | ||
| 331 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
| 332 | } | ||
| 222 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 333 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
| 223 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 334 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
| 335 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
| 336 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
| 224 | return 0; | 337 | return 0; |
| 225 | } | 338 | } |
| 226 | 339 | ||
| @@ -228,6 +341,7 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
| 228 | { | 341 | { |
| 229 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 342 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
| 230 | uint32_t irq_mask = ~C_000044_SW_INT; | 343 | uint32_t irq_mask = ~C_000044_SW_INT; |
| 344 | u32 tmp; | ||
| 231 | 345 | ||
| 232 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 346 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
| 233 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 347 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
| @@ -239,6 +353,16 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
| 239 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, | 353 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
| 240 | S_006D34_D2MODE_VBLANK_ACK(1)); | 354 | S_006D34_D2MODE_VBLANK_ACK(1)); |
| 241 | } | 355 | } |
| 356 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { | ||
| 357 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
| 358 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); | ||
| 359 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
| 360 | } | ||
| 361 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { | ||
| 362 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
| 363 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); | ||
| 364 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
| 365 | } | ||
| 242 | } else { | 366 | } else { |
| 243 | *r500_disp_int = 0; | 367 | *r500_disp_int = 0; |
| 244 | } | 368 | } |
| @@ -264,6 +388,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
| 264 | { | 388 | { |
| 265 | uint32_t status, msi_rearm; | 389 | uint32_t status, msi_rearm; |
| 266 | uint32_t r500_disp_int; | 390 | uint32_t r500_disp_int; |
| 391 | bool queue_hotplug = false; | ||
| 267 | 392 | ||
| 268 | status = rs600_irq_ack(rdev, &r500_disp_int); | 393 | status = rs600_irq_ack(rdev, &r500_disp_int); |
| 269 | if (!status && !r500_disp_int) { | 394 | if (!status && !r500_disp_int) { |
| @@ -278,8 +403,18 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
| 278 | drm_handle_vblank(rdev->ddev, 0); | 403 | drm_handle_vblank(rdev->ddev, 0); |
| 279 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) | 404 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) |
| 280 | drm_handle_vblank(rdev->ddev, 1); | 405 | drm_handle_vblank(rdev->ddev, 1); |
| 406 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { | ||
| 407 | queue_hotplug = true; | ||
| 408 | DRM_DEBUG("HPD1\n"); | ||
| 409 | } | ||
| 410 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { | ||
| 411 | queue_hotplug = true; | ||
| 412 | DRM_DEBUG("HPD2\n"); | ||
| 413 | } | ||
| 281 | status = rs600_irq_ack(rdev, &r500_disp_int); | 414 | status = rs600_irq_ack(rdev, &r500_disp_int); |
| 282 | } | 415 | } |
| 416 | if (queue_hotplug) | ||
| 417 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
| 283 | if (rdev->msi_enabled) { | 418 | if (rdev->msi_enabled) { |
| 284 | switch (rdev->family) { | 419 | switch (rdev->family) { |
| 285 | case CHIP_RS600: | 420 | case CHIP_RS600: |
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index 81308924859a..c1c8f5885cbb 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h | |||
| @@ -30,27 +30,12 @@ | |||
| 30 | 30 | ||
| 31 | /* Registers */ | 31 | /* Registers */ |
| 32 | #define R_000040_GEN_INT_CNTL 0x000040 | 32 | #define R_000040_GEN_INT_CNTL 0x000040 |
| 33 | #define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0) | 33 | #define S_000040_SCRATCH_INT_MASK(x) (((x) & 0x1) << 18) |
| 34 | #define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1) | 34 | #define G_000040_SCRATCH_INT_MASK(x) (((x) >> 18) & 0x1) |
| 35 | #define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE | 35 | #define C_000040_SCRATCH_INT_MASK 0xFFFBFFFF |
| 36 | #define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12) | 36 | #define S_000040_GUI_IDLE_MASK(x) (((x) & 0x1) << 19) |
| 37 | #define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1) | 37 | #define G_000040_GUI_IDLE_MASK(x) (((x) >> 19) & 0x1) |
| 38 | #define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF | 38 | #define C_000040_GUI_IDLE_MASK 0xFFF7FFFF |
| 39 | #define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6) | ||
| 40 | #define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1) | ||
| 41 | #define C_000040_CRTC2_VSYNC 0xFFFFFFBF | ||
| 42 | #define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7) | ||
| 43 | #define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1) | ||
| 44 | #define C_000040_SNAPSHOT2 0xFFFFFF7F | ||
| 45 | #define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9) | ||
| 46 | #define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1) | ||
| 47 | #define C_000040_CRTC2_VBLANK 0xFFFFFDFF | ||
| 48 | #define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10) | ||
| 49 | #define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1) | ||
| 50 | #define C_000040_FP2_DETECT 0xFFFFFBFF | ||
| 51 | #define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11) | ||
| 52 | #define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1) | ||
| 53 | #define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF | ||
| 54 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) | 39 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) |
| 55 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) | 40 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) |
| 56 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF | 41 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF |
| @@ -370,7 +355,90 @@ | |||
| 370 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) | 355 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) |
| 371 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) | 356 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) |
| 372 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF | 357 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF |
| 373 | 358 | #define S_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 16) | |
| 359 | #define G_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) >> 16) & 0x1) | ||
| 360 | #define C_007EDC_DACA_AUTODETECT_INTERRUPT 0xFFFEFFFF | ||
| 361 | #define S_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 17) | ||
| 362 | #define G_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) >> 17) & 0x1) | ||
| 363 | #define C_007EDC_DACB_AUTODETECT_INTERRUPT 0xFFFDFFFF | ||
| 364 | #define S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) & 0x1) << 18) | ||
| 365 | #define G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) >> 18) & 0x1) | ||
| 366 | #define C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT 0xFFFBFFFF | ||
| 367 | #define S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) & 0x1) << 19) | ||
| 368 | #define G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) >> 19) & 0x1) | ||
| 369 | #define C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT 0xFFF7FFFF | ||
| 370 | #define R_007828_DACA_AUTODETECT_CONTROL 0x007828 | ||
| 371 | #define S_007828_DACA_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
| 372 | #define G_007828_DACA_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
| 373 | #define C_007828_DACA_AUTODETECT_MODE 0xFFFFFFFC | ||
| 374 | #define S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
| 375 | #define G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
| 376 | #define C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
| 377 | #define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
| 378 | #define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
| 379 | #define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
| 380 | #define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838 | ||
| 381 | #define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
| 382 | #define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
| 383 | #define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
| 384 | #define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
| 385 | #define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
| 386 | #define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28 | ||
| 387 | #define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
| 388 | #define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
| 389 | #define C_007A28_DACB_AUTODETECT_MODE 0xFFFFFFFC | ||
| 390 | #define S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
| 391 | #define G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
| 392 | #define C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
| 393 | #define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
| 394 | #define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
| 395 | #define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
| 396 | #define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38 | ||
| 397 | #define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
| 398 | #define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
| 399 | #define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
| 400 | #define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
| 401 | #define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
| 402 | #define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00 | ||
| 403 | #define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0) | ||
| 404 | #define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1) | ||
| 405 | #define C_007D00_DC_HOT_PLUG_DETECT1_EN 0xFFFFFFFE | ||
| 406 | #define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0x007D04 | ||
| 407 | #define S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) & 0x1) << 0) | ||
| 408 | #define G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
| 409 | #define C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0xFFFFFFFE | ||
| 410 | #define S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) & 0x1) << 1) | ||
| 411 | #define G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) >> 1) & 0x1) | ||
| 412 | #define C_007D04_DC_HOT_PLUG_DETECT1_SENSE 0xFFFFFFFD | ||
| 413 | #define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL 0x007D08 | ||
| 414 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x) (((x) & 0x1) << 0) | ||
| 415 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK 0xFFFFFFFE | ||
| 416 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
| 417 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
| 418 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY 0xFFFFFEFF | ||
| 419 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) & 0x1) << 16) | ||
| 420 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) >> 16) & 0x1) | ||
| 421 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_EN 0xFFFEFFFF | ||
| 422 | #define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL 0x007D10 | ||
| 423 | #define S_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) & 0x1) << 0) | ||
| 424 | #define G_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) >> 0) & 0x1) | ||
| 425 | #define C_007D10_DC_HOT_PLUG_DETECT2_EN 0xFFFFFFFE | ||
| 426 | #define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0x007D14 | ||
| 427 | #define S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) & 0x1) << 0) | ||
| 428 | #define G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
| 429 | #define C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0xFFFFFFFE | ||
| 430 | #define S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) & 0x1) << 1) | ||
| 431 | #define G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) >> 1) & 0x1) | ||
| 432 | #define C_007D14_DC_HOT_PLUG_DETECT2_SENSE 0xFFFFFFFD | ||
| 433 | #define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL 0x007D18 | ||
| 434 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x) (((x) & 0x1) << 0) | ||
| 435 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK 0xFFFFFFFE | ||
| 436 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
| 437 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
| 438 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY 0xFFFFFEFF | ||
| 439 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) | ||
| 440 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) | ||
| 441 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF | ||
| 374 | 442 | ||
| 375 | /* MC registers */ | 443 | /* MC registers */ |
| 376 | #define R_000000_MC_STATUS 0x000000 | 444 | #define R_000000_MC_STATUS 0x000000 |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index e49879ce95f9..a49e791db0b0 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
| @@ -43,16 +43,41 @@ | |||
| 43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) | 43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) |
| 44 | 44 | ||
| 45 | /* AUX CH addresses */ | 45 | /* AUX CH addresses */ |
| 46 | #define DP_LINK_BW_SET 0x100 | 46 | /* DPCD */ |
| 47 | #define DP_DPCD_REV 0x000 | ||
| 48 | |||
| 49 | #define DP_MAX_LINK_RATE 0x001 | ||
| 50 | |||
| 51 | #define DP_MAX_LANE_COUNT 0x002 | ||
| 52 | # define DP_MAX_LANE_COUNT_MASK 0x1f | ||
| 53 | # define DP_ENHANCED_FRAME_CAP (1 << 7) | ||
| 54 | |||
| 55 | #define DP_MAX_DOWNSPREAD 0x003 | ||
| 56 | # define DP_NO_AUX_HANDSHAKE_LINK_TRAINING (1 << 6) | ||
| 57 | |||
| 58 | #define DP_NORP 0x004 | ||
| 59 | |||
| 60 | #define DP_DOWNSTREAMPORT_PRESENT 0x005 | ||
| 61 | # define DP_DWN_STRM_PORT_PRESENT (1 << 0) | ||
| 62 | # define DP_DWN_STRM_PORT_TYPE_MASK 0x06 | ||
| 63 | /* 00b = DisplayPort */ | ||
| 64 | /* 01b = Analog */ | ||
| 65 | /* 10b = TMDS or HDMI */ | ||
| 66 | /* 11b = Other */ | ||
| 67 | # define DP_FORMAT_CONVERSION (1 << 3) | ||
| 68 | |||
| 69 | #define DP_MAIN_LINK_CHANNEL_CODING 0x006 | ||
| 70 | |||
| 71 | /* link configuration */ | ||
| 72 | #define DP_LINK_BW_SET 0x100 | ||
| 47 | # define DP_LINK_BW_1_62 0x06 | 73 | # define DP_LINK_BW_1_62 0x06 |
| 48 | # define DP_LINK_BW_2_7 0x0a | 74 | # define DP_LINK_BW_2_7 0x0a |
| 49 | 75 | ||
| 50 | #define DP_LANE_COUNT_SET 0x101 | 76 | #define DP_LANE_COUNT_SET 0x101 |
| 51 | # define DP_LANE_COUNT_MASK 0x0f | 77 | # define DP_LANE_COUNT_MASK 0x0f |
| 52 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) | 78 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) |
| 53 | 79 | ||
| 54 | #define DP_TRAINING_PATTERN_SET 0x102 | 80 | #define DP_TRAINING_PATTERN_SET 0x102 |
| 55 | |||
| 56 | # define DP_TRAINING_PATTERN_DISABLE 0 | 81 | # define DP_TRAINING_PATTERN_DISABLE 0 |
| 57 | # define DP_TRAINING_PATTERN_1 1 | 82 | # define DP_TRAINING_PATTERN_1 1 |
| 58 | # define DP_TRAINING_PATTERN_2 2 | 83 | # define DP_TRAINING_PATTERN_2 2 |
| @@ -102,11 +127,14 @@ | |||
| 102 | 127 | ||
| 103 | #define DP_LANE0_1_STATUS 0x202 | 128 | #define DP_LANE0_1_STATUS 0x202 |
| 104 | #define DP_LANE2_3_STATUS 0x203 | 129 | #define DP_LANE2_3_STATUS 0x203 |
| 105 | |||
| 106 | # define DP_LANE_CR_DONE (1 << 0) | 130 | # define DP_LANE_CR_DONE (1 << 0) |
| 107 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) | 131 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) |
| 108 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) | 132 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) |
| 109 | 133 | ||
| 134 | #define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE | \ | ||
| 135 | DP_LANE_CHANNEL_EQ_DONE | \ | ||
| 136 | DP_LANE_SYMBOL_LOCKED) | ||
| 137 | |||
| 110 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 | 138 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 |
| 111 | 139 | ||
| 112 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) | 140 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) |
| @@ -120,15 +148,18 @@ | |||
| 120 | 148 | ||
| 121 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 | 149 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 |
| 122 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 | 150 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 |
| 123 | 151 | # define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | |
| 124 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | 152 | # define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 |
| 125 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 | 153 | # define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c |
| 126 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c | 154 | # define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 |
| 127 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 | 155 | # define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 |
| 128 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 | 156 | # define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 |
| 129 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 | 157 | # define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 |
| 130 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 | 158 | # define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 |
| 131 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 | 159 | |
| 160 | #define DP_SET_POWER 0x600 | ||
| 161 | # define DP_SET_POWER_D0 0x1 | ||
| 162 | # define DP_SET_POWER_D3 0x2 | ||
| 132 | 163 | ||
| 133 | #define MODE_I2C_START 1 | 164 | #define MODE_I2C_START 1 |
| 134 | #define MODE_I2C_WRITE 2 | 165 | #define MODE_I2C_WRITE 2 |
