]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/mgag200/mgag200_mode.c
Merge branch 'v3.5-rc7-fixes' of git://github.com/lunn/linux into fixes
[karo-tx-linux.git] / drivers / gpu / drm / mgag200 / mgag200_mode.c
1 /*
2  * Copyright 2010 Matt Turner.
3  * Copyright 2012 Red Hat
4  *
5  * This file is subject to the terms and conditions of the GNU General
6  * Public License version 2. See the file COPYING in the main
7  * directory of this archive for more details.
8  *
9  * Authors: Matthew Garrett
10  *          Matt Turner
11  *          Dave Airlie
12  */
13
14 #include <linux/delay.h>
15
16 #include "drmP.h"
17 #include "drm.h"
18 #include "drm_crtc_helper.h"
19
20 #include "mgag200_drv.h"
21
22 #define MGAG200_LUT_SIZE 256
23
24 /*
25  * This file contains setup code for the CRTC.
26  */
27
28 static void mga_crtc_load_lut(struct drm_crtc *crtc)
29 {
30         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
31         struct drm_device *dev = crtc->dev;
32         struct mga_device *mdev = dev->dev_private;
33         int i;
34
35         if (!crtc->enabled)
36                 return;
37
38         WREG8(DAC_INDEX + MGA1064_INDEX, 0);
39
40         for (i = 0; i < MGAG200_LUT_SIZE; i++) {
41                 /* VGA registers */
42                 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]);
43                 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
44                 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_b[i]);
45         }
46 }
47
48 static inline void mga_wait_vsync(struct mga_device *mdev)
49 {
50         unsigned int count = 0;
51         unsigned int status = 0;
52
53         do {
54                 status = RREG32(MGAREG_Status);
55                 count++;
56         } while ((status & 0x08) && (count < 250000));
57         count = 0;
58         status = 0;
59         do {
60                 status = RREG32(MGAREG_Status);
61                 count++;
62         } while (!(status & 0x08) && (count < 250000));
63 }
64
65 static inline void mga_wait_busy(struct mga_device *mdev)
66 {
67         unsigned int count = 0;
68         unsigned int status = 0;
69         do {
70                 status = RREG8(MGAREG_Status + 2);
71                 count++;
72         } while ((status & 0x01) && (count < 500000));
73 }
74
75 /*
76  * The core passes the desired mode to the CRTC code to see whether any
77  * CRTC-specific modifications need to be made to it. We're in a position
78  * to just pass that straight through, so this does nothing
79  */
80 static bool mga_crtc_mode_fixup(struct drm_crtc *crtc,
81                                    struct drm_display_mode *mode,
82                                    struct drm_display_mode *adjusted_mode)
83 {
84         return true;
85 }
86
87 static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
88 {
89         unsigned int vcomax, vcomin, pllreffreq;
90         unsigned int delta, tmpdelta, permitteddelta;
91         unsigned int testp, testm, testn;
92         unsigned int p, m, n;
93         unsigned int computed;
94
95         m = n = p = 0;
96         vcomax = 320000;
97         vcomin = 160000;
98         pllreffreq = 25000;
99
100         delta = 0xffffffff;
101         permitteddelta = clock * 5 / 1000;
102
103         for (testp = 8; testp > 0; testp /= 2) {
104                 if (clock * testp > vcomax)
105                         continue;
106                 if (clock * testp < vcomin)
107                         continue;
108
109                 for (testn = 17; testn < 256; testn++) {
110                         for (testm = 1; testm < 32; testm++) {
111                                 computed = (pllreffreq * testn) /
112                                         (testm * testp);
113                                 if (computed > clock)
114                                         tmpdelta = computed - clock;
115                                 else
116                                         tmpdelta = clock - computed;
117                                 if (tmpdelta < delta) {
118                                         delta = tmpdelta;
119                                         m = testm - 1;
120                                         n = testn - 1;
121                                         p = testp - 1;
122                                 }
123                         }
124                 }
125         }
126
127         if (delta > permitteddelta) {
128                 printk(KERN_WARNING "PLL delta too large\n");
129                 return 1;
130         }
131
132         WREG_DAC(MGA1064_PIX_PLLC_M, m);
133         WREG_DAC(MGA1064_PIX_PLLC_N, n);
134         WREG_DAC(MGA1064_PIX_PLLC_P, p);
135         return 0;
136 }
137
138 static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
139 {
140         unsigned int vcomax, vcomin, pllreffreq;
141         unsigned int delta, tmpdelta, permitteddelta;
142         unsigned int testp, testm, testn;
143         unsigned int p, m, n;
144         unsigned int computed;
145         int i, j, tmpcount, vcount;
146         bool pll_locked = false;
147         u8 tmp;
148
149         m = n = p = 0;
150         vcomax = 550000;
151         vcomin = 150000;
152         pllreffreq = 48000;
153
154         delta = 0xffffffff;
155         permitteddelta = clock * 5 / 1000;
156
157         for (testp = 1; testp < 9; testp++) {
158                 if (clock * testp > vcomax)
159                         continue;
160                 if (clock * testp < vcomin)
161                         continue;
162
163                 for (testm = 1; testm < 17; testm++) {
164                         for (testn = 1; testn < 151; testn++) {
165                                 computed = (pllreffreq * testn) /
166                                         (testm * testp);
167                                 if (computed > clock)
168                                         tmpdelta = computed - clock;
169                                 else
170                                         tmpdelta = clock - computed;
171                                 if (tmpdelta < delta) {
172                                         delta = tmpdelta;
173                                         n = testn - 1;
174                                         m = (testm - 1) | ((n >> 1) & 0x80);
175                                         p = testp - 1;
176                                 }
177                         }
178                 }
179         }
180
181         for (i = 0; i <= 32 && pll_locked == false; i++) {
182                 if (i > 0) {
183                         WREG8(MGAREG_CRTC_INDEX, 0x1e);
184                         tmp = RREG8(MGAREG_CRTC_DATA);
185                         if (tmp < 0xff)
186                                 WREG8(MGAREG_CRTC_DATA, tmp+1);
187                 }
188
189                 /* set pixclkdis to 1 */
190                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
191                 tmp = RREG8(DAC_DATA);
192                 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
193                 WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
194
195                 WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
196                 tmp = RREG8(DAC_DATA);
197                 tmp |= MGA1064_REMHEADCTL_CLKDIS;
198                 WREG_DAC(MGA1064_REMHEADCTL, tmp);
199
200                 /* select PLL Set C */
201                 tmp = RREG8(MGAREG_MEM_MISC_READ);
202                 tmp |= 0x3 << 2;
203                 WREG8(MGAREG_MEM_MISC_WRITE, tmp);
204
205                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
206                 tmp = RREG8(DAC_DATA);
207                 tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
208                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
209
210                 udelay(500);
211
212                 /* reset the PLL */
213                 WREG8(DAC_INDEX, MGA1064_VREF_CTL);
214                 tmp = RREG8(DAC_DATA);
215                 tmp &= ~0x04;
216                 WREG_DAC(MGA1064_VREF_CTL, tmp);
217
218                 udelay(50);
219
220                 /* program pixel pll register */
221                 WREG_DAC(MGA1064_WB_PIX_PLLC_N, n);
222                 WREG_DAC(MGA1064_WB_PIX_PLLC_M, m);
223                 WREG_DAC(MGA1064_WB_PIX_PLLC_P, p);
224
225                 udelay(50);
226
227                 /* turn pll on */
228                 WREG8(DAC_INDEX, MGA1064_VREF_CTL);
229                 tmp = RREG8(DAC_DATA);
230                 tmp |= 0x04;
231                 WREG_DAC(MGA1064_VREF_CTL, tmp);
232
233                 udelay(500);
234
235                 /* select the pixel pll */
236                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
237                 tmp = RREG8(DAC_DATA);
238                 tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
239                 tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
240                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
241
242                 WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
243                 tmp = RREG8(DAC_DATA);
244                 tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
245                 tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
246                 WREG_DAC(MGA1064_REMHEADCTL, tmp);
247
248                 /* reset dotclock rate bit */
249                 WREG8(MGAREG_SEQ_INDEX, 1);
250                 tmp = RREG8(MGAREG_SEQ_DATA);
251                 tmp &= ~0x8;
252                 WREG8(MGAREG_SEQ_DATA, tmp);
253
254                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
255                 tmp = RREG8(DAC_DATA);
256                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
257                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
258
259                 vcount = RREG8(MGAREG_VCOUNT);
260
261                 for (j = 0; j < 30 && pll_locked == false; j++) {
262                         tmpcount = RREG8(MGAREG_VCOUNT);
263                         if (tmpcount < vcount)
264                                 vcount = 0;
265                         if ((tmpcount - vcount) > 2)
266                                 pll_locked = true;
267                         else
268                                 udelay(5);
269                 }
270         }
271         WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
272         tmp = RREG8(DAC_DATA);
273         tmp &= ~MGA1064_REMHEADCTL_CLKDIS;
274         WREG_DAC(MGA1064_REMHEADCTL, tmp);
275         return 0;
276 }
277
278 static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
279 {
280         unsigned int vcomax, vcomin, pllreffreq;
281         unsigned int delta, tmpdelta, permitteddelta;
282         unsigned int testp, testm, testn;
283         unsigned int p, m, n;
284         unsigned int computed;
285         u8 tmp;
286
287         m = n = p = 0;
288         vcomax = 550000;
289         vcomin = 150000;
290         pllreffreq = 50000;
291
292         delta = 0xffffffff;
293         permitteddelta = clock * 5 / 1000;
294
295         for (testp = 16; testp > 0; testp--) {
296                 if (clock * testp > vcomax)
297                         continue;
298                 if (clock * testp < vcomin)
299                         continue;
300
301                 for (testn = 1; testn < 257; testn++) {
302                         for (testm = 1; testm < 17; testm++) {
303                                 computed = (pllreffreq * testn) /
304                                         (testm * testp);
305                                 if (computed > clock)
306                                         tmpdelta = computed - clock;
307                                 else
308                                         tmpdelta = clock - computed;
309                                 if (tmpdelta < delta) {
310                                         delta = tmpdelta;
311                                         n = testn - 1;
312                                         m = testm - 1;
313                                         p = testp - 1;
314                                 }
315                         }
316                 }
317         }
318
319         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
320         tmp = RREG8(DAC_DATA);
321         tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
322         WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
323
324         tmp = RREG8(MGAREG_MEM_MISC_READ);
325         tmp |= 0x3 << 2;
326         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
327
328         WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
329         tmp = RREG8(DAC_DATA);
330         WREG_DAC(MGA1064_PIX_PLL_STAT, tmp & ~0x40);
331
332         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
333         tmp = RREG8(DAC_DATA);
334         tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
335         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
336
337         WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
338         WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
339         WREG_DAC(MGA1064_EV_PIX_PLLC_P, p);
340
341         udelay(50);
342
343         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
344         tmp = RREG8(DAC_DATA);
345         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
346         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
347
348         udelay(500);
349
350         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
351         tmp = RREG8(DAC_DATA);
352         tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
353         tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
354         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
355
356         WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
357         tmp = RREG8(DAC_DATA);
358         WREG_DAC(MGA1064_PIX_PLL_STAT, tmp | 0x40);
359
360         tmp = RREG8(MGAREG_MEM_MISC_READ);
361         tmp |= (0x3 << 2);
362         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
363
364         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
365         tmp = RREG8(DAC_DATA);
366         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
367         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
368
369         return 0;
370 }
371
372 static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
373 {
374         unsigned int vcomax, vcomin, pllreffreq;
375         unsigned int delta, tmpdelta, permitteddelta;
376         unsigned int testp, testm, testn;
377         unsigned int p, m, n;
378         unsigned int computed;
379         int i, j, tmpcount, vcount;
380         u8 tmp;
381         bool pll_locked = false;
382
383         m = n = p = 0;
384         vcomax = 800000;
385         vcomin = 400000;
386         pllreffreq = 3333;
387
388         delta = 0xffffffff;
389         permitteddelta = clock * 5 / 1000;
390
391         for (testp = 16; testp > 0; testp--) {
392                 if (clock * testp > vcomax)
393                         continue;
394                 if (clock * testp < vcomin)
395                         continue;
396
397                 for (testm = 1; testm < 33; testm++) {
398                         for (testn = 1; testn < 257; testn++) {
399                                 computed = (pllreffreq * testn) /
400                                         (testm * testp);
401                                 if (computed > clock)
402                                         tmpdelta = computed - clock;
403                                 else
404                                         tmpdelta = clock - computed;
405                                 if (tmpdelta < delta) {
406                                         delta = tmpdelta;
407                                         n = testn - 1;
408                                         m = (testm - 1) | ((n >> 1) & 0x80);
409                                         p = testp - 1;
410                                 }
411                                 if ((clock * testp) >= 600000)
412                                         p |= 80;
413                         }
414                 }
415         }
416         for (i = 0; i <= 32 && pll_locked == false; i++) {
417                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
418                 tmp = RREG8(DAC_DATA);
419                 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
420                 WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
421
422                 tmp = RREG8(MGAREG_MEM_MISC_READ);
423                 tmp |= 0x3 << 2;
424                 WREG8(MGAREG_MEM_MISC_WRITE, tmp);
425
426                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
427                 tmp = RREG8(DAC_DATA);
428                 tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
429                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
430
431                 udelay(500);
432
433                 WREG_DAC(MGA1064_EH_PIX_PLLC_M, m);
434                 WREG_DAC(MGA1064_EH_PIX_PLLC_N, n);
435                 WREG_DAC(MGA1064_EH_PIX_PLLC_P, p);
436
437                 udelay(500);
438
439                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
440                 tmp = RREG8(DAC_DATA);
441                 tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
442                 tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
443                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
444
445                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
446                 tmp = RREG8(DAC_DATA);
447                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
448                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
449                 WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
450
451                 vcount = RREG8(MGAREG_VCOUNT);
452
453                 for (j = 0; j < 30 && pll_locked == false; j++) {
454                         tmpcount = RREG8(MGAREG_VCOUNT);
455                         if (tmpcount < vcount)
456                                 vcount = 0;
457                         if ((tmpcount - vcount) > 2)
458                                 pll_locked = true;
459                         else
460                                 udelay(5);
461                 }
462         }
463
464         return 0;
465 }
466
467 static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
468 {
469         unsigned int vcomax, vcomin, pllreffreq;
470         unsigned int delta, tmpdelta;
471         unsigned int testr, testn, testm, testo;
472         unsigned int p, m, n;
473         unsigned int computed;
474         int tmp;
475
476         m = n = p = 0;
477         vcomax = 1488000;
478         vcomin = 1056000;
479         pllreffreq = 48000;
480
481         delta = 0xffffffff;
482
483         for (testr = 0; testr < 4; testr++) {
484                 if (delta == 0)
485                         break;
486                 for (testn = 5; testn < 129; testn++) {
487                         if (delta == 0)
488                                 break;
489                         for (testm = 3; testm >= 0; testm--) {
490                                 if (delta == 0)
491                                         break;
492                                 for (testo = 5; testo < 33; testo++) {
493                                         computed = pllreffreq * (testn + 1) /
494                                                 (testr + 1);
495                                         if (computed < vcomin)
496                                                 continue;
497                                         if (computed > vcomax)
498                                                 continue;
499                                         if (computed > clock)
500                                                 tmpdelta = computed - clock;
501                                         else
502                                                 tmpdelta = clock - computed;
503                                         if (tmpdelta < delta) {
504                                                 delta = tmpdelta;
505                                                 m = testm | (testo << 3);
506                                                 n = testn;
507                                                 p = testr | (testr << 3);
508                                         }
509                                 }
510                         }
511                 }
512         }
513
514         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
515         tmp = RREG8(DAC_DATA);
516         tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
517         WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
518
519         WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
520         tmp = RREG8(DAC_DATA);
521         tmp |= MGA1064_REMHEADCTL_CLKDIS;
522         WREG_DAC(MGA1064_REMHEADCTL, tmp);
523
524         tmp = RREG8(MGAREG_MEM_MISC_READ);
525         tmp |= (0x3<<2) | 0xc0;
526         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
527
528         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
529         tmp = RREG8(DAC_DATA);
530         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
531         tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
532         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
533
534         udelay(500);
535
536         WREG_DAC(MGA1064_ER_PIX_PLLC_N, n);
537         WREG_DAC(MGA1064_ER_PIX_PLLC_M, m);
538         WREG_DAC(MGA1064_ER_PIX_PLLC_P, p);
539
540         udelay(50);
541
542         return 0;
543 }
544
545 static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
546 {
547         switch(mdev->type) {
548         case G200_SE_A:
549         case G200_SE_B:
550                 return mga_g200se_set_plls(mdev, clock);
551                 break;
552         case G200_WB:
553                 return mga_g200wb_set_plls(mdev, clock);
554                 break;
555         case G200_EV:
556                 return mga_g200ev_set_plls(mdev, clock);
557                 break;
558         case G200_EH:
559                 return mga_g200eh_set_plls(mdev, clock);
560                 break;
561         case G200_ER:
562                 return mga_g200er_set_plls(mdev, clock);
563                 break;
564         }
565         return 0;
566 }
567
568 static void mga_g200wb_prepare(struct drm_crtc *crtc)
569 {
570         struct mga_device *mdev = crtc->dev->dev_private;
571         u8 tmp;
572         int iter_max;
573
574         /* 1- The first step is to warn the BMC of an upcoming mode change.
575          * We are putting the misc<0> to output.*/
576
577         WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
578         tmp = RREG8(DAC_DATA);
579         tmp |= 0x10;
580         WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
581
582         /* we are putting a 1 on the misc<0> line */
583         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
584         tmp = RREG8(DAC_DATA);
585         tmp |= 0x10;
586         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
587
588         /* 2- Second step to mask and further scan request
589          * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
590          */
591         WREG8(DAC_INDEX, MGA1064_SPAREREG);
592         tmp = RREG8(DAC_DATA);
593         tmp |= 0x80;
594         WREG_DAC(MGA1064_SPAREREG, tmp);
595
596         /* 3a- the third step is to verifu if there is an active scan
597          * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
598          */
599         iter_max = 300;
600         while (!(tmp & 0x1) && iter_max) {
601                 WREG8(DAC_INDEX, MGA1064_SPAREREG);
602                 tmp = RREG8(DAC_DATA);
603                 udelay(1000);
604                 iter_max--;
605         }
606
607         /* 3b- this step occurs only if the remove is actually scanning
608          * we are waiting for the end of the frame which is a 1 on
609          * remvsyncsts (XSPAREREG<1>)
610          */
611         if (iter_max) {
612                 iter_max = 300;
613                 while ((tmp & 0x2) && iter_max) {
614                         WREG8(DAC_INDEX, MGA1064_SPAREREG);
615                         tmp = RREG8(DAC_DATA);
616                         udelay(1000);
617                         iter_max--;
618                 }
619         }
620 }
621
622 static void mga_g200wb_commit(struct drm_crtc *crtc)
623 {
624         u8 tmp;
625         struct mga_device *mdev = crtc->dev->dev_private;
626
627         /* 1- The first step is to ensure that the vrsten and hrsten are set */
628         WREG8(MGAREG_CRTCEXT_INDEX, 1);
629         tmp = RREG8(MGAREG_CRTCEXT_DATA);
630         WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
631
632         /* 2- second step is to assert the rstlvl2 */
633         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
634         tmp = RREG8(DAC_DATA);
635         tmp |= 0x8;
636         WREG8(DAC_DATA, tmp);
637
638         /* wait 10 us */
639         udelay(10);
640
641         /* 3- deassert rstlvl2 */
642         tmp &= ~0x08;
643         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
644         WREG8(DAC_DATA, tmp);
645
646         /* 4- remove mask of scan request */
647         WREG8(DAC_INDEX, MGA1064_SPAREREG);
648         tmp = RREG8(DAC_DATA);
649         tmp &= ~0x80;
650         WREG8(DAC_DATA, tmp);
651
652         /* 5- put back a 0 on the misc<0> line */
653         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
654         tmp = RREG8(DAC_DATA);
655         tmp &= ~0x10;
656         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
657 }
658
659
660 void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
661 {
662         struct mga_device *mdev = crtc->dev->dev_private;
663         u32 addr;
664         int count;
665
666         while (RREG8(0x1fda) & 0x08);
667         while (!(RREG8(0x1fda) & 0x08));
668
669         count = RREG8(MGAREG_VCOUNT) + 2;
670         while (RREG8(MGAREG_VCOUNT) < count);
671
672         addr = offset >> 2;
673         WREG_CRT(0x0d, (u8)(addr & 0xff));
674         WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
675         WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf);
676 }
677
678
679 /* ast is different - we will force move buffers out of VRAM */
680 static int mga_crtc_do_set_base(struct drm_crtc *crtc,
681                                 struct drm_framebuffer *fb,
682                                 int x, int y, int atomic)
683 {
684         struct mga_device *mdev = crtc->dev->dev_private;
685         struct drm_gem_object *obj;
686         struct mga_framebuffer *mga_fb;
687         struct mgag200_bo *bo;
688         int ret;
689         u64 gpu_addr;
690
691         /* push the previous fb to system ram */
692         if (!atomic && fb) {
693                 mga_fb = to_mga_framebuffer(fb);
694                 obj = mga_fb->obj;
695                 bo = gem_to_mga_bo(obj);
696                 ret = mgag200_bo_reserve(bo, false);
697                 if (ret)
698                         return ret;
699                 mgag200_bo_push_sysram(bo);
700                 mgag200_bo_unreserve(bo);
701         }
702
703         mga_fb = to_mga_framebuffer(crtc->fb);
704         obj = mga_fb->obj;
705         bo = gem_to_mga_bo(obj);
706
707         ret = mgag200_bo_reserve(bo, false);
708         if (ret)
709                 return ret;
710
711         ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
712         if (ret) {
713                 mgag200_bo_unreserve(bo);
714                 return ret;
715         }
716
717         if (&mdev->mfbdev->mfb == mga_fb) {
718                 /* if pushing console in kmap it */
719                 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
720                 if (ret)
721                         DRM_ERROR("failed to kmap fbcon\n");
722
723         }
724         mgag200_bo_unreserve(bo);
725
726         DRM_INFO("mga base %llx\n", gpu_addr);
727
728         mga_set_start_address(crtc, (u32)gpu_addr);
729
730         return 0;
731 }
732
733 static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
734                                   struct drm_framebuffer *old_fb)
735 {
736         return mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
737 }
738
739 static int mga_crtc_mode_set(struct drm_crtc *crtc,
740                                 struct drm_display_mode *mode,
741                                 struct drm_display_mode *adjusted_mode,
742                                 int x, int y, struct drm_framebuffer *old_fb)
743 {
744         struct drm_device *dev = crtc->dev;
745         struct mga_device *mdev = dev->dev_private;
746         int hdisplay, hsyncstart, hsyncend, htotal;
747         int vdisplay, vsyncstart, vsyncend, vtotal;
748         int pitch;
749         int option = 0, option2 = 0;
750         int i;
751         unsigned char misc = 0;
752         unsigned char ext_vga[6];
753         unsigned char ext_vga_index24;
754         unsigned char dac_index90 = 0;
755         u8 bppshift;
756
757         static unsigned char dacvalue[] = {
758                 /* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,
759                 /* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,
760                 /* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,
761                 /* 0x18: */     0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
762                 /* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763                 /* 0x28: */     0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
764                 /* 0x30: */     0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
765                 /* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
766                 /* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,
767                 /* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
768         };
769
770         bppshift = mdev->bpp_shifts[(crtc->fb->bits_per_pixel >> 3) - 1];
771
772         switch (mdev->type) {
773         case G200_SE_A:
774         case G200_SE_B:
775                 dacvalue[MGA1064_VREF_CTL] = 0x03;
776                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
777                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
778                                              MGA1064_MISC_CTL_VGA8 |
779                                              MGA1064_MISC_CTL_DAC_RAM_CS;
780                 if (mdev->has_sdram)
781                         option = 0x40049120;
782                 else
783                         option = 0x4004d120;
784                 option2 = 0x00008000;
785                 break;
786         case G200_WB:
787                 dacvalue[MGA1064_VREF_CTL] = 0x07;
788                 option = 0x41049120;
789                 option2 = 0x0000b000;
790                 break;
791         case G200_EV:
792                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
793                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
794                                              MGA1064_MISC_CTL_DAC_RAM_CS;
795                 option = 0x00000120;
796                 option2 = 0x0000b000;
797                 break;
798         case G200_EH:
799                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
800                                              MGA1064_MISC_CTL_DAC_RAM_CS;
801                 option = 0x00000120;
802                 option2 = 0x0000b000;
803                 break;
804         case G200_ER:
805                 dac_index90 = 0;
806                 break;
807         }
808
809         switch (crtc->fb->bits_per_pixel) {
810         case 8:
811                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
812                 break;
813         case 16:
814                 if (crtc->fb->depth == 15)
815                         dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
816                 else
817                         dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
818                 break;
819         case 24:
820                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits;
821                 break;
822         case 32:
823                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits;
824                 break;
825         }
826
827         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
828                 misc |= 0x40;
829         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
830                 misc |= 0x80;
831
832
833         for (i = 0; i < sizeof(dacvalue); i++) {
834                 if ((i <= 0x03) ||
835                     (i == 0x07) ||
836                     (i == 0x0b) ||
837                     (i == 0x0f) ||
838                     ((i >= 0x13) && (i <= 0x17)) ||
839                     (i == 0x1b) ||
840                     (i == 0x1c) ||
841                     ((i >= 0x1f) && (i <= 0x29)) ||
842                     ((i >= 0x30) && (i <= 0x37)))
843                         continue;
844                 if (IS_G200_SE(mdev) &&
845                     ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
846                         continue;
847                 if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH) &&
848                     (i >= 0x44) && (i <= 0x4e))
849                         continue;
850
851                 WREG_DAC(i, dacvalue[i]);
852         }
853
854         if (mdev->type == G200_ER) {
855                 WREG_DAC(0x90, dac_index90);
856         }
857
858
859         if (option)
860                 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
861         if (option2)
862                 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
863
864         WREG_SEQ(2, 0xf);
865         WREG_SEQ(3, 0);
866         WREG_SEQ(4, 0xe);
867
868         pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8);
869         if (crtc->fb->bits_per_pixel == 24)
870                 pitch = pitch >> (4 - bppshift);
871         else
872                 pitch = pitch >> (4 - bppshift);
873
874         hdisplay = mode->hdisplay / 8 - 1;
875         hsyncstart = mode->hsync_start / 8 - 1;
876         hsyncend = mode->hsync_end / 8 - 1;
877         htotal = mode->htotal / 8 - 1;
878
879         /* Work around hardware quirk */
880         if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
881                 htotal++;
882
883         vdisplay = mode->vdisplay - 1;
884         vsyncstart = mode->vsync_start - 1;
885         vsyncend = mode->vsync_end - 1;
886         vtotal = mode->vtotal - 2;
887
888         WREG_GFX(0, 0);
889         WREG_GFX(1, 0);
890         WREG_GFX(2, 0);
891         WREG_GFX(3, 0);
892         WREG_GFX(4, 0);
893         WREG_GFX(5, 0x40);
894         WREG_GFX(6, 0x5);
895         WREG_GFX(7, 0xf);
896         WREG_GFX(8, 0xf);
897
898         WREG_CRT(0, htotal - 4);
899         WREG_CRT(1, hdisplay);
900         WREG_CRT(2, hdisplay);
901         WREG_CRT(3, (htotal & 0x1F) | 0x80);
902         WREG_CRT(4, hsyncstart);
903         WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F));
904         WREG_CRT(6, vtotal & 0xFF);
905         WREG_CRT(7, ((vtotal & 0x100) >> 8) |
906                  ((vdisplay & 0x100) >> 7) |
907                  ((vsyncstart & 0x100) >> 6) |
908                  ((vdisplay & 0x100) >> 5) |
909                  ((vdisplay & 0x100) >> 4) | /* linecomp */
910                  ((vtotal & 0x200) >> 4)|
911                  ((vdisplay & 0x200) >> 3) |
912                  ((vsyncstart & 0x200) >> 2));
913         WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
914                  ((vdisplay & 0x200) >> 3));
915         WREG_CRT(10, 0);
916         WREG_CRT(11, 0);
917         WREG_CRT(12, 0);
918         WREG_CRT(13, 0);
919         WREG_CRT(14, 0);
920         WREG_CRT(15, 0);
921         WREG_CRT(16, vsyncstart & 0xFF);
922         WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
923         WREG_CRT(18, vdisplay & 0xFF);
924         WREG_CRT(19, pitch & 0xFF);
925         WREG_CRT(20, 0);
926         WREG_CRT(21, vdisplay & 0xFF);
927         WREG_CRT(22, (vtotal + 1) & 0xFF);
928         WREG_CRT(23, 0xc3);
929         WREG_CRT(24, vdisplay & 0xFF);
930
931         ext_vga[0] = 0;
932         ext_vga[5] = 0;
933
934         /* TODO interlace */
935
936         ext_vga[0] |= (pitch & 0x300) >> 4;
937         ext_vga[1] = (((htotal - 4) & 0x100) >> 8) |
938                 ((hdisplay & 0x100) >> 7) |
939                 ((hsyncstart & 0x100) >> 6) |
940                 (htotal & 0x40);
941         ext_vga[2] = ((vtotal & 0xc00) >> 10) |
942                 ((vdisplay & 0x400) >> 8) |
943                 ((vdisplay & 0xc00) >> 7) |
944                 ((vsyncstart & 0xc00) >> 5) |
945                 ((vdisplay & 0x400) >> 3);
946         if (crtc->fb->bits_per_pixel == 24)
947                 ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
948         else
949                 ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
950         ext_vga[4] = 0;
951         if (mdev->type == G200_WB)
952                 ext_vga[1] |= 0x88;
953
954         ext_vga_index24 = 0x05;
955
956         /* Set pixel clocks */
957         misc = 0x2d;
958         WREG8(MGA_MISC_OUT, misc);
959
960         mga_crtc_set_plls(mdev, mode->clock);
961
962         for (i = 0; i < 6; i++) {
963                 WREG_ECRT(i, ext_vga[i]);
964         }
965
966         if (mdev->type == G200_ER)
967                 WREG_ECRT(24, ext_vga_index24);
968
969         if (mdev->type == G200_EV) {
970                 WREG_ECRT(6, 0);
971         }
972
973         WREG_ECRT(0, ext_vga[0]);
974         /* Enable mga pixel clock */
975         misc = 0x2d;
976
977         WREG8(MGA_MISC_OUT, misc);
978
979         if (adjusted_mode)
980                 memcpy(&mdev->mode, mode, sizeof(struct drm_display_mode));
981
982         mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
983
984         /* reset tagfifo */
985         if (mdev->type == G200_ER) {
986                 u32 mem_ctl = RREG32(MGAREG_MEMCTL);
987                 u8 seq1;
988
989                 /* screen off */
990                 WREG8(MGAREG_SEQ_INDEX, 0x01);
991                 seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20;
992                 WREG8(MGAREG_SEQ_DATA, seq1);
993
994                 WREG32(MGAREG_MEMCTL, mem_ctl | 0x00200000);
995                 udelay(1000);
996                 WREG32(MGAREG_MEMCTL, mem_ctl & ~0x00200000);
997
998                 WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20);
999         }
1000
1001
1002         if (IS_G200_SE(mdev)) {
1003                 if (mdev->reg_1e24 >= 0x02) {
1004                         u8 hi_pri_lvl;
1005                         u32 bpp;
1006                         u32 mb;
1007
1008                         if (crtc->fb->bits_per_pixel > 16)
1009                                 bpp = 32;
1010                         else if (crtc->fb->bits_per_pixel > 8)
1011                                 bpp = 16;
1012                         else
1013                                 bpp = 8;
1014
1015                         mb = (mode->clock * bpp) / 1000;
1016                         if (mb > 3100)
1017                                 hi_pri_lvl = 0;
1018                         else if (mb > 2600)
1019                                 hi_pri_lvl = 1;
1020                         else if (mb > 1900)
1021                                 hi_pri_lvl = 2;
1022                         else if (mb > 1160)
1023                                 hi_pri_lvl = 3;
1024                         else if (mb > 440)
1025                                 hi_pri_lvl = 4;
1026                         else
1027                                 hi_pri_lvl = 5;
1028
1029                         WREG8(0x1fde, 0x06);
1030                         WREG8(0x1fdf, hi_pri_lvl);
1031                 } else {
1032                         if (mdev->reg_1e24 >= 0x01)
1033                                 WREG8(0x1fdf, 0x03);
1034                         else
1035                                 WREG8(0x1fdf, 0x04);
1036                 }
1037         }
1038         return 0;
1039 }
1040
1041 #if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */
1042 static int mga_suspend(struct drm_crtc *crtc)
1043 {
1044         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1045         struct drm_device *dev = crtc->dev;
1046         struct mga_device *mdev = dev->dev_private;
1047         struct pci_dev *pdev = dev->pdev;
1048         int option;
1049
1050         if (mdev->suspended)
1051                 return 0;
1052
1053         WREG_SEQ(1, 0x20);
1054         WREG_ECRT(1, 0x30);
1055         /* Disable the pixel clock */
1056         WREG_DAC(0x1a, 0x05);
1057         /* Power down the DAC */
1058         WREG_DAC(0x1e, 0x18);
1059         /* Power down the pixel PLL */
1060         WREG_DAC(0x1a, 0x0d);
1061
1062         /* Disable PLLs and clocks */
1063         pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1064         option &= ~(0x1F8024);
1065         pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1066         pci_set_power_state(pdev, PCI_D3hot);
1067         pci_disable_device(pdev);
1068
1069         mdev->suspended = true;
1070
1071         return 0;
1072 }
1073
1074 static int mga_resume(struct drm_crtc *crtc)
1075 {
1076         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1077         struct drm_device *dev = crtc->dev;
1078         struct mga_device *mdev = dev->dev_private;
1079         struct pci_dev *pdev = dev->pdev;
1080         int option;
1081
1082         if (!mdev->suspended)
1083                 return 0;
1084
1085         pci_set_power_state(pdev, PCI_D0);
1086         pci_enable_device(pdev);
1087
1088         /* Disable sysclk */
1089         pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1090         option &= ~(0x4);
1091         pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1092
1093         mdev->suspended = false;
1094
1095         return 0;
1096 }
1097
1098 #endif
1099
1100 static void mga_crtc_dpms(struct drm_crtc *crtc, int mode)
1101 {
1102         struct drm_device *dev = crtc->dev;
1103         struct mga_device *mdev = dev->dev_private;
1104         u8 seq1 = 0, crtcext1 = 0;
1105
1106         switch (mode) {
1107         case DRM_MODE_DPMS_ON:
1108                 seq1 = 0;
1109                 crtcext1 = 0;
1110                 mga_crtc_load_lut(crtc);
1111                 break;
1112         case DRM_MODE_DPMS_STANDBY:
1113                 seq1 = 0x20;
1114                 crtcext1 = 0x10;
1115                 break;
1116         case DRM_MODE_DPMS_SUSPEND:
1117                 seq1 = 0x20;
1118                 crtcext1 = 0x20;
1119                 break;
1120         case DRM_MODE_DPMS_OFF:
1121                 seq1 = 0x20;
1122                 crtcext1 = 0x30;
1123                 break;
1124         }
1125
1126 #if 0
1127         if (mode == DRM_MODE_DPMS_OFF) {
1128                 mga_suspend(crtc);
1129         }
1130 #endif
1131         WREG8(MGAREG_SEQ_INDEX, 0x01);
1132         seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20;
1133         mga_wait_vsync(mdev);
1134         mga_wait_busy(mdev);
1135         WREG8(MGAREG_SEQ_DATA, seq1);
1136         msleep(20);
1137         WREG8(MGAREG_CRTCEXT_INDEX, 0x01);
1138         crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
1139         WREG8(MGAREG_CRTCEXT_DATA, crtcext1);
1140
1141 #if 0
1142         if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) {
1143                 mga_resume(crtc);
1144                 drm_helper_resume_force_mode(dev);
1145         }
1146 #endif
1147 }
1148
1149 /*
1150  * This is called before a mode is programmed. A typical use might be to
1151  * enable DPMS during the programming to avoid seeing intermediate stages,
1152  * but that's not relevant to us
1153  */
1154 static void mga_crtc_prepare(struct drm_crtc *crtc)
1155 {
1156         struct drm_device *dev = crtc->dev;
1157         struct mga_device *mdev = dev->dev_private;
1158         u8 tmp;
1159
1160         /*      mga_resume(crtc);*/
1161
1162         WREG8(MGAREG_CRTC_INDEX, 0x11);
1163         tmp = RREG8(MGAREG_CRTC_DATA);
1164         WREG_CRT(0x11, tmp | 0x80);
1165
1166         if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1167                 WREG_SEQ(0, 1);
1168                 msleep(50);
1169                 WREG_SEQ(1, 0x20);
1170                 msleep(20);
1171         } else {
1172                 WREG8(MGAREG_SEQ_INDEX, 0x1);
1173                 tmp = RREG8(MGAREG_SEQ_DATA);
1174
1175                 /* start sync reset */
1176                 WREG_SEQ(0, 1);
1177                 WREG_SEQ(1, tmp | 0x20);
1178         }
1179
1180         if (mdev->type == G200_WB)
1181                 mga_g200wb_prepare(crtc);
1182
1183         WREG_CRT(17, 0);
1184 }
1185
1186 /*
1187  * This is called after a mode is programmed. It should reverse anything done
1188  * by the prepare function
1189  */
1190 static void mga_crtc_commit(struct drm_crtc *crtc)
1191 {
1192         struct drm_device *dev = crtc->dev;
1193         struct mga_device *mdev = dev->dev_private;
1194         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1195         u8 tmp;
1196
1197         if (mdev->type == G200_WB)
1198                 mga_g200wb_commit(crtc);
1199
1200         if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1201                 msleep(50);
1202                 WREG_SEQ(1, 0x0);
1203                 msleep(20);
1204                 WREG_SEQ(0, 0x3);
1205         } else {
1206                 WREG8(MGAREG_SEQ_INDEX, 0x1);
1207                 tmp = RREG8(MGAREG_SEQ_DATA);
1208
1209                 tmp &= ~0x20;
1210                 WREG_SEQ(0x1, tmp);
1211                 WREG_SEQ(0, 3);
1212         }
1213         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1214 }
1215
1216 /*
1217  * The core can pass us a set of gamma values to program. We actually only
1218  * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1219  * but it's a requirement that we provide the function
1220  */
1221 static void mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1222                                   u16 *blue, uint32_t start, uint32_t size)
1223 {
1224         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1225         int end = (start + size > MGAG200_LUT_SIZE) ? MGAG200_LUT_SIZE : start + size;
1226         int i;
1227
1228         for (i = start; i < end; i++) {
1229                 mga_crtc->lut_r[i] = red[i] >> 8;
1230                 mga_crtc->lut_g[i] = green[i] >> 8;
1231                 mga_crtc->lut_b[i] = blue[i] >> 8;
1232         }
1233         mga_crtc_load_lut(crtc);
1234 }
1235
1236 /* Simple cleanup function */
1237 static void mga_crtc_destroy(struct drm_crtc *crtc)
1238 {
1239         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1240
1241         drm_crtc_cleanup(crtc);
1242         kfree(mga_crtc);
1243 }
1244
1245 /* These provide the minimum set of functions required to handle a CRTC */
1246 static const struct drm_crtc_funcs mga_crtc_funcs = {
1247         .gamma_set = mga_crtc_gamma_set,
1248         .set_config = drm_crtc_helper_set_config,
1249         .destroy = mga_crtc_destroy,
1250 };
1251
1252 static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1253         .dpms = mga_crtc_dpms,
1254         .mode_fixup = mga_crtc_mode_fixup,
1255         .mode_set = mga_crtc_mode_set,
1256         .mode_set_base = mga_crtc_mode_set_base,
1257         .prepare = mga_crtc_prepare,
1258         .commit = mga_crtc_commit,
1259         .load_lut = mga_crtc_load_lut,
1260 };
1261
1262 /* CRTC setup */
1263 static void mga_crtc_init(struct drm_device *dev)
1264 {
1265         struct mga_device *mdev = dev->dev_private;
1266         struct mga_crtc *mga_crtc;
1267         int i;
1268
1269         mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1270                               (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
1271                               GFP_KERNEL);
1272
1273         if (mga_crtc == NULL)
1274                 return;
1275
1276         drm_crtc_init(dev, &mga_crtc->base, &mga_crtc_funcs);
1277
1278         drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1279         mdev->mode_info.crtc = mga_crtc;
1280
1281         for (i = 0; i < MGAG200_LUT_SIZE; i++) {
1282                 mga_crtc->lut_r[i] = i;
1283                 mga_crtc->lut_g[i] = i;
1284                 mga_crtc->lut_b[i] = i;
1285         }
1286
1287         drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1288 }
1289
1290 /** Sets the color ramps on behalf of fbcon */
1291 void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1292                               u16 blue, int regno)
1293 {
1294         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1295
1296         mga_crtc->lut_r[regno] = red >> 8;
1297         mga_crtc->lut_g[regno] = green >> 8;
1298         mga_crtc->lut_b[regno] = blue >> 8;
1299 }
1300
1301 /** Gets the color ramps on behalf of fbcon */
1302 void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
1303                               u16 *blue, int regno)
1304 {
1305         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1306
1307         *red = (u16)mga_crtc->lut_r[regno] << 8;
1308         *green = (u16)mga_crtc->lut_g[regno] << 8;
1309         *blue = (u16)mga_crtc->lut_b[regno] << 8;
1310 }
1311
1312 /*
1313  * The encoder comes after the CRTC in the output pipeline, but before
1314  * the connector. It's responsible for ensuring that the digital
1315  * stream is appropriately converted into the output format. Setup is
1316  * very simple in this case - all we have to do is inform qemu of the
1317  * colour depth in order to ensure that it displays appropriately
1318  */
1319
1320 /*
1321  * These functions are analagous to those in the CRTC code, but are intended
1322  * to handle any encoder-specific limitations
1323  */
1324 static bool mga_encoder_mode_fixup(struct drm_encoder *encoder,
1325                                   struct drm_display_mode *mode,
1326                                   struct drm_display_mode *adjusted_mode)
1327 {
1328         return true;
1329 }
1330
1331 static void mga_encoder_mode_set(struct drm_encoder *encoder,
1332                                 struct drm_display_mode *mode,
1333                                 struct drm_display_mode *adjusted_mode)
1334 {
1335
1336 }
1337
1338 static void mga_encoder_dpms(struct drm_encoder *encoder, int state)
1339 {
1340         return;
1341 }
1342
1343 static void mga_encoder_prepare(struct drm_encoder *encoder)
1344 {
1345 }
1346
1347 static void mga_encoder_commit(struct drm_encoder *encoder)
1348 {
1349 }
1350
1351 void mga_encoder_destroy(struct drm_encoder *encoder)
1352 {
1353         struct mga_encoder *mga_encoder = to_mga_encoder(encoder);
1354         drm_encoder_cleanup(encoder);
1355         kfree(mga_encoder);
1356 }
1357
1358 static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1359         .dpms = mga_encoder_dpms,
1360         .mode_fixup = mga_encoder_mode_fixup,
1361         .mode_set = mga_encoder_mode_set,
1362         .prepare = mga_encoder_prepare,
1363         .commit = mga_encoder_commit,
1364 };
1365
1366 static const struct drm_encoder_funcs mga_encoder_encoder_funcs = {
1367         .destroy = mga_encoder_destroy,
1368 };
1369
1370 static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
1371 {
1372         struct drm_encoder *encoder;
1373         struct mga_encoder *mga_encoder;
1374
1375         mga_encoder = kzalloc(sizeof(struct mga_encoder), GFP_KERNEL);
1376         if (!mga_encoder)
1377                 return NULL;
1378
1379         encoder = &mga_encoder->base;
1380         encoder->possible_crtcs = 0x1;
1381
1382         drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
1383                          DRM_MODE_ENCODER_DAC);
1384         drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
1385
1386         return encoder;
1387 }
1388
1389
1390 static int mga_vga_get_modes(struct drm_connector *connector)
1391 {
1392         struct mga_connector *mga_connector = to_mga_connector(connector);
1393         struct edid *edid;
1394         int ret = 0;
1395
1396         edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
1397         if (edid) {
1398                 drm_mode_connector_update_edid_property(connector, edid);
1399                 ret = drm_add_edid_modes(connector, edid);
1400                 connector->display_info.raw_edid = NULL;
1401                 kfree(edid);
1402         }
1403         return ret;
1404 }
1405
1406 static int mga_vga_mode_valid(struct drm_connector *connector,
1407                                  struct drm_display_mode *mode)
1408 {
1409         /* FIXME: Add bandwidth and g200se limitations */
1410
1411         if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1412             mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
1413             mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
1414             mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
1415                 return MODE_BAD;
1416         }
1417
1418         return MODE_OK;
1419 }
1420
1421 struct drm_encoder *mga_connector_best_encoder(struct drm_connector
1422                                                   *connector)
1423 {
1424         int enc_id = connector->encoder_ids[0];
1425         struct drm_mode_object *obj;
1426         struct drm_encoder *encoder;
1427
1428         /* pick the encoder ids */
1429         if (enc_id) {
1430                 obj =
1431                     drm_mode_object_find(connector->dev, enc_id,
1432                                          DRM_MODE_OBJECT_ENCODER);
1433                 if (!obj)
1434                         return NULL;
1435                 encoder = obj_to_encoder(obj);
1436                 return encoder;
1437         }
1438         return NULL;
1439 }
1440
1441 static enum drm_connector_status mga_vga_detect(struct drm_connector
1442                                                    *connector, bool force)
1443 {
1444         return connector_status_connected;
1445 }
1446
1447 static void mga_connector_destroy(struct drm_connector *connector)
1448 {
1449         struct mga_connector *mga_connector = to_mga_connector(connector);
1450         mgag200_i2c_destroy(mga_connector->i2c);
1451         drm_connector_cleanup(connector);
1452         kfree(connector);
1453 }
1454
1455 struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1456         .get_modes = mga_vga_get_modes,
1457         .mode_valid = mga_vga_mode_valid,
1458         .best_encoder = mga_connector_best_encoder,
1459 };
1460
1461 struct drm_connector_funcs mga_vga_connector_funcs = {
1462         .dpms = drm_helper_connector_dpms,
1463         .detect = mga_vga_detect,
1464         .fill_modes = drm_helper_probe_single_connector_modes,
1465         .destroy = mga_connector_destroy,
1466 };
1467
1468 static struct drm_connector *mga_vga_init(struct drm_device *dev)
1469 {
1470         struct drm_connector *connector;
1471         struct mga_connector *mga_connector;
1472
1473         mga_connector = kzalloc(sizeof(struct mga_connector), GFP_KERNEL);
1474         if (!mga_connector)
1475                 return NULL;
1476
1477         connector = &mga_connector->base;
1478
1479         drm_connector_init(dev, connector,
1480                            &mga_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA);
1481
1482         drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1483
1484         mga_connector->i2c = mgag200_i2c_create(dev);
1485         if (!mga_connector->i2c)
1486                 DRM_ERROR("failed to add ddc bus\n");
1487
1488         return connector;
1489 }
1490
1491
1492 int mgag200_modeset_init(struct mga_device *mdev)
1493 {
1494         struct drm_encoder *encoder;
1495         struct drm_connector *connector;
1496         int ret;
1497
1498         mdev->mode_info.mode_config_initialized = true;
1499
1500         mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1501         mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1502
1503         mdev->dev->mode_config.fb_base = mdev->mc.vram_base;
1504
1505         mga_crtc_init(mdev->dev);
1506
1507         encoder = mga_encoder_init(mdev->dev);
1508         if (!encoder) {
1509                 DRM_ERROR("mga_encoder_init failed\n");
1510                 return -1;
1511         }
1512
1513         connector = mga_vga_init(mdev->dev);
1514         if (!connector) {
1515                 DRM_ERROR("mga_vga_init failed\n");
1516                 return -1;
1517         }
1518
1519         drm_mode_connector_attach_encoder(connector, encoder);
1520
1521         ret = mgag200_fbdev_init(mdev);
1522         if (ret) {
1523                 DRM_ERROR("mga_fbdev_init failed\n");
1524                 return ret;
1525         }
1526
1527         return 0;
1528 }
1529
1530 void mgag200_modeset_fini(struct mga_device *mdev)
1531 {
1532
1533 }