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