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