]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blame - drivers/gpu/drm/radeon/radeon_connectors.c
drm/radeon: Save and restore bios scratch regs during S/R
[mirror_ubuntu-kernels.git] / drivers / gpu / drm / radeon / radeon_connectors.c
CommitLineData
771fe6b9
JG
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 "drm_edid.h"
28#include "drm_crtc_helper.h"
29#include "radeon_drm.h"
30#include "radeon.h"
923f6848 31#include "atom.h"
771fe6b9
JG
32
33extern void
34radeon_combios_connected_scratch_regs(struct drm_connector *connector,
35 struct drm_encoder *encoder,
36 bool connected);
37extern void
38radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
39 struct drm_encoder *encoder,
40 bool connected);
41
42static void
43radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
44{
45 struct drm_device *dev = connector->dev;
46 struct radeon_device *rdev = dev->dev_private;
47 struct drm_encoder *best_encoder = NULL;
48 struct drm_encoder *encoder = NULL;
49 struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
50 struct drm_mode_object *obj;
51 bool connected;
52 int i;
53
54 best_encoder = connector_funcs->best_encoder(connector);
55
56 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
57 if (connector->encoder_ids[i] == 0)
58 break;
59
60 obj = drm_mode_object_find(connector->dev,
61 connector->encoder_ids[i],
62 DRM_MODE_OBJECT_ENCODER);
63 if (!obj)
64 continue;
65
66 encoder = obj_to_encoder(obj);
67
68 if ((encoder == best_encoder) && (status == connector_status_connected))
69 connected = true;
70 else
71 connected = false;
72
73 if (rdev->is_atom_bios)
74 radeon_atombios_connected_scratch_regs(connector, encoder, connected);
75 else
76 radeon_combios_connected_scratch_regs(connector, encoder, connected);
77
78 }
79}
80
81struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
82{
83 int enc_id = connector->encoder_ids[0];
84 struct drm_mode_object *obj;
85 struct drm_encoder *encoder;
86
87 /* pick the encoder ids */
88 if (enc_id) {
89 obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
90 if (!obj)
91 return NULL;
92 encoder = obj_to_encoder(obj);
93 return encoder;
94 }
95 return NULL;
96}
97
4ce001ab
DA
98
99/*
100 * radeon_connector_analog_encoder_conflict_solve
101 * - search for other connectors sharing this encoder
102 * if priority is true, then set them disconnected if this is connected
103 * if priority is false, set us disconnected if they are connected
104 */
105static enum drm_connector_status
106radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
107 struct drm_encoder *encoder,
108 enum drm_connector_status current_status,
109 bool priority)
110{
111 struct drm_device *dev = connector->dev;
112 struct drm_connector *conflict;
113 int i;
114
115 list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
116 if (conflict == connector)
117 continue;
118
119 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
120 if (conflict->encoder_ids[i] == 0)
121 break;
122
123 /* if the IDs match */
124 if (conflict->encoder_ids[i] == encoder->base.id) {
125 if (conflict->status != connector_status_connected)
126 continue;
127
128 if (priority == true) {
129 DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
130 DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
131 conflict->status = connector_status_disconnected;
132 radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
133 } else {
134 DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
135 DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict));
136 current_status = connector_status_disconnected;
137 }
138 break;
139 }
140 }
141 }
142 return current_status;
143
144}
145
771fe6b9
JG
146static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
147{
148 struct drm_device *dev = encoder->dev;
149 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
150 struct drm_display_mode *mode = NULL;
151 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
152
153 if (native_mode->panel_xres != 0 &&
154 native_mode->panel_yres != 0 &&
155 native_mode->dotclock != 0) {
156 mode = drm_mode_create(dev);
157
158 mode->hdisplay = native_mode->panel_xres;
159 mode->vdisplay = native_mode->panel_yres;
160
161 mode->htotal = mode->hdisplay + native_mode->hblank;
162 mode->hsync_start = mode->hdisplay + native_mode->hoverplus;
163 mode->hsync_end = mode->hsync_start + native_mode->hsync_width;
164 mode->vtotal = mode->vdisplay + native_mode->vblank;
165 mode->vsync_start = mode->vdisplay + native_mode->voverplus;
166 mode->vsync_end = mode->vsync_start + native_mode->vsync_width;
167 mode->clock = native_mode->dotclock;
168 mode->flags = 0;
169
170 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
171 drm_mode_set_name(mode);
172
173 DRM_DEBUG("Adding native panel mode %s\n", mode->name);
174 }
175 return mode;
176}
177
923f6848
AD
178static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector)
179{
180 struct drm_device *dev = encoder->dev;
181 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
182 struct drm_display_mode *mode = NULL;
183 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
184 int i;
185 struct mode_size {
186 int w;
187 int h;
188 } common_modes[17] = {
189 { 640, 480},
190 { 720, 480},
191 { 800, 600},
192 { 848, 480},
193 {1024, 768},
194 {1152, 768},
195 {1280, 720},
196 {1280, 800},
197 {1280, 854},
198 {1280, 960},
199 {1280, 1024},
200 {1440, 900},
201 {1400, 1050},
202 {1680, 1050},
203 {1600, 1200},
204 {1920, 1080},
205 {1920, 1200}
206 };
207
208 for (i = 0; i < 17; i++) {
209 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
fb1fbf8e
MD
210 if (common_modes[i].w > native_mode->panel_xres ||
211 common_modes[i].h > native_mode->panel_yres ||
212 (common_modes[i].w == native_mode->panel_xres &&
213 common_modes[i].h == native_mode->panel_yres))
923f6848
AD
214 continue;
215 }
216 if (common_modes[i].w < 320 || common_modes[i].h < 200)
217 continue;
218
219 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false);
220 drm_mode_probed_add(connector, mode);
221 }
222}
223
771fe6b9
JG
224int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
225 uint64_t val)
226{
227 return 0;
228}
229
230
231static int radeon_lvds_get_modes(struct drm_connector *connector)
232{
233 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
234 struct drm_encoder *encoder;
235 int ret = 0;
236 struct drm_display_mode *mode;
237
238 if (radeon_connector->ddc_bus) {
239 ret = radeon_ddc_get_modes(radeon_connector);
240 if (ret > 0) {
7747b713
AD
241 encoder = radeon_best_single_encoder(connector);
242 if (encoder)
243 /* add scaled modes */
244 radeon_add_common_modes(encoder, connector);
771fe6b9
JG
245 return ret;
246 }
247 }
248
249 encoder = radeon_best_single_encoder(connector);
250 if (!encoder)
251 return 0;
252
253 /* we have no EDID modes */
254 mode = radeon_fp_native_mode(encoder);
255 if (mode) {
256 ret = 1;
257 drm_mode_probed_add(connector, mode);
7747b713
AD
258 /* add scaled modes */
259 radeon_add_common_modes(encoder, connector);
771fe6b9 260 }
923f6848 261
771fe6b9
JG
262 return ret;
263}
264
265static int radeon_lvds_mode_valid(struct drm_connector *connector,
266 struct drm_display_mode *mode)
267{
268 return MODE_OK;
269}
270
271static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
272{
273 enum drm_connector_status ret = connector_status_connected;
274 /* check acpi lid status ??? */
275 radeon_connector_update_scratch_regs(connector, ret);
276 return ret;
277}
278
279static void radeon_connector_destroy(struct drm_connector *connector)
280{
281 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
282
283 if (radeon_connector->ddc_bus)
284 radeon_i2c_destroy(radeon_connector->ddc_bus);
285 kfree(radeon_connector->con_priv);
286 drm_sysfs_connector_remove(connector);
287 drm_connector_cleanup(connector);
288 kfree(connector);
289}
290
291struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
292 .get_modes = radeon_lvds_get_modes,
293 .mode_valid = radeon_lvds_mode_valid,
294 .best_encoder = radeon_best_single_encoder,
295};
296
297struct drm_connector_funcs radeon_lvds_connector_funcs = {
298 .dpms = drm_helper_connector_dpms,
299 .detect = radeon_lvds_detect,
300 .fill_modes = drm_helper_probe_single_connector_modes,
301 .destroy = radeon_connector_destroy,
302 .set_property = radeon_connector_set_property,
303};
304
305static int radeon_vga_get_modes(struct drm_connector *connector)
306{
307 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
308 int ret;
309
310 ret = radeon_ddc_get_modes(radeon_connector);
311
312 return ret;
313}
314
315static int radeon_vga_mode_valid(struct drm_connector *connector,
316 struct drm_display_mode *mode)
317{
771fe6b9
JG
318 return MODE_OK;
319}
320
321static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
322{
323 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
324 struct drm_encoder *encoder;
325 struct drm_encoder_helper_funcs *encoder_funcs;
326 bool dret;
327 enum drm_connector_status ret = connector_status_disconnected;
328
4ce001ab
DA
329 encoder = radeon_best_single_encoder(connector);
330 if (!encoder)
331 ret = connector_status_disconnected;
332
771fe6b9
JG
333 radeon_i2c_do_lock(radeon_connector, 1);
334 dret = radeon_ddc_probe(radeon_connector);
335 radeon_i2c_do_lock(radeon_connector, 0);
336 if (dret)
337 ret = connector_status_connected;
338 else {
4ce001ab
DA
339 encoder_funcs = encoder->helper_private;
340 ret = encoder_funcs->detect(encoder, connector);
771fe6b9
JG
341 }
342
4ce001ab
DA
343 if (ret == connector_status_connected)
344 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
771fe6b9
JG
345 radeon_connector_update_scratch_regs(connector, ret);
346 return ret;
347}
348
349struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
350 .get_modes = radeon_vga_get_modes,
351 .mode_valid = radeon_vga_mode_valid,
352 .best_encoder = radeon_best_single_encoder,
353};
354
355struct drm_connector_funcs radeon_vga_connector_funcs = {
356 .dpms = drm_helper_connector_dpms,
357 .detect = radeon_vga_detect,
358 .fill_modes = drm_helper_probe_single_connector_modes,
359 .destroy = radeon_connector_destroy,
360 .set_property = radeon_connector_set_property,
361};
362
4ce001ab
DA
363static int radeon_tv_get_modes(struct drm_connector *connector)
364{
365 struct drm_device *dev = connector->dev;
923f6848 366 struct radeon_device *rdev = dev->dev_private;
4ce001ab 367 struct drm_display_mode *tv_mode;
923f6848 368 struct drm_encoder *encoder;
4ce001ab 369
923f6848
AD
370 encoder = radeon_best_single_encoder(connector);
371 if (!encoder)
372 return 0;
4ce001ab 373
923f6848
AD
374 /* avivo chips can scale any mode */
375 if (rdev->family >= CHIP_RS600)
376 /* add scaled modes */
377 radeon_add_common_modes(encoder, connector);
378 else {
379 /* only 800x600 is supported right now on pre-avivo chips */
380 tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false);
381 tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
382 drm_mode_probed_add(connector, tv_mode);
383 }
4ce001ab
DA
384 return 1;
385}
386
387static int radeon_tv_mode_valid(struct drm_connector *connector,
388 struct drm_display_mode *mode)
389{
390 return MODE_OK;
391}
392
393static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
394{
395 struct drm_encoder *encoder;
396 struct drm_encoder_helper_funcs *encoder_funcs;
397 int ret;
398
399 encoder = radeon_best_single_encoder(connector);
400 if (!encoder)
401 ret = connector_status_disconnected;
402 else {
403 encoder_funcs = encoder->helper_private;
404 ret = encoder_funcs->detect(encoder, connector);
405 }
406 if (ret == connector_status_connected)
407 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
408 radeon_connector_update_scratch_regs(connector, ret);
409 return ret;
410}
411
412struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
413 .get_modes = radeon_tv_get_modes,
414 .mode_valid = radeon_tv_mode_valid,
415 .best_encoder = radeon_best_single_encoder,
416};
417
418struct drm_connector_funcs radeon_tv_connector_funcs = {
419 .dpms = drm_helper_connector_dpms,
420 .detect = radeon_tv_detect,
421 .fill_modes = drm_helper_probe_single_connector_modes,
422 .destroy = radeon_connector_destroy,
423 .set_property = radeon_connector_set_property,
424};
425
771fe6b9
JG
426static int radeon_dvi_get_modes(struct drm_connector *connector)
427{
428 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
429 int ret;
430
431 ret = radeon_ddc_get_modes(radeon_connector);
771fe6b9
JG
432 return ret;
433}
434
4ce001ab
DA
435/*
436 * DVI is complicated
437 * Do a DDC probe, if DDC probe passes, get the full EDID so
438 * we can do analog/digital monitor detection at this point.
439 * If the monitor is an analog monitor or we got no DDC,
440 * we need to find the DAC encoder object for this connector.
441 * If we got no DDC, we do load detection on the DAC encoder object.
442 * If we got analog DDC or load detection passes on the DAC encoder
443 * we have to check if this analog encoder is shared with anyone else (TV)
444 * if its shared we have to set the other connector to disconnected.
445 */
771fe6b9
JG
446static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
447{
448 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
4ce001ab 449 struct drm_encoder *encoder = NULL;
771fe6b9
JG
450 struct drm_encoder_helper_funcs *encoder_funcs;
451 struct drm_mode_object *obj;
452 int i;
453 enum drm_connector_status ret = connector_status_disconnected;
454 bool dret;
455
456 radeon_i2c_do_lock(radeon_connector, 1);
457 dret = radeon_ddc_probe(radeon_connector);
458 radeon_i2c_do_lock(radeon_connector, 0);
4ce001ab
DA
459 if (dret) {
460 radeon_i2c_do_lock(radeon_connector, 1);
461 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
462 radeon_i2c_do_lock(radeon_connector, 0);
463
464 if (!radeon_connector->edid) {
465 DRM_ERROR("DDC responded but not EDID found for %s\n",
466 drm_get_connector_name(connector));
467 } else {
468 radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
469
470 /* if this isn't a digital monitor
471 then we need to make sure we don't have any
472 TV conflicts */
473 ret = connector_status_connected;
474 }
475 }
476
477 if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
478 goto out;
479
480 /* find analog encoder */
481 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
482 if (connector->encoder_ids[i] == 0)
483 break;
771fe6b9 484
4ce001ab
DA
485 obj = drm_mode_object_find(connector->dev,
486 connector->encoder_ids[i],
487 DRM_MODE_OBJECT_ENCODER);
488 if (!obj)
489 continue;
771fe6b9 490
4ce001ab 491 encoder = obj_to_encoder(obj);
771fe6b9 492
4ce001ab
DA
493 encoder_funcs = encoder->helper_private;
494 if (encoder_funcs->detect) {
495 if (ret != connector_status_connected) {
771fe6b9
JG
496 ret = encoder_funcs->detect(encoder, connector);
497 if (ret == connector_status_connected) {
4ce001ab 498 radeon_connector->use_digital = false;
771fe6b9
JG
499 }
500 }
4ce001ab 501 break;
771fe6b9
JG
502 }
503 }
504
4ce001ab
DA
505 if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
506 encoder) {
507 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
508 }
509
510out:
771fe6b9
JG
511 /* updated in get modes as well since we need to know if it's analog or digital */
512 radeon_connector_update_scratch_regs(connector, ret);
513 return ret;
514}
515
516/* okay need to be smart in here about which encoder to pick */
517struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
518{
519 int enc_id = connector->encoder_ids[0];
520 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
521 struct drm_mode_object *obj;
522 struct drm_encoder *encoder;
523 int i;
524 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
525 if (connector->encoder_ids[i] == 0)
526 break;
527
528 obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
529 if (!obj)
530 continue;
531
532 encoder = obj_to_encoder(obj);
533
4ce001ab 534 if (radeon_connector->use_digital == true) {
771fe6b9
JG
535 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
536 return encoder;
537 } else {
538 if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
539 encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
540 return encoder;
541 }
542 }
543
544 /* see if we have a default encoder TODO */
545
546 /* then check use digitial */
547 /* pick the first one */
548 if (enc_id) {
549 obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
550 if (!obj)
551 return NULL;
552 encoder = obj_to_encoder(obj);
553 return encoder;
554 }
555 return NULL;
556}
557
558struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
559 .get_modes = radeon_dvi_get_modes,
560 .mode_valid = radeon_vga_mode_valid,
561 .best_encoder = radeon_dvi_encoder,
562};
563
564struct drm_connector_funcs radeon_dvi_connector_funcs = {
565 .dpms = drm_helper_connector_dpms,
566 .detect = radeon_dvi_detect,
567 .fill_modes = drm_helper_probe_single_connector_modes,
568 .set_property = radeon_connector_set_property,
569 .destroy = radeon_connector_destroy,
570};
571
572void
573radeon_add_atom_connector(struct drm_device *dev,
574 uint32_t connector_id,
575 uint32_t supported_device,
576 int connector_type,
577 struct radeon_i2c_bus_rec *i2c_bus,
578 bool linkb,
579 uint32_t igp_lane_info)
580{
581 struct drm_connector *connector;
582 struct radeon_connector *radeon_connector;
583 struct radeon_connector_atom_dig *radeon_dig_connector;
584 uint32_t subpixel_order = SubPixelNone;
585
586 /* fixme - tv/cv/din */
4ce001ab 587 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
771fe6b9
JG
588 return;
589
590 /* see if we already added it */
591 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
592 radeon_connector = to_radeon_connector(connector);
593 if (radeon_connector->connector_id == connector_id) {
594 radeon_connector->devices |= supported_device;
595 return;
596 }
597 }
598
599 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
600 if (!radeon_connector)
601 return;
602
603 connector = &radeon_connector->base;
604
605 radeon_connector->connector_id = connector_id;
606 radeon_connector->devices = supported_device;
607 switch (connector_type) {
608 case DRM_MODE_CONNECTOR_VGA:
609 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
610 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
611 if (i2c_bus->valid) {
612 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
613 if (!radeon_connector->ddc_bus)
614 goto failed;
615 }
616 break;
617 case DRM_MODE_CONNECTOR_DVIA:
618 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
619 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
620 if (i2c_bus->valid) {
621 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
622 if (!radeon_connector->ddc_bus)
623 goto failed;
624 }
625 break;
626 case DRM_MODE_CONNECTOR_DVII:
627 case DRM_MODE_CONNECTOR_DVID:
628 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
629 if (!radeon_dig_connector)
630 goto failed;
631 radeon_dig_connector->linkb = linkb;
632 radeon_dig_connector->igp_lane_info = igp_lane_info;
633 radeon_connector->con_priv = radeon_dig_connector;
634 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
635 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
636 if (i2c_bus->valid) {
637 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
638 if (!radeon_connector->ddc_bus)
639 goto failed;
640 }
641 subpixel_order = SubPixelHorizontalRGB;
642 break;
643 case DRM_MODE_CONNECTOR_HDMIA:
644 case DRM_MODE_CONNECTOR_HDMIB:
645 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
646 if (!radeon_dig_connector)
647 goto failed;
648 radeon_dig_connector->linkb = linkb;
649 radeon_dig_connector->igp_lane_info = igp_lane_info;
650 radeon_connector->con_priv = radeon_dig_connector;
651 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
652 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
653 if (i2c_bus->valid) {
654 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
655 if (!radeon_connector->ddc_bus)
656 goto failed;
657 }
658 subpixel_order = SubPixelHorizontalRGB;
659 break;
660 case DRM_MODE_CONNECTOR_DisplayPort:
661 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
662 if (!radeon_dig_connector)
663 goto failed;
664 radeon_dig_connector->linkb = linkb;
665 radeon_dig_connector->igp_lane_info = igp_lane_info;
666 radeon_connector->con_priv = radeon_dig_connector;
667 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
668 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
669 if (i2c_bus->valid) {
670 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
671 if (!radeon_connector->ddc_bus)
672 goto failed;
673 }
674 subpixel_order = SubPixelHorizontalRGB;
675 break;
676 case DRM_MODE_CONNECTOR_SVIDEO:
677 case DRM_MODE_CONNECTOR_Composite:
678 case DRM_MODE_CONNECTOR_9PinDIN:
4ce001ab
DA
679 if (radeon_tv == 1) {
680 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
681 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
682 }
771fe6b9
JG
683 break;
684 case DRM_MODE_CONNECTOR_LVDS:
685 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
686 if (!radeon_dig_connector)
687 goto failed;
688 radeon_dig_connector->linkb = linkb;
689 radeon_dig_connector->igp_lane_info = igp_lane_info;
690 radeon_connector->con_priv = radeon_dig_connector;
691 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
692 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
693 if (i2c_bus->valid) {
694 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
695 if (!radeon_connector->ddc_bus)
696 goto failed;
697 }
698 subpixel_order = SubPixelHorizontalRGB;
699 break;
700 }
701
702 connector->display_info.subpixel_order = subpixel_order;
703 drm_sysfs_connector_add(connector);
704 return;
705
706failed:
707 if (radeon_connector->ddc_bus)
708 radeon_i2c_destroy(radeon_connector->ddc_bus);
709 drm_connector_cleanup(connector);
710 kfree(connector);
711}
712
713void
714radeon_add_legacy_connector(struct drm_device *dev,
715 uint32_t connector_id,
716 uint32_t supported_device,
717 int connector_type,
718 struct radeon_i2c_bus_rec *i2c_bus)
719{
720 struct drm_connector *connector;
721 struct radeon_connector *radeon_connector;
722 uint32_t subpixel_order = SubPixelNone;
723
724 /* fixme - tv/cv/din */
4ce001ab 725 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
771fe6b9
JG
726 return;
727
728 /* see if we already added it */
729 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
730 radeon_connector = to_radeon_connector(connector);
731 if (radeon_connector->connector_id == connector_id) {
732 radeon_connector->devices |= supported_device;
733 return;
734 }
735 }
736
737 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
738 if (!radeon_connector)
739 return;
740
741 connector = &radeon_connector->base;
742
743 radeon_connector->connector_id = connector_id;
744 radeon_connector->devices = supported_device;
745 switch (connector_type) {
746 case DRM_MODE_CONNECTOR_VGA:
747 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
748 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
749 if (i2c_bus->valid) {
750 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
751 if (!radeon_connector->ddc_bus)
752 goto failed;
753 }
754 break;
755 case DRM_MODE_CONNECTOR_DVIA:
756 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
757 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
758 if (i2c_bus->valid) {
759 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
760 if (!radeon_connector->ddc_bus)
761 goto failed;
762 }
763 break;
764 case DRM_MODE_CONNECTOR_DVII:
765 case DRM_MODE_CONNECTOR_DVID:
766 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
767 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
768 if (i2c_bus->valid) {
769 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
770 if (!radeon_connector->ddc_bus)
771 goto failed;
772 }
773 subpixel_order = SubPixelHorizontalRGB;
774 break;
775 case DRM_MODE_CONNECTOR_SVIDEO:
776 case DRM_MODE_CONNECTOR_Composite:
777 case DRM_MODE_CONNECTOR_9PinDIN:
4ce001ab
DA
778 if (radeon_tv == 1) {
779 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
780 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
781 }
771fe6b9
JG
782 break;
783 case DRM_MODE_CONNECTOR_LVDS:
784 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
785 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
786 if (i2c_bus->valid) {
787 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
788 if (!radeon_connector->ddc_bus)
789 goto failed;
790 }
791 subpixel_order = SubPixelHorizontalRGB;
792 break;
793 }
794
795 connector->display_info.subpixel_order = subpixel_order;
796 drm_sysfs_connector_add(connector);
797 return;
798
799failed:
800 if (radeon_connector->ddc_bus)
801 radeon_i2c_destroy(radeon_connector->ddc_bus);
802 drm_connector_cleanup(connector);
803 kfree(connector);
804}