NV50: basic fbcon + misc fixes
[platform/upstream/libdrm.git] / linux-core / nv50_kms_wrapper.c
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 "nv50_kms_wrapper.h"
28 #include "drm_crtc_helper.h" /* be careful what you use from this */
29
30 /* This file serves as the interface between the common kernel modesetting code and the device dependent implementation. */
31
32 /*
33  * Get private functions.
34  */
35
36 struct nv50_kms_priv *nv50_get_kms_priv(struct drm_device *dev)
37 {
38         struct drm_nouveau_private *dev_priv = dev->dev_private;
39         return dev_priv->kms_priv;
40 }
41
42 /*
43  * Allocation functions.
44  */
45
46 static void *nv50_kms_alloc_crtc(struct drm_device *dev)
47 {
48         struct nv50_kms_priv *kms_priv = nv50_get_kms_priv(dev);
49         struct nv50_kms_crtc *crtc = kzalloc(sizeof(struct nv50_kms_crtc), GFP_KERNEL);
50
51         if (!crtc)
52                 return NULL;
53
54         list_add_tail(&crtc->item, &kms_priv->crtcs);
55
56         return &(crtc->priv);
57 }
58
59 static void *nv50_kms_alloc_output(struct drm_device *dev)
60 {
61         struct nv50_kms_priv *kms_priv = nv50_get_kms_priv(dev);
62         struct nv50_kms_encoder *encoder = kzalloc(sizeof(struct nv50_kms_encoder), GFP_KERNEL);
63
64         if (!encoder)
65                 return NULL;
66
67         list_add_tail(&encoder->item, &kms_priv->encoders);
68
69         return &(encoder->priv);
70 }
71
72 static void *nv50_kms_alloc_connector(struct drm_device *dev)
73 {
74         struct nv50_kms_priv *kms_priv = nv50_get_kms_priv(dev);
75         struct nv50_kms_connector *connector = kzalloc(sizeof(struct nv50_kms_connector), GFP_KERNEL);
76
77         if (!connector)
78                 return NULL;
79
80         list_add_tail(&connector->item, &kms_priv->connectors);
81
82         return &(connector->priv);
83 }
84
85 static void nv50_kms_free_crtc(void *crtc)
86 {
87         struct nv50_kms_crtc *kms_crtc = from_nv50_crtc(crtc);
88
89         list_del(&kms_crtc->item);
90
91         kfree(kms_crtc);
92 }
93
94 static void nv50_kms_free_output(void *output)
95 {
96         struct nv50_kms_encoder *kms_encoder = from_nv50_output(output);
97
98         list_del(&kms_encoder->item);
99
100         kfree(kms_encoder);
101 }
102
103 static void nv50_kms_free_connector(void *connector)
104 {
105         struct nv50_kms_connector *kms_connector = from_nv50_connector(connector);
106
107         list_del(&kms_connector->item);
108
109         kfree(kms_connector);
110 }
111
112 /*
113  * Mode conversion functions.
114  */
115
116 static struct nouveau_hw_mode *nv50_kms_to_hw_mode(struct drm_display_mode *mode)
117 {
118         struct nouveau_hw_mode *hw_mode = kzalloc(sizeof(struct nouveau_hw_mode), GFP_KERNEL);
119         if (!hw_mode)
120                 return NULL;
121
122         /* create hw values. */
123         hw_mode->clock = mode->clock;
124         hw_mode->flags = hw_mode->flags;
125
126         hw_mode->hdisplay = mode->hdisplay;
127         hw_mode->hsync_start = mode->hsync_start;
128         hw_mode->hsync_end = mode->hsync_end;
129         hw_mode->htotal = mode->htotal;
130
131         hw_mode->hblank_start = mode->hdisplay + 1;
132         hw_mode->hblank_end = mode->htotal;
133
134         hw_mode->vdisplay = mode->vdisplay;
135         hw_mode->vsync_start = mode->vsync_start;
136         hw_mode->vsync_end = mode->vsync_end;
137         hw_mode->vtotal = mode->vtotal;
138
139         hw_mode->vblank_start = mode->vdisplay + 1;
140         hw_mode->vblank_end = mode->vtotal;
141
142         return hw_mode;
143 }
144
145 /*
146  * State mirroring functions.
147  */
148
149 static void nv50_kms_mirror_routing(struct drm_device *dev)
150 {
151         struct nv50_display *display = nv50_get_display(dev);
152         struct nv50_crtc *crtc = NULL;
153         struct nv50_output *output = NULL;
154         struct nv50_connector *connector = NULL;
155         struct drm_connector *drm_connector = NULL;
156         struct drm_crtc *drm_crtc = NULL;
157
158         /* Wipe all previous connections. */
159         list_for_each_entry(connector, &display->connectors, item) {
160                 connector->output = NULL;
161         }
162
163         list_for_each_entry(output, &display->outputs, item) {
164                 output->crtc = NULL;
165         }
166
167         list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
168                 if (drm_connector->encoder) {
169                         output = to_nv50_output(drm_connector->encoder);
170                         connector = to_nv50_connector(drm_connector);
171
172                         /* hook up output to connector. */
173                         connector->output = output;
174
175                         if (drm_connector->encoder->crtc) {
176                                 crtc = to_nv50_crtc(drm_connector->encoder->crtc);
177
178                                 /* hook up output to crtc. */
179                                 output->crtc = crtc;
180                         }
181                 }
182         }
183
184         /* mirror crtc active state */
185         list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
186                 crtc = to_nv50_crtc(drm_crtc);
187
188                 crtc->active = drm_crtc->enabled;
189         }
190 }
191
192 /*
193  * FB functions.
194  */
195
196 static void nv50_kms_framebuffer_destroy(struct drm_framebuffer *drm_framebuffer)
197 {
198         drm_framebuffer_cleanup(drm_framebuffer);
199
200         kfree(drm_framebuffer);
201 }
202
203 static const struct drm_framebuffer_funcs nv50_kms_fb_funcs = {
204         .destroy = nv50_kms_framebuffer_destroy,
205 };
206
207 /*
208  * Mode config functions.
209  */
210
211 static struct drm_framebuffer *nv50_kms_framebuffer_create(struct drm_device *dev,
212                                                 struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd)
213 {
214         struct drm_framebuffer *drm_framebuffer = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
215         if (!drm_framebuffer)
216                 return NULL;
217
218         drm_framebuffer_init(dev, drm_framebuffer, &nv50_kms_fb_funcs);
219         drm_helper_mode_fill_fb_struct(drm_framebuffer, mode_cmd);
220
221         return drm_framebuffer;
222 }
223
224 static int nv50_kms_fb_changed(struct drm_device *dev)
225 {
226         return 0; /* not needed until nouveaufb? */
227 }
228
229 static const struct drm_mode_config_funcs nv50_kms_mode_funcs = {
230         .resize_fb = NULL,
231         .fb_create = nv50_kms_framebuffer_create,
232         .fb_changed = nv50_kms_fb_changed,
233 };
234
235 /*
236  * CRTC functions.
237  */
238
239 static int nv50_kms_crtc_cursor_set(struct drm_crtc *drm_crtc, uint32_t buffer_handle,
240                           uint32_t width, uint32_t height)
241 {
242         struct nv50_crtc *crtc = to_nv50_crtc(drm_crtc);
243         struct nv50_display *display = nv50_get_display(crtc->dev);
244         int rval = 0;
245
246         if (width != 64 || height != 64)
247                 return -EINVAL;
248
249         /* set bo before doing show cursor */
250         if (buffer_handle) {
251                 rval = crtc->cursor->set_bo(crtc, (drm_handle_t) buffer_handle);
252                 if (rval != 0)
253                         goto out;
254         }
255
256         crtc->cursor->visible = buffer_handle ? true : false;
257
258         if (buffer_handle) {
259                 rval = crtc->cursor->show(crtc);
260                 if (rval != 0)
261                         goto out;
262         } else { /* no handle implies hiding the cursor */
263                 rval = crtc->cursor->hide(crtc);
264                 goto out;
265         }
266
267         if (rval != 0)
268                 return rval;
269
270 out:
271         /* in case this triggers any other cursor changes */
272         display->update(display);
273
274         return rval;
275 }
276
277 static int nv50_kms_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y)
278 {
279         struct nv50_crtc *crtc = to_nv50_crtc(drm_crtc);
280
281         return crtc->cursor->set_pos(crtc, x, y);
282 }
283
284 void nv50_kms_crtc_gamma_set(struct drm_crtc *drm_crtc, u16 *r, u16 *g, u16 *b,
285                 uint32_t size)
286 {
287         struct nv50_crtc *crtc = to_nv50_crtc(drm_crtc);
288
289         if (size != 256)
290                 return;
291
292         crtc->lut->set(crtc, (uint16_t *)r, (uint16_t *)g, (uint16_t *)b);
293 }
294
295 int nv50_kms_crtc_set_config(struct drm_mode_set *set)
296 {
297         int rval = 0, i;
298         uint32_t crtc_mask = 0;
299         struct drm_device *dev = NULL;
300         struct drm_nouveau_private *dev_priv = NULL;
301         struct nv50_display *display = NULL;
302         struct drm_connector *drm_connector = NULL;
303         struct drm_encoder *drm_encoder = NULL;
304         struct drm_crtc *drm_crtc = NULL;
305
306         struct nv50_crtc *crtc = NULL;
307         struct nv50_output *output = NULL;
308         struct nv50_connector *connector = NULL;
309         struct nouveau_hw_mode *hw_mode = NULL;
310         struct nv50_fb_info fb_info;
311
312         bool blank = false;
313         bool switch_fb = false;
314         bool modeset = false;
315
316         NV50_DEBUG("\n");
317
318         /*
319          * Supported operations:
320          * - Switch mode.
321          * - Switch framebuffer.
322          * - Blank screen.
323          */
324
325         /* Sanity checking */
326         if (!set) {
327                 DRM_ERROR("Sanity check failed\n");
328                 goto out;
329         }
330
331         if (!set->crtc) {
332                 DRM_ERROR("Sanity check failed\n");
333                 goto out;
334         }
335
336         if (set->mode) {
337                 if (set->fb) {
338                         if (!drm_mode_equal(set->mode, &set->crtc->mode))
339                                 modeset = true;
340
341                         if (set->fb != set->crtc->fb)
342                                 switch_fb = true;
343
344                         if (set->x != set->crtc->x || set->y != set->crtc->y)
345                                 switch_fb = true;
346                 }
347         } else {
348                 blank = true;
349         }
350
351         if (!set->connectors && modeset) {
352                 DRM_ERROR("Sanity check failed\n");
353                 goto out;
354         }
355
356         if (!modeset && !switch_fb && !blank) {
357                 DRM_ERROR("There is nothing to do, bad input.\n");
358                 goto out;
359         }
360
361         /* Basic variable setting */
362         dev = set->crtc->dev;
363         dev_priv = dev->dev_private;
364         display = nv50_get_display(dev);
365         crtc = to_nv50_crtc(set->crtc);
366
367         /**
368          * Wiring up the encoders and connectors.
369          */
370
371         if (modeset) {
372                 /* Mode validation */
373                 hw_mode = nv50_kms_to_hw_mode(set->mode);
374
375                 rval = crtc->validate_mode(crtc, hw_mode);
376
377                 if (rval != MODE_OK) {
378                         DRM_ERROR("Mode not ok\n");
379                         goto out;
380                 }
381
382                 for (i = 0; i < set->num_connectors; i++) {
383                         drm_connector = set->connectors[i];
384                         if (!drm_connector) {
385                                 DRM_ERROR("No connector\n");
386                                 goto out;
387                         }
388                         connector = to_nv50_connector(drm_connector);
389
390                         output = connector->to_output(connector, connector->digital);
391                         if (!output) {
392                                 DRM_ERROR("No output\n");
393                                 goto out;
394                         }
395
396                         rval = output->validate_mode(output, hw_mode);
397                         if (rval != MODE_OK) {
398                                 DRM_ERROR("Mode not ok\n");
399                                 goto out;
400                         }
401                 }
402
403                 /* Validation done, move on to cleaning of existing structures. */
404
405                 /* find encoders that use this crtc. */
406                 list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
407                         if (drm_encoder->crtc == set->crtc) {
408                                 /* find the connector that goes with it */
409                                 list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
410                                         if (drm_connector->encoder == drm_encoder) {
411                                                 drm_connector->encoder =  NULL;
412                                                 break;
413                                         }
414                                 }
415                                 drm_encoder->crtc = NULL;
416                         }
417                 }
418
419                 /* now find if our desired encoders or connectors are in use already. */
420                 for (i = 0; i < set->num_connectors; i++) {
421                         drm_connector = set->connectors[i];
422                         if (!drm_connector) {
423                                 DRM_ERROR("No connector\n");
424                                 goto out;
425                         }
426
427                         if (!drm_connector->encoder)
428                                 continue;
429
430                         drm_encoder = drm_connector->encoder;
431                         drm_connector->encoder = NULL;
432
433                         if (!drm_encoder->crtc)
434                                 continue;
435
436                         drm_crtc = drm_encoder->crtc;
437                         drm_encoder->crtc = NULL;
438
439                         drm_crtc->enabled = false;
440                 }
441
442                 /* Time to wire up the public encoder, the private one will be handled later. */
443                 for (i = 0; i < set->num_connectors; i++) {
444                         drm_connector = set->connectors[i];
445                         if (!drm_connector) {
446                                 DRM_ERROR("No connector\n");
447                                 goto out;
448                         }
449
450                         output = connector->to_output(connector, connector->digital);
451                         if (!output) {
452                                 DRM_ERROR("No output\n");
453                                 goto out;
454                         }
455
456                         /* find the encoder public structure that matches out output structure. */
457                         drm_encoder = to_nv50_kms_encoder(output);
458
459                         if (!drm_encoder) {
460                                 DRM_ERROR("No encoder\n");
461                                 goto out;
462                         }
463
464                         drm_encoder->crtc = set->crtc;
465                         set->crtc->enabled = true;
466                         drm_connector->encoder = drm_encoder;
467                 }
468         }
469
470         /**
471          * Disable crtc.
472          */
473
474         if (blank) {
475                 crtc = to_nv50_crtc(set->crtc);
476
477                 /* keeping the encoders and connectors attached, so they can be tracked */
478                 set->crtc->enabled = false;
479         }
480
481         /**
482          * All state should now be updated, now onto the real work.
483          */
484
485         /* mirror everything to the private structs */
486         nv50_kms_mirror_routing(dev);
487
488         /**
489          * Bind framebuffer.
490          */
491
492         if (switch_fb) {
493                 crtc = to_nv50_crtc(set->crtc);
494
495                 /* set framebuffer */
496                 set->crtc->fb = set->fb;
497
498                 /* set private framebuffer */
499                 crtc = to_nv50_crtc(set->crtc);
500                 fb_info.block = find_block_by_handle(dev_priv->fb_heap, set->fb->mm_handle);
501                 fb_info.width = set->fb->width;
502                 fb_info.height = set->fb->height;
503                 fb_info.depth = set->fb->depth;
504                 fb_info.bpp = set->fb->bits_per_pixel;
505                 fb_info.pitch = set->fb->pitch;
506                 fb_info.x = set->x;
507                 fb_info.y = set->y;
508
509                 rval = crtc->fb->bind(crtc, &fb_info);
510                 if (rval != 0) {
511                         DRM_ERROR("fb_bind failed\n");
512                         goto out;
513                 }
514         }
515
516         /* this is !cursor_show */
517         if (!crtc->cursor->enabled) {
518                 rval = crtc->cursor->enable(crtc);
519                 if (rval != 0) {
520                         DRM_ERROR("cursor_enable failed\n");
521                         goto out;
522                 }
523         }
524
525         /**
526          * Blanking.
527          */
528
529         if (blank) {
530                 crtc = to_nv50_crtc(set->crtc);
531
532                 rval = crtc->blank(crtc, TRUE);
533                 if (rval != 0) {
534                         DRM_ERROR("blanking failed\n");
535                         goto out;
536                 }
537
538                 /* detach any outputs that are currently running on this crtc */
539                 list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
540                         if (drm_encoder->crtc == set->crtc) {
541                                 output = to_nv50_output(drm_encoder);
542
543                                 rval = output->execute_mode(output, TRUE);
544                                 if (rval != 0) {
545                                         DRM_ERROR("detaching output failed\n");
546                                         goto out;
547                                 }
548                         }
549                 }
550         }
551
552         /**
553          * Change framebuffer, without changing mode.
554          */
555
556         if (switch_fb && !modeset && !blank) {
557                 crtc = to_nv50_crtc(set->crtc);
558
559                 rval = crtc->blank(crtc, TRUE);
560                 if (rval != 0) {
561                         DRM_ERROR("blanking failed\n");
562                         goto out;
563                 }
564
565                 rval = crtc->set_fb(crtc);
566                 if (rval != 0) {
567                         DRM_ERROR("set_fb failed\n");
568                         goto out;
569                 }
570
571                 /* this also sets the fb offset */
572                 rval = crtc->blank(crtc, FALSE);
573                 if (rval != 0) {
574                         DRM_ERROR("unblanking failed\n");
575                         goto out;
576                 }
577         }
578
579         /**
580          * Normal modesetting.
581          */
582
583         if (modeset) {
584                 crtc = to_nv50_crtc(set->crtc);
585
586                 /* disconnect unused outputs */
587                 list_for_each_entry(output, &display->outputs, item) {
588                         if (output->crtc) {
589                                 crtc_mask |= 1 << output->crtc->index;
590                         } else {
591                                 rval = output->execute_mode(output, TRUE);
592                                 if (rval != 0) {
593                                         DRM_ERROR("detaching output failed\n");
594                                         goto out;
595                                 }
596                         }
597                 }
598
599                 /* blank any unused crtcs */
600                 list_for_each_entry(crtc, &display->crtcs, item) {
601                         if (!(crtc_mask & (1 << crtc->index)))
602                                 crtc->blank(crtc, TRUE);
603                 }
604
605                 crtc = to_nv50_crtc(set->crtc);
606
607                 rval = crtc->set_mode(crtc, hw_mode);
608                 if (rval != 0) {
609                         DRM_ERROR("crtc mode set failed\n");
610                         goto out;
611                 }
612
613                 /* find native mode. */
614                 list_for_each_entry(output, &display->outputs, item) {
615                         if (output->crtc != crtc)
616                                 continue;
617
618                         *crtc->native_mode = *output->native_mode;
619                         list_for_each_entry(connector, &display->connectors, item) {
620                                 if (connector->output != output)
621                                         continue;
622
623                                 crtc->scaling_mode = connector->scaling_mode;
624                                 break;
625                         }
626
627                         if (crtc->scaling_mode == SCALE_PANEL)
628                                 crtc->use_native_mode = false;
629                         else
630                                 crtc->use_native_mode = true;
631
632                         break; /* no use in finding more than one mode */
633                 }
634
635                 rval = crtc->execute_mode(crtc);
636                 if (rval != 0) {
637                         DRM_ERROR("crtc execute mode failed\n");
638                         goto out;
639                 }
640
641                 list_for_each_entry(output, &display->outputs, item) {
642                         if (output->crtc != crtc)
643                                 continue;
644
645                         rval = output->execute_mode(output, FALSE);
646                         if (rval != 0) {
647                                 DRM_ERROR("output execute mode failed\n");
648                                 goto out;
649                         }
650                 }
651
652                 rval = crtc->set_scale(crtc);
653                 if (rval != 0) {
654                         DRM_ERROR("crtc set scale failed\n");
655                         goto out;
656                 }
657
658                 /* next line changes crtc, so putting it here is important */
659                 display->last_crtc = crtc->index;
660
661                 /* this is executed immediately */
662                 list_for_each_entry(output, &display->outputs, item) {
663                         if (output->crtc != crtc)
664                                 continue;
665
666                         rval = output->set_power_mode(output, DPMSModeOn);
667                         if (rval != 0) {
668                                 DRM_ERROR("output set power mode failed\n");
669                                 goto out;
670                         }
671                 }
672
673                 /* update dpms state to DPMSModeOn */
674                 for (i = 0; i < set->num_connectors; i++) {
675                         drm_connector = set->connectors[i];
676                         if (!drm_connector) {
677                                 DRM_ERROR("No connector\n");
678                                 goto out;
679                         }
680
681                         rval = drm_connector_property_set_value(drm_connector,
682                                         dev->mode_config.dpms_property,
683                                         DPMSModeOn);
684                         if (rval != 0) {
685                                 DRM_ERROR("failed to update dpms state\n");
686                                 goto out;
687                         }
688                 }
689         }
690
691         display->update(display);
692
693         kfree(hw_mode);
694
695         return 0;
696
697 out:
698         kfree(hw_mode);
699
700         if (rval != 0)
701                 return rval;
702         else
703                 return -EINVAL;
704 }
705
706 static void nv50_kms_crtc_destroy(struct drm_crtc *drm_crtc)
707 {
708         struct nv50_crtc *crtc = to_nv50_crtc(drm_crtc);
709
710         drm_crtc_cleanup(drm_crtc);
711
712         /* this will even destroy the public structure. */
713         crtc->destroy(crtc);
714 }
715
716 static const struct drm_crtc_funcs nv50_kms_crtc_funcs = {
717         .save = NULL,
718         .restore = NULL,
719         .cursor_set = nv50_kms_crtc_cursor_set,
720         .cursor_move = nv50_kms_crtc_cursor_move,
721         .gamma_set = nv50_kms_crtc_gamma_set,
722         .set_config = nv50_kms_crtc_set_config,
723         .destroy = nv50_kms_crtc_destroy,
724 };
725
726 static int nv50_kms_crtcs_init(struct drm_device *dev)
727 {
728         struct nv50_display *display = nv50_get_display(dev);
729         struct nv50_crtc *crtc = NULL;
730
731         /*
732          * This may look a bit confusing, but:
733          * The internal structure is already allocated and so is the public one.
734          * Just a matter of getting to the memory and register it.
735          */
736         list_for_each_entry(crtc, &display->crtcs, item) {
737                 struct drm_crtc *drm_crtc = to_nv50_kms_crtc(crtc);
738
739                 drm_crtc_init(dev, drm_crtc, &nv50_kms_crtc_funcs);
740         }
741
742         return 0;
743 }
744
745 /*
746  * Encoder functions
747  */
748
749 static void nv50_kms_encoder_destroy(struct drm_encoder *drm_encoder)
750 {
751         struct nv50_output *output = to_nv50_output(drm_encoder);
752
753         drm_encoder_cleanup(drm_encoder);
754
755         /* this will even destroy the public structure. */
756         output->destroy(output);
757 }
758
759 static const struct drm_encoder_funcs nv50_kms_encoder_funcs = {
760         .destroy = nv50_kms_encoder_destroy,
761 };
762
763 static int nv50_kms_encoders_init(struct drm_device *dev)
764 {
765         struct nv50_display *display = nv50_get_display(dev);
766         struct nv50_output *output = NULL;
767
768         list_for_each_entry(output, &display->outputs, item) {
769                 struct drm_encoder *drm_encoder = to_nv50_kms_encoder(output);
770                 uint32_t type = DRM_MODE_ENCODER_NONE;
771
772                 switch (output->type) {
773                         case OUTPUT_DAC:
774                                 type = DRM_MODE_ENCODER_DAC;
775                                 break;
776                         case OUTPUT_TMDS:
777                                 type = DRM_MODE_ENCODER_TMDS;
778                                 break;
779                         case OUTPUT_LVDS:
780                                 type = DRM_MODE_ENCODER_LVDS;
781                                 break;
782                         case OUTPUT_TV:
783                                 type = DRM_MODE_ENCODER_TVDAC;
784                                 break;
785                         default:
786                                 type = DRM_MODE_ENCODER_NONE;
787                                 break;
788                 }
789
790                 if (type == DRM_MODE_ENCODER_NONE) {
791                         DRM_ERROR("DRM_MODE_ENCODER_NONE encountered\n");
792                         continue;
793                 }
794
795                 drm_encoder_init(dev, drm_encoder, &nv50_kms_encoder_funcs, type);
796
797                 /* I've never seen possible crtc's restricted. */
798                 drm_encoder->possible_crtcs = 3;
799                 drm_encoder->possible_clones = 0;
800         }
801
802         return 0;
803 }
804
805 /*
806  * Connector functions
807  */
808
809 void nv50_kms_connector_detect_all(struct drm_device *dev)
810 {
811         struct drm_connector *drm_connector = NULL;
812
813         list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
814                 drm_connector->funcs->detect(drm_connector);
815         }
816 }
817
818 static enum drm_connector_status nv50_kms_connector_detect(struct drm_connector *drm_connector)
819 {
820         struct nv50_connector *connector = to_nv50_connector(drm_connector);
821         struct drm_device *dev = drm_connector->dev;
822         bool connected;
823         int old_status;
824
825         connected = connector->detect(connector);
826
827         old_status = drm_connector->status;
828
829         if (connected)
830                 drm_connector->status = connector_status_connected;
831         else
832                 drm_connector->status = connector_status_disconnected;
833
834         /* update our modes whenever there is reason to */
835         if (old_status != drm_connector->status) {
836                 drm_connector->funcs->fill_modes(drm_connector, 0, 0);
837                 /* notify fb of changes */
838                 dev->mode_config.funcs->fb_changed(dev);
839         }
840
841         return drm_connector->status;
842 }
843
844 static void nv50_kms_connector_destroy(struct drm_connector *drm_connector)
845 {
846         struct nv50_connector *connector = to_nv50_connector(drm_connector);
847
848         drm_sysfs_connector_remove(drm_connector);
849         drm_connector_cleanup(drm_connector);
850
851         /* this will even destroy the public structure. */
852         connector->destroy(connector);
853 }
854
855 /*
856  * Detailed mode info for a standard 640x480@60Hz monitor
857  */
858 static struct drm_display_mode std_mode[] = {
859         /*{ DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
860                  752, 800, 0, 480, 490, 492, 525, 0,
861                  V_NHSYNC | V_NVSYNC) },*/ /* 640x480@60Hz */
862         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DEFAULT, 135000, 1280, 1296,
863                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
864                    V_PHSYNC | V_PVSYNC) }, /* 1280x1024@75Hz */
865 };
866
867 static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, uint32_t maxX, uint32_t maxY)
868 {
869         struct nv50_connector *connector = to_nv50_connector(drm_connector);
870         int ret = 0;
871         bool connected;
872         struct drm_display_mode *mode, *t;
873         struct edid *edid = NULL;
874
875         NV50_DEBUG("%s\n", drm_get_connector_name(drm_connector));
876         /* set all modes to the unverified state */
877         list_for_each_entry_safe(mode, t, &drm_connector->modes, head)
878                 mode->status = MODE_UNVERIFIED;
879
880         connected = connector->detect(connector);
881
882         if (connected)
883                 drm_connector->status = connector_status_connected;
884         else
885                 drm_connector->status = connector_status_disconnected;
886
887         if (!connected) {
888                 NV50_DEBUG("%s is disconnected\n", drm_get_connector_name(drm_connector));
889                 /* TODO set EDID to NULL */
890                 return;
891         }
892
893         /* Not all connnectors have an i2c channel. */
894         if (connector->i2c_chan)
895                 edid = (struct edid *) drm_do_probe_ddc_edid(&connector->i2c_chan->adapter);
896
897         if (edid) {
898                 drm_mode_connector_update_edid_property(drm_connector, edid);
899                 ret = drm_add_edid_modes(drm_connector, edid);
900                 connector->digital = edid->digital; /* cache */
901                 kfree(edid);
902         }
903
904         if (ret) /* number of modes  > 1 */
905                 drm_mode_connector_list_update(drm_connector);
906
907         if (maxX && maxY)
908                 drm_mode_validate_size(drm_connector->dev, &drm_connector->modes, maxX, maxY, 0);
909
910         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
911                 if (mode->status == MODE_OK) {
912                         struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
913                         struct nv50_output *output = connector->to_output(connector, connector->digital);
914
915                         mode->status = output->validate_mode(output, hw_mode);
916                         /* find native mode, TODO: also check if we actually found one */
917                         if (mode->status == MODE_OK) {
918                                 if (mode->type & DRM_MODE_TYPE_PREFERRED)
919                                         *output->native_mode = *hw_mode;
920                         }
921                         kfree(hw_mode);
922                 }
923         }
924
925         /* revalidate now that we have native mode */
926         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
927                 if (mode->status == MODE_OK) {
928                         struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
929                         struct nv50_output *output = connector->to_output(connector, connector->digital);
930
931                         mode->status = output->validate_mode(output, hw_mode);
932                         kfree(hw_mode);
933                 }
934         }
935
936         drm_mode_prune_invalid(drm_connector->dev, &drm_connector->modes, TRUE);
937
938         if (list_empty(&drm_connector->modes)) {
939                 struct drm_display_mode *stdmode;
940                 struct nouveau_hw_mode *hw_mode;
941                 struct nv50_output *output;
942
943                 NV50_DEBUG("No valid modes on %s\n", drm_get_connector_name(drm_connector));
944
945                 /* Should we do this here ???
946                  * When no valid EDID modes are available we end up
947                  * here and bailed in the past, now we add a standard
948                  * 640x480@60Hz mode and carry on.
949                  */
950                 stdmode = drm_mode_duplicate(drm_connector->dev, &std_mode[0]);
951                 drm_mode_probed_add(drm_connector, stdmode);
952                 drm_mode_list_concat(&drm_connector->probed_modes,
953                                      &drm_connector->modes);
954
955                 /* also add it as native mode */
956                 hw_mode = nv50_kms_to_hw_mode(mode);
957                 output = connector->to_output(connector, connector->digital);
958
959                 if (hw_mode)
960                         *output->native_mode = *hw_mode;
961
962                 DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
963                           drm_get_connector_name(drm_connector));
964         }
965
966         drm_mode_sort(&drm_connector->modes);
967
968         NV50_DEBUG("Probed modes for %s\n", drm_get_connector_name(drm_connector));
969
970         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
971                 mode->vrefresh = drm_mode_vrefresh(mode);
972
973                 /* is this needed, as it's unused by the driver? */
974                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
975                 drm_mode_debug_printmodeline(mode);
976         }
977 }
978
979 static bool nv50_kms_connector_set_property(struct drm_connector *connector,
980                                         struct drm_property *property,
981                                         uint64_t value)
982 {
983         struct drm_device *dev = connector->dev;
984
985         if (property == dev->mode_config.dpms_property && connector->encoder) {
986                 struct nv50_output *output = to_nv50_output(connector->encoder);
987
988                 if (!output->set_power_mode(output, (int) value))
989                         return true;
990                 else
991                         return false;
992         }
993
994         return false;
995 }
996
997 static const struct drm_connector_funcs nv50_kms_connector_funcs = {
998         .save = NULL,
999         .restore = NULL,
1000         .detect = nv50_kms_connector_detect,
1001         .destroy = nv50_kms_connector_destroy,
1002         .fill_modes = nv50_kms_connector_fill_modes,
1003         .set_property = nv50_kms_connector_set_property
1004 };
1005
1006 static int nv50_kms_connectors_init(struct drm_device *dev)
1007 {
1008         struct nv50_display *display = nv50_get_display(dev);
1009         struct nv50_connector *connector = NULL;
1010         int i;
1011
1012         list_for_each_entry(connector, &display->connectors, item) {
1013                 struct drm_connector *drm_connector = to_nv50_kms_connector(connector);
1014                 uint32_t type = DRM_MODE_CONNECTOR_Unknown;
1015
1016                 switch (connector->type) {
1017                         case CONNECTOR_VGA:
1018                                 type = DRM_MODE_CONNECTOR_VGA;
1019                                 break;
1020                         case CONNECTOR_DVI_D:
1021                                 type = DRM_MODE_CONNECTOR_DVID;
1022                                 break;
1023                         case CONNECTOR_DVI_I:
1024                                 type = DRM_MODE_CONNECTOR_DVII;
1025                                 break;
1026                         case CONNECTOR_LVDS:
1027                                 type = DRM_MODE_CONNECTOR_LVDS;
1028                                 break;
1029                         case CONNECTOR_TV:
1030                                 type = DRM_MODE_CONNECTOR_SVIDEO;
1031                                 break;
1032                         default:
1033                                 type = DRM_MODE_CONNECTOR_Unknown;
1034                                 break;
1035                 }
1036
1037                 if (type == DRM_MODE_CONNECTOR_Unknown) {
1038                         DRM_ERROR("DRM_MODE_CONNECTOR_Unknown encountered\n");
1039                         continue;
1040                 }
1041
1042                 /* It should be allowed sometimes, but let's be safe for the moment. */
1043                 drm_connector->interlace_allowed = false;
1044                 drm_connector->doublescan_allowed = false;
1045
1046                 drm_connector_init(dev, drm_connector, &nv50_kms_connector_funcs, type);
1047
1048                 /* attach encoders, possibilities are analog + digital */
1049                 for (i = 0; i < 2; i++) {
1050                         struct drm_encoder *drm_encoder = NULL;
1051                         struct nv50_output *output = connector->to_output(connector, i);
1052                         if (!output)
1053                                 continue;
1054
1055                         drm_encoder = to_nv50_kms_encoder(output);
1056                         if (!drm_encoder) {
1057                                 DRM_ERROR("No struct drm_connector to match struct nv50_output\n");
1058                                 continue;
1059                         }
1060
1061                         drm_mode_connector_attach_encoder(drm_connector, drm_encoder);
1062                 }
1063
1064                 drm_sysfs_connector_add(drm_connector);
1065         }
1066
1067         return 0;
1068 }
1069
1070 /*
1071  * Main functions
1072  */
1073
1074 int nv50_kms_init(struct drm_device *dev)
1075 {
1076         struct drm_nouveau_private *dev_priv = dev->dev_private;
1077         struct nv50_kms_priv *kms_priv = kzalloc(sizeof(struct nv50_kms_priv), GFP_KERNEL);
1078         struct nv50_display *display = NULL;
1079         int rval = 0;
1080
1081         if (!kms_priv)
1082                 return -ENOMEM;
1083
1084         dev_priv->kms_priv = kms_priv;
1085
1086         /* function pointers */
1087         /* an allocation interface that deals with the outside world, without polluting the core. */
1088         dev_priv->alloc_crtc = nv50_kms_alloc_crtc;
1089         dev_priv->alloc_output = nv50_kms_alloc_output;
1090         dev_priv->alloc_connector = nv50_kms_alloc_connector;
1091
1092         dev_priv->free_crtc = nv50_kms_free_crtc;
1093         dev_priv->free_output = nv50_kms_free_output;
1094         dev_priv->free_connector = nv50_kms_free_connector;
1095
1096         /* bios is needed for tables. */
1097         rval = nouveau_parse_bios(dev);
1098         if (rval != 0)
1099                 goto out;
1100
1101         /* init basic kernel modesetting */
1102         drm_mode_config_init(dev);
1103
1104         dev->mode_config.min_width = 0;
1105         dev->mode_config.min_height = 0;
1106
1107         dev->mode_config.funcs = (void *)&nv50_kms_mode_funcs;
1108
1109         dev->mode_config.max_width = 8192;
1110         dev->mode_config.max_height = 8192;
1111
1112         dev->mode_config.fb_base = dev_priv->fb_phys;
1113
1114         /* init kms lists */
1115         INIT_LIST_HEAD(&kms_priv->crtcs);
1116         INIT_LIST_HEAD(&kms_priv->encoders);
1117         INIT_LIST_HEAD(&kms_priv->connectors);
1118
1119         /* init the internal core, must be done first. */
1120         rval = nv50_display_create(dev);
1121         if (rval != 0)
1122                 goto out;
1123
1124         display = nv50_get_display(dev);
1125         if (!display) {
1126                 rval = -EINVAL;
1127                 goto out;
1128         }
1129
1130         /* pre-init now */
1131         rval = display->pre_init(display);
1132         if (rval != 0)
1133                 goto out;
1134
1135         /* init external layer */
1136         rval = nv50_kms_crtcs_init(dev);
1137         if (rval != 0)
1138                 goto out;
1139
1140         rval = nv50_kms_encoders_init(dev);
1141         if (rval != 0)
1142                 goto out;
1143
1144         rval = nv50_kms_connectors_init(dev);
1145         if (rval != 0)
1146                 goto out;
1147
1148         /* init now, this'll kill the textmode */
1149         rval = display->init(display);
1150         if (rval != 0)
1151                 goto out;
1152
1153         /* process cmdbuffer */
1154         display->update(display);
1155
1156         return 0;
1157
1158 out:
1159         kfree(kms_priv);
1160         dev_priv->kms_priv = NULL;
1161
1162         return rval;
1163 }
1164
1165 int nv50_kms_destroy(struct drm_device *dev)
1166 {
1167         drm_mode_config_cleanup(dev);
1168
1169         return 0;
1170 }
1171