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