drm/mgag200: fix G200ER pll picking algorithm
[pandora-kernel.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                                 const 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         int testr, testn, testm, testo;
472         unsigned int p, m, n;
473         unsigned int computed, vco;
474         int tmp;
475         const unsigned int m_div_val[] = { 1, 2, 4, 8 };
476
477         m = n = p = 0;
478         vcomax = 1488000;
479         vcomin = 1056000;
480         pllreffreq = 48000;
481
482         delta = 0xffffffff;
483
484         for (testr = 0; testr < 4; testr++) {
485                 if (delta == 0)
486                         break;
487                 for (testn = 5; testn < 129; testn++) {
488                         if (delta == 0)
489                                 break;
490                         for (testm = 3; testm >= 0; testm--) {
491                                 if (delta == 0)
492                                         break;
493                                 for (testo = 5; testo < 33; testo++) {
494                                         vco = pllreffreq * (testn + 1) /
495                                                 (testr + 1);
496                                         if (vco < vcomin)
497                                                 continue;
498                                         if (vco > vcomax)
499                                                 continue;
500                                         computed = vco / (m_div_val[testm] * (testo + 1));
501                                         if (computed > clock)
502                                                 tmpdelta = computed - clock;
503                                         else
504                                                 tmpdelta = clock - computed;
505                                         if (tmpdelta < delta) {
506                                                 delta = tmpdelta;
507                                                 m = testm | (testo << 3);
508                                                 n = testn;
509                                                 p = testr | (testr << 3);
510                                         }
511                                 }
512                         }
513                 }
514         }
515
516         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
517         tmp = RREG8(DAC_DATA);
518         tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
519         WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
520
521         WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
522         tmp = RREG8(DAC_DATA);
523         tmp |= MGA1064_REMHEADCTL_CLKDIS;
524         WREG_DAC(MGA1064_REMHEADCTL, tmp);
525
526         tmp = RREG8(MGAREG_MEM_MISC_READ);
527         tmp |= (0x3<<2) | 0xc0;
528         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
529
530         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
531         tmp = RREG8(DAC_DATA);
532         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
533         tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
534         WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
535
536         udelay(500);
537
538         WREG_DAC(MGA1064_ER_PIX_PLLC_N, n);
539         WREG_DAC(MGA1064_ER_PIX_PLLC_M, m);
540         WREG_DAC(MGA1064_ER_PIX_PLLC_P, p);
541
542         udelay(50);
543
544         return 0;
545 }
546
547 static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
548 {
549         switch(mdev->type) {
550         case G200_SE_A:
551         case G200_SE_B:
552                 return mga_g200se_set_plls(mdev, clock);
553                 break;
554         case G200_WB:
555                 return mga_g200wb_set_plls(mdev, clock);
556                 break;
557         case G200_EV:
558                 return mga_g200ev_set_plls(mdev, clock);
559                 break;
560         case G200_EH:
561                 return mga_g200eh_set_plls(mdev, clock);
562                 break;
563         case G200_ER:
564                 return mga_g200er_set_plls(mdev, clock);
565                 break;
566         }
567         return 0;
568 }
569
570 static void mga_g200wb_prepare(struct drm_crtc *crtc)
571 {
572         struct mga_device *mdev = crtc->dev->dev_private;
573         u8 tmp;
574         int iter_max;
575
576         /* 1- The first step is to warn the BMC of an upcoming mode change.
577          * We are putting the misc<0> to output.*/
578
579         WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
580         tmp = RREG8(DAC_DATA);
581         tmp |= 0x10;
582         WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
583
584         /* we are putting a 1 on the misc<0> line */
585         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
586         tmp = RREG8(DAC_DATA);
587         tmp |= 0x10;
588         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
589
590         /* 2- Second step to mask and further scan request
591          * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
592          */
593         WREG8(DAC_INDEX, MGA1064_SPAREREG);
594         tmp = RREG8(DAC_DATA);
595         tmp |= 0x80;
596         WREG_DAC(MGA1064_SPAREREG, tmp);
597
598         /* 3a- the third step is to verifu if there is an active scan
599          * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
600          */
601         iter_max = 300;
602         while (!(tmp & 0x1) && iter_max) {
603                 WREG8(DAC_INDEX, MGA1064_SPAREREG);
604                 tmp = RREG8(DAC_DATA);
605                 udelay(1000);
606                 iter_max--;
607         }
608
609         /* 3b- this step occurs only if the remove is actually scanning
610          * we are waiting for the end of the frame which is a 1 on
611          * remvsyncsts (XSPAREREG<1>)
612          */
613         if (iter_max) {
614                 iter_max = 300;
615                 while ((tmp & 0x2) && iter_max) {
616                         WREG8(DAC_INDEX, MGA1064_SPAREREG);
617                         tmp = RREG8(DAC_DATA);
618                         udelay(1000);
619                         iter_max--;
620                 }
621         }
622 }
623
624 static void mga_g200wb_commit(struct drm_crtc *crtc)
625 {
626         u8 tmp;
627         struct mga_device *mdev = crtc->dev->dev_private;
628
629         /* 1- The first step is to ensure that the vrsten and hrsten are set */
630         WREG8(MGAREG_CRTCEXT_INDEX, 1);
631         tmp = RREG8(MGAREG_CRTCEXT_DATA);
632         WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
633
634         /* 2- second step is to assert the rstlvl2 */
635         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
636         tmp = RREG8(DAC_DATA);
637         tmp |= 0x8;
638         WREG8(DAC_DATA, tmp);
639
640         /* wait 10 us */
641         udelay(10);
642
643         /* 3- deassert rstlvl2 */
644         tmp &= ~0x08;
645         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
646         WREG8(DAC_DATA, tmp);
647
648         /* 4- remove mask of scan request */
649         WREG8(DAC_INDEX, MGA1064_SPAREREG);
650         tmp = RREG8(DAC_DATA);
651         tmp &= ~0x80;
652         WREG8(DAC_DATA, tmp);
653
654         /* 5- put back a 0 on the misc<0> line */
655         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
656         tmp = RREG8(DAC_DATA);
657         tmp &= ~0x10;
658         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
659 }
660
661
662 void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
663 {
664         struct mga_device *mdev = crtc->dev->dev_private;
665         u32 addr;
666         int count;
667
668         while (RREG8(0x1fda) & 0x08);
669         while (!(RREG8(0x1fda) & 0x08));
670
671         count = RREG8(MGAREG_VCOUNT) + 2;
672         while (RREG8(MGAREG_VCOUNT) < count);
673
674         addr = offset >> 2;
675         WREG_CRT(0x0d, (u8)(addr & 0xff));
676         WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
677         WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf);
678 }
679
680
681 /* ast is different - we will force move buffers out of VRAM */
682 static int mga_crtc_do_set_base(struct drm_crtc *crtc,
683                                 struct drm_framebuffer *fb,
684                                 int x, int y, int atomic)
685 {
686         struct mga_device *mdev = crtc->dev->dev_private;
687         struct drm_gem_object *obj;
688         struct mga_framebuffer *mga_fb;
689         struct mgag200_bo *bo;
690         int ret;
691         u64 gpu_addr;
692
693         /* push the previous fb to system ram */
694         if (!atomic && fb) {
695                 mga_fb = to_mga_framebuffer(fb);
696                 obj = mga_fb->obj;
697                 bo = gem_to_mga_bo(obj);
698                 ret = mgag200_bo_reserve(bo, false);
699                 if (ret)
700                         return ret;
701                 mgag200_bo_push_sysram(bo);
702                 mgag200_bo_unreserve(bo);
703         }
704
705         mga_fb = to_mga_framebuffer(crtc->fb);
706         obj = mga_fb->obj;
707         bo = gem_to_mga_bo(obj);
708
709         ret = mgag200_bo_reserve(bo, false);
710         if (ret)
711                 return ret;
712
713         ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
714         if (ret) {
715                 mgag200_bo_unreserve(bo);
716                 return ret;
717         }
718
719         if (&mdev->mfbdev->mfb == mga_fb) {
720                 /* if pushing console in kmap it */
721                 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
722                 if (ret)
723                         DRM_ERROR("failed to kmap fbcon\n");
724
725         }
726         mgag200_bo_unreserve(bo);
727
728         DRM_INFO("mga base %llx\n", gpu_addr);
729
730         mga_set_start_address(crtc, (u32)gpu_addr);
731
732         return 0;
733 }
734
735 static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
736                                   struct drm_framebuffer *old_fb)
737 {
738         return mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
739 }
740
741 static int mga_crtc_mode_set(struct drm_crtc *crtc,
742                                 struct drm_display_mode *mode,
743                                 struct drm_display_mode *adjusted_mode,
744                                 int x, int y, struct drm_framebuffer *old_fb)
745 {
746         struct drm_device *dev = crtc->dev;
747         struct mga_device *mdev = dev->dev_private;
748         int hdisplay, hsyncstart, hsyncend, htotal;
749         int vdisplay, vsyncstart, vsyncend, vtotal;
750         int pitch;
751         int option = 0, option2 = 0;
752         int i;
753         unsigned char misc = 0;
754         unsigned char ext_vga[6];
755         unsigned char ext_vga_index24;
756         unsigned char dac_index90 = 0;
757         u8 bppshift;
758
759         static unsigned char dacvalue[] = {
760                 /* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,
761                 /* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,
762                 /* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,
763                 /* 0x18: */     0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
764                 /* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765                 /* 0x28: */     0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
766                 /* 0x30: */     0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
767                 /* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
768                 /* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,
769                 /* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
770         };
771
772         bppshift = mdev->bpp_shifts[(crtc->fb->bits_per_pixel >> 3) - 1];
773
774         switch (mdev->type) {
775         case G200_SE_A:
776         case G200_SE_B:
777                 dacvalue[MGA1064_VREF_CTL] = 0x03;
778                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
779                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
780                                              MGA1064_MISC_CTL_VGA8 |
781                                              MGA1064_MISC_CTL_DAC_RAM_CS;
782                 if (mdev->has_sdram)
783                         option = 0x40049120;
784                 else
785                         option = 0x4004d120;
786                 option2 = 0x00008000;
787                 break;
788         case G200_WB:
789                 dacvalue[MGA1064_VREF_CTL] = 0x07;
790                 option = 0x41049120;
791                 option2 = 0x0000b000;
792                 break;
793         case G200_EV:
794                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
795                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
796                                              MGA1064_MISC_CTL_DAC_RAM_CS;
797                 option = 0x00000120;
798                 option2 = 0x0000b000;
799                 break;
800         case G200_EH:
801                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
802                                              MGA1064_MISC_CTL_DAC_RAM_CS;
803                 option = 0x00000120;
804                 option2 = 0x0000b000;
805                 break;
806         case G200_ER:
807                 dac_index90 = 0;
808                 break;
809         }
810
811         switch (crtc->fb->bits_per_pixel) {
812         case 8:
813                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
814                 break;
815         case 16:
816                 if (crtc->fb->depth == 15)
817                         dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
818                 else
819                         dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
820                 break;
821         case 24:
822                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits;
823                 break;
824         case 32:
825                 dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits;
826                 break;
827         }
828
829         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
830                 misc |= 0x40;
831         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
832                 misc |= 0x80;
833
834
835         for (i = 0; i < sizeof(dacvalue); i++) {
836                 if ((i <= 0x03) ||
837                     (i == 0x07) ||
838                     (i == 0x0b) ||
839                     (i == 0x0f) ||
840                     ((i >= 0x13) && (i <= 0x17)) ||
841                     (i == 0x1b) ||
842                     (i == 0x1c) ||
843                     ((i >= 0x1f) && (i <= 0x29)) ||
844                     ((i >= 0x30) && (i <= 0x37)))
845                         continue;
846                 if (IS_G200_SE(mdev) &&
847                     ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
848                         continue;
849                 if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH) &&
850                     (i >= 0x44) && (i <= 0x4e))
851                         continue;
852
853                 WREG_DAC(i, dacvalue[i]);
854         }
855
856         if (mdev->type == G200_ER) {
857                 WREG_DAC(0x90, dac_index90);
858         }
859
860
861         if (option)
862                 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
863         if (option2)
864                 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
865
866         WREG_SEQ(2, 0xf);
867         WREG_SEQ(3, 0);
868         WREG_SEQ(4, 0xe);
869
870         pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8);
871         if (crtc->fb->bits_per_pixel == 24)
872                 pitch = pitch >> (4 - bppshift);
873         else
874                 pitch = pitch >> (4 - bppshift);
875
876         hdisplay = mode->hdisplay / 8 - 1;
877         hsyncstart = mode->hsync_start / 8 - 1;
878         hsyncend = mode->hsync_end / 8 - 1;
879         htotal = mode->htotal / 8 - 1;
880
881         /* Work around hardware quirk */
882         if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
883                 htotal++;
884
885         vdisplay = mode->vdisplay - 1;
886         vsyncstart = mode->vsync_start - 1;
887         vsyncend = mode->vsync_end - 1;
888         vtotal = mode->vtotal - 2;
889
890         WREG_GFX(0, 0);
891         WREG_GFX(1, 0);
892         WREG_GFX(2, 0);
893         WREG_GFX(3, 0);
894         WREG_GFX(4, 0);
895         WREG_GFX(5, 0x40);
896         WREG_GFX(6, 0x5);
897         WREG_GFX(7, 0xf);
898         WREG_GFX(8, 0xf);
899
900         WREG_CRT(0, htotal - 4);
901         WREG_CRT(1, hdisplay);
902         WREG_CRT(2, hdisplay);
903         WREG_CRT(3, (htotal & 0x1F) | 0x80);
904         WREG_CRT(4, hsyncstart);
905         WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F));
906         WREG_CRT(6, vtotal & 0xFF);
907         WREG_CRT(7, ((vtotal & 0x100) >> 8) |
908                  ((vdisplay & 0x100) >> 7) |
909                  ((vsyncstart & 0x100) >> 6) |
910                  ((vdisplay & 0x100) >> 5) |
911                  ((vdisplay & 0x100) >> 4) | /* linecomp */
912                  ((vtotal & 0x200) >> 4)|
913                  ((vdisplay & 0x200) >> 3) |
914                  ((vsyncstart & 0x200) >> 2));
915         WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
916                  ((vdisplay & 0x200) >> 3));
917         WREG_CRT(10, 0);
918         WREG_CRT(11, 0);
919         WREG_CRT(12, 0);
920         WREG_CRT(13, 0);
921         WREG_CRT(14, 0);
922         WREG_CRT(15, 0);
923         WREG_CRT(16, vsyncstart & 0xFF);
924         WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
925         WREG_CRT(18, vdisplay & 0xFF);
926         WREG_CRT(19, pitch & 0xFF);
927         WREG_CRT(20, 0);
928         WREG_CRT(21, vdisplay & 0xFF);
929         WREG_CRT(22, (vtotal + 1) & 0xFF);
930         WREG_CRT(23, 0xc3);
931         WREG_CRT(24, vdisplay & 0xFF);
932
933         ext_vga[0] = 0;
934         ext_vga[5] = 0;
935
936         /* TODO interlace */
937
938         ext_vga[0] |= (pitch & 0x300) >> 4;
939         ext_vga[1] = (((htotal - 4) & 0x100) >> 8) |
940                 ((hdisplay & 0x100) >> 7) |
941                 ((hsyncstart & 0x100) >> 6) |
942                 (htotal & 0x40);
943         ext_vga[2] = ((vtotal & 0xc00) >> 10) |
944                 ((vdisplay & 0x400) >> 8) |
945                 ((vdisplay & 0xc00) >> 7) |
946                 ((vsyncstart & 0xc00) >> 5) |
947                 ((vdisplay & 0x400) >> 3);
948         if (crtc->fb->bits_per_pixel == 24)
949                 ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
950         else
951                 ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
952         ext_vga[4] = 0;
953         if (mdev->type == G200_WB)
954                 ext_vga[1] |= 0x88;
955
956         ext_vga_index24 = 0x05;
957
958         /* Set pixel clocks */
959         misc = 0x2d;
960         WREG8(MGA_MISC_OUT, misc);
961
962         mga_crtc_set_plls(mdev, mode->clock);
963
964         for (i = 0; i < 6; i++) {
965                 WREG_ECRT(i, ext_vga[i]);
966         }
967
968         if (mdev->type == G200_ER)
969                 WREG_ECRT(24, ext_vga_index24);
970
971         if (mdev->type == G200_EV) {
972                 WREG_ECRT(6, 0);
973         }
974
975         WREG_ECRT(0, ext_vga[0]);
976         /* Enable mga pixel clock */
977         misc = 0x2d;
978
979         WREG8(MGA_MISC_OUT, misc);
980
981         if (adjusted_mode)
982                 memcpy(&mdev->mode, mode, sizeof(struct drm_display_mode));
983
984         mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
985
986         /* reset tagfifo */
987         if (mdev->type == G200_ER) {
988                 u32 mem_ctl = RREG32(MGAREG_MEMCTL);
989                 u8 seq1;
990
991                 /* screen off */
992                 WREG8(MGAREG_SEQ_INDEX, 0x01);
993                 seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20;
994                 WREG8(MGAREG_SEQ_DATA, seq1);
995
996                 WREG32(MGAREG_MEMCTL, mem_ctl | 0x00200000);
997                 udelay(1000);
998                 WREG32(MGAREG_MEMCTL, mem_ctl & ~0x00200000);
999
1000                 WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20);
1001         }
1002
1003
1004         if (IS_G200_SE(mdev)) {
1005                 if (mdev->reg_1e24 >= 0x02) {
1006                         u8 hi_pri_lvl;
1007                         u32 bpp;
1008                         u32 mb;
1009
1010                         if (crtc->fb->bits_per_pixel > 16)
1011                                 bpp = 32;
1012                         else if (crtc->fb->bits_per_pixel > 8)
1013                                 bpp = 16;
1014                         else
1015                                 bpp = 8;
1016
1017                         mb = (mode->clock * bpp) / 1000;
1018                         if (mb > 3100)
1019                                 hi_pri_lvl = 0;
1020                         else if (mb > 2600)
1021                                 hi_pri_lvl = 1;
1022                         else if (mb > 1900)
1023                                 hi_pri_lvl = 2;
1024                         else if (mb > 1160)
1025                                 hi_pri_lvl = 3;
1026                         else if (mb > 440)
1027                                 hi_pri_lvl = 4;
1028                         else
1029                                 hi_pri_lvl = 5;
1030
1031                         WREG8(0x1fde, 0x06);
1032                         WREG8(0x1fdf, hi_pri_lvl);
1033                 } else {
1034                         if (mdev->reg_1e24 >= 0x01)
1035                                 WREG8(0x1fdf, 0x03);
1036                         else
1037                                 WREG8(0x1fdf, 0x04);
1038                 }
1039         }
1040         return 0;
1041 }
1042
1043 #if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */
1044 static int mga_suspend(struct drm_crtc *crtc)
1045 {
1046         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1047         struct drm_device *dev = crtc->dev;
1048         struct mga_device *mdev = dev->dev_private;
1049         struct pci_dev *pdev = dev->pdev;
1050         int option;
1051
1052         if (mdev->suspended)
1053                 return 0;
1054
1055         WREG_SEQ(1, 0x20);
1056         WREG_ECRT(1, 0x30);
1057         /* Disable the pixel clock */
1058         WREG_DAC(0x1a, 0x05);
1059         /* Power down the DAC */
1060         WREG_DAC(0x1e, 0x18);
1061         /* Power down the pixel PLL */
1062         WREG_DAC(0x1a, 0x0d);
1063
1064         /* Disable PLLs and clocks */
1065         pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1066         option &= ~(0x1F8024);
1067         pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1068         pci_set_power_state(pdev, PCI_D3hot);
1069         pci_disable_device(pdev);
1070
1071         mdev->suspended = true;
1072
1073         return 0;
1074 }
1075
1076 static int mga_resume(struct drm_crtc *crtc)
1077 {
1078         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1079         struct drm_device *dev = crtc->dev;
1080         struct mga_device *mdev = dev->dev_private;
1081         struct pci_dev *pdev = dev->pdev;
1082         int option;
1083
1084         if (!mdev->suspended)
1085                 return 0;
1086
1087         pci_set_power_state(pdev, PCI_D0);
1088         pci_enable_device(pdev);
1089
1090         /* Disable sysclk */
1091         pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1092         option &= ~(0x4);
1093         pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1094
1095         mdev->suspended = false;
1096
1097         return 0;
1098 }
1099
1100 #endif
1101
1102 static void mga_crtc_dpms(struct drm_crtc *crtc, int mode)
1103 {
1104         struct drm_device *dev = crtc->dev;
1105         struct mga_device *mdev = dev->dev_private;
1106         u8 seq1 = 0, crtcext1 = 0;
1107
1108         switch (mode) {
1109         case DRM_MODE_DPMS_ON:
1110                 seq1 = 0;
1111                 crtcext1 = 0;
1112                 mga_crtc_load_lut(crtc);
1113                 break;
1114         case DRM_MODE_DPMS_STANDBY:
1115                 seq1 = 0x20;
1116                 crtcext1 = 0x10;
1117                 break;
1118         case DRM_MODE_DPMS_SUSPEND:
1119                 seq1 = 0x20;
1120                 crtcext1 = 0x20;
1121                 break;
1122         case DRM_MODE_DPMS_OFF:
1123                 seq1 = 0x20;
1124                 crtcext1 = 0x30;
1125                 break;
1126         }
1127
1128 #if 0
1129         if (mode == DRM_MODE_DPMS_OFF) {
1130                 mga_suspend(crtc);
1131         }
1132 #endif
1133         WREG8(MGAREG_SEQ_INDEX, 0x01);
1134         seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20;
1135         mga_wait_vsync(mdev);
1136         mga_wait_busy(mdev);
1137         WREG8(MGAREG_SEQ_DATA, seq1);
1138         msleep(20);
1139         WREG8(MGAREG_CRTCEXT_INDEX, 0x01);
1140         crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
1141         WREG8(MGAREG_CRTCEXT_DATA, crtcext1);
1142
1143 #if 0
1144         if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) {
1145                 mga_resume(crtc);
1146                 drm_helper_resume_force_mode(dev);
1147         }
1148 #endif
1149 }
1150
1151 /*
1152  * This is called before a mode is programmed. A typical use might be to
1153  * enable DPMS during the programming to avoid seeing intermediate stages,
1154  * but that's not relevant to us
1155  */
1156 static void mga_crtc_prepare(struct drm_crtc *crtc)
1157 {
1158         struct drm_device *dev = crtc->dev;
1159         struct mga_device *mdev = dev->dev_private;
1160         u8 tmp;
1161
1162         /*      mga_resume(crtc);*/
1163
1164         WREG8(MGAREG_CRTC_INDEX, 0x11);
1165         tmp = RREG8(MGAREG_CRTC_DATA);
1166         WREG_CRT(0x11, tmp | 0x80);
1167
1168         if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1169                 WREG_SEQ(0, 1);
1170                 msleep(50);
1171                 WREG_SEQ(1, 0x20);
1172                 msleep(20);
1173         } else {
1174                 WREG8(MGAREG_SEQ_INDEX, 0x1);
1175                 tmp = RREG8(MGAREG_SEQ_DATA);
1176
1177                 /* start sync reset */
1178                 WREG_SEQ(0, 1);
1179                 WREG_SEQ(1, tmp | 0x20);
1180         }
1181
1182         if (mdev->type == G200_WB)
1183                 mga_g200wb_prepare(crtc);
1184
1185         WREG_CRT(17, 0);
1186 }
1187
1188 /*
1189  * This is called after a mode is programmed. It should reverse anything done
1190  * by the prepare function
1191  */
1192 static void mga_crtc_commit(struct drm_crtc *crtc)
1193 {
1194         struct drm_device *dev = crtc->dev;
1195         struct mga_device *mdev = dev->dev_private;
1196         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1197         u8 tmp;
1198
1199         if (mdev->type == G200_WB)
1200                 mga_g200wb_commit(crtc);
1201
1202         if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1203                 msleep(50);
1204                 WREG_SEQ(1, 0x0);
1205                 msleep(20);
1206                 WREG_SEQ(0, 0x3);
1207         } else {
1208                 WREG8(MGAREG_SEQ_INDEX, 0x1);
1209                 tmp = RREG8(MGAREG_SEQ_DATA);
1210
1211                 tmp &= ~0x20;
1212                 WREG_SEQ(0x1, tmp);
1213                 WREG_SEQ(0, 3);
1214         }
1215         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1216 }
1217
1218 /*
1219  * The core can pass us a set of gamma values to program. We actually only
1220  * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1221  * but it's a requirement that we provide the function
1222  */
1223 static void mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1224                                   u16 *blue, uint32_t start, uint32_t size)
1225 {
1226         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1227         int end = (start + size > MGAG200_LUT_SIZE) ? MGAG200_LUT_SIZE : start + size;
1228         int i;
1229
1230         for (i = start; i < end; i++) {
1231                 mga_crtc->lut_r[i] = red[i] >> 8;
1232                 mga_crtc->lut_g[i] = green[i] >> 8;
1233                 mga_crtc->lut_b[i] = blue[i] >> 8;
1234         }
1235         mga_crtc_load_lut(crtc);
1236 }
1237
1238 /* Simple cleanup function */
1239 static void mga_crtc_destroy(struct drm_crtc *crtc)
1240 {
1241         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1242
1243         drm_crtc_cleanup(crtc);
1244         kfree(mga_crtc);
1245 }
1246
1247 /* These provide the minimum set of functions required to handle a CRTC */
1248 static const struct drm_crtc_funcs mga_crtc_funcs = {
1249         .gamma_set = mga_crtc_gamma_set,
1250         .set_config = drm_crtc_helper_set_config,
1251         .destroy = mga_crtc_destroy,
1252 };
1253
1254 static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1255         .dpms = mga_crtc_dpms,
1256         .mode_fixup = mga_crtc_mode_fixup,
1257         .mode_set = mga_crtc_mode_set,
1258         .mode_set_base = mga_crtc_mode_set_base,
1259         .prepare = mga_crtc_prepare,
1260         .commit = mga_crtc_commit,
1261         .load_lut = mga_crtc_load_lut,
1262 };
1263
1264 /* CRTC setup */
1265 static void mga_crtc_init(struct drm_device *dev)
1266 {
1267         struct mga_device *mdev = dev->dev_private;
1268         struct mga_crtc *mga_crtc;
1269         int i;
1270
1271         mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1272                               (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
1273                               GFP_KERNEL);
1274
1275         if (mga_crtc == NULL)
1276                 return;
1277
1278         drm_crtc_init(dev, &mga_crtc->base, &mga_crtc_funcs);
1279
1280         drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1281         mdev->mode_info.crtc = mga_crtc;
1282
1283         for (i = 0; i < MGAG200_LUT_SIZE; i++) {
1284                 mga_crtc->lut_r[i] = i;
1285                 mga_crtc->lut_g[i] = i;
1286                 mga_crtc->lut_b[i] = i;
1287         }
1288
1289         drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1290 }
1291
1292 /** Sets the color ramps on behalf of fbcon */
1293 void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1294                               u16 blue, int regno)
1295 {
1296         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1297
1298         mga_crtc->lut_r[regno] = red >> 8;
1299         mga_crtc->lut_g[regno] = green >> 8;
1300         mga_crtc->lut_b[regno] = blue >> 8;
1301 }
1302
1303 /** Gets the color ramps on behalf of fbcon */
1304 void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
1305                               u16 *blue, int regno)
1306 {
1307         struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1308
1309         *red = (u16)mga_crtc->lut_r[regno] << 8;
1310         *green = (u16)mga_crtc->lut_g[regno] << 8;
1311         *blue = (u16)mga_crtc->lut_b[regno] << 8;
1312 }
1313
1314 /*
1315  * The encoder comes after the CRTC in the output pipeline, but before
1316  * the connector. It's responsible for ensuring that the digital
1317  * stream is appropriately converted into the output format. Setup is
1318  * very simple in this case - all we have to do is inform qemu of the
1319  * colour depth in order to ensure that it displays appropriately
1320  */
1321
1322 /*
1323  * These functions are analagous to those in the CRTC code, but are intended
1324  * to handle any encoder-specific limitations
1325  */
1326 static bool mga_encoder_mode_fixup(struct drm_encoder *encoder,
1327                                    const struct drm_display_mode *mode,
1328                                    struct drm_display_mode *adjusted_mode)
1329 {
1330         return true;
1331 }
1332
1333 static void mga_encoder_mode_set(struct drm_encoder *encoder,
1334                                 struct drm_display_mode *mode,
1335                                 struct drm_display_mode *adjusted_mode)
1336 {
1337
1338 }
1339
1340 static void mga_encoder_dpms(struct drm_encoder *encoder, int state)
1341 {
1342         return;
1343 }
1344
1345 static void mga_encoder_prepare(struct drm_encoder *encoder)
1346 {
1347 }
1348
1349 static void mga_encoder_commit(struct drm_encoder *encoder)
1350 {
1351 }
1352
1353 void mga_encoder_destroy(struct drm_encoder *encoder)
1354 {
1355         struct mga_encoder *mga_encoder = to_mga_encoder(encoder);
1356         drm_encoder_cleanup(encoder);
1357         kfree(mga_encoder);
1358 }
1359
1360 static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1361         .dpms = mga_encoder_dpms,
1362         .mode_fixup = mga_encoder_mode_fixup,
1363         .mode_set = mga_encoder_mode_set,
1364         .prepare = mga_encoder_prepare,
1365         .commit = mga_encoder_commit,
1366 };
1367
1368 static const struct drm_encoder_funcs mga_encoder_encoder_funcs = {
1369         .destroy = mga_encoder_destroy,
1370 };
1371
1372 static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
1373 {
1374         struct drm_encoder *encoder;
1375         struct mga_encoder *mga_encoder;
1376
1377         mga_encoder = kzalloc(sizeof(struct mga_encoder), GFP_KERNEL);
1378         if (!mga_encoder)
1379                 return NULL;
1380
1381         encoder = &mga_encoder->base;
1382         encoder->possible_crtcs = 0x1;
1383
1384         drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
1385                          DRM_MODE_ENCODER_DAC);
1386         drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
1387
1388         return encoder;
1389 }
1390
1391
1392 static int mga_vga_get_modes(struct drm_connector *connector)
1393 {
1394         struct mga_connector *mga_connector = to_mga_connector(connector);
1395         struct edid *edid;
1396         int ret = 0;
1397
1398         edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
1399         if (edid) {
1400                 drm_mode_connector_update_edid_property(connector, edid);
1401                 ret = drm_add_edid_modes(connector, edid);
1402                 connector->display_info.raw_edid = NULL;
1403                 kfree(edid);
1404         }
1405         return ret;
1406 }
1407
1408 static int mga_vga_mode_valid(struct drm_connector *connector,
1409                                  struct drm_display_mode *mode)
1410 {
1411         /* FIXME: Add bandwidth and g200se limitations */
1412
1413         if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1414             mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
1415             mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
1416             mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
1417                 return MODE_BAD;
1418         }
1419
1420         return MODE_OK;
1421 }
1422
1423 struct drm_encoder *mga_connector_best_encoder(struct drm_connector
1424                                                   *connector)
1425 {
1426         int enc_id = connector->encoder_ids[0];
1427         struct drm_mode_object *obj;
1428         struct drm_encoder *encoder;
1429
1430         /* pick the encoder ids */
1431         if (enc_id) {
1432                 obj =
1433                     drm_mode_object_find(connector->dev, enc_id,
1434                                          DRM_MODE_OBJECT_ENCODER);
1435                 if (!obj)
1436                         return NULL;
1437                 encoder = obj_to_encoder(obj);
1438                 return encoder;
1439         }
1440         return NULL;
1441 }
1442
1443 static enum drm_connector_status mga_vga_detect(struct drm_connector
1444                                                    *connector, bool force)
1445 {
1446         return connector_status_connected;
1447 }
1448
1449 static void mga_connector_destroy(struct drm_connector *connector)
1450 {
1451         struct mga_connector *mga_connector = to_mga_connector(connector);
1452         mgag200_i2c_destroy(mga_connector->i2c);
1453         drm_connector_cleanup(connector);
1454         kfree(connector);
1455 }
1456
1457 struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1458         .get_modes = mga_vga_get_modes,
1459         .mode_valid = mga_vga_mode_valid,
1460         .best_encoder = mga_connector_best_encoder,
1461 };
1462
1463 struct drm_connector_funcs mga_vga_connector_funcs = {
1464         .dpms = drm_helper_connector_dpms,
1465         .detect = mga_vga_detect,
1466         .fill_modes = drm_helper_probe_single_connector_modes,
1467         .destroy = mga_connector_destroy,
1468 };
1469
1470 static struct drm_connector *mga_vga_init(struct drm_device *dev)
1471 {
1472         struct drm_connector *connector;
1473         struct mga_connector *mga_connector;
1474
1475         mga_connector = kzalloc(sizeof(struct mga_connector), GFP_KERNEL);
1476         if (!mga_connector)
1477                 return NULL;
1478
1479         connector = &mga_connector->base;
1480
1481         drm_connector_init(dev, connector,
1482                            &mga_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA);
1483
1484         drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1485
1486         mga_connector->i2c = mgag200_i2c_create(dev);
1487         if (!mga_connector->i2c)
1488                 DRM_ERROR("failed to add ddc bus\n");
1489
1490         return connector;
1491 }
1492
1493
1494 int mgag200_modeset_init(struct mga_device *mdev)
1495 {
1496         struct drm_encoder *encoder;
1497         struct drm_connector *connector;
1498         int ret;
1499
1500         mdev->mode_info.mode_config_initialized = true;
1501
1502         mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1503         mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1504
1505         mdev->dev->mode_config.fb_base = mdev->mc.vram_base;
1506
1507         mga_crtc_init(mdev->dev);
1508
1509         encoder = mga_encoder_init(mdev->dev);
1510         if (!encoder) {
1511                 DRM_ERROR("mga_encoder_init failed\n");
1512                 return -1;
1513         }
1514
1515         connector = mga_vga_init(mdev->dev);
1516         if (!connector) {
1517                 DRM_ERROR("mga_vga_init failed\n");
1518                 return -1;
1519         }
1520
1521         drm_mode_connector_attach_encoder(connector, encoder);
1522
1523         ret = mgag200_fbdev_init(mdev);
1524         if (ret) {
1525                 DRM_ERROR("mga_fbdev_init failed\n");
1526                 return ret;
1527         }
1528
1529         return 0;
1530 }
1531
1532 void mgag200_modeset_fini(struct mga_device *mdev)
1533 {
1534
1535 }