drm/radeon: introduce kernel modesetting for radeon hardware
[linux-2.6-block.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
97static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
98{
99 struct drm_device *dev = encoder->dev;
100 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
101 struct drm_display_mode *mode = NULL;
102 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
103
104 if (native_mode->panel_xres != 0 &&
105 native_mode->panel_yres != 0 &&
106 native_mode->dotclock != 0) {
107 mode = drm_mode_create(dev);
108
109 mode->hdisplay = native_mode->panel_xres;
110 mode->vdisplay = native_mode->panel_yres;
111
112 mode->htotal = mode->hdisplay + native_mode->hblank;
113 mode->hsync_start = mode->hdisplay + native_mode->hoverplus;
114 mode->hsync_end = mode->hsync_start + native_mode->hsync_width;
115 mode->vtotal = mode->vdisplay + native_mode->vblank;
116 mode->vsync_start = mode->vdisplay + native_mode->voverplus;
117 mode->vsync_end = mode->vsync_start + native_mode->vsync_width;
118 mode->clock = native_mode->dotclock;
119 mode->flags = 0;
120
121 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
122 drm_mode_set_name(mode);
123
124 DRM_DEBUG("Adding native panel mode %s\n", mode->name);
125 }
126 return mode;
127}
128
129int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
130 uint64_t val)
131{
132 return 0;
133}
134
135
136static int radeon_lvds_get_modes(struct drm_connector *connector)
137{
138 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
139 struct drm_encoder *encoder;
140 int ret = 0;
141 struct drm_display_mode *mode;
142
143 if (radeon_connector->ddc_bus) {
144 ret = radeon_ddc_get_modes(radeon_connector);
145 if (ret > 0) {
146 return ret;
147 }
148 }
149
150 encoder = radeon_best_single_encoder(connector);
151 if (!encoder)
152 return 0;
153
154 /* we have no EDID modes */
155 mode = radeon_fp_native_mode(encoder);
156 if (mode) {
157 ret = 1;
158 drm_mode_probed_add(connector, mode);
159 }
160 return ret;
161}
162
163static int radeon_lvds_mode_valid(struct drm_connector *connector,
164 struct drm_display_mode *mode)
165{
166 return MODE_OK;
167}
168
169static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
170{
171 enum drm_connector_status ret = connector_status_connected;
172 /* check acpi lid status ??? */
173 radeon_connector_update_scratch_regs(connector, ret);
174 return ret;
175}
176
177static void radeon_connector_destroy(struct drm_connector *connector)
178{
179 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
180
181 if (radeon_connector->ddc_bus)
182 radeon_i2c_destroy(radeon_connector->ddc_bus);
183 kfree(radeon_connector->con_priv);
184 drm_sysfs_connector_remove(connector);
185 drm_connector_cleanup(connector);
186 kfree(connector);
187}
188
189struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
190 .get_modes = radeon_lvds_get_modes,
191 .mode_valid = radeon_lvds_mode_valid,
192 .best_encoder = radeon_best_single_encoder,
193};
194
195struct drm_connector_funcs radeon_lvds_connector_funcs = {
196 .dpms = drm_helper_connector_dpms,
197 .detect = radeon_lvds_detect,
198 .fill_modes = drm_helper_probe_single_connector_modes,
199 .destroy = radeon_connector_destroy,
200 .set_property = radeon_connector_set_property,
201};
202
203static int radeon_vga_get_modes(struct drm_connector *connector)
204{
205 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
206 int ret;
207
208 ret = radeon_ddc_get_modes(radeon_connector);
209
210 return ret;
211}
212
213static int radeon_vga_mode_valid(struct drm_connector *connector,
214 struct drm_display_mode *mode)
215{
216
217 return MODE_OK;
218}
219
220static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
221{
222 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
223 struct drm_encoder *encoder;
224 struct drm_encoder_helper_funcs *encoder_funcs;
225 bool dret;
226 enum drm_connector_status ret = connector_status_disconnected;
227
228 radeon_i2c_do_lock(radeon_connector, 1);
229 dret = radeon_ddc_probe(radeon_connector);
230 radeon_i2c_do_lock(radeon_connector, 0);
231 if (dret)
232 ret = connector_status_connected;
233 else {
234 /* if EDID fails to a load detect */
235 encoder = radeon_best_single_encoder(connector);
236 if (!encoder)
237 ret = connector_status_disconnected;
238 else {
239 encoder_funcs = encoder->helper_private;
240 ret = encoder_funcs->detect(encoder, connector);
241 }
242 }
243
244 radeon_connector_update_scratch_regs(connector, ret);
245 return ret;
246}
247
248struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
249 .get_modes = radeon_vga_get_modes,
250 .mode_valid = radeon_vga_mode_valid,
251 .best_encoder = radeon_best_single_encoder,
252};
253
254struct drm_connector_funcs radeon_vga_connector_funcs = {
255 .dpms = drm_helper_connector_dpms,
256 .detect = radeon_vga_detect,
257 .fill_modes = drm_helper_probe_single_connector_modes,
258 .destroy = radeon_connector_destroy,
259 .set_property = radeon_connector_set_property,
260};
261
262static int radeon_dvi_get_modes(struct drm_connector *connector)
263{
264 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
265 int ret;
266
267 ret = radeon_ddc_get_modes(radeon_connector);
268 /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */
269 radeon_connector_update_scratch_regs(connector, connector_status_connected);
270 return ret;
271}
272
273static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
274{
275 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
276 struct drm_encoder *encoder;
277 struct drm_encoder_helper_funcs *encoder_funcs;
278 struct drm_mode_object *obj;
279 int i;
280 enum drm_connector_status ret = connector_status_disconnected;
281 bool dret;
282
283 radeon_i2c_do_lock(radeon_connector, 1);
284 dret = radeon_ddc_probe(radeon_connector);
285 radeon_i2c_do_lock(radeon_connector, 0);
286 if (dret)
287 ret = connector_status_connected;
288 else {
289 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
290 if (connector->encoder_ids[i] == 0)
291 break;
292
293 obj = drm_mode_object_find(connector->dev,
294 connector->encoder_ids[i],
295 DRM_MODE_OBJECT_ENCODER);
296 if (!obj)
297 continue;
298
299 encoder = obj_to_encoder(obj);
300
301 encoder_funcs = encoder->helper_private;
302 if (encoder_funcs->detect) {
303 ret = encoder_funcs->detect(encoder, connector);
304 if (ret == connector_status_connected) {
305 radeon_connector->use_digital = 0;
306 break;
307 }
308 }
309 }
310 }
311
312 /* updated in get modes as well since we need to know if it's analog or digital */
313 radeon_connector_update_scratch_regs(connector, ret);
314 return ret;
315}
316
317/* okay need to be smart in here about which encoder to pick */
318struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
319{
320 int enc_id = connector->encoder_ids[0];
321 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
322 struct drm_mode_object *obj;
323 struct drm_encoder *encoder;
324 int i;
325 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
326 if (connector->encoder_ids[i] == 0)
327 break;
328
329 obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
330 if (!obj)
331 continue;
332
333 encoder = obj_to_encoder(obj);
334
335 if (radeon_connector->use_digital) {
336 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
337 return encoder;
338 } else {
339 if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
340 encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
341 return encoder;
342 }
343 }
344
345 /* see if we have a default encoder TODO */
346
347 /* then check use digitial */
348 /* pick the first one */
349 if (enc_id) {
350 obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
351 if (!obj)
352 return NULL;
353 encoder = obj_to_encoder(obj);
354 return encoder;
355 }
356 return NULL;
357}
358
359struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
360 .get_modes = radeon_dvi_get_modes,
361 .mode_valid = radeon_vga_mode_valid,
362 .best_encoder = radeon_dvi_encoder,
363};
364
365struct drm_connector_funcs radeon_dvi_connector_funcs = {
366 .dpms = drm_helper_connector_dpms,
367 .detect = radeon_dvi_detect,
368 .fill_modes = drm_helper_probe_single_connector_modes,
369 .set_property = radeon_connector_set_property,
370 .destroy = radeon_connector_destroy,
371};
372
373void
374radeon_add_atom_connector(struct drm_device *dev,
375 uint32_t connector_id,
376 uint32_t supported_device,
377 int connector_type,
378 struct radeon_i2c_bus_rec *i2c_bus,
379 bool linkb,
380 uint32_t igp_lane_info)
381{
382 struct drm_connector *connector;
383 struct radeon_connector *radeon_connector;
384 struct radeon_connector_atom_dig *radeon_dig_connector;
385 uint32_t subpixel_order = SubPixelNone;
386
387 /* fixme - tv/cv/din */
388 if ((connector_type == DRM_MODE_CONNECTOR_Unknown) ||
389 (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
390 (connector_type == DRM_MODE_CONNECTOR_Composite) ||
391 (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
392 return;
393
394 /* see if we already added it */
395 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
396 radeon_connector = to_radeon_connector(connector);
397 if (radeon_connector->connector_id == connector_id) {
398 radeon_connector->devices |= supported_device;
399 return;
400 }
401 }
402
403 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
404 if (!radeon_connector)
405 return;
406
407 connector = &radeon_connector->base;
408
409 radeon_connector->connector_id = connector_id;
410 radeon_connector->devices = supported_device;
411 switch (connector_type) {
412 case DRM_MODE_CONNECTOR_VGA:
413 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
414 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
415 if (i2c_bus->valid) {
416 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
417 if (!radeon_connector->ddc_bus)
418 goto failed;
419 }
420 break;
421 case DRM_MODE_CONNECTOR_DVIA:
422 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
423 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
424 if (i2c_bus->valid) {
425 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
426 if (!radeon_connector->ddc_bus)
427 goto failed;
428 }
429 break;
430 case DRM_MODE_CONNECTOR_DVII:
431 case DRM_MODE_CONNECTOR_DVID:
432 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
433 if (!radeon_dig_connector)
434 goto failed;
435 radeon_dig_connector->linkb = linkb;
436 radeon_dig_connector->igp_lane_info = igp_lane_info;
437 radeon_connector->con_priv = radeon_dig_connector;
438 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
439 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
440 if (i2c_bus->valid) {
441 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
442 if (!radeon_connector->ddc_bus)
443 goto failed;
444 }
445 subpixel_order = SubPixelHorizontalRGB;
446 break;
447 case DRM_MODE_CONNECTOR_HDMIA:
448 case DRM_MODE_CONNECTOR_HDMIB:
449 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
450 if (!radeon_dig_connector)
451 goto failed;
452 radeon_dig_connector->linkb = linkb;
453 radeon_dig_connector->igp_lane_info = igp_lane_info;
454 radeon_connector->con_priv = radeon_dig_connector;
455 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
456 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
457 if (i2c_bus->valid) {
458 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
459 if (!radeon_connector->ddc_bus)
460 goto failed;
461 }
462 subpixel_order = SubPixelHorizontalRGB;
463 break;
464 case DRM_MODE_CONNECTOR_DisplayPort:
465 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
466 if (!radeon_dig_connector)
467 goto failed;
468 radeon_dig_connector->linkb = linkb;
469 radeon_dig_connector->igp_lane_info = igp_lane_info;
470 radeon_connector->con_priv = radeon_dig_connector;
471 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
472 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
473 if (i2c_bus->valid) {
474 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
475 if (!radeon_connector->ddc_bus)
476 goto failed;
477 }
478 subpixel_order = SubPixelHorizontalRGB;
479 break;
480 case DRM_MODE_CONNECTOR_SVIDEO:
481 case DRM_MODE_CONNECTOR_Composite:
482 case DRM_MODE_CONNECTOR_9PinDIN:
483 break;
484 case DRM_MODE_CONNECTOR_LVDS:
485 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
486 if (!radeon_dig_connector)
487 goto failed;
488 radeon_dig_connector->linkb = linkb;
489 radeon_dig_connector->igp_lane_info = igp_lane_info;
490 radeon_connector->con_priv = radeon_dig_connector;
491 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
492 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
493 if (i2c_bus->valid) {
494 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
495 if (!radeon_connector->ddc_bus)
496 goto failed;
497 }
498 subpixel_order = SubPixelHorizontalRGB;
499 break;
500 }
501
502 connector->display_info.subpixel_order = subpixel_order;
503 drm_sysfs_connector_add(connector);
504 return;
505
506failed:
507 if (radeon_connector->ddc_bus)
508 radeon_i2c_destroy(radeon_connector->ddc_bus);
509 drm_connector_cleanup(connector);
510 kfree(connector);
511}
512
513void
514radeon_add_legacy_connector(struct drm_device *dev,
515 uint32_t connector_id,
516 uint32_t supported_device,
517 int connector_type,
518 struct radeon_i2c_bus_rec *i2c_bus)
519{
520 struct drm_connector *connector;
521 struct radeon_connector *radeon_connector;
522 uint32_t subpixel_order = SubPixelNone;
523
524 /* fixme - tv/cv/din */
525 if ((connector_type == DRM_MODE_CONNECTOR_Unknown) ||
526 (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
527 (connector_type == DRM_MODE_CONNECTOR_Composite) ||
528 (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
529 return;
530
531 /* see if we already added it */
532 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
533 radeon_connector = to_radeon_connector(connector);
534 if (radeon_connector->connector_id == connector_id) {
535 radeon_connector->devices |= supported_device;
536 return;
537 }
538 }
539
540 radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
541 if (!radeon_connector)
542 return;
543
544 connector = &radeon_connector->base;
545
546 radeon_connector->connector_id = connector_id;
547 radeon_connector->devices = supported_device;
548 switch (connector_type) {
549 case DRM_MODE_CONNECTOR_VGA:
550 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
551 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
552 if (i2c_bus->valid) {
553 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
554 if (!radeon_connector->ddc_bus)
555 goto failed;
556 }
557 break;
558 case DRM_MODE_CONNECTOR_DVIA:
559 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
560 drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
561 if (i2c_bus->valid) {
562 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
563 if (!radeon_connector->ddc_bus)
564 goto failed;
565 }
566 break;
567 case DRM_MODE_CONNECTOR_DVII:
568 case DRM_MODE_CONNECTOR_DVID:
569 drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
570 drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
571 if (i2c_bus->valid) {
572 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
573 if (!radeon_connector->ddc_bus)
574 goto failed;
575 }
576 subpixel_order = SubPixelHorizontalRGB;
577 break;
578 case DRM_MODE_CONNECTOR_SVIDEO:
579 case DRM_MODE_CONNECTOR_Composite:
580 case DRM_MODE_CONNECTOR_9PinDIN:
581 break;
582 case DRM_MODE_CONNECTOR_LVDS:
583 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
584 drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
585 if (i2c_bus->valid) {
586 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
587 if (!radeon_connector->ddc_bus)
588 goto failed;
589 }
590 subpixel_order = SubPixelHorizontalRGB;
591 break;
592 }
593
594 connector->display_info.subpixel_order = subpixel_order;
595 drm_sysfs_connector_add(connector);
596 return;
597
598failed:
599 if (radeon_connector->ddc_bus)
600 radeon_i2c_destroy(radeon_connector->ddc_bus);
601 drm_connector_cleanup(connector);
602 kfree(connector);
603}