67836f3f6e558a9123d4046ed31965b4e93dfbdc
[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         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->enabled = 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 && !blank) {
352                 DRM_ERROR("Sanity check failed\n");
353                 goto out;
354         }
355
356         /* Basic variable setting */
357         dev = set->crtc->dev;
358         dev_priv = dev->dev_private;
359         display = nv50_get_display(dev);
360         crtc = to_nv50_crtc(set->crtc);
361
362         /**
363          * Wiring up the encoders and connectors.
364          */
365
366         /* for switch_fb we verify if any important changes happened */
367         if (!blank) {
368                 /* Mode validation */
369                 hw_mode = nv50_kms_to_hw_mode(set->mode);
370
371                 rval = crtc->validate_mode(crtc, hw_mode);
372
373                 if (rval != MODE_OK) {
374                         DRM_ERROR("Mode not ok\n");
375                         goto out;
376                 }
377
378                 for (i = 0; i < set->num_connectors; i++) {
379                         drm_connector = set->connectors[i];
380                         if (!drm_connector) {
381                                 DRM_ERROR("No connector\n");
382                                 goto out;
383                         }
384                         connector = to_nv50_connector(drm_connector);
385
386                         /* This is to ensure it knows the connector subtype. */
387                         drm_connector->funcs->fill_modes(drm_connector, 0, 0);
388
389                         output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
390                         if (!output) {
391                                 DRM_ERROR("No output\n");
392                                 goto out;
393                         }
394
395                         rval = output->validate_mode(output, hw_mode);
396                         if (rval != MODE_OK) {
397                                 DRM_ERROR("Mode not ok\n");
398                                 goto out;
399                         }
400
401                         /* verify if any "sneaky" changes happened */
402                         if (output != connector->output)
403                                 modeset = true;
404
405                         if (output->crtc != crtc)
406                                 modeset = true;
407                 }
408         }
409
410         /* Now we verified if anything changed, fail if nothing has. */
411         if (!modeset && !switch_fb && !blank)
412                 DRM_INFO("A seemingly empty modeset encountered, this could be a bug.\n");
413
414         /* Validation done, move on to cleaning of existing structures. */
415         if (modeset) {
416                 /* find encoders that use this crtc. */
417                 list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
418                         if (drm_encoder->crtc == set->crtc) {
419                                 /* find the connector that goes with it */
420                                 list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
421                                         if (drm_connector->encoder == drm_encoder) {
422                                                 drm_connector->encoder =  NULL;
423                                                 break;
424                                         }
425                                 }
426                                 drm_encoder->crtc = NULL;
427                         }
428                 }
429
430                 /* now find if our desired encoders or connectors are in use already. */
431                 for (i = 0; i < set->num_connectors; i++) {
432                         drm_connector = set->connectors[i];
433                         if (!drm_connector) {
434                                 DRM_ERROR("No connector\n");
435                                 goto out;
436                         }
437
438                         if (!drm_connector->encoder)
439                                 continue;
440
441                         drm_encoder = drm_connector->encoder;
442                         drm_connector->encoder = NULL;
443
444                         if (!drm_encoder->crtc)
445                                 continue;
446
447                         drm_crtc = drm_encoder->crtc;
448                         drm_encoder->crtc = NULL;
449
450                         drm_crtc->enabled = false;
451                 }
452
453                 /* Time to wire up the public encoder, the private one will be handled later. */
454                 for (i = 0; i < set->num_connectors; i++) {
455                         drm_connector = set->connectors[i];
456                         if (!drm_connector) {
457                                 DRM_ERROR("No connector\n");
458                                 goto out;
459                         }
460
461                         output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
462                         if (!output) {
463                                 DRM_ERROR("No output\n");
464                                 goto out;
465                         }
466
467                         /* find the encoder public structure that matches out output structure. */
468                         drm_encoder = to_nv50_kms_encoder(output);
469
470                         if (!drm_encoder) {
471                                 DRM_ERROR("No encoder\n");
472                                 goto out;
473                         }
474
475                         drm_encoder->crtc = set->crtc;
476                         set->crtc->enabled = true;
477                         drm_connector->encoder = drm_encoder;
478                 }
479         }
480
481         /**
482          * Disable crtc.
483          */
484
485         if (blank) {
486                 crtc = to_nv50_crtc(set->crtc);
487
488                 set->crtc->enabled = false;
489
490                 /* disconnect encoders and connectors */
491                 for (i = 0; i < set->num_connectors; i++) {
492                         drm_connector = set->connectors[i];
493
494                         if (!drm_connector->encoder)
495                                 continue;
496
497                         drm_connector->encoder->crtc = NULL;
498                         drm_connector->encoder = NULL;
499                 }
500         }
501
502         /**
503          * All state should now be updated, now onto the real work.
504          */
505
506         /* mirror everything to the private structs */
507         nv50_kms_mirror_routing(dev);
508
509         /**
510          * Bind framebuffer.
511          */
512
513         if (switch_fb) {
514                 crtc = to_nv50_crtc(set->crtc);
515
516                 /* set framebuffer */
517                 set->crtc->fb = set->fb;
518
519                 /* set private framebuffer */
520                 crtc = to_nv50_crtc(set->crtc);
521                 fb_info.block = find_block_by_handle(dev_priv->fb_heap, set->fb->mm_handle);
522                 fb_info.width = set->fb->width;
523                 fb_info.height = set->fb->height;
524                 fb_info.depth = set->fb->depth;
525                 fb_info.bpp = set->fb->bits_per_pixel;
526                 fb_info.pitch = set->fb->pitch;
527                 fb_info.x = set->x;
528                 fb_info.y = set->y;
529
530                 rval = crtc->fb->bind(crtc, &fb_info);
531                 if (rval != 0) {
532                         DRM_ERROR("fb_bind failed\n");
533                         goto out;
534                 }
535         }
536
537         /* this is !cursor_show */
538         if (!crtc->cursor->enabled) {
539                 rval = crtc->cursor->enable(crtc);
540                 if (rval != 0) {
541                         DRM_ERROR("cursor_enable failed\n");
542                         goto out;
543                 }
544         }
545
546         /**
547          * Blanking.
548          */
549
550         if (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                 /* detach any outputs that are currently unused */
560                 list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
561                         if (!drm_encoder->crtc) {
562                                 output = to_nv50_output(drm_encoder);
563
564                                 rval = output->execute_mode(output, true);
565                                 if (rval != 0) {
566                                         DRM_ERROR("detaching output failed\n");
567                                         goto out;
568                                 }
569                         }
570                 }
571         }
572
573         /**
574          * Change framebuffer, without changing mode.
575          */
576
577         if (switch_fb && !modeset && !blank) {
578                 crtc = to_nv50_crtc(set->crtc);
579
580                 rval = crtc->set_fb(crtc);
581                 if (rval != 0) {
582                         DRM_ERROR("set_fb failed\n");
583                         goto out;
584                 }
585
586                 /* this also sets the fb offset */
587                 rval = crtc->blank(crtc, false);
588                 if (rval != 0) {
589                         DRM_ERROR("unblanking failed\n");
590                         goto out;
591                 }
592         }
593
594         /**
595          * Normal modesetting.
596          */
597
598         if (modeset) {
599                 crtc = to_nv50_crtc(set->crtc);
600
601                 /* disconnect unused outputs */
602                 list_for_each_entry(output, &display->outputs, item) {
603                         if (output->crtc) {
604                                 crtc_mask |= 1 << output->crtc->index;
605                         } else {
606                                 rval = output->execute_mode(output, true);
607                                 if (rval != 0) {
608                                         DRM_ERROR("detaching output failed\n");
609                                         goto out;
610                                 }
611                         }
612                 }
613
614                 /* blank any unused crtcs */
615                 list_for_each_entry(crtc, &display->crtcs, item) {
616                         if (!(crtc_mask & (1 << crtc->index)))
617                                 crtc->blank(crtc, true);
618                 }
619
620                 crtc = to_nv50_crtc(set->crtc);
621
622                 rval = crtc->set_mode(crtc, hw_mode);
623                 if (rval != 0) {
624                         DRM_ERROR("crtc mode set failed\n");
625                         goto out;
626                 }
627
628                 /* find native mode. */
629                 list_for_each_entry(output, &display->outputs, item) {
630                         if (output->crtc != crtc)
631                                 continue;
632
633                         *crtc->native_mode = *output->native_mode;
634                         list_for_each_entry(connector, &display->connectors, item) {
635                                 if (connector->output != output)
636                                         continue;
637
638                                 crtc->requested_scaling_mode = connector->requested_scaling_mode;
639                                 crtc->use_dithering = connector->use_dithering;
640                                 break;
641                         }
642
643                         if (crtc->requested_scaling_mode == SCALE_NON_GPU)
644                                 crtc->use_native_mode = false;
645                         else
646                                 crtc->use_native_mode = true;
647
648                         break; /* no use in finding more than one mode */
649                 }
650
651                 rval = crtc->execute_mode(crtc);
652                 if (rval != 0) {
653                         DRM_ERROR("crtc execute mode failed\n");
654                         goto out;
655                 }
656
657                 list_for_each_entry(output, &display->outputs, item) {
658                         if (output->crtc != crtc)
659                                 continue;
660
661                         rval = output->execute_mode(output, false);
662                         if (rval != 0) {
663                                 DRM_ERROR("output execute mode failed\n");
664                                 goto out;
665                         }
666                 }
667
668                 rval = crtc->set_scale(crtc);
669                 if (rval != 0) {
670                         DRM_ERROR("crtc set scale failed\n");
671                         goto out;
672                 }
673
674                 /* next line changes crtc, so putting it here is important */
675                 display->last_crtc = crtc->index;
676         }
677
678         /* always reset dpms, regardless if any other modesetting is done. */
679         if (!blank) {
680                 /* this is executed immediately */
681                 list_for_each_entry(output, &display->outputs, item) {
682                         if (output->crtc != crtc)
683                                 continue;
684
685                         rval = output->set_power_mode(output, DRM_MODE_DPMS_ON);
686                         if (rval != 0) {
687                                 DRM_ERROR("output set power mode failed\n");
688                                 goto out;
689                         }
690                 }
691
692                 /* update dpms state to DPMSModeOn */
693                 for (i = 0; i < set->num_connectors; i++) {
694                         drm_connector = set->connectors[i];
695                         if (!drm_connector) {
696                                 DRM_ERROR("No connector\n");
697                                 goto out;
698                         }
699
700                         rval = drm_connector_property_set_value(drm_connector,
701                                         dev->mode_config.dpms_property,
702                                         DRM_MODE_DPMS_ON);
703                         if (rval != 0) {
704                                 DRM_ERROR("failed to update dpms state\n");
705                                 goto out;
706                         }
707                 }
708         }
709
710         display->update(display);
711
712         /* Update the current mode, now that all has gone well. */
713         if (modeset) {
714                 set->crtc->mode = *(set->mode);
715                 set->crtc->x = set->x;
716                 set->crtc->y = set->y;
717         }
718
719         kfree(hw_mode);
720
721         return 0;
722
723 out:
724         kfree(hw_mode);
725
726         if (rval != 0)
727                 return rval;
728         else
729                 return -EINVAL;
730 }
731
732 static void nv50_kms_crtc_destroy(struct drm_crtc *drm_crtc)
733 {
734         struct nv50_crtc *crtc = to_nv50_crtc(drm_crtc);
735
736         drm_crtc_cleanup(drm_crtc);
737
738         /* this will even destroy the public structure. */
739         crtc->destroy(crtc);
740 }
741
742 static const struct drm_crtc_funcs nv50_kms_crtc_funcs = {
743         .save = NULL,
744         .restore = NULL,
745         .cursor_set = nv50_kms_crtc_cursor_set,
746         .cursor_move = nv50_kms_crtc_cursor_move,
747         .gamma_set = nv50_kms_crtc_gamma_set,
748         .set_config = nv50_kms_crtc_set_config,
749         .destroy = nv50_kms_crtc_destroy,
750 };
751
752 static int nv50_kms_crtcs_init(struct drm_device *dev)
753 {
754         struct nv50_display *display = nv50_get_display(dev);
755         struct nv50_crtc *crtc = NULL;
756
757         /*
758          * This may look a bit confusing, but:
759          * The internal structure is already allocated and so is the public one.
760          * Just a matter of getting to the memory and register it.
761          */
762         list_for_each_entry(crtc, &display->crtcs, item) {
763                 struct drm_crtc *drm_crtc = to_nv50_kms_crtc(crtc);
764
765                 drm_crtc_init(dev, drm_crtc, &nv50_kms_crtc_funcs);
766
767                 /* init lut storage */
768                 drm_mode_crtc_set_gamma_size(drm_crtc, 256);
769         }
770
771         return 0;
772 }
773
774 /*
775  * Encoder functions
776  */
777
778 static void nv50_kms_encoder_destroy(struct drm_encoder *drm_encoder)
779 {
780         struct nv50_output *output = to_nv50_output(drm_encoder);
781
782         drm_encoder_cleanup(drm_encoder);
783
784         /* this will even destroy the public structure. */
785         output->destroy(output);
786 }
787
788 static const struct drm_encoder_funcs nv50_kms_encoder_funcs = {
789         .destroy = nv50_kms_encoder_destroy,
790 };
791
792 static int nv50_kms_encoders_init(struct drm_device *dev)
793 {
794         struct nv50_display *display = nv50_get_display(dev);
795         struct nv50_output *output = NULL;
796
797         list_for_each_entry(output, &display->outputs, item) {
798                 struct drm_encoder *drm_encoder = to_nv50_kms_encoder(output);
799                 uint32_t type = DRM_MODE_ENCODER_NONE;
800
801                 switch (output->type) {
802                         case OUTPUT_DAC:
803                                 type = DRM_MODE_ENCODER_DAC;
804                                 break;
805                         case OUTPUT_TMDS:
806                                 type = DRM_MODE_ENCODER_TMDS;
807                                 break;
808                         case OUTPUT_LVDS:
809                                 type = DRM_MODE_ENCODER_LVDS;
810                                 break;
811                         case OUTPUT_TV:
812                                 type = DRM_MODE_ENCODER_TVDAC;
813                                 break;
814                         default:
815                                 type = DRM_MODE_ENCODER_NONE;
816                                 break;
817                 }
818
819                 if (type == DRM_MODE_ENCODER_NONE) {
820                         DRM_ERROR("DRM_MODE_ENCODER_NONE encountered\n");
821                         continue;
822                 }
823
824                 drm_encoder_init(dev, drm_encoder, &nv50_kms_encoder_funcs, type);
825
826                 /* I've never seen possible crtc's restricted. */
827                 drm_encoder->possible_crtcs = 3;
828                 drm_encoder->possible_clones = 0;
829         }
830
831         return 0;
832 }
833
834 /*
835  * Connector functions
836  */
837
838 bool nv50_kms_connector_is_digital(struct drm_connector *drm_connector)
839 {
840         struct drm_device *dev = drm_connector->dev;
841
842         switch (drm_connector->connector_type) {
843                 case DRM_MODE_CONNECTOR_VGA:
844                 case DRM_MODE_CONNECTOR_SVIDEO:
845                         return false;
846                 case DRM_MODE_CONNECTOR_DVID:
847                 case DRM_MODE_CONNECTOR_LVDS:
848                         return true;
849                 default:
850                         break;
851         }
852
853         if (drm_connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
854                 int rval;
855                 uint64_t prop_val;
856
857                 rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_select_subconnector_property, &prop_val);
858                 if (rval) {
859                         DRM_ERROR("Unable to find select subconnector property, defaulting to DVI-D\n");
860                         return true;
861                 }
862
863                 /* Is a subconnector explicitly selected? */
864                 switch (prop_val) {
865                         case DRM_MODE_SUBCONNECTOR_DVID:
866                                 return true;
867                         case DRM_MODE_SUBCONNECTOR_DVIA:
868                                 return false;
869                         default:
870                                 break;
871                 }
872
873                 rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_subconnector_property, &prop_val);
874                 if (rval) {
875                         DRM_ERROR("Unable to find subconnector property, defaulting to DVI-D\n");
876                         return true;
877                 }
878
879                 /* Do we know what subconnector we currently have connected? */
880                 switch (prop_val) {
881                         case DRM_MODE_SUBCONNECTOR_DVID:
882                                 return true;
883                         case DRM_MODE_SUBCONNECTOR_DVIA:
884                                 return false;
885                         default:
886                                 DRM_ERROR("Unknown subconnector value, defaulting to DVI-D\n");
887                                 return true;
888                 }
889         }
890
891         DRM_ERROR("Unknown connector type, defaulting to analog\n");
892         return false;
893 }
894
895 void nv50_kms_connector_detect_all(struct drm_device *dev)
896 {
897         struct drm_connector *drm_connector = NULL;
898
899         list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
900                 drm_connector->funcs->detect(drm_connector);
901         }
902 }
903
904 static enum drm_connector_status nv50_kms_connector_detect(struct drm_connector *drm_connector)
905 {
906         struct nv50_connector *connector = to_nv50_connector(drm_connector);
907         struct drm_device *dev = drm_connector->dev;
908         bool connected;
909         int old_status;
910
911         connected = connector->detect(connector);
912
913         old_status = drm_connector->status;
914
915         if (connected)
916                 drm_connector->status = connector_status_connected;
917         else
918                 drm_connector->status = connector_status_disconnected;
919
920         /* update our modes whenever there is reason to */
921         if (old_status != drm_connector->status) {
922                 drm_connector->funcs->fill_modes(drm_connector, 0, 0);
923
924                 /* notify fb of changes */
925                 dev->mode_config.funcs->fb_changed(dev);
926         }
927
928         return drm_connector->status;
929 }
930
931 static void nv50_kms_connector_destroy(struct drm_connector *drm_connector)
932 {
933         struct nv50_connector *connector = to_nv50_connector(drm_connector);
934
935         drm_sysfs_connector_remove(drm_connector);
936         drm_connector_cleanup(drm_connector);
937
938         /* this will even destroy the public structure. */
939         connector->destroy(connector);
940 }
941
942 /*
943  * Detailed mode info for a standard 640x480@60Hz monitor
944  */
945 static struct drm_display_mode std_mode[] = {
946         /*{ DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
947                  752, 800, 0, 480, 490, 492, 525, 0,
948                  DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },*/ /* 640x480@60Hz */
949         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DEFAULT, 135000, 1280, 1296,
950                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
951                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
952 };
953
954 static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, uint32_t maxX, uint32_t maxY)
955 {
956         struct nv50_connector *connector = to_nv50_connector(drm_connector);
957         struct drm_device *dev = drm_connector->dev;
958         int rval = 0;
959         bool connected;
960         struct drm_display_mode *mode, *t;
961         struct edid *edid = NULL;
962
963         NV50_DEBUG("%s\n", drm_get_connector_name(drm_connector));
964         /* set all modes to the unverified state */
965         list_for_each_entry_safe(mode, t, &drm_connector->modes, head)
966                 mode->status = MODE_UNVERIFIED;
967
968         connected = connector->detect(connector);
969
970         if (connected)
971                 drm_connector->status = connector_status_connected;
972         else
973                 drm_connector->status = connector_status_disconnected;
974
975         if (!connected) {
976                 NV50_DEBUG("%s is disconnected\n", drm_get_connector_name(drm_connector));
977         }
978
979         /* Not all connnectors have an i2c channel. */
980         if (connected && connector->i2c_chan)
981                 edid = (struct edid *) drm_do_probe_ddc_edid(&connector->i2c_chan->adapter);
982
983         /* This will remove edid if needed. */
984         drm_mode_connector_update_edid_property(drm_connector, edid);
985
986         if (edid) {
987                 rval = drm_add_edid_modes(drm_connector, edid);
988
989                 /* 2 encoders per connector */
990                 /* eventually do this based on load detect and hot plug detect */
991                 if (drm_connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
992                         uint64_t subtype = 0;
993                         if (edid->digital)
994                                 subtype = DRM_MODE_SUBCONNECTOR_DVID;
995                         else
996                                 subtype = DRM_MODE_SUBCONNECTOR_DVIA;
997                         drm_connector_property_set_value(drm_connector, dev->mode_config.dvi_i_subconnector_property, subtype);
998                 }
999
1000                 kfree(edid);
1001         }
1002
1003         if (rval) /* number of modes  > 1 */
1004                 drm_mode_connector_list_update(drm_connector);
1005
1006         if (maxX && maxY)
1007                 drm_mode_validate_size(dev, &drm_connector->modes, maxX, maxY, 0);
1008
1009         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
1010                 if (mode->status == MODE_OK) {
1011                         struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
1012                         struct nv50_output *output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
1013
1014                         mode->status = output->validate_mode(output, hw_mode);
1015                         /* find native mode, TODO: also check if we actually found one */
1016                         if (mode->status == MODE_OK) {
1017                                 if (mode->type & DRM_MODE_TYPE_PREFERRED)
1018                                         *output->native_mode = *hw_mode;
1019                         }
1020                         kfree(hw_mode);
1021                 }
1022         }
1023
1024         /* revalidate now that we have native mode */
1025         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
1026                 if (mode->status == MODE_OK) {
1027                         struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
1028                         struct nv50_output *output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
1029
1030                         mode->status = output->validate_mode(output, hw_mode);
1031                         kfree(hw_mode);
1032                 }
1033         }
1034
1035         drm_mode_prune_invalid(dev, &drm_connector->modes, true);
1036
1037         /* pruning is done, so bail out. */
1038         if (!connected)
1039                 return;
1040
1041         if (list_empty(&drm_connector->modes)) {
1042                 struct drm_display_mode *stdmode;
1043                 struct nouveau_hw_mode *hw_mode;
1044                 struct nv50_output *output;
1045
1046                 NV50_DEBUG("No valid modes on %s\n", drm_get_connector_name(drm_connector));
1047
1048                 /* Should we do this here ???
1049                  * When no valid EDID modes are available we end up
1050                  * here and bailed in the past, now we add a standard
1051                  * 640x480@60Hz mode and carry on.
1052                  */
1053                 stdmode = drm_mode_duplicate(dev, &std_mode[0]);
1054                 drm_mode_probed_add(drm_connector, stdmode);
1055                 drm_mode_list_concat(&drm_connector->probed_modes,
1056                                      &drm_connector->modes);
1057
1058                 /* also add it as native mode */
1059                 hw_mode = nv50_kms_to_hw_mode(mode);
1060                 output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
1061
1062                 if (hw_mode)
1063                         *output->native_mode = *hw_mode;
1064
1065                 DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
1066                           drm_get_connector_name(drm_connector));
1067         }
1068
1069         drm_mode_sort(&drm_connector->modes);
1070
1071         NV50_DEBUG("Probed modes for %s\n", drm_get_connector_name(drm_connector));
1072
1073         list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
1074                 mode->vrefresh = drm_mode_vrefresh(mode);
1075
1076                 /* is this needed, as it's unused by the driver? */
1077                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1078                 drm_mode_debug_printmodeline(mode);
1079         }
1080 }
1081
1082 static int nv50_kms_connector_set_property(struct drm_connector *drm_connector,
1083                                         struct drm_property *property,
1084                                         uint64_t value)
1085 {
1086         struct drm_device *dev = drm_connector->dev;
1087         struct nv50_connector *connector = to_nv50_connector(drm_connector);
1088         int rval = 0;
1089         bool delay_change = false;
1090
1091         /* DPMS */
1092         if (property == dev->mode_config.dpms_property && drm_connector->encoder) {
1093                 struct nv50_output *output = to_nv50_output(drm_connector->encoder);
1094
1095                 rval = output->set_power_mode(output, (int) value);
1096
1097                 return rval;
1098         }
1099
1100         /* Scaling mode */
1101         if (property == dev->mode_config.scaling_mode_property) {
1102                 struct nv50_crtc *crtc = NULL;
1103                 struct nv50_display *display = nv50_get_display(dev);
1104                 int internal_value = 0;
1105
1106                 switch (value) {
1107                         case DRM_MODE_SCALE_NON_GPU:
1108                                 internal_value = SCALE_NON_GPU;
1109                                 break;
1110                         case DRM_MODE_SCALE_FULLSCREEN:
1111                                 internal_value = SCALE_FULLSCREEN;
1112                                 break;
1113                         case DRM_MODE_SCALE_NO_SCALE:
1114                                 internal_value = SCALE_NOSCALE;
1115                                 break;
1116                         case DRM_MODE_SCALE_ASPECT:
1117                                 internal_value = SCALE_ASPECT;
1118                                 break;
1119                         default:
1120                                 break;
1121                 }
1122
1123                 /* LVDS always needs gpu scaling */
1124                 if (connector->type == CONNECTOR_LVDS && internal_value == SCALE_NON_GPU)
1125                         return -EINVAL;
1126
1127                 connector->requested_scaling_mode = internal_value;
1128
1129                 if (drm_connector->encoder && drm_connector->encoder->crtc)
1130                         crtc = to_nv50_crtc(drm_connector->encoder->crtc);
1131
1132                 if (!crtc)
1133                         return 0;
1134
1135                 crtc->requested_scaling_mode = connector->requested_scaling_mode;
1136
1137                 /* going from and to a gpu scaled regime requires a modesetting, so wait until next modeset */
1138                 if (crtc->scaling_mode == SCALE_NON_GPU || internal_value == SCALE_NON_GPU) {
1139                         DRM_INFO("Moving from or to a non-gpu scaled mode, this will be processed upon next modeset.");
1140                         delay_change = true;
1141                 }
1142
1143                 if (delay_change)
1144                         return 0;
1145
1146                 rval = crtc->set_scale(crtc);
1147                 if (rval)
1148                         return rval;
1149
1150                 /* process command buffer */
1151                 display->update(display);
1152
1153                 return 0;
1154         }
1155
1156         /* Dithering */
1157         if (property == dev->mode_config.dithering_mode_property) {
1158                 struct nv50_crtc *crtc = NULL;
1159                 struct nv50_display *display = nv50_get_display(dev);
1160
1161                 if (value == DRM_MODE_DITHERING_ON)
1162                         connector->use_dithering = true;
1163                 else
1164                         connector->use_dithering = false;
1165
1166                 if (drm_connector->encoder && drm_connector->encoder->crtc)
1167                         crtc = to_nv50_crtc(drm_connector->encoder->crtc);
1168
1169                 if (!crtc)
1170                         return 0;
1171
1172                 /* update hw state */
1173                 crtc->use_dithering = connector->use_dithering;
1174                 rval = crtc->set_dither(crtc);
1175                 if (rval)
1176                         return rval;
1177
1178                 /* process command buffer */
1179                 display->update(display);
1180
1181                 return 0;
1182         }
1183
1184         return -EINVAL;
1185 }
1186
1187 static const struct drm_connector_funcs nv50_kms_connector_funcs = {
1188         .save = NULL,
1189         .restore = NULL,
1190         .detect = nv50_kms_connector_detect,
1191         .destroy = nv50_kms_connector_destroy,
1192         .fill_modes = nv50_kms_connector_fill_modes,
1193         .set_property = nv50_kms_connector_set_property
1194 };
1195
1196 static int nv50_kms_get_scaling_mode(struct drm_connector *drm_connector)
1197 {
1198         struct nv50_connector *connector = NULL;
1199         int drm_mode = 0;
1200
1201         if (!drm_connector) {
1202                 DRM_ERROR("drm_connector is NULL\n");
1203                 return 0;
1204         }
1205
1206         connector = to_nv50_connector(drm_connector);
1207
1208         switch (connector->requested_scaling_mode) {
1209                 case SCALE_NON_GPU:
1210                         drm_mode = DRM_MODE_SCALE_NON_GPU;
1211                         break;
1212                 case SCALE_FULLSCREEN:
1213                         drm_mode = DRM_MODE_SCALE_FULLSCREEN;
1214                         break;
1215                 case SCALE_NOSCALE:
1216                         drm_mode = DRM_MODE_SCALE_NO_SCALE;
1217                         break;
1218                 case SCALE_ASPECT:
1219                         drm_mode = DRM_MODE_SCALE_ASPECT;
1220                         break;
1221                 default:
1222                         break;
1223         }
1224
1225         return drm_mode;
1226 }
1227
1228 static int nv50_kms_connectors_init(struct drm_device *dev)
1229 {
1230         struct nv50_display *display = nv50_get_display(dev);
1231         struct nv50_connector *connector = NULL;
1232         int i;
1233
1234         /* Initialise some optional connector properties. */
1235         drm_mode_create_scaling_mode_property(dev);
1236         drm_mode_create_dithering_property(dev);
1237
1238         list_for_each_entry(connector, &display->connectors, item) {
1239                 struct drm_connector *drm_connector = to_nv50_kms_connector(connector);
1240                 uint32_t type = DRM_MODE_CONNECTOR_Unknown;
1241
1242                 switch (connector->type) {
1243                         case CONNECTOR_VGA:
1244                                 type = DRM_MODE_CONNECTOR_VGA;
1245                                 break;
1246                         case CONNECTOR_DVI_D:
1247                                 type = DRM_MODE_CONNECTOR_DVID;
1248                                 break;
1249                         case CONNECTOR_DVI_I:
1250                                 type = DRM_MODE_CONNECTOR_DVII;
1251                                 break;
1252                         case CONNECTOR_LVDS:
1253                                 type = DRM_MODE_CONNECTOR_LVDS;
1254                                 break;
1255                         case CONNECTOR_TV:
1256                                 type = DRM_MODE_CONNECTOR_SVIDEO;
1257                                 break;
1258                         default:
1259                                 type = DRM_MODE_CONNECTOR_Unknown;
1260                                 break;
1261                 }
1262
1263                 if (type == DRM_MODE_CONNECTOR_Unknown) {
1264                         DRM_ERROR("DRM_MODE_CONNECTOR_Unknown encountered\n");
1265                         continue;
1266                 }
1267
1268                 /* It should be allowed sometimes, but let's be safe for the moment. */
1269                 drm_connector->interlace_allowed = false;
1270                 drm_connector->doublescan_allowed = false;
1271
1272                 drm_connector_init(dev, drm_connector, &nv50_kms_connector_funcs, type);
1273
1274                 /* Init DVI-I specific properties */
1275                 if (type == DRM_MODE_CONNECTOR_DVII) {
1276                         drm_mode_create_dvi_i_properties(dev);
1277                         drm_connector_attach_property(drm_connector, dev->mode_config.dvi_i_subconnector_property, 0);
1278                         drm_connector_attach_property(drm_connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
1279                 }
1280
1281                 /* If supported in the future, it will have to use the scalers internally and not expose them. */
1282                 if (type != DRM_MODE_CONNECTOR_SVIDEO) {
1283                         drm_connector_attach_property(drm_connector, dev->mode_config.scaling_mode_property, nv50_kms_get_scaling_mode(drm_connector));
1284                 }
1285
1286                 drm_connector_attach_property(drm_connector, dev->mode_config.dithering_mode_property, connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
1287
1288                 /* attach encoders, possibilities are analog + digital */
1289                 for (i = 0; i < 2; i++) {
1290                         struct drm_encoder *drm_encoder = NULL;
1291                         struct nv50_output *output = connector->to_output(connector, i);
1292                         if (!output)
1293                                 continue;
1294
1295                         drm_encoder = to_nv50_kms_encoder(output);
1296                         if (!drm_encoder) {
1297                                 DRM_ERROR("No struct drm_connector to match struct nv50_output\n");
1298                                 continue;
1299                         }
1300
1301                         drm_mode_connector_attach_encoder(drm_connector, drm_encoder);
1302                 }
1303
1304                 drm_sysfs_connector_add(drm_connector);
1305         }
1306
1307         return 0;
1308 }
1309
1310 /*
1311  * Main functions
1312  */
1313
1314 int nv50_kms_init(struct drm_device *dev)
1315 {
1316         struct drm_nouveau_private *dev_priv = dev->dev_private;
1317         struct nv50_kms_priv *kms_priv = kzalloc(sizeof(struct nv50_kms_priv), GFP_KERNEL);
1318         struct nv50_display *display = NULL;
1319         int rval = 0;
1320
1321         if (!kms_priv)
1322                 return -ENOMEM;
1323
1324         dev_priv->kms_priv = kms_priv;
1325
1326         /* function pointers */
1327         /* an allocation interface that deals with the outside world, without polluting the core. */
1328         dev_priv->alloc_crtc = nv50_kms_alloc_crtc;
1329         dev_priv->alloc_output = nv50_kms_alloc_output;
1330         dev_priv->alloc_connector = nv50_kms_alloc_connector;
1331
1332         dev_priv->free_crtc = nv50_kms_free_crtc;
1333         dev_priv->free_output = nv50_kms_free_output;
1334         dev_priv->free_connector = nv50_kms_free_connector;
1335
1336         /* bios is needed for tables. */
1337         rval = nouveau_parse_bios(dev);
1338         if (rval != 0)
1339                 goto out;
1340
1341         /* init basic kernel modesetting */
1342         drm_mode_config_init(dev);
1343
1344         dev->mode_config.min_width = 0;
1345         dev->mode_config.min_height = 0;
1346
1347         dev->mode_config.funcs = (void *)&nv50_kms_mode_funcs;
1348
1349         dev->mode_config.max_width = 8192;
1350         dev->mode_config.max_height = 8192;
1351
1352         dev->mode_config.fb_base = dev_priv->fb_phys;
1353
1354         /* init kms lists */
1355         INIT_LIST_HEAD(&kms_priv->crtcs);
1356         INIT_LIST_HEAD(&kms_priv->encoders);
1357         INIT_LIST_HEAD(&kms_priv->connectors);
1358
1359         /* init the internal core, must be done first. */
1360         rval = nv50_display_create(dev);
1361         if (rval != 0)
1362                 goto out;
1363
1364         display = nv50_get_display(dev);
1365         if (!display) {
1366                 rval = -EINVAL;
1367                 goto out;
1368         }
1369
1370         /* pre-init now */
1371         rval = display->pre_init(display);
1372         if (rval != 0)
1373                 goto out;
1374
1375         /* init external layer */
1376         rval = nv50_kms_crtcs_init(dev);
1377         if (rval != 0)
1378                 goto out;
1379
1380         rval = nv50_kms_encoders_init(dev);
1381         if (rval != 0)
1382                 goto out;
1383
1384         rval = nv50_kms_connectors_init(dev);
1385         if (rval != 0)
1386                 goto out;
1387
1388         /* init now, this'll kill the textmode */
1389         rval = display->init(display);
1390         if (rval != 0)
1391                 goto out;
1392
1393         /* process cmdbuffer */
1394         display->update(display);
1395
1396         return 0;
1397
1398 out:
1399         kfree(kms_priv);
1400         dev_priv->kms_priv = NULL;
1401
1402         return rval;
1403 }
1404
1405 int nv50_kms_destroy(struct drm_device *dev)
1406 {
1407         drm_mode_config_cleanup(dev);
1408
1409         return 0;
1410 }
1411