Merge tag 'x86_mm_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-microblaze.git] / drivers / gpu / drm / mgag200 / mgag200_mode.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2010 Matt Turner.
4  * Copyright 2012 Red Hat
5  *
6  * Authors: Matthew Garrett
7  *          Matt Turner
8  *          Dave Airlie
9  */
10
11 #include <linux/delay.h>
12 #include <linux/dma-buf-map.h>
13
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_atomic_state_helper.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_damage_helper.h>
18 #include <drm/drm_format_helper.h>
19 #include <drm/drm_fourcc.h>
20 #include <drm/drm_gem_framebuffer_helper.h>
21 #include <drm/drm_plane_helper.h>
22 #include <drm/drm_print.h>
23 #include <drm/drm_probe_helper.h>
24 #include <drm/drm_simple_kms_helper.h>
25
26 #include "mgag200_drv.h"
27
28 #define MGAG200_LUT_SIZE 256
29
30 /*
31  * This file contains setup code for the CRTC.
32  */
33
34 static void mga_crtc_load_lut(struct drm_crtc *crtc)
35 {
36         struct drm_device *dev = crtc->dev;
37         struct mga_device *mdev = to_mga_device(dev);
38         struct drm_framebuffer *fb;
39         u16 *r_ptr, *g_ptr, *b_ptr;
40         int i;
41
42         if (!crtc->enabled)
43                 return;
44
45         if (!mdev->display_pipe.plane.state)
46                 return;
47
48         fb = mdev->display_pipe.plane.state->fb;
49
50         r_ptr = crtc->gamma_store;
51         g_ptr = r_ptr + crtc->gamma_size;
52         b_ptr = g_ptr + crtc->gamma_size;
53
54         WREG8(DAC_INDEX + MGA1064_INDEX, 0);
55
56         if (fb && fb->format->cpp[0] * 8 == 16) {
57                 int inc = (fb->format->depth == 15) ? 8 : 4;
58                 u8 r, b;
59                 for (i = 0; i < MGAG200_LUT_SIZE; i += inc) {
60                         if (fb->format->depth == 16) {
61                                 if (i > (MGAG200_LUT_SIZE >> 1)) {
62                                         r = b = 0;
63                                 } else {
64                                         r = *r_ptr++ >> 8;
65                                         b = *b_ptr++ >> 8;
66                                         r_ptr++;
67                                         b_ptr++;
68                                 }
69                         } else {
70                                 r = *r_ptr++ >> 8;
71                                 b = *b_ptr++ >> 8;
72                         }
73                         /* VGA registers */
74                         WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
75                         WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
76                         WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
77                 }
78                 return;
79         }
80         for (i = 0; i < MGAG200_LUT_SIZE; i++) {
81                 /* VGA registers */
82                 WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8);
83                 WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
84                 WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8);
85         }
86 }
87
88 static inline void mga_wait_vsync(struct mga_device *mdev)
89 {
90         unsigned long timeout = jiffies + HZ/10;
91         unsigned int status = 0;
92
93         do {
94                 status = RREG32(MGAREG_Status);
95         } while ((status & 0x08) && time_before(jiffies, timeout));
96         timeout = jiffies + HZ/10;
97         status = 0;
98         do {
99                 status = RREG32(MGAREG_Status);
100         } while (!(status & 0x08) && time_before(jiffies, timeout));
101 }
102
103 static inline void mga_wait_busy(struct mga_device *mdev)
104 {
105         unsigned long timeout = jiffies + HZ;
106         unsigned int status = 0;
107         do {
108                 status = RREG8(MGAREG_Status + 2);
109         } while ((status & 0x01) && time_before(jiffies, timeout));
110 }
111
112 /*
113  * PLL setup
114  */
115
116 static int mgag200_g200_set_plls(struct mga_device *mdev, long clock)
117 {
118         struct drm_device *dev = &mdev->base;
119         const int post_div_max = 7;
120         const int in_div_min = 1;
121         const int in_div_max = 6;
122         const int feed_div_min = 7;
123         const int feed_div_max = 127;
124         u8 testm, testn;
125         u8 n = 0, m = 0, p, s;
126         long f_vco;
127         long computed;
128         long delta, tmp_delta;
129         long ref_clk = mdev->model.g200.ref_clk;
130         long p_clk_min = mdev->model.g200.pclk_min;
131         long p_clk_max =  mdev->model.g200.pclk_max;
132
133         if (clock > p_clk_max) {
134                 drm_err(dev, "Pixel Clock %ld too high\n", clock);
135                 return 1;
136         }
137
138         if (clock < p_clk_min >> 3)
139                 clock = p_clk_min >> 3;
140
141         f_vco = clock;
142         for (p = 0;
143              p <= post_div_max && f_vco < p_clk_min;
144              p = (p << 1) + 1, f_vco <<= 1)
145                 ;
146
147         delta = clock;
148
149         for (testm = in_div_min; testm <= in_div_max; testm++) {
150                 for (testn = feed_div_min; testn <= feed_div_max; testn++) {
151                         computed = ref_clk * (testn + 1) / (testm + 1);
152                         if (computed < f_vco)
153                                 tmp_delta = f_vco - computed;
154                         else
155                                 tmp_delta = computed - f_vco;
156                         if (tmp_delta < delta) {
157                                 delta = tmp_delta;
158                                 m = testm;
159                                 n = testn;
160                         }
161                 }
162         }
163         f_vco = ref_clk * (n + 1) / (m + 1);
164         if (f_vco < 100000)
165                 s = 0;
166         else if (f_vco < 140000)
167                 s = 1;
168         else if (f_vco < 180000)
169                 s = 2;
170         else
171                 s = 3;
172
173         drm_dbg_kms(dev, "clock: %ld vco: %ld m: %d n: %d p: %d s: %d\n",
174                     clock, f_vco, m, n, p, s);
175
176         WREG_DAC(MGA1064_PIX_PLLC_M, m);
177         WREG_DAC(MGA1064_PIX_PLLC_N, n);
178         WREG_DAC(MGA1064_PIX_PLLC_P, (p | (s << 3)));
179
180         return 0;
181 }
182
183 #define P_ARRAY_SIZE 9
184
185 static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
186 {
187         u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
188         unsigned int vcomax, vcomin, pllreffreq;
189         unsigned int delta, tmpdelta, permitteddelta;
190         unsigned int testp, testm, testn;
191         unsigned int p, m, n;
192         unsigned int computed;
193         unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
194         unsigned int fvv;
195         unsigned int i;
196
197         if (unique_rev_id <= 0x03) {
198
199                 m = n = p = 0;
200                 vcomax = 320000;
201                 vcomin = 160000;
202                 pllreffreq = 25000;
203
204                 delta = 0xffffffff;
205                 permitteddelta = clock * 5 / 1000;
206
207                 for (testp = 8; testp > 0; testp /= 2) {
208                         if (clock * testp > vcomax)
209                                 continue;
210                         if (clock * testp < vcomin)
211                                 continue;
212
213                         for (testn = 17; testn < 256; testn++) {
214                                 for (testm = 1; testm < 32; testm++) {
215                                         computed = (pllreffreq * testn) /
216                                                 (testm * testp);
217                                         if (computed > clock)
218                                                 tmpdelta = computed - clock;
219                                         else
220                                                 tmpdelta = clock - computed;
221                                         if (tmpdelta < delta) {
222                                                 delta = tmpdelta;
223                                                 m = testm - 1;
224                                                 n = testn - 1;
225                                                 p = testp - 1;
226                                         }
227                                 }
228                         }
229                 }
230         } else {
231
232
233                 m = n = p = 0;
234                 vcomax        = 1600000;
235                 vcomin        = 800000;
236                 pllreffreq    = 25000;
237
238                 if (clock < 25000)
239                         clock = 25000;
240
241                 clock = clock * 2;
242
243                 delta = 0xFFFFFFFF;
244                 /* Permited delta is 0.5% as VESA Specification */
245                 permitteddelta = clock * 5 / 1000;
246
247                 for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
248                         testp = pvalues_e4[i];
249
250                         if ((clock * testp) > vcomax)
251                                 continue;
252                         if ((clock * testp) < vcomin)
253                                 continue;
254
255                         for (testn = 50; testn <= 256; testn++) {
256                                 for (testm = 1; testm <= 32; testm++) {
257                                         computed = (pllreffreq * testn) /
258                                                 (testm * testp);
259                                         if (computed > clock)
260                                                 tmpdelta = computed - clock;
261                                         else
262                                                 tmpdelta = clock - computed;
263
264                                         if (tmpdelta < delta) {
265                                                 delta = tmpdelta;
266                                                 m = testm - 1;
267                                                 n = testn - 1;
268                                                 p = testp - 1;
269                                         }
270                                 }
271                         }
272                 }
273
274                 fvv = pllreffreq * (n + 1) / (m + 1);
275                 fvv = (fvv - 800000) / 50000;
276
277                 if (fvv > 15)
278                         fvv = 15;
279
280                 p |= (fvv << 4);
281                 m |= 0x80;
282
283                 clock = clock / 2;
284         }
285
286         if (delta > permitteddelta) {
287                 pr_warn("PLL delta too large\n");
288                 return 1;
289         }
290
291         WREG_DAC(MGA1064_PIX_PLLC_M, m);
292         WREG_DAC(MGA1064_PIX_PLLC_N, n);
293         WREG_DAC(MGA1064_PIX_PLLC_P, p);
294
295         if (unique_rev_id >= 0x04) {
296                 WREG_DAC(0x1a, 0x09);
297                 msleep(20);
298                 WREG_DAC(0x1a, 0x01);
299
300         }
301
302         return 0;
303 }
304
305 static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
306 {
307         unsigned int vcomax, vcomin, pllreffreq;
308         unsigned int delta, tmpdelta;
309         unsigned int testp, testm, testn, testp2;
310         unsigned int p, m, n;
311         unsigned int computed;
312         int i, j, tmpcount, vcount;
313         bool pll_locked = false;
314         u8 tmp;
315
316         m = n = p = 0;
317
318         delta = 0xffffffff;
319
320         if (mdev->type == G200_EW3) {
321
322                 vcomax = 800000;
323                 vcomin = 400000;
324                 pllreffreq = 25000;
325
326                 for (testp = 1; testp < 8; testp++) {
327                         for (testp2 = 1; testp2 < 8; testp2++) {
328                                 if (testp < testp2)
329                                         continue;
330                                 if ((clock * testp * testp2) > vcomax)
331                                         continue;
332                                 if ((clock * testp * testp2) < vcomin)
333                                         continue;
334                                 for (testm = 1; testm < 26; testm++) {
335                                         for (testn = 32; testn < 2048 ; testn++) {
336                                                 computed = (pllreffreq * testn) /
337                                                         (testm * testp * testp2);
338                                                 if (computed > clock)
339                                                         tmpdelta = computed - clock;
340                                                 else
341                                                         tmpdelta = clock - computed;
342                                                 if (tmpdelta < delta) {
343                                                         delta = tmpdelta;
344                                                         m = ((testn & 0x100) >> 1) |
345                                                                 (testm);
346                                                         n = (testn & 0xFF);
347                                                         p = ((testn & 0x600) >> 3) |
348                                                                 (testp2 << 3) |
349                                                                 (testp);
350                                                 }
351                                         }
352                                 }
353                         }
354                 }
355         } else {
356
357                 vcomax = 550000;
358                 vcomin = 150000;
359                 pllreffreq = 48000;
360
361                 for (testp = 1; testp < 9; testp++) {
362                         if (clock * testp > vcomax)
363                                 continue;
364                         if (clock * testp < vcomin)
365                                 continue;
366
367                         for (testm = 1; testm < 17; testm++) {
368                                 for (testn = 1; testn < 151; testn++) {
369                                         computed = (pllreffreq * testn) /
370                                                 (testm * testp);
371                                         if (computed > clock)
372                                                 tmpdelta = computed - clock;
373                                         else
374                                                 tmpdelta = clock - computed;
375                                         if (tmpdelta < delta) {
376                                                 delta = tmpdelta;
377                                                 n = testn - 1;
378                                                 m = (testm - 1) |
379                                                         ((n >> 1) & 0x80);
380                                                 p = testp - 1;
381                                         }
382                                 }
383                         }
384                 }
385         }
386
387         for (i = 0; i <= 32 && pll_locked == false; i++) {
388                 if (i > 0) {
389                         WREG8(MGAREG_CRTC_INDEX, 0x1e);
390                         tmp = RREG8(MGAREG_CRTC_DATA);
391                         if (tmp < 0xff)
392                                 WREG8(MGAREG_CRTC_DATA, tmp+1);
393                 }
394
395                 /* set pixclkdis to 1 */
396                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
397                 tmp = RREG8(DAC_DATA);
398                 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
399                 WREG8(DAC_DATA, tmp);
400
401                 WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
402                 tmp = RREG8(DAC_DATA);
403                 tmp |= MGA1064_REMHEADCTL_CLKDIS;
404                 WREG8(DAC_DATA, tmp);
405
406                 /* select PLL Set C */
407                 tmp = RREG8(MGAREG_MEM_MISC_READ);
408                 tmp |= 0x3 << 2;
409                 WREG8(MGAREG_MEM_MISC_WRITE, tmp);
410
411                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
412                 tmp = RREG8(DAC_DATA);
413                 tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
414                 WREG8(DAC_DATA, tmp);
415
416                 udelay(500);
417
418                 /* reset the PLL */
419                 WREG8(DAC_INDEX, MGA1064_VREF_CTL);
420                 tmp = RREG8(DAC_DATA);
421                 tmp &= ~0x04;
422                 WREG8(DAC_DATA, tmp);
423
424                 udelay(50);
425
426                 /* program pixel pll register */
427                 WREG_DAC(MGA1064_WB_PIX_PLLC_N, n);
428                 WREG_DAC(MGA1064_WB_PIX_PLLC_M, m);
429                 WREG_DAC(MGA1064_WB_PIX_PLLC_P, p);
430
431                 udelay(50);
432
433                 /* turn pll on */
434                 WREG8(DAC_INDEX, MGA1064_VREF_CTL);
435                 tmp = RREG8(DAC_DATA);
436                 tmp |= 0x04;
437                 WREG_DAC(MGA1064_VREF_CTL, tmp);
438
439                 udelay(500);
440
441                 /* select the pixel pll */
442                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
443                 tmp = RREG8(DAC_DATA);
444                 tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
445                 tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
446                 WREG8(DAC_DATA, tmp);
447
448                 WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
449                 tmp = RREG8(DAC_DATA);
450                 tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
451                 tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
452                 WREG8(DAC_DATA, tmp);
453
454                 /* reset dotclock rate bit */
455                 WREG8(MGAREG_SEQ_INDEX, 1);
456                 tmp = RREG8(MGAREG_SEQ_DATA);
457                 tmp &= ~0x8;
458                 WREG8(MGAREG_SEQ_DATA, tmp);
459
460                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
461                 tmp = RREG8(DAC_DATA);
462                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
463                 WREG8(DAC_DATA, tmp);
464
465                 vcount = RREG8(MGAREG_VCOUNT);
466
467                 for (j = 0; j < 30 && pll_locked == false; j++) {
468                         tmpcount = RREG8(MGAREG_VCOUNT);
469                         if (tmpcount < vcount)
470                                 vcount = 0;
471                         if ((tmpcount - vcount) > 2)
472                                 pll_locked = true;
473                         else
474                                 udelay(5);
475                 }
476         }
477         WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
478         tmp = RREG8(DAC_DATA);
479         tmp &= ~MGA1064_REMHEADCTL_CLKDIS;
480         WREG_DAC(MGA1064_REMHEADCTL, tmp);
481         return 0;
482 }
483
484 static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
485 {
486         unsigned int vcomax, vcomin, pllreffreq;
487         unsigned int delta, tmpdelta;
488         unsigned int testp, testm, testn;
489         unsigned int p, m, n;
490         unsigned int computed;
491         u8 tmp;
492
493         m = n = p = 0;
494         vcomax = 550000;
495         vcomin = 150000;
496         pllreffreq = 50000;
497
498         delta = 0xffffffff;
499
500         for (testp = 16; testp > 0; testp--) {
501                 if (clock * testp > vcomax)
502                         continue;
503                 if (clock * testp < vcomin)
504                         continue;
505
506                 for (testn = 1; testn < 257; testn++) {
507                         for (testm = 1; testm < 17; testm++) {
508                                 computed = (pllreffreq * testn) /
509                                         (testm * testp);
510                                 if (computed > clock)
511                                         tmpdelta = computed - clock;
512                                 else
513                                         tmpdelta = clock - computed;
514                                 if (tmpdelta < delta) {
515                                         delta = tmpdelta;
516                                         n = testn - 1;
517                                         m = testm - 1;
518                                         p = testp - 1;
519                                 }
520                         }
521                 }
522         }
523
524         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
525         tmp = RREG8(DAC_DATA);
526         tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
527         WREG8(DAC_DATA, tmp);
528
529         tmp = RREG8(MGAREG_MEM_MISC_READ);
530         tmp |= 0x3 << 2;
531         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
532
533         WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
534         tmp = RREG8(DAC_DATA);
535         WREG8(DAC_DATA, tmp & ~0x40);
536
537         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
538         tmp = RREG8(DAC_DATA);
539         tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
540         WREG8(DAC_DATA, tmp);
541
542         WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
543         WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
544         WREG_DAC(MGA1064_EV_PIX_PLLC_P, p);
545
546         udelay(50);
547
548         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
549         tmp = RREG8(DAC_DATA);
550         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
551         WREG8(DAC_DATA, tmp);
552
553         udelay(500);
554
555         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
556         tmp = RREG8(DAC_DATA);
557         tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
558         tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
559         WREG8(DAC_DATA, tmp);
560
561         WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
562         tmp = RREG8(DAC_DATA);
563         WREG8(DAC_DATA, tmp | 0x40);
564
565         tmp = RREG8(MGAREG_MEM_MISC_READ);
566         tmp |= (0x3 << 2);
567         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
568
569         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
570         tmp = RREG8(DAC_DATA);
571         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
572         WREG8(DAC_DATA, tmp);
573
574         return 0;
575 }
576
577 static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
578 {
579         unsigned int vcomax, vcomin, pllreffreq;
580         unsigned int delta, tmpdelta;
581         unsigned int testp, testm, testn;
582         unsigned int p, m, n;
583         unsigned int computed;
584         int i, j, tmpcount, vcount;
585         u8 tmp;
586         bool pll_locked = false;
587
588         m = n = p = 0;
589
590         if (mdev->type == G200_EH3) {
591                 vcomax = 3000000;
592                 vcomin = 1500000;
593                 pllreffreq = 25000;
594
595                 delta = 0xffffffff;
596
597                 testp = 0;
598
599                 for (testm = 150; testm >= 6; testm--) {
600                         if (clock * testm > vcomax)
601                                 continue;
602                         if (clock * testm < vcomin)
603                                 continue;
604                         for (testn = 120; testn >= 60; testn--) {
605                                 computed = (pllreffreq * testn) / testm;
606                                 if (computed > clock)
607                                         tmpdelta = computed - clock;
608                                 else
609                                         tmpdelta = clock - computed;
610                                 if (tmpdelta < delta) {
611                                         delta = tmpdelta;
612                                         n = testn;
613                                         m = testm;
614                                         p = testp;
615                                 }
616                                 if (delta == 0)
617                                         break;
618                         }
619                         if (delta == 0)
620                                 break;
621                 }
622         } else {
623
624                 vcomax = 800000;
625                 vcomin = 400000;
626                 pllreffreq = 33333;
627
628                 delta = 0xffffffff;
629
630                 for (testp = 16; testp > 0; testp >>= 1) {
631                         if (clock * testp > vcomax)
632                                 continue;
633                         if (clock * testp < vcomin)
634                                 continue;
635
636                         for (testm = 1; testm < 33; testm++) {
637                                 for (testn = 17; testn < 257; testn++) {
638                                         computed = (pllreffreq * testn) /
639                                                 (testm * testp);
640                                         if (computed > clock)
641                                                 tmpdelta = computed - clock;
642                                         else
643                                                 tmpdelta = clock - computed;
644                                         if (tmpdelta < delta) {
645                                                 delta = tmpdelta;
646                                                 n = testn - 1;
647                                                 m = (testm - 1);
648                                                 p = testp - 1;
649                                         }
650                                         if ((clock * testp) >= 600000)
651                                                 p |= 0x80;
652                                 }
653                         }
654                 }
655         }
656         for (i = 0; i <= 32 && pll_locked == false; i++) {
657                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
658                 tmp = RREG8(DAC_DATA);
659                 tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
660                 WREG8(DAC_DATA, tmp);
661
662                 tmp = RREG8(MGAREG_MEM_MISC_READ);
663                 tmp |= 0x3 << 2;
664                 WREG8(MGAREG_MEM_MISC_WRITE, tmp);
665
666                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
667                 tmp = RREG8(DAC_DATA);
668                 tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
669                 WREG8(DAC_DATA, tmp);
670
671                 udelay(500);
672
673                 WREG_DAC(MGA1064_EH_PIX_PLLC_M, m);
674                 WREG_DAC(MGA1064_EH_PIX_PLLC_N, n);
675                 WREG_DAC(MGA1064_EH_PIX_PLLC_P, p);
676
677                 udelay(500);
678
679                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
680                 tmp = RREG8(DAC_DATA);
681                 tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
682                 tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
683                 WREG8(DAC_DATA, tmp);
684
685                 WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
686                 tmp = RREG8(DAC_DATA);
687                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
688                 tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
689                 WREG8(DAC_DATA, tmp);
690
691                 vcount = RREG8(MGAREG_VCOUNT);
692
693                 for (j = 0; j < 30 && pll_locked == false; j++) {
694                         tmpcount = RREG8(MGAREG_VCOUNT);
695                         if (tmpcount < vcount)
696                                 vcount = 0;
697                         if ((tmpcount - vcount) > 2)
698                                 pll_locked = true;
699                         else
700                                 udelay(5);
701                 }
702         }
703
704         return 0;
705 }
706
707 static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
708 {
709         unsigned int vcomax, vcomin, pllreffreq;
710         unsigned int delta, tmpdelta;
711         int testr, testn, testm, testo;
712         unsigned int p, m, n;
713         unsigned int computed, vco;
714         int tmp;
715         const unsigned int m_div_val[] = { 1, 2, 4, 8 };
716
717         m = n = p = 0;
718         vcomax = 1488000;
719         vcomin = 1056000;
720         pllreffreq = 48000;
721
722         delta = 0xffffffff;
723
724         for (testr = 0; testr < 4; testr++) {
725                 if (delta == 0)
726                         break;
727                 for (testn = 5; testn < 129; testn++) {
728                         if (delta == 0)
729                                 break;
730                         for (testm = 3; testm >= 0; testm--) {
731                                 if (delta == 0)
732                                         break;
733                                 for (testo = 5; testo < 33; testo++) {
734                                         vco = pllreffreq * (testn + 1) /
735                                                 (testr + 1);
736                                         if (vco < vcomin)
737                                                 continue;
738                                         if (vco > vcomax)
739                                                 continue;
740                                         computed = vco / (m_div_val[testm] * (testo + 1));
741                                         if (computed > clock)
742                                                 tmpdelta = computed - clock;
743                                         else
744                                                 tmpdelta = clock - computed;
745                                         if (tmpdelta < delta) {
746                                                 delta = tmpdelta;
747                                                 m = testm | (testo << 3);
748                                                 n = testn;
749                                                 p = testr | (testr << 3);
750                                         }
751                                 }
752                         }
753                 }
754         }
755
756         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
757         tmp = RREG8(DAC_DATA);
758         tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
759         WREG8(DAC_DATA, tmp);
760
761         WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
762         tmp = RREG8(DAC_DATA);
763         tmp |= MGA1064_REMHEADCTL_CLKDIS;
764         WREG8(DAC_DATA, tmp);
765
766         tmp = RREG8(MGAREG_MEM_MISC_READ);
767         tmp |= (0x3<<2) | 0xc0;
768         WREG8(MGAREG_MEM_MISC_WRITE, tmp);
769
770         WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
771         tmp = RREG8(DAC_DATA);
772         tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
773         tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
774         WREG8(DAC_DATA, tmp);
775
776         udelay(500);
777
778         WREG_DAC(MGA1064_ER_PIX_PLLC_N, n);
779         WREG_DAC(MGA1064_ER_PIX_PLLC_M, m);
780         WREG_DAC(MGA1064_ER_PIX_PLLC_P, p);
781
782         udelay(50);
783
784         return 0;
785 }
786
787 static int mgag200_crtc_set_plls(struct mga_device *mdev, long clock)
788 {
789         u8 misc;
790
791         switch(mdev->type) {
792         case G200_PCI:
793         case G200_AGP:
794                 return mgag200_g200_set_plls(mdev, clock);
795         case G200_SE_A:
796         case G200_SE_B:
797                 return mga_g200se_set_plls(mdev, clock);
798         case G200_WB:
799         case G200_EW3:
800                 return mga_g200wb_set_plls(mdev, clock);
801         case G200_EV:
802                 return mga_g200ev_set_plls(mdev, clock);
803         case G200_EH:
804         case G200_EH3:
805                 return mga_g200eh_set_plls(mdev, clock);
806         case G200_ER:
807                 return mga_g200er_set_plls(mdev, clock);
808         }
809
810         misc = RREG8(MGA_MISC_IN);
811         misc &= ~MGAREG_MISC_CLK_SEL_MASK;
812         misc |= MGAREG_MISC_CLK_SEL_MGA_MSK;
813         WREG8(MGA_MISC_OUT, misc);
814
815         return 0;
816 }
817
818 static void mgag200_g200wb_hold_bmc(struct mga_device *mdev)
819 {
820         u8 tmp;
821         int iter_max;
822
823         /* 1- The first step is to warn the BMC of an upcoming mode change.
824          * We are putting the misc<0> to output.*/
825
826         WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
827         tmp = RREG8(DAC_DATA);
828         tmp |= 0x10;
829         WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
830
831         /* we are putting a 1 on the misc<0> line */
832         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
833         tmp = RREG8(DAC_DATA);
834         tmp |= 0x10;
835         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
836
837         /* 2- Second step to mask and further scan request
838          * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
839          */
840         WREG8(DAC_INDEX, MGA1064_SPAREREG);
841         tmp = RREG8(DAC_DATA);
842         tmp |= 0x80;
843         WREG_DAC(MGA1064_SPAREREG, tmp);
844
845         /* 3a- the third step is to verifu if there is an active scan
846          * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
847          */
848         iter_max = 300;
849         while (!(tmp & 0x1) && iter_max) {
850                 WREG8(DAC_INDEX, MGA1064_SPAREREG);
851                 tmp = RREG8(DAC_DATA);
852                 udelay(1000);
853                 iter_max--;
854         }
855
856         /* 3b- this step occurs only if the remove is actually scanning
857          * we are waiting for the end of the frame which is a 1 on
858          * remvsyncsts (XSPAREREG<1>)
859          */
860         if (iter_max) {
861                 iter_max = 300;
862                 while ((tmp & 0x2) && iter_max) {
863                         WREG8(DAC_INDEX, MGA1064_SPAREREG);
864                         tmp = RREG8(DAC_DATA);
865                         udelay(1000);
866                         iter_max--;
867                 }
868         }
869 }
870
871 static void mgag200_g200wb_release_bmc(struct mga_device *mdev)
872 {
873         u8 tmp;
874
875         /* 1- The first step is to ensure that the vrsten and hrsten are set */
876         WREG8(MGAREG_CRTCEXT_INDEX, 1);
877         tmp = RREG8(MGAREG_CRTCEXT_DATA);
878         WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
879
880         /* 2- second step is to assert the rstlvl2 */
881         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
882         tmp = RREG8(DAC_DATA);
883         tmp |= 0x8;
884         WREG8(DAC_DATA, tmp);
885
886         /* wait 10 us */
887         udelay(10);
888
889         /* 3- deassert rstlvl2 */
890         tmp &= ~0x08;
891         WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
892         WREG8(DAC_DATA, tmp);
893
894         /* 4- remove mask of scan request */
895         WREG8(DAC_INDEX, MGA1064_SPAREREG);
896         tmp = RREG8(DAC_DATA);
897         tmp &= ~0x80;
898         WREG8(DAC_DATA, tmp);
899
900         /* 5- put back a 0 on the misc<0> line */
901         WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
902         tmp = RREG8(DAC_DATA);
903         tmp &= ~0x10;
904         WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
905 }
906
907 /*
908  * This is how the framebuffer base address is stored in g200 cards:
909  *   * Assume @offset is the gpu_addr variable of the framebuffer object
910  *   * Then addr is the number of _pixels_ (not bytes) from the start of
911  *     VRAM to the first pixel we want to display. (divided by 2 for 32bit
912  *     framebuffers)
913  *   * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
914  *      addr<20> -> CRTCEXT0<6>
915  *      addr<19-16> -> CRTCEXT0<3-0>
916  *      addr<15-8> -> CRTCC<7-0>
917  *      addr<7-0> -> CRTCD<7-0>
918  *
919  *  CRTCEXT0 has to be programmed last to trigger an update and make the
920  *  new addr variable take effect.
921  */
922 static void mgag200_set_startadd(struct mga_device *mdev,
923                                  unsigned long offset)
924 {
925         struct drm_device *dev = &mdev->base;
926         u32 startadd;
927         u8 crtcc, crtcd, crtcext0;
928
929         startadd = offset / 8;
930
931         /*
932          * Can't store addresses any higher than that, but we also
933          * don't have more than 16 MiB of memory, so it should be fine.
934          */
935         drm_WARN_ON(dev, startadd > 0x1fffff);
936
937         RREG_ECRT(0x00, crtcext0);
938
939         crtcc = (startadd >> 8) & 0xff;
940         crtcd = startadd & 0xff;
941         crtcext0 &= 0xb0;
942         crtcext0 |= ((startadd >> 14) & BIT(6)) |
943                     ((startadd >> 16) & 0x0f);
944
945         WREG_CRT(0x0c, crtcc);
946         WREG_CRT(0x0d, crtcd);
947         WREG_ECRT(0x00, crtcext0);
948 }
949
950 static void mgag200_set_dac_regs(struct mga_device *mdev)
951 {
952         size_t i;
953         u8 dacvalue[] = {
954                 /* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,
955                 /* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,
956                 /* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,
957                 /* 0x18: */     0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
958                 /* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959                 /* 0x28: */     0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
960                 /* 0x30: */     0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
961                 /* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
962                 /* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,
963                 /* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
964         };
965
966         switch (mdev->type) {
967         case G200_PCI:
968         case G200_AGP:
969                 dacvalue[MGA1064_SYS_PLL_M] = 0x04;
970                 dacvalue[MGA1064_SYS_PLL_N] = 0x2D;
971                 dacvalue[MGA1064_SYS_PLL_P] = 0x19;
972                 break;
973         case G200_SE_A:
974         case G200_SE_B:
975                 dacvalue[MGA1064_VREF_CTL] = 0x03;
976                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
977                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
978                                              MGA1064_MISC_CTL_VGA8 |
979                                              MGA1064_MISC_CTL_DAC_RAM_CS;
980                 break;
981         case G200_WB:
982         case G200_EW3:
983                 dacvalue[MGA1064_VREF_CTL] = 0x07;
984                 break;
985         case G200_EV:
986                 dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
987                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
988                                              MGA1064_MISC_CTL_DAC_RAM_CS;
989                 break;
990         case G200_EH:
991         case G200_EH3:
992                 dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
993                                              MGA1064_MISC_CTL_DAC_RAM_CS;
994                 break;
995         case G200_ER:
996                 break;
997         }
998
999         for (i = 0; i < ARRAY_SIZE(dacvalue); i++) {
1000                 if ((i <= 0x17) ||
1001                     (i == 0x1b) ||
1002                     (i == 0x1c) ||
1003                     ((i >= 0x1f) && (i <= 0x29)) ||
1004                     ((i >= 0x30) && (i <= 0x37)))
1005                         continue;
1006                 if (IS_G200_SE(mdev) &&
1007                     ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
1008                         continue;
1009                 if ((mdev->type == G200_EV ||
1010                     mdev->type == G200_WB ||
1011                     mdev->type == G200_EH ||
1012                     mdev->type == G200_EW3 ||
1013                     mdev->type == G200_EH3) &&
1014                     (i >= 0x44) && (i <= 0x4e))
1015                         continue;
1016
1017                 WREG_DAC(i, dacvalue[i]);
1018         }
1019
1020         if (mdev->type == G200_ER)
1021                 WREG_DAC(0x90, 0);
1022 }
1023
1024 static void mgag200_init_regs(struct mga_device *mdev)
1025 {
1026         u8 crtc11, misc;
1027
1028         mgag200_set_dac_regs(mdev);
1029
1030         WREG_SEQ(2, 0x0f);
1031         WREG_SEQ(3, 0x00);
1032         WREG_SEQ(4, 0x0e);
1033
1034         WREG_CRT(10, 0);
1035         WREG_CRT(11, 0);
1036         WREG_CRT(12, 0);
1037         WREG_CRT(13, 0);
1038         WREG_CRT(14, 0);
1039         WREG_CRT(15, 0);
1040
1041         RREG_CRT(0x11, crtc11);
1042         crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT |
1043                     MGAREG_CRTC11_VINTEN |
1044                     MGAREG_CRTC11_VINTCLR);
1045         WREG_CRT(0x11, crtc11);
1046
1047         if (mdev->type == G200_ER)
1048                 WREG_ECRT(0x24, 0x5);
1049
1050         if (mdev->type == G200_EW3)
1051                 WREG_ECRT(0x34, 0x5);
1052
1053         misc = RREG8(MGA_MISC_IN);
1054         misc |= MGAREG_MISC_IOADSEL;
1055         WREG8(MGA_MISC_OUT, misc);
1056 }
1057
1058 static void mgag200_set_mode_regs(struct mga_device *mdev,
1059                                   const struct drm_display_mode *mode)
1060 {
1061         unsigned int hdisplay, hsyncstart, hsyncend, htotal;
1062         unsigned int vdisplay, vsyncstart, vsyncend, vtotal;
1063         u8 misc, crtcext1, crtcext2, crtcext5;
1064
1065         hdisplay = mode->hdisplay / 8 - 1;
1066         hsyncstart = mode->hsync_start / 8 - 1;
1067         hsyncend = mode->hsync_end / 8 - 1;
1068         htotal = mode->htotal / 8 - 1;
1069
1070         /* Work around hardware quirk */
1071         if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
1072                 htotal++;
1073
1074         vdisplay = mode->vdisplay - 1;
1075         vsyncstart = mode->vsync_start - 1;
1076         vsyncend = mode->vsync_end - 1;
1077         vtotal = mode->vtotal - 2;
1078
1079         misc = RREG8(MGA_MISC_IN);
1080
1081         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1082                 misc |= MGAREG_MISC_HSYNCPOL;
1083         else
1084                 misc &= ~MGAREG_MISC_HSYNCPOL;
1085
1086         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1087                 misc |= MGAREG_MISC_VSYNCPOL;
1088         else
1089                 misc &= ~MGAREG_MISC_VSYNCPOL;
1090
1091         crtcext1 = (((htotal - 4) & 0x100) >> 8) |
1092                    ((hdisplay & 0x100) >> 7) |
1093                    ((hsyncstart & 0x100) >> 6) |
1094                     (htotal & 0x40);
1095         if (mdev->type == G200_WB || mdev->type == G200_EW3)
1096                 crtcext1 |= BIT(7) | /* vrsten */
1097                             BIT(3); /* hrsten */
1098
1099         crtcext2 = ((vtotal & 0xc00) >> 10) |
1100                    ((vdisplay & 0x400) >> 8) |
1101                    ((vdisplay & 0xc00) >> 7) |
1102                    ((vsyncstart & 0xc00) >> 5) |
1103                    ((vdisplay & 0x400) >> 3);
1104         crtcext5 = 0x00;
1105
1106         WREG_CRT(0, htotal - 4);
1107         WREG_CRT(1, hdisplay);
1108         WREG_CRT(2, hdisplay);
1109         WREG_CRT(3, (htotal & 0x1F) | 0x80);
1110         WREG_CRT(4, hsyncstart);
1111         WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F));
1112         WREG_CRT(6, vtotal & 0xFF);
1113         WREG_CRT(7, ((vtotal & 0x100) >> 8) |
1114                  ((vdisplay & 0x100) >> 7) |
1115                  ((vsyncstart & 0x100) >> 6) |
1116                  ((vdisplay & 0x100) >> 5) |
1117                  ((vdisplay & 0x100) >> 4) | /* linecomp */
1118                  ((vtotal & 0x200) >> 4) |
1119                  ((vdisplay & 0x200) >> 3) |
1120                  ((vsyncstart & 0x200) >> 2));
1121         WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
1122                  ((vdisplay & 0x200) >> 3));
1123         WREG_CRT(16, vsyncstart & 0xFF);
1124         WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
1125         WREG_CRT(18, vdisplay & 0xFF);
1126         WREG_CRT(20, 0);
1127         WREG_CRT(21, vdisplay & 0xFF);
1128         WREG_CRT(22, (vtotal + 1) & 0xFF);
1129         WREG_CRT(23, 0xc3);
1130         WREG_CRT(24, vdisplay & 0xFF);
1131
1132         WREG_ECRT(0x01, crtcext1);
1133         WREG_ECRT(0x02, crtcext2);
1134         WREG_ECRT(0x05, crtcext5);
1135
1136         WREG8(MGA_MISC_OUT, misc);
1137 }
1138
1139 static u8 mgag200_get_bpp_shift(struct mga_device *mdev,
1140                                 const struct drm_format_info *format)
1141 {
1142         return mdev->bpp_shifts[format->cpp[0] - 1];
1143 }
1144
1145 /*
1146  * Calculates the HW offset value from the framebuffer's pitch. The
1147  * offset is a multiple of the pixel size and depends on the display
1148  * format.
1149  */
1150 static u32 mgag200_calculate_offset(struct mga_device *mdev,
1151                                     const struct drm_framebuffer *fb)
1152 {
1153         u32 offset = fb->pitches[0] / fb->format->cpp[0];
1154         u8 bppshift = mgag200_get_bpp_shift(mdev, fb->format);
1155
1156         if (fb->format->cpp[0] * 8 == 24)
1157                 offset = (offset * 3) >> (4 - bppshift);
1158         else
1159                 offset = offset >> (4 - bppshift);
1160
1161         return offset;
1162 }
1163
1164 static void mgag200_set_offset(struct mga_device *mdev,
1165                                const struct drm_framebuffer *fb)
1166 {
1167         u8 crtc13, crtcext0;
1168         u32 offset = mgag200_calculate_offset(mdev, fb);
1169
1170         RREG_ECRT(0, crtcext0);
1171
1172         crtc13 = offset & 0xff;
1173
1174         crtcext0 &= ~MGAREG_CRTCEXT0_OFFSET_MASK;
1175         crtcext0 |= (offset >> 4) & MGAREG_CRTCEXT0_OFFSET_MASK;
1176
1177         WREG_CRT(0x13, crtc13);
1178         WREG_ECRT(0x00, crtcext0);
1179 }
1180
1181 static void mgag200_set_format_regs(struct mga_device *mdev,
1182                                     const struct drm_framebuffer *fb)
1183 {
1184         struct drm_device *dev = &mdev->base;
1185         const struct drm_format_info *format = fb->format;
1186         unsigned int bpp, bppshift, scale;
1187         u8 crtcext3, xmulctrl;
1188
1189         bpp = format->cpp[0] * 8;
1190
1191         bppshift = mgag200_get_bpp_shift(mdev, format);
1192         switch (bpp) {
1193         case 24:
1194                 scale = ((1 << bppshift) * 3) - 1;
1195                 break;
1196         default:
1197                 scale = (1 << bppshift) - 1;
1198                 break;
1199         }
1200
1201         RREG_ECRT(3, crtcext3);
1202
1203         switch (bpp) {
1204         case 8:
1205                 xmulctrl = MGA1064_MUL_CTL_8bits;
1206                 break;
1207         case 16:
1208                 if (format->depth == 15)
1209                         xmulctrl = MGA1064_MUL_CTL_15bits;
1210                 else
1211                         xmulctrl = MGA1064_MUL_CTL_16bits;
1212                 break;
1213         case 24:
1214                 xmulctrl = MGA1064_MUL_CTL_24bits;
1215                 break;
1216         case 32:
1217                 xmulctrl = MGA1064_MUL_CTL_32_24bits;
1218                 break;
1219         default:
1220                 /* BUG: We should have caught this problem already. */
1221                 drm_WARN_ON(dev, "invalid format depth\n");
1222                 return;
1223         }
1224
1225         crtcext3 &= ~GENMASK(2, 0);
1226         crtcext3 |= scale;
1227
1228         WREG_DAC(MGA1064_MUL_CTL, xmulctrl);
1229
1230         WREG_GFX(0, 0x00);
1231         WREG_GFX(1, 0x00);
1232         WREG_GFX(2, 0x00);
1233         WREG_GFX(3, 0x00);
1234         WREG_GFX(4, 0x00);
1235         WREG_GFX(5, 0x40);
1236         WREG_GFX(6, 0x05);
1237         WREG_GFX(7, 0x0f);
1238         WREG_GFX(8, 0x0f);
1239
1240         WREG_ECRT(3, crtcext3);
1241 }
1242
1243 static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev)
1244 {
1245         static uint32_t RESET_FLAG = 0x00200000; /* undocumented magic value */
1246         u32 memctl;
1247
1248         memctl = RREG32(MGAREG_MEMCTL);
1249
1250         memctl |= RESET_FLAG;
1251         WREG32(MGAREG_MEMCTL, memctl);
1252
1253         udelay(1000);
1254
1255         memctl &= ~RESET_FLAG;
1256         WREG32(MGAREG_MEMCTL, memctl);
1257 }
1258
1259 static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev,
1260                                         const struct drm_display_mode *mode,
1261                                         const struct drm_framebuffer *fb)
1262 {
1263         u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1264         unsigned int hiprilvl;
1265         u8 crtcext6;
1266
1267         if  (unique_rev_id >= 0x04) {
1268                 hiprilvl = 0;
1269         } else if (unique_rev_id >= 0x02) {
1270                 unsigned int bpp;
1271                 unsigned long mb;
1272
1273                 if (fb->format->cpp[0] * 8 > 16)
1274                         bpp = 32;
1275                 else if (fb->format->cpp[0] * 8 > 8)
1276                         bpp = 16;
1277                 else
1278                         bpp = 8;
1279
1280                 mb = (mode->clock * bpp) / 1000;
1281                 if (mb > 3100)
1282                         hiprilvl = 0;
1283                 else if (mb > 2600)
1284                         hiprilvl = 1;
1285                 else if (mb > 1900)
1286                         hiprilvl = 2;
1287                 else if (mb > 1160)
1288                         hiprilvl = 3;
1289                 else if (mb > 440)
1290                         hiprilvl = 4;
1291                 else
1292                         hiprilvl = 5;
1293
1294         } else if (unique_rev_id >= 0x01) {
1295                 hiprilvl = 3;
1296         } else {
1297                 hiprilvl = 4;
1298         }
1299
1300         crtcext6 = hiprilvl; /* implicitly sets maxhipri to 0 */
1301
1302         WREG_ECRT(0x06, crtcext6);
1303 }
1304
1305 static void mgag200_g200ev_set_hiprilvl(struct mga_device *mdev)
1306 {
1307         WREG_ECRT(0x06, 0x00);
1308 }
1309
1310 static void mgag200_enable_display(struct mga_device *mdev)
1311 {
1312         u8 seq0, seq1, crtcext1;
1313
1314         RREG_SEQ(0x00, seq0);
1315         seq0 |= MGAREG_SEQ0_SYNCRST |
1316                 MGAREG_SEQ0_ASYNCRST;
1317         WREG_SEQ(0x00, seq0);
1318
1319         /*
1320          * TODO: replace busy waiting with vblank IRQ; put
1321          *       msleep(50) before changing SCROFF
1322          */
1323         mga_wait_vsync(mdev);
1324         mga_wait_busy(mdev);
1325
1326         RREG_SEQ(0x01, seq1);
1327         seq1 &= ~MGAREG_SEQ1_SCROFF;
1328         WREG_SEQ(0x01, seq1);
1329
1330         msleep(20);
1331
1332         RREG_ECRT(0x01, crtcext1);
1333         crtcext1 &= ~MGAREG_CRTCEXT1_VSYNCOFF;
1334         crtcext1 &= ~MGAREG_CRTCEXT1_HSYNCOFF;
1335         WREG_ECRT(0x01, crtcext1);
1336 }
1337
1338 static void mgag200_disable_display(struct mga_device *mdev)
1339 {
1340         u8 seq0, seq1, crtcext1;
1341
1342         RREG_SEQ(0x00, seq0);
1343         seq0 &= ~MGAREG_SEQ0_SYNCRST;
1344         WREG_SEQ(0x00, seq0);
1345
1346         /*
1347          * TODO: replace busy waiting with vblank IRQ; put
1348          *       msleep(50) before changing SCROFF
1349          */
1350         mga_wait_vsync(mdev);
1351         mga_wait_busy(mdev);
1352
1353         RREG_SEQ(0x01, seq1);
1354         seq1 |= MGAREG_SEQ1_SCROFF;
1355         WREG_SEQ(0x01, seq1);
1356
1357         msleep(20);
1358
1359         RREG_ECRT(0x01, crtcext1);
1360         crtcext1 |= MGAREG_CRTCEXT1_VSYNCOFF |
1361                     MGAREG_CRTCEXT1_HSYNCOFF;
1362         WREG_ECRT(0x01, crtcext1);
1363 }
1364
1365 /*
1366  * Connector
1367  */
1368
1369 static int mga_vga_get_modes(struct drm_connector *connector)
1370 {
1371         struct mga_connector *mga_connector = to_mga_connector(connector);
1372         struct edid *edid;
1373         int ret = 0;
1374
1375         edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
1376         if (edid) {
1377                 drm_connector_update_edid_property(connector, edid);
1378                 ret = drm_add_edid_modes(connector, edid);
1379                 kfree(edid);
1380         }
1381         return ret;
1382 }
1383
1384 static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
1385                                                         int bits_per_pixel)
1386 {
1387         uint32_t total_area, divisor;
1388         uint64_t active_area, pixels_per_second, bandwidth;
1389         uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
1390
1391         divisor = 1024;
1392
1393         if (!mode->htotal || !mode->vtotal || !mode->clock)
1394                 return 0;
1395
1396         active_area = mode->hdisplay * mode->vdisplay;
1397         total_area = mode->htotal * mode->vtotal;
1398
1399         pixels_per_second = active_area * mode->clock * 1000;
1400         do_div(pixels_per_second, total_area);
1401
1402         bandwidth = pixels_per_second * bytes_per_pixel * 100;
1403         do_div(bandwidth, divisor);
1404
1405         return (uint32_t)(bandwidth);
1406 }
1407
1408 #define MODE_BANDWIDTH  MODE_BAD
1409
1410 static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector,
1411                                  struct drm_display_mode *mode)
1412 {
1413         struct drm_device *dev = connector->dev;
1414         struct mga_device *mdev = to_mga_device(dev);
1415         int bpp = 32;
1416
1417         if (IS_G200_SE(mdev)) {
1418                 u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1419
1420                 if (unique_rev_id == 0x01) {
1421                         if (mode->hdisplay > 1600)
1422                                 return MODE_VIRTUAL_X;
1423                         if (mode->vdisplay > 1200)
1424                                 return MODE_VIRTUAL_Y;
1425                         if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1426                                 > (24400 * 1024))
1427                                 return MODE_BANDWIDTH;
1428                 } else if (unique_rev_id == 0x02) {
1429                         if (mode->hdisplay > 1920)
1430                                 return MODE_VIRTUAL_X;
1431                         if (mode->vdisplay > 1200)
1432                                 return MODE_VIRTUAL_Y;
1433                         if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1434                                 > (30100 * 1024))
1435                                 return MODE_BANDWIDTH;
1436                 } else {
1437                         if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1438                                 > (55000 * 1024))
1439                                 return MODE_BANDWIDTH;
1440                 }
1441         } else if (mdev->type == G200_WB) {
1442                 if (mode->hdisplay > 1280)
1443                         return MODE_VIRTUAL_X;
1444                 if (mode->vdisplay > 1024)
1445                         return MODE_VIRTUAL_Y;
1446                 if (mga_vga_calculate_mode_bandwidth(mode, bpp) >
1447                     (31877 * 1024))
1448                         return MODE_BANDWIDTH;
1449         } else if (mdev->type == G200_EV &&
1450                 (mga_vga_calculate_mode_bandwidth(mode, bpp)
1451                         > (32700 * 1024))) {
1452                 return MODE_BANDWIDTH;
1453         } else if (mdev->type == G200_EH &&
1454                 (mga_vga_calculate_mode_bandwidth(mode, bpp)
1455                         > (37500 * 1024))) {
1456                 return MODE_BANDWIDTH;
1457         } else if (mdev->type == G200_ER &&
1458                 (mga_vga_calculate_mode_bandwidth(mode,
1459                         bpp) > (55000 * 1024))) {
1460                 return MODE_BANDWIDTH;
1461         }
1462
1463         if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 ||
1464             (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) {
1465                 return MODE_H_ILLEGAL;
1466         }
1467
1468         if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1469             mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
1470             mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
1471             mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
1472                 return MODE_BAD;
1473         }
1474
1475         /* Validate the mode input by the user */
1476         if (connector->cmdline_mode.specified) {
1477                 if (connector->cmdline_mode.bpp_specified)
1478                         bpp = connector->cmdline_mode.bpp;
1479         }
1480
1481         if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->vram_fb_available) {
1482                 if (connector->cmdline_mode.specified)
1483                         connector->cmdline_mode.specified = false;
1484                 return MODE_BAD;
1485         }
1486
1487         return MODE_OK;
1488 }
1489
1490 static void mga_connector_destroy(struct drm_connector *connector)
1491 {
1492         struct mga_connector *mga_connector = to_mga_connector(connector);
1493         mgag200_i2c_destroy(mga_connector->i2c);
1494         drm_connector_cleanup(connector);
1495 }
1496
1497 static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1498         .get_modes  = mga_vga_get_modes,
1499         .mode_valid = mga_vga_mode_valid,
1500 };
1501
1502 static const struct drm_connector_funcs mga_vga_connector_funcs = {
1503         .reset                  = drm_atomic_helper_connector_reset,
1504         .fill_modes             = drm_helper_probe_single_connector_modes,
1505         .destroy                = mga_connector_destroy,
1506         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1507         .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
1508 };
1509
1510 static int mgag200_vga_connector_init(struct mga_device *mdev)
1511 {
1512         struct drm_device *dev = &mdev->base;
1513         struct mga_connector *mconnector = &mdev->connector;
1514         struct drm_connector *connector = &mconnector->base;
1515         struct mga_i2c_chan *i2c;
1516         int ret;
1517
1518         i2c = mgag200_i2c_create(dev);
1519         if (!i2c)
1520                 drm_warn(dev, "failed to add DDC bus\n");
1521
1522         ret = drm_connector_init_with_ddc(dev, connector,
1523                                           &mga_vga_connector_funcs,
1524                                           DRM_MODE_CONNECTOR_VGA,
1525                                           &i2c->adapter);
1526         if (ret)
1527                 goto err_mgag200_i2c_destroy;
1528         drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1529
1530         mconnector->i2c = i2c;
1531
1532         return 0;
1533
1534 err_mgag200_i2c_destroy:
1535         mgag200_i2c_destroy(i2c);
1536         return ret;
1537 }
1538
1539 /*
1540  * Simple Display Pipe
1541  */
1542
1543 static enum drm_mode_status
1544 mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
1545                                        const struct drm_display_mode *mode)
1546 {
1547         return MODE_OK;
1548 }
1549
1550 static void
1551 mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
1552                       struct drm_rect *clip)
1553 {
1554         struct drm_device *dev = &mdev->base;
1555         struct dma_buf_map map;
1556         void *vmap;
1557         int ret;
1558
1559         ret = drm_gem_shmem_vmap(fb->obj[0], &map);
1560         if (drm_WARN_ON(dev, ret))
1561                 return; /* BUG: SHMEM BO should always be vmapped */
1562         vmap = map.vaddr; /* TODO: Use mapping abstraction properly */
1563
1564         drm_fb_memcpy_dstclip(mdev->vram, vmap, fb, clip);
1565
1566         drm_gem_shmem_vunmap(fb->obj[0], &map);
1567
1568         /* Always scanout image at VRAM offset 0 */
1569         mgag200_set_startadd(mdev, (u32)0);
1570         mgag200_set_offset(mdev, fb);
1571 }
1572
1573 static void
1574 mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
1575                                    struct drm_crtc_state *crtc_state,
1576                                    struct drm_plane_state *plane_state)
1577 {
1578         struct drm_crtc *crtc = &pipe->crtc;
1579         struct drm_device *dev = crtc->dev;
1580         struct mga_device *mdev = to_mga_device(dev);
1581         struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1582         struct drm_framebuffer *fb = plane_state->fb;
1583         struct drm_rect fullscreen = {
1584                 .x1 = 0,
1585                 .x2 = fb->width,
1586                 .y1 = 0,
1587                 .y2 = fb->height,
1588         };
1589
1590         if (mdev->type == G200_WB || mdev->type == G200_EW3)
1591                 mgag200_g200wb_hold_bmc(mdev);
1592
1593         mgag200_set_format_regs(mdev, fb);
1594         mgag200_set_mode_regs(mdev, adjusted_mode);
1595         mgag200_crtc_set_plls(mdev, adjusted_mode->clock);
1596
1597         if (mdev->type == G200_ER)
1598                 mgag200_g200er_reset_tagfifo(mdev);
1599
1600         if (IS_G200_SE(mdev))
1601                 mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, fb);
1602         else if (mdev->type == G200_EV)
1603                 mgag200_g200ev_set_hiprilvl(mdev);
1604
1605         if (mdev->type == G200_WB || mdev->type == G200_EW3)
1606                 mgag200_g200wb_release_bmc(mdev);
1607
1608         mga_crtc_load_lut(crtc);
1609         mgag200_enable_display(mdev);
1610
1611         mgag200_handle_damage(mdev, fb, &fullscreen);
1612 }
1613
1614 static void
1615 mgag200_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
1616 {
1617         struct drm_crtc *crtc = &pipe->crtc;
1618         struct mga_device *mdev = to_mga_device(crtc->dev);
1619
1620         mgag200_disable_display(mdev);
1621 }
1622
1623 static int
1624 mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe,
1625                                   struct drm_plane_state *plane_state,
1626                                   struct drm_crtc_state *crtc_state)
1627 {
1628         struct drm_plane *plane = plane_state->plane;
1629         struct drm_framebuffer *new_fb = plane_state->fb;
1630         struct drm_framebuffer *fb = NULL;
1631
1632         if (!new_fb)
1633                 return 0;
1634
1635         if (plane->state)
1636                 fb = plane->state->fb;
1637
1638         if (!fb || (fb->format != new_fb->format))
1639                 crtc_state->mode_changed = true; /* update PLL settings */
1640
1641         return 0;
1642 }
1643
1644 static void
1645 mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
1646                                    struct drm_plane_state *old_state)
1647 {
1648         struct drm_plane *plane = &pipe->plane;
1649         struct drm_device *dev = plane->dev;
1650         struct mga_device *mdev = to_mga_device(dev);
1651         struct drm_plane_state *state = plane->state;
1652         struct drm_framebuffer *fb = state->fb;
1653         struct drm_rect damage;
1654
1655         if (!fb)
1656                 return;
1657
1658         if (drm_atomic_helper_damage_merged(old_state, state, &damage))
1659                 mgag200_handle_damage(mdev, fb, &damage);
1660 }
1661
1662 static const struct drm_simple_display_pipe_funcs
1663 mgag200_simple_display_pipe_funcs = {
1664         .mode_valid = mgag200_simple_display_pipe_mode_valid,
1665         .enable     = mgag200_simple_display_pipe_enable,
1666         .disable    = mgag200_simple_display_pipe_disable,
1667         .check      = mgag200_simple_display_pipe_check,
1668         .update     = mgag200_simple_display_pipe_update,
1669         .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
1670 };
1671
1672 static const uint32_t mgag200_simple_display_pipe_formats[] = {
1673         DRM_FORMAT_XRGB8888,
1674         DRM_FORMAT_RGB565,
1675         DRM_FORMAT_RGB888,
1676 };
1677
1678 static const uint64_t mgag200_simple_display_pipe_fmtmods[] = {
1679         DRM_FORMAT_MOD_LINEAR,
1680         DRM_FORMAT_MOD_INVALID
1681 };
1682
1683 /*
1684  * Mode config
1685  */
1686
1687 static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
1688         .fb_create     = drm_gem_fb_create_with_dirty,
1689         .atomic_check  = drm_atomic_helper_check,
1690         .atomic_commit = drm_atomic_helper_commit,
1691 };
1692
1693 static unsigned int mgag200_preferred_depth(struct mga_device *mdev)
1694 {
1695         if (IS_G200_SE(mdev) && mdev->vram_fb_available < (2048*1024))
1696                 return 16;
1697         else
1698                 return 32;
1699 }
1700
1701 int mgag200_modeset_init(struct mga_device *mdev)
1702 {
1703         struct drm_device *dev = &mdev->base;
1704         struct drm_connector *connector = &mdev->connector.base;
1705         struct drm_simple_display_pipe *pipe = &mdev->display_pipe;
1706         size_t format_count = ARRAY_SIZE(mgag200_simple_display_pipe_formats);
1707         int ret;
1708
1709         mdev->bpp_shifts[0] = 0;
1710         mdev->bpp_shifts[1] = 1;
1711         mdev->bpp_shifts[2] = 0;
1712         mdev->bpp_shifts[3] = 2;
1713
1714         mgag200_init_regs(mdev);
1715
1716         ret = drmm_mode_config_init(dev);
1717         if (ret) {
1718                 drm_err(dev, "drmm_mode_config_init() failed, error %d\n",
1719                         ret);
1720                 return ret;
1721         }
1722
1723         dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1724         dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1725
1726         dev->mode_config.preferred_depth = mgag200_preferred_depth(mdev);
1727
1728         dev->mode_config.fb_base = mdev->mc.vram_base;
1729
1730         dev->mode_config.funcs = &mgag200_mode_config_funcs;
1731
1732         ret = mgag200_vga_connector_init(mdev);
1733         if (ret) {
1734                 drm_err(dev,
1735                         "mgag200_vga_connector_init() failed, error %d\n",
1736                         ret);
1737                 return ret;
1738         }
1739
1740         ret = drm_simple_display_pipe_init(dev, pipe,
1741                                            &mgag200_simple_display_pipe_funcs,
1742                                            mgag200_simple_display_pipe_formats,
1743                                            format_count,
1744                                            mgag200_simple_display_pipe_fmtmods,
1745                                            connector);
1746         if (ret) {
1747                 drm_err(dev,
1748                         "drm_simple_display_pipe_init() failed, error %d\n",
1749                         ret);
1750                 return ret;
1751         }
1752
1753         /* FIXME: legacy gamma tables; convert to CRTC state */
1754         drm_mode_crtc_set_gamma_size(&pipe->crtc, MGAG200_LUT_SIZE);
1755
1756         drm_mode_config_reset(dev);
1757
1758         return 0;
1759 }