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