aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_connector.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2009-12-11 04:24:15 -0500
committerDave Airlie <airlied@redhat.com>2009-12-11 06:29:34 -0500
commit6ee738610f41b59733f63718f0bdbcba7d3a3f12 (patch)
treeeccb9f07671998c50a1bc606a54cd6f82ba43e0a /drivers/gpu/drm/nouveau/nouveau_connector.c
parentd1ede145cea25c5b6d2ebb19b167af14e374bb45 (diff)
drm/nouveau: Add DRM driver for NVIDIA GPUs
This adds a drm/kms staging non-API stable driver for GPUs from NVIDIA. This driver is a KMS-based driver and requires a compatible nouveau userspace libdrm and nouveau X.org driver. This driver requires firmware files not available in this kernel tree, interested parties can find them via the nouveau project git archive. This driver is reverse engineered, and is in no way supported by nVidia. Support for nearly the complete range of nvidia hw from nv04->g80 (nv50) is available, and the kms driver should support driving nearly all output types (displayport is under development still) along with supporting suspend/resume. This work is all from the upstream nouveau project found at nouveau.freedesktop.org. The original authors list from nouveau git tree is: Anssi Hannula <anssi.hannula@iki.fi> Ben Skeggs <bskeggs@redhat.com> Francisco Jerez <currojerez@riseup.net> Maarten Maathuis <madman2003@gmail.com> Marcin Koƛcielnicki <koriakin@0x04.net> Matthew Garrett <mjg@redhat.com> Matt Parnell <mparnell@gmail.com> Patrice Mandin <patmandin@gmail.com> Pekka Paalanen <pq@iki.fi> Xavier Chantry <shiningxc@gmail.com> along with project founder Stephane Marchesin <marchesin@icps.u-strasbg.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c824
1 files changed, 824 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
new file mode 100644
index 000000000000..032cf098fa1c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -0,0 +1,824 @@
1/*
2 * Copyright (C) 2008 Maarten Maathuis.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include "drmP.h"
28#include "drm_edid.h"
29#include "drm_crtc_helper.h"
30#include "nouveau_reg.h"
31#include "nouveau_drv.h"
32#include "nouveau_encoder.h"
33#include "nouveau_crtc.h"
34#include "nouveau_connector.h"
35#include "nouveau_hw.h"
36
37static inline struct drm_encoder_slave_funcs *
38get_slave_funcs(struct nouveau_encoder *enc)
39{
40 return to_encoder_slave(to_drm_encoder(enc))->slave_funcs;
41}
42
43static struct nouveau_encoder *
44find_encoder_by_type(struct drm_connector *connector, int type)
45{
46 struct drm_device *dev = connector->dev;
47 struct nouveau_encoder *nv_encoder;
48 struct drm_mode_object *obj;
49 int i, id;
50
51 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
52 id = connector->encoder_ids[i];
53 if (!id)
54 break;
55
56 obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
57 if (!obj)
58 continue;
59 nv_encoder = nouveau_encoder(obj_to_encoder(obj));
60
61 if (type == OUTPUT_ANY || nv_encoder->dcb->type == type)
62 return nv_encoder;
63 }
64
65 return NULL;
66}
67
68struct nouveau_connector *
69nouveau_encoder_connector_get(struct nouveau_encoder *encoder)
70{
71 struct drm_device *dev = to_drm_encoder(encoder)->dev;
72 struct drm_connector *drm_connector;
73
74 list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
75 if (drm_connector->encoder == to_drm_encoder(encoder))
76 return nouveau_connector(drm_connector);
77 }
78
79 return NULL;
80}
81
82
83static void
84nouveau_connector_destroy(struct drm_connector *drm_connector)
85{
86 struct nouveau_connector *connector = nouveau_connector(drm_connector);
87 struct drm_device *dev = connector->base.dev;
88
89 NV_DEBUG(dev, "\n");
90
91 if (!connector)
92 return;
93
94 drm_sysfs_connector_remove(drm_connector);
95 drm_connector_cleanup(drm_connector);
96 kfree(drm_connector);
97}
98
99static void
100nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
101{
102 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
103
104 if (dev_priv->card_type >= NV_50)
105 return;
106
107 *flags = 0;
108 if (NVLockVgaCrtcs(dev_priv->dev, false))
109 *flags |= 1;
110 if (nv_heads_tied(dev_priv->dev))
111 *flags |= 2;
112
113 if (*flags & 2)
114 NVSetOwner(dev_priv->dev, 0); /* necessary? */
115}
116
117static void
118nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
119{
120 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
121
122 if (dev_priv->card_type >= NV_50)
123 return;
124
125 if (flags & 2)
126 NVSetOwner(dev_priv->dev, 4);
127 if (flags & 1)
128 NVLockVgaCrtcs(dev_priv->dev, true);
129}
130
131static struct nouveau_i2c_chan *
132nouveau_connector_ddc_detect(struct drm_connector *connector,
133 struct nouveau_encoder **pnv_encoder)
134{
135 struct drm_device *dev = connector->dev;
136 uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
137 int ret, flags, i;
138
139 struct i2c_msg msgs[] = {
140 {
141 .addr = 0x50,
142 .flags = 0,
143 .len = 1,
144 .buf = out_buf,
145 },
146 {
147 .addr = 0x50,
148 .flags = I2C_M_RD,
149 .len = 1,
150 .buf = buf,
151 }
152 };
153
154 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
155 struct nouveau_i2c_chan *i2c = NULL;
156 struct nouveau_encoder *nv_encoder;
157 struct drm_mode_object *obj;
158 int id;
159
160 id = connector->encoder_ids[i];
161 if (!id)
162 break;
163
164 obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
165 if (!obj)
166 continue;
167 nv_encoder = nouveau_encoder(obj_to_encoder(obj));
168
169 if (nv_encoder->dcb->i2c_index < 0xf)
170 i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
171 if (!i2c)
172 continue;
173
174 nouveau_connector_ddc_prepare(connector, &flags);
175 ret = i2c_transfer(&i2c->adapter, msgs, 2);
176 nouveau_connector_ddc_finish(connector, flags);
177
178 if (ret == 2) {
179 *pnv_encoder = nv_encoder;
180 return i2c;
181 }
182 }
183
184 return NULL;
185}
186
187static void
188nouveau_connector_set_encoder(struct drm_connector *connector,
189 struct nouveau_encoder *nv_encoder)
190{
191 struct nouveau_connector *nv_connector = nouveau_connector(connector);
192 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
193 struct drm_device *dev = connector->dev;
194
195 if (nv_connector->detected_encoder == nv_encoder)
196 return;
197 nv_connector->detected_encoder = nv_encoder;
198
199 if (nv_encoder->dcb->type == OUTPUT_LVDS ||
200 nv_encoder->dcb->type == OUTPUT_TMDS) {
201 connector->doublescan_allowed = false;
202 connector->interlace_allowed = false;
203 } else {
204 connector->doublescan_allowed = true;
205 if (dev_priv->card_type == NV_20 ||
206 (dev_priv->card_type == NV_10 &&
207 (dev->pci_device & 0x0ff0) != 0x0100 &&
208 (dev->pci_device & 0x0ff0) != 0x0150))
209 /* HW is broken */
210 connector->interlace_allowed = false;
211 else
212 connector->interlace_allowed = true;
213 }
214
215 if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
216 drm_connector_property_set_value(connector,
217 dev->mode_config.dvi_i_subconnector_property,
218 nv_encoder->dcb->type == OUTPUT_TMDS ?
219 DRM_MODE_SUBCONNECTOR_DVID :
220 DRM_MODE_SUBCONNECTOR_DVIA);
221 }
222}
223
224static enum drm_connector_status
225nouveau_connector_detect(struct drm_connector *connector)
226{
227 struct drm_device *dev = connector->dev;
228 struct nouveau_connector *nv_connector = nouveau_connector(connector);
229 struct nouveau_encoder *nv_encoder = NULL;
230 struct nouveau_i2c_chan *i2c;
231 int type, flags;
232
233 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
234 nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
235 if (nv_encoder && nv_connector->native_mode) {
236 nouveau_connector_set_encoder(connector, nv_encoder);
237 return connector_status_connected;
238 }
239
240 i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
241 if (i2c) {
242 nouveau_connector_ddc_prepare(connector, &flags);
243 nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
244 nouveau_connector_ddc_finish(connector, flags);
245 drm_mode_connector_update_edid_property(connector,
246 nv_connector->edid);
247 if (!nv_connector->edid) {
248 NV_ERROR(dev, "DDC responded, but no EDID for %s\n",
249 drm_get_connector_name(connector));
250 return connector_status_disconnected;
251 }
252
253 if (nv_encoder->dcb->type == OUTPUT_DP &&
254 !nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
255 NV_ERROR(dev, "Detected %s, but failed init\n",
256 drm_get_connector_name(connector));
257 return connector_status_disconnected;
258 }
259
260 /* Override encoder type for DVI-I based on whether EDID
261 * says the display is digital or analog, both use the
262 * same i2c channel so the value returned from ddc_detect
263 * isn't necessarily correct.
264 */
265 if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
266 if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
267 type = OUTPUT_TMDS;
268 else
269 type = OUTPUT_ANALOG;
270
271 nv_encoder = find_encoder_by_type(connector, type);
272 if (!nv_encoder) {
273 NV_ERROR(dev, "Detected %d encoder on %s, "
274 "but no object!\n", type,
275 drm_get_connector_name(connector));
276 return connector_status_disconnected;
277 }
278 }
279
280 nouveau_connector_set_encoder(connector, nv_encoder);
281 return connector_status_connected;
282 }
283
284 nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
285 if (!nv_encoder)
286 nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
287 if (nv_encoder) {
288 struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
289 struct drm_encoder_helper_funcs *helper =
290 encoder->helper_private;
291
292 if (helper->detect(encoder, connector) ==
293 connector_status_connected) {
294 nouveau_connector_set_encoder(connector, nv_encoder);
295 return connector_status_connected;
296 }
297
298 }
299
300 return connector_status_disconnected;
301}
302
303static void
304nouveau_connector_force(struct drm_connector *connector)
305{
306 struct drm_device *dev = connector->dev;
307 struct nouveau_encoder *nv_encoder;
308 int type;
309
310 if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
311 if (connector->force == DRM_FORCE_ON_DIGITAL)
312 type = OUTPUT_TMDS;
313 else
314 type = OUTPUT_ANALOG;
315 } else
316 type = OUTPUT_ANY;
317
318 nv_encoder = find_encoder_by_type(connector, type);
319 if (!nv_encoder) {
320 NV_ERROR(dev, "can't find encoder to force %s on!\n",
321 drm_get_connector_name(connector));
322 connector->status = connector_status_disconnected;
323 return;
324 }
325
326 nouveau_connector_set_encoder(connector, nv_encoder);
327}
328
329static int
330nouveau_connector_set_property(struct drm_connector *connector,
331 struct drm_property *property, uint64_t value)
332{
333 struct nouveau_connector *nv_connector = nouveau_connector(connector);
334 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
335 struct drm_device *dev = connector->dev;
336 int ret;
337
338 /* Scaling mode */
339 if (property == dev->mode_config.scaling_mode_property) {
340 struct nouveau_crtc *nv_crtc = NULL;
341 bool modeset = false;
342
343 switch (value) {
344 case DRM_MODE_SCALE_NONE:
345 case DRM_MODE_SCALE_FULLSCREEN:
346 case DRM_MODE_SCALE_CENTER:
347 case DRM_MODE_SCALE_ASPECT:
348 break;
349 default:
350 return -EINVAL;
351 }
352
353 /* LVDS always needs gpu scaling */
354 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
355 value == DRM_MODE_SCALE_NONE)
356 return -EINVAL;
357
358 /* Changing between GPU and panel scaling requires a full
359 * modeset
360 */
361 if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) ||
362 (value == DRM_MODE_SCALE_NONE))
363 modeset = true;
364 nv_connector->scaling_mode = value;
365
366 if (connector->encoder && connector->encoder->crtc)
367 nv_crtc = nouveau_crtc(connector->encoder->crtc);
368 if (!nv_crtc)
369 return 0;
370
371 if (modeset || !nv_crtc->set_scale) {
372 ret = drm_crtc_helper_set_mode(&nv_crtc->base,
373 &nv_crtc->base.mode,
374 nv_crtc->base.x,
375 nv_crtc->base.y, NULL);
376 if (!ret)
377 return -EINVAL;
378 } else {
379 ret = nv_crtc->set_scale(nv_crtc, value, true);
380 if (ret)
381 return ret;
382 }
383
384 return 0;
385 }
386
387 /* Dithering */
388 if (property == dev->mode_config.dithering_mode_property) {
389 struct nouveau_crtc *nv_crtc = NULL;
390
391 if (value == DRM_MODE_DITHERING_ON)
392 nv_connector->use_dithering = true;
393 else
394 nv_connector->use_dithering = false;
395
396 if (connector->encoder && connector->encoder->crtc)
397 nv_crtc = nouveau_crtc(connector->encoder->crtc);
398
399 if (!nv_crtc || !nv_crtc->set_dither)
400 return 0;
401
402 return nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering,
403 true);
404 }
405
406 if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV)
407 return get_slave_funcs(nv_encoder)->
408 set_property(to_drm_encoder(nv_encoder), connector, property, value);
409
410 return -EINVAL;
411}
412
413static struct drm_display_mode *
414nouveau_connector_native_mode(struct nouveau_connector *connector)
415{
416 struct drm_device *dev = connector->base.dev;
417 struct drm_display_mode *mode, *largest = NULL;
418 int high_w = 0, high_h = 0, high_v = 0;
419
420 /* Use preferred mode if there is one.. */
421 list_for_each_entry(mode, &connector->base.probed_modes, head) {
422 if (mode->type & DRM_MODE_TYPE_PREFERRED) {
423 NV_DEBUG(dev, "native mode from preferred\n");
424 return drm_mode_duplicate(dev, mode);
425 }
426 }
427
428 /* Otherwise, take the resolution with the largest width, then height,
429 * then vertical refresh
430 */
431 list_for_each_entry(mode, &connector->base.probed_modes, head) {
432 if (mode->hdisplay < high_w)
433 continue;
434
435 if (mode->hdisplay == high_w && mode->vdisplay < high_h)
436 continue;
437
438 if (mode->hdisplay == high_w && mode->vdisplay == high_h &&
439 mode->vrefresh < high_v)
440 continue;
441
442 high_w = mode->hdisplay;
443 high_h = mode->vdisplay;
444 high_v = mode->vrefresh;
445 largest = mode;
446 }
447
448 NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n",
449 high_w, high_h, high_v);
450 return largest ? drm_mode_duplicate(dev, largest) : NULL;
451}
452
453struct moderec {
454 int hdisplay;
455 int vdisplay;
456};
457
458static struct moderec scaler_modes[] = {
459 { 1920, 1200 },
460 { 1920, 1080 },
461 { 1680, 1050 },
462 { 1600, 1200 },
463 { 1400, 1050 },
464 { 1280, 1024 },
465 { 1280, 960 },
466 { 1152, 864 },
467 { 1024, 768 },
468 { 800, 600 },
469 { 720, 400 },
470 { 640, 480 },
471 { 640, 400 },
472 { 640, 350 },
473 {}
474};
475
476static int
477nouveau_connector_scaler_modes_add(struct drm_connector *connector)
478{
479 struct nouveau_connector *nv_connector = nouveau_connector(connector);
480 struct drm_display_mode *native = nv_connector->native_mode, *m;
481 struct drm_device *dev = connector->dev;
482 struct moderec *mode = &scaler_modes[0];
483 int modes = 0;
484
485 if (!native)
486 return 0;
487
488 while (mode->hdisplay) {
489 if (mode->hdisplay <= native->hdisplay &&
490 mode->vdisplay <= native->vdisplay) {
491 m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay,
492 drm_mode_vrefresh(native), false,
493 false, false);
494 if (!m)
495 continue;
496
497 m->type |= DRM_MODE_TYPE_DRIVER;
498
499 drm_mode_probed_add(connector, m);
500 modes++;
501 }
502
503 mode++;
504 }
505
506 return modes;
507}
508
509static int
510nouveau_connector_get_modes(struct drm_connector *connector)
511{
512 struct drm_device *dev = connector->dev;
513 struct nouveau_connector *nv_connector = nouveau_connector(connector);
514 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
515 int ret = 0;
516
517 /* If we're not LVDS, destroy the previous native mode, the attached
518 * monitor could have changed.
519 */
520 if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
521 nv_connector->native_mode) {
522 drm_mode_destroy(dev, nv_connector->native_mode);
523 nv_connector->native_mode = NULL;
524 }
525
526 if (nv_connector->edid)
527 ret = drm_add_edid_modes(connector, nv_connector->edid);
528
529 /* Find the native mode if this is a digital panel, if we didn't
530 * find any modes through DDC previously add the native mode to
531 * the list of modes.
532 */
533 if (!nv_connector->native_mode)
534 nv_connector->native_mode =
535 nouveau_connector_native_mode(nv_connector);
536 if (ret == 0 && nv_connector->native_mode) {
537 struct drm_display_mode *mode;
538
539 mode = drm_mode_duplicate(dev, nv_connector->native_mode);
540 drm_mode_probed_add(connector, mode);
541 ret = 1;
542 }
543
544 if (nv_encoder->dcb->type == OUTPUT_TV)
545 ret = get_slave_funcs(nv_encoder)->
546 get_modes(to_drm_encoder(nv_encoder), connector);
547
548 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
549 ret += nouveau_connector_scaler_modes_add(connector);
550
551 return ret;
552}
553
554static int
555nouveau_connector_mode_valid(struct drm_connector *connector,
556 struct drm_display_mode *mode)
557{
558 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
559 struct nouveau_connector *nv_connector = nouveau_connector(connector);
560 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
561 unsigned min_clock = 25000, max_clock = min_clock;
562 unsigned clock = mode->clock;
563
564 switch (nv_encoder->dcb->type) {
565 case OUTPUT_LVDS:
566 BUG_ON(!nv_connector->native_mode);
567 if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
568 mode->vdisplay > nv_connector->native_mode->vdisplay)
569 return MODE_PANEL;
570
571 min_clock = 0;
572 max_clock = 400000;
573 break;
574 case OUTPUT_TMDS:
575 if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
576 (dev_priv->card_type < NV_50 &&
577 !nv_encoder->dcb->duallink_possible))
578 max_clock = 165000;
579 else
580 max_clock = 330000;
581 break;
582 case OUTPUT_ANALOG:
583 max_clock = nv_encoder->dcb->crtconf.maxfreq;
584 if (!max_clock)
585 max_clock = 350000;
586 break;
587 case OUTPUT_TV:
588 return get_slave_funcs(nv_encoder)->
589 mode_valid(to_drm_encoder(nv_encoder), mode);
590 case OUTPUT_DP:
591 if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7)
592 max_clock = nv_encoder->dp.link_nr * 270000;
593 else
594 max_clock = nv_encoder->dp.link_nr * 162000;
595
596 clock *= 3;
597 break;
598 }
599
600 if (clock < min_clock)
601 return MODE_CLOCK_LOW;
602
603 if (clock > max_clock)
604 return MODE_CLOCK_HIGH;
605
606 return MODE_OK;
607}
608
609static struct drm_encoder *
610nouveau_connector_best_encoder(struct drm_connector *connector)
611{
612 struct nouveau_connector *nv_connector = nouveau_connector(connector);
613
614 if (nv_connector->detected_encoder)
615 return to_drm_encoder(nv_connector->detected_encoder);
616
617 return NULL;
618}
619
620static const struct drm_connector_helper_funcs
621nouveau_connector_helper_funcs = {
622 .get_modes = nouveau_connector_get_modes,
623 .mode_valid = nouveau_connector_mode_valid,
624 .best_encoder = nouveau_connector_best_encoder,
625};
626
627static const struct drm_connector_funcs
628nouveau_connector_funcs = {
629 .dpms = drm_helper_connector_dpms,
630 .save = NULL,
631 .restore = NULL,
632 .detect = nouveau_connector_detect,
633 .destroy = nouveau_connector_destroy,
634 .fill_modes = drm_helper_probe_single_connector_modes,
635 .set_property = nouveau_connector_set_property,
636 .force = nouveau_connector_force
637};
638
639static int
640nouveau_connector_create_lvds(struct drm_device *dev,
641 struct drm_connector *connector)
642{
643 struct nouveau_connector *nv_connector = nouveau_connector(connector);
644 struct drm_nouveau_private *dev_priv = dev->dev_private;
645 struct nouveau_i2c_chan *i2c = NULL;
646 struct nouveau_encoder *nv_encoder;
647 struct drm_display_mode native, *mode, *temp;
648 bool dummy, if_is_24bit = false;
649 int ret, flags;
650
651 nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
652 if (!nv_encoder)
653 return -ENODEV;
654
655 ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
656 if (ret) {
657 NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
658 return ret;
659 }
660 nv_connector->use_dithering = !if_is_24bit;
661
662 /* Firstly try getting EDID over DDC, if allowed and I2C channel
663 * is available.
664 */
665 if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
666 i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
667
668 if (i2c) {
669 nouveau_connector_ddc_prepare(connector, &flags);
670 nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
671 nouveau_connector_ddc_finish(connector, flags);
672 }
673
674 /* If no EDID found above, and the VBIOS indicates a hardcoded
675 * modeline is avalilable for the panel, set it as the panel's
676 * native mode and exit.
677 */
678 if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
679 (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
680 dev_priv->VBIOS.pub.fp_no_ddc)) {
681 nv_connector->native_mode = drm_mode_duplicate(dev, &native);
682 goto out;
683 }
684
685 /* Still nothing, some VBIOS images have a hardcoded EDID block
686 * stored for the panel stored in them.
687 */
688 if (!nv_connector->edid && !nv_connector->native_mode &&
689 !dev_priv->VBIOS.pub.fp_no_ddc) {
690 nv_connector->edid =
691 (struct edid *)nouveau_bios_embedded_edid(dev);
692 }
693
694 if (!nv_connector->edid)
695 goto out;
696
697 /* We didn't find/use a panel mode from the VBIOS, so parse the EDID
698 * block and look for the preferred mode there.
699 */
700 ret = drm_add_edid_modes(connector, nv_connector->edid);
701 if (ret == 0)
702 goto out;
703 nv_connector->detected_encoder = nv_encoder;
704 nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
705 list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
706 drm_mode_remove(connector, mode);
707
708out:
709 if (!nv_connector->native_mode) {
710 NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
711 "determine its native mode. Disabling.\n");
712 return -ENODEV;
713 }
714
715 drm_mode_connector_update_edid_property(connector, nv_connector->edid);
716 return 0;
717}
718
719int
720nouveau_connector_create(struct drm_device *dev, int index, int type)
721{
722 struct drm_nouveau_private *dev_priv = dev->dev_private;
723 struct nouveau_connector *nv_connector = NULL;
724 struct drm_connector *connector;
725 struct drm_encoder *encoder;
726 int ret;
727
728 NV_DEBUG(dev, "\n");
729
730 nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
731 if (!nv_connector)
732 return -ENOMEM;
733 nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
734 connector = &nv_connector->base;
735
736 switch (type) {
737 case DRM_MODE_CONNECTOR_VGA:
738 NV_INFO(dev, "Detected a VGA connector\n");
739 break;
740 case DRM_MODE_CONNECTOR_DVID:
741 NV_INFO(dev, "Detected a DVI-D connector\n");
742 break;
743 case DRM_MODE_CONNECTOR_DVII:
744 NV_INFO(dev, "Detected a DVI-I connector\n");
745 break;
746 case DRM_MODE_CONNECTOR_LVDS:
747 NV_INFO(dev, "Detected a LVDS connector\n");
748 break;
749 case DRM_MODE_CONNECTOR_TV:
750 NV_INFO(dev, "Detected a TV connector\n");
751 break;
752 case DRM_MODE_CONNECTOR_DisplayPort:
753 NV_INFO(dev, "Detected a DisplayPort connector\n");
754 break;
755 default:
756 NV_ERROR(dev, "Unknown connector, this is not good.\n");
757 break;
758 }
759
760 /* defaults, will get overridden in detect() */
761 connector->interlace_allowed = false;
762 connector->doublescan_allowed = false;
763
764 drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
765 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
766
767 /* Init DVI-I specific properties */
768 if (type == DRM_MODE_CONNECTOR_DVII) {
769 drm_mode_create_dvi_i_properties(dev);
770 drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0);
771 drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
772 }
773
774 if (type != DRM_MODE_CONNECTOR_LVDS)
775 nv_connector->use_dithering = false;
776
777 if (type == DRM_MODE_CONNECTOR_DVID ||
778 type == DRM_MODE_CONNECTOR_DVII ||
779 type == DRM_MODE_CONNECTOR_LVDS ||
780 type == DRM_MODE_CONNECTOR_DisplayPort) {
781 nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
782
783 drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property,
784 nv_connector->scaling_mode);
785 drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property,
786 nv_connector->use_dithering ? DRM_MODE_DITHERING_ON
787 : DRM_MODE_DITHERING_OFF);
788
789 } else {
790 nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
791
792 if (type == DRM_MODE_CONNECTOR_VGA &&
793 dev_priv->card_type >= NV_50) {
794 drm_connector_attach_property(connector,
795 dev->mode_config.scaling_mode_property,
796 nv_connector->scaling_mode);
797 }
798 }
799
800 /* attach encoders */
801 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
802 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
803
804 if (nv_encoder->dcb->connector != index)
805 continue;
806
807 if (get_slave_funcs(nv_encoder))
808 get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
809
810 drm_mode_connector_attach_encoder(connector, encoder);
811 }
812
813 drm_sysfs_connector_add(connector);
814
815 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
816 ret = nouveau_connector_create_lvds(dev, connector);
817 if (ret) {
818 connector->funcs->destroy(connector);
819 return ret;
820 }
821 }
822
823 return 0;
824}