drm/radeon/kms: add common scaled modes for TV and LVDS
[GitHub/mt8127/android_kernel_alcatel_ttab.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)) {
210 if (common_modes[i].w >= native_mode->panel_xres &&
211 common_modes[i].h >= native_mode->panel_yres)
212 continue;
213 }
214 if (common_modes[i].w < 320 || common_modes[i].h < 200)
215 continue;
216
217 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false);
218 drm_mode_probed_add(connector, mode);
219 }
220}
221
771fe6b9
JG
222int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
223 uint64_t val)
224{
225 return 0;
226}
227
228
229static int radeon_lvds_get_modes(struct drm_connector *connector)
230{
231 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
232 struct drm_encoder *encoder;
233 int ret = 0;
234 struct drm_display_mode *mode;
235
236 if (radeon_connector->ddc_bus) {
237 ret = radeon_ddc_get_modes(radeon_connector);
238 if (ret > 0) {
239 return ret;
240 }
241 }
242
243 encoder = radeon_best_single_encoder(connector);
244 if (!encoder)
245 return 0;
246
247 /* we have no EDID modes */
248 mode = radeon_fp_native_mode(encoder);
249 if (mode) {
250 ret = 1;
251 drm_mode_probed_add(connector, mode);
252 }
923f6848
AD
253
254 /* add scaled modes */
255 radeon_add_common_modes(encoder, connector);
256
771fe6b9
JG
257 return ret;
258}
259
260static int radeon_lvds_mode_valid(struct drm_connector *connector,
261 struct drm_display_mode *mode)
262{
263 return MODE_OK;
264}
265
266static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
267{
268 enum drm_connector_status ret = connector_status_connected;
269 /* check acpi lid status ??? */
270 radeon_connector_update_scratch_regs(connector, ret);
271 return ret;
272}
273
274static void radeon_connector_destroy(struct drm_connector *connector)
275{
276 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
277
278 if (radeon_connector->ddc_bus)
279 radeon_i2c_destroy(radeon_connector->ddc_bus);
280 kfree(radeon_connector->con_priv);
281 drm_sysfs_connector_remove(connector);
282 drm_connector_cleanup(connector);
283 kfree(connector);
284}
285
286struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
287 .get_modes = radeon_lvds_get_modes,
288 .mode_valid = radeon_lvds_mode_valid,
289 .best_encoder = radeon_best_single_encoder,
290};
291
292struct drm_connector_funcs radeon_lvds_connector_funcs = {
293 .dpms = drm_helper_connector_dpms,
294 .detect = radeon_lvds_detect,
295 .fill_modes = drm_helper_probe_single_connector_modes,
296 .destroy = radeon_connector_destroy,
297 .set_property = radeon_connector_set_property,
298};
299
300static int radeon_vga_get_modes(struct drm_connector *connector)
301{
302 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
303 int ret;
304
305 ret = radeon_ddc_get_modes(radeon_connector);
306
307 return ret;
308}
309
310static int radeon_vga_mode_valid(struct drm_connector *connector,
311 struct drm_display_mode *mode)
312{
771fe6b9
JG
313 return MODE_OK;
314}
315
316static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
317{
318 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
319 struct drm_encoder *encoder;
320 struct drm_encoder_helper_funcs *encoder_funcs;
321 bool dret;
322 enum drm_connector_status ret = connector_status_disconnected;
323
4ce001ab
DA
324 encoder = radeon_best_single_encoder(connector);
325 if (!encoder)
326 ret = connector_status_disconnected;
327
771fe6b9
JG
328 radeon_i2c_do_lock(radeon_connector, 1);
329 dret = radeon_ddc_probe(radeon_connector);
330 radeon_i2c_do_lock(radeon_connector, 0);
331 if (dret)
332 ret = connector_status_connected;
333 else {
4ce001ab
DA
334 encoder_funcs = encoder->helper_private;
335 ret = encoder_funcs->detect(encoder, connector);
771fe6b9
JG
336 }
337
4ce001ab
DA
338 if (ret == connector_status_connected)
339 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
771fe6b9
JG
340 radeon_connector_update_scratch_regs(connector, ret);
341 return ret;
342}
343
344struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
345 .get_modes = radeon_vga_get_modes,
346 .mode_valid = radeon_vga_mode_valid,
347 .best_encoder = radeon_best_single_encoder,
348};
349
350struct drm_connector_funcs radeon_vga_connector_funcs = {
351 .dpms = drm_helper_connector_dpms,
352 .detect = radeon_vga_detect,
353 .fill_modes = drm_helper_probe_single_connector_modes,
354 .destroy = radeon_connector_destroy,
355 .set_property = radeon_connector_set_property,
356};
357
4ce001ab
DA
358static int radeon_tv_get_modes(struct drm_connector *connector)
359{
360 struct drm_device *dev = connector->dev;
923f6848 361 struct radeon_device *rdev = dev->dev_private;
4ce001ab 362 struct drm_display_mode *tv_mode;
923f6848 363 struct drm_encoder *encoder;
4ce001ab 364
923f6848
AD
365 encoder = radeon_best_single_encoder(connector);
366 if (!encoder)
367 return 0;
4ce001ab 368
923f6848
AD
369 /* avivo chips can scale any mode */
370 if (rdev->family >= CHIP_RS600)
371 /* add scaled modes */
372 radeon_add_common_modes(encoder, connector);
373 else {
374 /* only 800x600 is supported right now on pre-avivo chips */
375 tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false);
376 tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
377 drm_mode_probed_add(connector, tv_mode);
378 }
4ce001ab
DA
379 return 1;
380}
381
382static int radeon_tv_mode_valid(struct drm_connector *connector,
383 struct drm_display_mode *mode)
384{
385 return MODE_OK;
386}
387
388static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
389{
390 struct drm_encoder *encoder;
391 struct drm_encoder_helper_funcs *encoder_funcs;
392 int ret;
393
394 encoder = radeon_best_single_encoder(connector);
395 if (!encoder)
396 ret = connector_status_disconnected;
397 else {
398 encoder_funcs = encoder->helper_private;
399 ret = encoder_funcs->detect(encoder, connector);
400 }
401 if (ret == connector_status_connected)
402 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
403 radeon_connector_update_scratch_regs(connector, ret);
404 return ret;
405}
406
407struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
408 .get_modes = radeon_tv_get_modes,
409 .mode_valid = radeon_tv_mode_valid,
410 .best_encoder = radeon_best_single_encoder,
411};
412
413struct drm_connector_funcs radeon_tv_connector_funcs = {
414 .dpms = drm_helper_connector_dpms,
415 .detect = radeon_tv_detect,
416 .fill_modes = drm_helper_probe_single_connector_modes,
417 .destroy = radeon_connector_destroy,
418 .set_property = radeon_connector_set_property,
419};
420
771fe6b9
JG
421static int radeon_dvi_get_modes(struct drm_connector *connector)
422{
423 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
424 int ret;
425
426 ret = radeon_ddc_get_modes(radeon_connector);
771fe6b9
JG
427 return ret;
428}
429
4ce001ab
DA
430/*
431 * DVI is complicated
432 * Do a DDC probe, if DDC probe passes, get the full EDID so
433 * we can do analog/digital monitor detection at this point.
434 * If the monitor is an analog monitor or we got no DDC,
435 * we need to find the DAC encoder object for this connector.
436 * If we got no DDC, we do load detection on the DAC encoder object.
437 * If we got analog DDC or load detection passes on the DAC encoder
438 * we have to check if this analog encoder is shared with anyone else (TV)
439 * if its shared we have to set the other connector to disconnected.
440 */
771fe6b9
JG
441static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
442{
443 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
4ce001ab 444 struct drm_encoder *encoder = NULL;
771fe6b9
JG
445 struct drm_encoder_helper_funcs *encoder_funcs;
446 struct drm_mode_object *obj;
447 int i;
448 enum drm_connector_status ret = connector_status_disconnected;
449 bool dret;
450
451 radeon_i2c_do_lock(radeon_connector, 1);
452 dret = radeon_ddc_probe(radeon_connector);
453 radeon_i2c_do_lock(radeon_connector, 0);
4ce001ab
DA
454 if (dret) {
455 radeon_i2c_do_lock(radeon_connector, 1);
456 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
457 radeon_i2c_do_lock(radeon_connector, 0);
458
459 if (!radeon_connector->edid) {
460 DRM_ERROR("DDC responded but not EDID found for %s\n",
461 drm_get_connector_name(connector));
462 } else {
463 radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
464
465 /* if this isn't a digital monitor
466 then we need to make sure we don't have any
467 TV conflicts */
468 ret = connector_status_connected;
469 }
470 }
471
472 if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
473 goto out;
474
475 /* find analog encoder */
476 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
477 if (connector->encoder_ids[i] == 0)
478 break;
771fe6b9 479
4ce001ab
DA
480 obj = drm_mode_object_find(connector->dev,
481 connector->encoder_ids[i],
482 DRM_MODE_OBJECT_ENCODER);
483 if (!obj)
484 continue;
771fe6b9 485
4ce001ab 486 encoder = obj_to_encoder(obj);
771fe6b9 487
4ce001ab
DA
488 encoder_funcs = encoder->helper_private;
489 if (encoder_funcs->detect) {
490 if (ret != connector_status_connected) {
771fe6b9
JG
491 ret = encoder_funcs->detect(encoder, connector);
492 if (ret == connector_status_connected) {
4ce001ab 493 radeon_connector->use_digital = false;
771fe6b9
JG
494 }
495 }
4ce001ab 496 break;
771fe6b9
JG
497 }
498 }
499
4ce001ab
DA
500 if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
501 encoder) {
502 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
503 }
504
505out:
771fe6b9
JG
506 /* updated in get modes as well since we need to know if it's analog or digital */
507 radeon_connector_update_scratch_regs(connector, ret);
508 return ret;
509}
510
511/* okay need to be smart in here about which encoder to pick */
512struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
513{
514 int enc_id = connector->encoder_ids[0];
515 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
516 struct drm_mode_object *obj;
517 struct drm_encoder *encoder;
518 int i;
519 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
520 if (connector->encoder_ids[i] == 0)
521 break;
522
523 obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
524 if (!obj)
525 continue;
526
527 encoder = obj_to_encoder(obj);
528
4ce001ab 529 if (radeon_connector->use_digital == true) {
771fe6b9
JG
530 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
531 return encoder;
532 } else {
533 if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
534 encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
535 return encoder;
536 }
537 }
538
539 /* see if we have a default encoder TODO */
540
541 /* then check use digitial */
542 /* pick the first one */
543 if (enc_id) {
544 obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
545 if (!obj)
546 return NULL;
547 encoder = obj_to_encoder(obj);
548 return encoder;
549 }
550 return NULL;
551}
552
553struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
554 .get_modes = radeon_dvi_get_modes,
555 .mode_valid = radeon_vga_mode_valid,
556 .best_encoder = radeon_dvi_encoder,
557};
558
559struct drm_connector_funcs radeon_dvi_connector_funcs = {
560 .dpms = drm_helper_connector_dpms,
561 .detect = radeon_dvi_detect,
562 .fill_modes = drm_helper_probe_single_connector_modes,
563 .set_property = radeon_connector_set_property,
564 .destroy = radeon_connector_destroy,
565};
566
567void
568radeon_add_atom_connector(struct drm_device *dev,
569 uint32_t connector_id,
570 uint32_t supported_device,
571 int connector_type,
572 struct radeon_i2c_bus_rec *i2c_bus,
573 bool linkb,
574 uint32_t igp_lane_info)
575{
576 struct drm_connector *connector;
577 struct radeon_connector *radeon_connector;
578 struct radeon_connector_atom_dig *radeon_dig_connector;
579 uint32_t subpixel_order = SubPixelNone;
580
581 /* fixme - tv/cv/din */
4ce001ab 582 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
771fe6b9
JG
583 return;
584
585 /* see if we already added it */
586 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
587 radeon_connector = to_radeon_connector(connector);
588 if (radeon_connector->connector_id == connector_id) {
589 radeon_connector->devices |= supported_device;
590 return;
591 }
592 }
593
594 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
595 if (!radeon_connector)
596 return;
597
598 connector = &radeon_connector->base;
599
600 radeon_connector->connector_id = connector_id;
601 radeon_connector->devices = supported_device;
602 switch (connector_type) {
603 case DRM_MODE_CONNECTOR_VGA:
604 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
605 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
606 if (i2c_bus->valid) {
607 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
608 if (!radeon_connector->ddc_bus)
609 goto failed;
610 }
611 break;
612 case DRM_MODE_CONNECTOR_DVIA:
613 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
614 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
615 if (i2c_bus->valid) {
616 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
617 if (!radeon_connector->ddc_bus)
618 goto failed;
619 }
620 break;
621 case DRM_MODE_CONNECTOR_DVII:
622 case DRM_MODE_CONNECTOR_DVID:
623 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
624 if (!radeon_dig_connector)
625 goto failed;
626 radeon_dig_connector->linkb = linkb;
627 radeon_dig_connector->igp_lane_info = igp_lane_info;
628 radeon_connector->con_priv = radeon_dig_connector;
629 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
630 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
631 if (i2c_bus->valid) {
632 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
633 if (!radeon_connector->ddc_bus)
634 goto failed;
635 }
636 subpixel_order = SubPixelHorizontalRGB;
637 break;
638 case DRM_MODE_CONNECTOR_HDMIA:
639 case DRM_MODE_CONNECTOR_HDMIB:
640 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
641 if (!radeon_dig_connector)
642 goto failed;
643 radeon_dig_connector->linkb = linkb;
644 radeon_dig_connector->igp_lane_info = igp_lane_info;
645 radeon_connector->con_priv = radeon_dig_connector;
646 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
647 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
648 if (i2c_bus->valid) {
649 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
650 if (!radeon_connector->ddc_bus)
651 goto failed;
652 }
653 subpixel_order = SubPixelHorizontalRGB;
654 break;
655 case DRM_MODE_CONNECTOR_DisplayPort:
656 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
657 if (!radeon_dig_connector)
658 goto failed;
659 radeon_dig_connector->linkb = linkb;
660 radeon_dig_connector->igp_lane_info = igp_lane_info;
661 radeon_connector->con_priv = radeon_dig_connector;
662 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
663 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
664 if (i2c_bus->valid) {
665 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
666 if (!radeon_connector->ddc_bus)
667 goto failed;
668 }
669 subpixel_order = SubPixelHorizontalRGB;
670 break;
671 case DRM_MODE_CONNECTOR_SVIDEO:
672 case DRM_MODE_CONNECTOR_Composite:
673 case DRM_MODE_CONNECTOR_9PinDIN:
4ce001ab
DA
674 if (radeon_tv == 1) {
675 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
676 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
677 }
771fe6b9
JG
678 break;
679 case DRM_MODE_CONNECTOR_LVDS:
680 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
681 if (!radeon_dig_connector)
682 goto failed;
683 radeon_dig_connector->linkb = linkb;
684 radeon_dig_connector->igp_lane_info = igp_lane_info;
685 radeon_connector->con_priv = radeon_dig_connector;
686 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
687 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
688 if (i2c_bus->valid) {
689 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
690 if (!radeon_connector->ddc_bus)
691 goto failed;
692 }
693 subpixel_order = SubPixelHorizontalRGB;
694 break;
695 }
696
697 connector->display_info.subpixel_order = subpixel_order;
698 drm_sysfs_connector_add(connector);
699 return;
700
701failed:
702 if (radeon_connector->ddc_bus)
703 radeon_i2c_destroy(radeon_connector->ddc_bus);
704 drm_connector_cleanup(connector);
705 kfree(connector);
706}
707
708void
709radeon_add_legacy_connector(struct drm_device *dev,
710 uint32_t connector_id,
711 uint32_t supported_device,
712 int connector_type,
713 struct radeon_i2c_bus_rec *i2c_bus)
714{
715 struct drm_connector *connector;
716 struct radeon_connector *radeon_connector;
717 uint32_t subpixel_order = SubPixelNone;
718
719 /* fixme - tv/cv/din */
4ce001ab 720 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
771fe6b9
JG
721 return;
722
723 /* see if we already added it */
724 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
725 radeon_connector = to_radeon_connector(connector);
726 if (radeon_connector->connector_id == connector_id) {
727 radeon_connector->devices |= supported_device;
728 return;
729 }
730 }
731
732 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
733 if (!radeon_connector)
734 return;
735
736 connector = &radeon_connector->base;
737
738 radeon_connector->connector_id = connector_id;
739 radeon_connector->devices = supported_device;
740 switch (connector_type) {
741 case DRM_MODE_CONNECTOR_VGA:
742 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
743 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
744 if (i2c_bus->valid) {
745 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
746 if (!radeon_connector->ddc_bus)
747 goto failed;
748 }
749 break;
750 case DRM_MODE_CONNECTOR_DVIA:
751 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
752 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
753 if (i2c_bus->valid) {
754 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
755 if (!radeon_connector->ddc_bus)
756 goto failed;
757 }
758 break;
759 case DRM_MODE_CONNECTOR_DVII:
760 case DRM_MODE_CONNECTOR_DVID:
761 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
762 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
763 if (i2c_bus->valid) {
764 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
765 if (!radeon_connector->ddc_bus)
766 goto failed;
767 }
768 subpixel_order = SubPixelHorizontalRGB;
769 break;
770 case DRM_MODE_CONNECTOR_SVIDEO:
771 case DRM_MODE_CONNECTOR_Composite:
772 case DRM_MODE_CONNECTOR_9PinDIN:
4ce001ab
DA
773 if (radeon_tv == 1) {
774 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
775 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
776 }
771fe6b9
JG
777 break;
778 case DRM_MODE_CONNECTOR_LVDS:
779 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
780 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
781 if (i2c_bus->valid) {
782 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
783 if (!radeon_connector->ddc_bus)
784 goto failed;
785 }
786 subpixel_order = SubPixelHorizontalRGB;
787 break;
788 }
789
790 connector->display_info.subpixel_order = subpixel_order;
791 drm_sysfs_connector_add(connector);
792 return;
793
794failed:
795 if (radeon_connector->ddc_bus)
796 radeon_i2c_destroy(radeon_connector->ddc_bus);
797 drm_connector_cleanup(connector);
798 kfree(connector);
799}