Merge /spare/repo/linux-2.6/
[linux-2.6] / drivers / video / aty / mach64_gx.c
1
2 /*
3  *  ATI Mach64 GX Support
4  */
5
6 #include <linux/delay.h>
7 #include <linux/fb.h>
8 #include <linux/sched.h>
9
10 #include <asm/io.h>
11
12 #include <video/mach64.h>
13 #include "atyfb.h"
14
15 /* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
16
17 #define REF_FREQ_2595       1432        /*  14.33 MHz  (exact   14.31818) */
18 #define REF_DIV_2595          46        /* really 43 on ICS 2595 !!!  */
19                                   /* ohne Prescaler */
20 #define MAX_FREQ_2595      15938        /* 159.38 MHz  (really 170.486) */
21 #define MIN_FREQ_2595       8000        /*  80.00 MHz  (        85.565) */
22                                   /* mit Prescaler 2, 4, 8 */
23 #define ABS_MIN_FREQ_2595   1000        /*  10.00 MHz  (really  10.697) */
24 #define N_ADJ_2595           257
25
26 #define STOP_BITS_2595     0x1800
27
28
29 #define MIN_N_408               2
30
31 #define MIN_N_1703              6
32
33 #define MIN_M           2
34 #define MAX_M           30
35 #define MIN_N           35
36 #define MAX_N           255-8
37
38
39     /*
40      *  Support Functions
41      */
42
43 static void aty_dac_waste4(const struct atyfb_par *par)
44 {
45         (void) aty_ld_8(DAC_REGS, par);
46
47         (void) aty_ld_8(DAC_REGS + 2, par);
48         (void) aty_ld_8(DAC_REGS + 2, par);
49         (void) aty_ld_8(DAC_REGS + 2, par);
50         (void) aty_ld_8(DAC_REGS + 2, par);
51 }
52
53 static void aty_StrobeClock(const struct atyfb_par *par)
54 {
55         u8 tmp;
56
57         udelay(26);
58
59         tmp = aty_ld_8(CLOCK_CNTL, par);
60         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, tmp | CLOCK_STROBE, par);
61         return;
62 }
63
64
65     /*
66      *  IBM RGB514 DAC and Clock Chip
67      */
68
69 static void aty_st_514(int offset, u8 val, const struct atyfb_par *par)
70 {
71         aty_st_8(DAC_CNTL, 1, par);
72         /* right addr byte */
73         aty_st_8(DAC_W_INDEX, offset & 0xff, par);
74         /* left addr byte */
75         aty_st_8(DAC_DATA, (offset >> 8) & 0xff, par);
76         aty_st_8(DAC_MASK, val, par);
77         aty_st_8(DAC_CNTL, 0, par);
78 }
79
80 static int aty_set_dac_514(const struct fb_info *info,
81                            const union aty_pll *pll, u32 bpp, u32 accel)
82 {
83         struct atyfb_par *par = (struct atyfb_par *) info->par;
84         static struct {
85                 u8 pixel_dly;
86                 u8 misc2_cntl;
87                 u8 pixel_rep;
88                 u8 pixel_cntl_index;
89                 u8 pixel_cntl_v1;
90         } tab[3] = {
91                 {
92                 0, 0x41, 0x03, 0x71, 0x45},     /* 8 bpp */
93                 {
94                 0, 0x45, 0x04, 0x0c, 0x01},     /* 555 */
95                 {
96                 0, 0x45, 0x06, 0x0e, 0x00},     /* XRGB */
97         };
98         int i;
99
100         switch (bpp) {
101         case 8:
102         default:
103                 i = 0;
104                 break;
105         case 16:
106                 i = 1;
107                 break;
108         case 32:
109                 i = 2;
110                 break;
111         }
112         aty_st_514(0x90, 0x00, par);    /* VRAM Mask Low */
113         aty_st_514(0x04, tab[i].pixel_dly, par);        /* Horizontal Sync Control */
114         aty_st_514(0x05, 0x00, par);    /* Power Management */
115         aty_st_514(0x02, 0x01, par);    /* Misc Clock Control */
116         aty_st_514(0x71, tab[i].misc2_cntl, par);       /* Misc Control 2 */
117         aty_st_514(0x0a, tab[i].pixel_rep, par);        /* Pixel Format */
118         aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, par);
119         /* Misc Control 2 / 16 BPP Control / 32 BPP Control */
120         return 0;
121 }
122
123 static int aty_var_to_pll_514(const struct fb_info *info, u32 vclk_per,
124                               u32 bpp, union aty_pll *pll)
125 {
126         /*
127          *  FIXME: use real calculations instead of using fixed values from the old
128          *         driver
129          */
130         static struct {
131                 u32 limit;      /* pixlock rounding limit (arbitrary) */
132                 u8 m;           /* (df<<6) | vco_div_count */
133                 u8 n;           /* ref_div_count */
134         } RGB514_clocks[7] = {
135                 {
136                 8000, (3 << 6) | 20, 9},        /*  7395 ps / 135.2273 MHz */
137                 {
138                 10000, (1 << 6) | 19, 3},       /*  9977 ps / 100.2273 MHz */
139                 {
140                 13000, (1 << 6) | 2, 3},        /* 12509 ps /  79.9432 MHz */
141                 {
142                 14000, (2 << 6) | 8, 7},        /* 13394 ps /  74.6591 MHz */
143                 {
144                 16000, (1 << 6) | 44, 6},       /* 15378 ps /  65.0284 MHz */
145                 {
146                 25000, (1 << 6) | 15, 5},       /* 17460 ps /  57.2727 MHz */
147                 {
148                 50000, (0 << 6) | 53, 7},       /* 33145 ps /  30.1705 MHz */
149         };
150         int i;
151
152         for (i = 0; i < sizeof(RGB514_clocks) / sizeof(*RGB514_clocks);
153              i++)
154                 if (vclk_per <= RGB514_clocks[i].limit) {
155                         pll->ibm514.m = RGB514_clocks[i].m;
156                         pll->ibm514.n = RGB514_clocks[i].n;
157                         return 0;
158                 }
159         return -EINVAL;
160 }
161
162 static u32 aty_pll_514_to_var(const struct fb_info *info,
163                               const union aty_pll *pll)
164 {
165         struct atyfb_par *par = (struct atyfb_par *) info->par;
166         u8 df, vco_div_count, ref_div_count;
167
168         df = pll->ibm514.m >> 6;
169         vco_div_count = pll->ibm514.m & 0x3f;
170         ref_div_count = pll->ibm514.n;
171
172         return ((par->ref_clk_per * ref_div_count) << (3 - df))/
173                         (vco_div_count + 65);
174 }
175
176 static void aty_set_pll_514(const struct fb_info *info,
177                             const union aty_pll *pll)
178 {
179         struct atyfb_par *par = (struct atyfb_par *) info->par;
180
181         aty_st_514(0x06, 0x02, par);    /* DAC Operation */
182         aty_st_514(0x10, 0x01, par);    /* PLL Control 1 */
183         aty_st_514(0x70, 0x01, par);    /* Misc Control 1 */
184         aty_st_514(0x8f, 0x1f, par);    /* PLL Ref. Divider Input */
185         aty_st_514(0x03, 0x00, par);    /* Sync Control */
186         aty_st_514(0x05, 0x00, par);    /* Power Management */
187         aty_st_514(0x20, pll->ibm514.m, par);   /* F0 / M0 */
188         aty_st_514(0x21, pll->ibm514.n, par);   /* F1 / N0 */
189 }
190
191 const struct aty_dac_ops aty_dac_ibm514 = {
192         .set_dac        = aty_set_dac_514,
193 };
194
195 const struct aty_pll_ops aty_pll_ibm514 = {
196         .var_to_pll     = aty_var_to_pll_514,
197         .pll_to_var     = aty_pll_514_to_var,
198         .set_pll        = aty_set_pll_514,
199 };
200
201
202     /*
203      *  ATI 68860-B DAC
204      */
205
206 static int aty_set_dac_ATI68860_B(const struct fb_info *info,
207                                   const union aty_pll *pll, u32 bpp,
208                                   u32 accel)
209 {
210         struct atyfb_par *par = (struct atyfb_par *) info->par;
211         u32 gModeReg, devSetupRegA, temp, mask;
212
213         gModeReg = 0;
214         devSetupRegA = 0;
215
216         switch (bpp) {
217         case 8:
218                 gModeReg = 0x83;
219                 devSetupRegA =
220                     0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */ ;
221                 break;
222         case 15:
223                 gModeReg = 0xA0;
224                 devSetupRegA = 0x60;
225                 break;
226         case 16:
227                 gModeReg = 0xA1;
228                 devSetupRegA = 0x60;
229                 break;
230         case 24:
231                 gModeReg = 0xC0;
232                 devSetupRegA = 0x60;
233                 break;
234         case 32:
235                 gModeReg = 0xE3;
236                 devSetupRegA = 0x60;
237                 break;
238         }
239
240         if (!accel) {
241                 gModeReg = 0x80;
242                 devSetupRegA = 0x61;
243         }
244
245         temp = aty_ld_8(DAC_CNTL, par);
246         aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3,
247                  par);
248
249         aty_st_8(DAC_REGS + 2, 0x1D, par);
250         aty_st_8(DAC_REGS + 3, gModeReg, par);
251         aty_st_8(DAC_REGS, 0x02, par);
252
253         temp = aty_ld_8(DAC_CNTL, par);
254         aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par);
255
256         if (info->fix.smem_len < ONE_MB)
257                 mask = 0x04;
258         else if (info->fix.smem_len == ONE_MB)
259                 mask = 0x08;
260         else
261                 mask = 0x0C;
262
263         /* The following assumes that the BIOS has correctly set R7 of the
264          * Device Setup Register A at boot time.
265          */
266 #define A860_DELAY_L    0x80
267
268         temp = aty_ld_8(DAC_REGS, par);
269         aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L),
270                  par);
271         temp = aty_ld_8(DAC_CNTL, par);
272         aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)),
273                  par);
274
275         aty_st_le32(BUS_CNTL, 0x890e20f1, par);
276         aty_st_le32(DAC_CNTL, 0x47052100, par);
277         return 0;
278 }
279
280 const struct aty_dac_ops aty_dac_ati68860b = {
281         .set_dac        = aty_set_dac_ATI68860_B,
282 };
283
284
285     /*
286      *  AT&T 21C498 DAC
287      */
288
289 static int aty_set_dac_ATT21C498(const struct fb_info *info,
290                                  const union aty_pll *pll, u32 bpp,
291                                  u32 accel)
292 {
293         struct atyfb_par *par = (struct atyfb_par *) info->par;
294         u32 dotClock;
295         int muxmode = 0;
296         int DACMask = 0;
297
298         dotClock = 100000000 / pll->ics2595.period_in_ps;
299
300         switch (bpp) {
301         case 8:
302                 if (dotClock > 8000) {
303                         DACMask = 0x24;
304                         muxmode = 1;
305                 } else
306                         DACMask = 0x04;
307                 break;
308         case 15:
309                 DACMask = 0x16;
310                 break;
311         case 16:
312                 DACMask = 0x36;
313                 break;
314         case 24:
315                 DACMask = 0xE6;
316                 break;
317         case 32:
318                 DACMask = 0xE6;
319                 break;
320         }
321
322         if (1 /* info->mach64DAC8Bit */ )
323                 DACMask |= 0x02;
324
325         aty_dac_waste4(par);
326         aty_st_8(DAC_REGS + 2, DACMask, par);
327
328         aty_st_le32(BUS_CNTL, 0x890e20f1, par);
329         aty_st_le32(DAC_CNTL, 0x00072000, par);
330         return muxmode;
331 }
332
333 const struct aty_dac_ops aty_dac_att21c498 = {
334         .set_dac        = aty_set_dac_ATT21C498,
335 };
336
337
338     /*
339      *  ATI 18818 / ICS 2595 Clock Chip
340      */
341
342 static int aty_var_to_pll_18818(const struct fb_info *info, u32 vclk_per,
343                                 u32 bpp, union aty_pll *pll)
344 {
345         u32 MHz100;             /* in 0.01 MHz */
346         u32 program_bits;
347         u32 post_divider;
348
349         /* Calculate the programming word */
350         MHz100 = 100000000 / vclk_per;
351
352         program_bits = -1;
353         post_divider = 1;
354
355         if (MHz100 > MAX_FREQ_2595) {
356                 MHz100 = MAX_FREQ_2595;
357                 return -EINVAL;
358         } else if (MHz100 < ABS_MIN_FREQ_2595) {
359                 program_bits = 0;       /* MHz100 = 257 */
360                 return -EINVAL;
361         } else {
362                 while (MHz100 < MIN_FREQ_2595) {
363                         MHz100 *= 2;
364                         post_divider *= 2;
365                 }
366         }
367         MHz100 *= 1000;
368         MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
369  
370         MHz100 += 500;          /* + 0.5 round */
371         MHz100 /= 1000;
372
373         if (program_bits == -1) {
374                 program_bits = MHz100 - N_ADJ_2595;
375                 switch (post_divider) {
376                 case 1:
377                         program_bits |= 0x0600;
378                         break;
379                 case 2:
380                         program_bits |= 0x0400;
381                         break;
382                 case 4:
383                         program_bits |= 0x0200;
384                         break;
385                 case 8:
386                 default:
387                         break;
388                 }
389         }
390
391         program_bits |= STOP_BITS_2595;
392
393         pll->ics2595.program_bits = program_bits;
394         pll->ics2595.locationAddr = 0;
395         pll->ics2595.post_divider = post_divider;
396         pll->ics2595.period_in_ps = vclk_per;
397
398         return 0;
399 }
400
401 static u32 aty_pll_18818_to_var(const struct fb_info *info,
402                                 const union aty_pll *pll)
403 {
404         return (pll->ics2595.period_in_ps);     /* default for now */
405 }
406
407 static void aty_ICS2595_put1bit(u8 data, const struct atyfb_par *par)
408 {
409         u8 tmp;
410
411         data &= 0x01;
412         tmp = aty_ld_8(CLOCK_CNTL, par);
413         aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
414                  (tmp & ~0x04) | (data << 2), par);
415
416         tmp = aty_ld_8(CLOCK_CNTL, par);
417         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, (tmp & ~0x08) | (0 << 3),
418                  par);
419
420         aty_StrobeClock(par);
421
422         tmp = aty_ld_8(CLOCK_CNTL, par);
423         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, (tmp & ~0x08) | (1 << 3),
424                  par);
425
426         aty_StrobeClock(par);
427         return;
428 }
429
430 static void aty_set_pll18818(const struct fb_info *info,
431                              const union aty_pll *pll)
432 {
433         struct atyfb_par *par = (struct atyfb_par *) info->par;
434         u32 program_bits;
435         u32 locationAddr;
436
437         u32 i;
438
439         u8 old_clock_cntl;
440         u8 old_crtc_ext_disp;
441
442         old_clock_cntl = aty_ld_8(CLOCK_CNTL, par);
443         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);
444
445         old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
446         aty_st_8(CRTC_GEN_CNTL + 3,
447                  old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
448
449         mdelay(15);             /* delay for 50 (15) ms */
450
451         program_bits = pll->ics2595.program_bits;
452         locationAddr = pll->ics2595.locationAddr;
453
454         /* Program the clock chip */
455         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);      /* Strobe = 0 */
456         aty_StrobeClock(par);
457         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 1, par);      /* Strobe = 0 */
458         aty_StrobeClock(par);
459
460         aty_ICS2595_put1bit(1, par);    /* Send start bits */
461         aty_ICS2595_put1bit(0, par);    /* Start bit */
462         aty_ICS2595_put1bit(0, par);    /* Read / ~Write */
463
464         for (i = 0; i < 5; i++) {       /* Location 0..4 */
465                 aty_ICS2595_put1bit(locationAddr & 1, par);
466                 locationAddr >>= 1;
467         }
468
469         for (i = 0; i < 8 + 1 + 2 + 2; i++) {
470                 aty_ICS2595_put1bit(program_bits & 1, par);
471                 program_bits >>= 1;
472         }
473
474         mdelay(1);              /* delay for 1 ms */
475
476         (void) aty_ld_8(DAC_REGS, par); /* Clear DAC Counter */
477         aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
478         aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
479                  old_clock_cntl | CLOCK_STROBE, par);
480
481         mdelay(50);             /* delay for 50 (15) ms */
482         aty_st_8(CLOCK_CNTL + par->clk_wr_offset,
483                  ((pll->ics2595.locationAddr & 0x0F) | CLOCK_STROBE), par);
484         return;
485 }
486
487 const struct aty_pll_ops aty_pll_ati18818_1 = {
488         .var_to_pll     = aty_var_to_pll_18818,
489         .pll_to_var     = aty_pll_18818_to_var,
490         .set_pll        = aty_set_pll18818,
491 };
492
493
494     /*
495      *  STG 1703 Clock Chip
496      */
497
498 static int aty_var_to_pll_1703(const struct fb_info *info, u32 vclk_per,
499                                u32 bpp, union aty_pll *pll)
500 {
501         u32 mhz100;             /* in 0.01 MHz */
502         u32 program_bits;
503         /* u32 post_divider; */
504         u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
505         u32 temp, tempB;
506         u16 remainder, preRemainder;
507         short divider = 0, tempA;
508
509         /* Calculate the programming word */
510         mhz100 = 100000000 / vclk_per;
511         mach64MinFreq = MIN_FREQ_2595;
512         mach64MaxFreq = MAX_FREQ_2595;
513         mach64RefFreq = REF_FREQ_2595;  /* 14.32 MHz */
514
515         /* Calculate program word */
516         if (mhz100 == 0)
517                 program_bits = 0xE0;
518         else {
519                 if (mhz100 < mach64MinFreq)
520                         mhz100 = mach64MinFreq;
521                 if (mhz100 > mach64MaxFreq)
522                         mhz100 = mach64MaxFreq;
523
524                 divider = 0;
525                 while (mhz100 < (mach64MinFreq << 3)) {
526                         mhz100 <<= 1;
527                         divider += 0x20;
528                 }
529
530                 temp = (unsigned int) (mhz100);
531                 temp = (unsigned int) (temp * (MIN_N_1703 + 2));
532                 temp -= (short) (mach64RefFreq << 1);
533
534                 tempA = MIN_N_1703;
535                 preRemainder = 0xffff;
536
537                 do {
538                         tempB = temp;
539                         remainder = tempB % mach64RefFreq;
540                         tempB = tempB / mach64RefFreq;
541
542                         if ((tempB & 0xffff) <= 127
543                             && (remainder <= preRemainder)) {
544                                 preRemainder = remainder;
545                                 divider &= ~0x1f;
546                                 divider |= tempA;
547                                 divider =
548                                     (divider & 0x00ff) +
549                                     ((tempB & 0xff) << 8);
550                         }
551
552                         temp += mhz100;
553                         tempA++;
554                 } while (tempA <= (MIN_N_1703 << 1));
555
556                 program_bits = divider;
557         }
558
559         pll->ics2595.program_bits = program_bits;
560         pll->ics2595.locationAddr = 0;
561         pll->ics2595.post_divider = divider;    /* fuer nix */
562         pll->ics2595.period_in_ps = vclk_per;
563
564         return 0;
565 }
566
567 static u32 aty_pll_1703_to_var(const struct fb_info *info,
568                                const union aty_pll *pll)
569 {
570         return (pll->ics2595.period_in_ps);     /* default for now */
571 }
572
573 static void aty_set_pll_1703(const struct fb_info *info,
574                              const union aty_pll *pll)
575 {
576         struct atyfb_par *par = (struct atyfb_par *) info->par;
577         u32 program_bits;
578         u32 locationAddr;
579
580         char old_crtc_ext_disp;
581
582         old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
583         aty_st_8(CRTC_GEN_CNTL + 3,
584                  old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
585
586         program_bits = pll->ics2595.program_bits;
587         locationAddr = pll->ics2595.locationAddr;
588
589         /* Program clock */
590         aty_dac_waste4(par);
591
592         (void) aty_ld_8(DAC_REGS + 2, par);
593         aty_st_8(DAC_REGS + 2, (locationAddr << 1) + 0x20, par);
594         aty_st_8(DAC_REGS + 2, 0, par);
595         aty_st_8(DAC_REGS + 2, (program_bits & 0xFF00) >> 8, par);
596         aty_st_8(DAC_REGS + 2, (program_bits & 0xFF), par);
597
598         (void) aty_ld_8(DAC_REGS, par); /* Clear DAC Counter */
599         aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
600         return;
601 }
602
603 const struct aty_pll_ops aty_pll_stg1703 = {
604         .var_to_pll     = aty_var_to_pll_1703,
605         .pll_to_var     = aty_pll_1703_to_var,
606         .set_pll        = aty_set_pll_1703,
607 };
608
609
610     /*
611      *  Chrontel 8398 Clock Chip
612      */
613
614 static int aty_var_to_pll_8398(const struct fb_info *info, u32 vclk_per,
615                                u32 bpp, union aty_pll *pll)
616 {
617         u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
618
619         u32 mhz100;             /* in 0.01 MHz */
620         u32 program_bits;
621         /* u32 post_divider; */
622         u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
623         u16 m, n, k = 0, save_m, save_n, twoToKth;
624
625         /* Calculate the programming word */
626         mhz100 = 100000000 / vclk_per;
627         mach64MinFreq = MIN_FREQ_2595;
628         mach64MaxFreq = MAX_FREQ_2595;
629         mach64RefFreq = REF_FREQ_2595;  /* 14.32 MHz */
630
631         save_m = 0;
632         save_n = 0;
633
634         /* Calculate program word */
635         if (mhz100 == 0)
636                 program_bits = 0xE0;
637         else {
638                 if (mhz100 < mach64MinFreq)
639                         mhz100 = mach64MinFreq;
640                 if (mhz100 > mach64MaxFreq)
641                         mhz100 = mach64MaxFreq;
642
643                 longMHz100 = mhz100 * 256 / 100;        /* 8 bit scale this */
644
645                 while (mhz100 < (mach64MinFreq << 3)) {
646                         mhz100 <<= 1;
647                         k++;
648                 }
649
650                 twoToKth = 1 << k;
651                 diff = 0;
652                 preDiff = 0xFFFFFFFF;
653
654                 for (m = MIN_M; m <= MAX_M; m++) {
655                         for (n = MIN_N; n <= MAX_N; n++) {
656                                 tempA = 938356;         /* 14.31818 * 65536 */
657                                 tempA *= (n + 8);       /* 43..256 */
658                                 tempB = twoToKth * 256;
659                                 tempB *= (m + 2);       /* 4..32 */
660                                 fOut = tempA / tempB;   /* 8 bit scale */
661
662                                 if (longMHz100 > fOut)
663                                         diff = longMHz100 - fOut;
664                                 else
665                                         diff = fOut - longMHz100;
666
667                                 if (diff < preDiff) {
668                                         save_m = m;
669                                         save_n = n;
670                                         preDiff = diff;
671                                 }
672                         }
673                 }
674
675                 program_bits = (k << 6) + (save_m) + (save_n << 8);
676         }
677
678         pll->ics2595.program_bits = program_bits;
679         pll->ics2595.locationAddr = 0;
680         pll->ics2595.post_divider = 0;
681         pll->ics2595.period_in_ps = vclk_per;
682
683         return 0;
684 }
685
686 static u32 aty_pll_8398_to_var(const struct fb_info *info,
687                                const union aty_pll *pll)
688 {
689         return (pll->ics2595.period_in_ps);     /* default for now */
690 }
691
692 static void aty_set_pll_8398(const struct fb_info *info,
693                              const union aty_pll *pll)
694 {
695         struct atyfb_par *par = (struct atyfb_par *) info->par;
696         u32 program_bits;
697         u32 locationAddr;
698
699         char old_crtc_ext_disp;
700         char tmp;
701
702         old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
703         aty_st_8(CRTC_GEN_CNTL + 3,
704                  old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
705
706         program_bits = pll->ics2595.program_bits;
707         locationAddr = pll->ics2595.locationAddr;
708
709         /* Program clock */
710         tmp = aty_ld_8(DAC_CNTL, par);
711         aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par);
712
713         aty_st_8(DAC_REGS, locationAddr, par);
714         aty_st_8(DAC_REGS + 1, (program_bits & 0xff00) >> 8, par);
715         aty_st_8(DAC_REGS + 1, (program_bits & 0xff), par);
716
717         tmp = aty_ld_8(DAC_CNTL, par);
718         aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3,
719                  par);
720
721         (void) aty_ld_8(DAC_REGS, par); /* Clear DAC Counter */
722         aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
723
724         return;
725 }
726
727 const struct aty_pll_ops aty_pll_ch8398 = {
728         .var_to_pll     = aty_var_to_pll_8398,
729         .pll_to_var     = aty_pll_8398_to_var,
730         .set_pll        = aty_set_pll_8398,
731 };
732
733
734     /*
735      *  AT&T 20C408 Clock Chip
736      */
737
738 static int aty_var_to_pll_408(const struct fb_info *info, u32 vclk_per,
739                               u32 bpp, union aty_pll *pll)
740 {
741         u32 mhz100;             /* in 0.01 MHz */
742         u32 program_bits;
743         /* u32 post_divider; */
744         u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
745         u32 temp, tempB;
746         u16 remainder, preRemainder;
747         short divider = 0, tempA;
748
749         /* Calculate the programming word */
750         mhz100 = 100000000 / vclk_per;
751         mach64MinFreq = MIN_FREQ_2595;
752         mach64MaxFreq = MAX_FREQ_2595;
753         mach64RefFreq = REF_FREQ_2595;  /* 14.32 MHz */
754
755         /* Calculate program word */
756         if (mhz100 == 0)
757                 program_bits = 0xFF;
758         else {
759                 if (mhz100 < mach64MinFreq)
760                         mhz100 = mach64MinFreq;
761                 if (mhz100 > mach64MaxFreq)
762                         mhz100 = mach64MaxFreq;
763
764                 while (mhz100 < (mach64MinFreq << 3)) {
765                         mhz100 <<= 1;
766                         divider += 0x40;
767                 }
768
769                 temp = (unsigned int) mhz100;
770                 temp = (unsigned int) (temp * (MIN_N_408 + 2));
771                 temp -= ((short) (mach64RefFreq << 1));
772
773                 tempA = MIN_N_408;
774                 preRemainder = 0xFFFF;
775
776                 do {
777                         tempB = temp;
778                         remainder = tempB % mach64RefFreq;
779                         tempB = tempB / mach64RefFreq;
780                         if (((tempB & 0xFFFF) <= 255)
781                             && (remainder <= preRemainder)) {
782                                 preRemainder = remainder;
783                                 divider &= ~0x3f;
784                                 divider |= tempA;
785                                 divider =
786                                     (divider & 0x00FF) +
787                                     ((tempB & 0xFF) << 8);
788                         }
789                         temp += mhz100;
790                         tempA++;
791                 } while (tempA <= 32);
792
793                 program_bits = divider;
794         }
795
796         pll->ics2595.program_bits = program_bits;
797         pll->ics2595.locationAddr = 0;
798         pll->ics2595.post_divider = divider;    /* fuer nix */
799         pll->ics2595.period_in_ps = vclk_per;
800
801         return 0;
802 }
803
804 static u32 aty_pll_408_to_var(const struct fb_info *info,
805                               const union aty_pll *pll)
806 {
807         return (pll->ics2595.period_in_ps);     /* default for now */
808 }
809
810 static void aty_set_pll_408(const struct fb_info *info,
811                             const union aty_pll *pll)
812 {
813         struct atyfb_par *par = (struct atyfb_par *) info->par;
814         u32 program_bits;
815         u32 locationAddr;
816
817         u8 tmpA, tmpB, tmpC;
818         char old_crtc_ext_disp;
819
820         old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
821         aty_st_8(CRTC_GEN_CNTL + 3,
822                  old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24), par);
823
824         program_bits = pll->ics2595.program_bits;
825         locationAddr = pll->ics2595.locationAddr;
826
827         /* Program clock */
828         aty_dac_waste4(par);
829         tmpB = aty_ld_8(DAC_REGS + 2, par) | 1;
830         aty_dac_waste4(par);
831         aty_st_8(DAC_REGS + 2, tmpB, par);
832
833         tmpA = tmpB;
834         tmpC = tmpA;
835         tmpA |= 8;
836         tmpB = 1;
837
838         aty_st_8(DAC_REGS, tmpB, par);
839         aty_st_8(DAC_REGS + 2, tmpA, par);
840
841         udelay(400);            /* delay for 400 us */
842
843         locationAddr = (locationAddr << 2) + 0x40;
844         tmpB = locationAddr;
845         tmpA = program_bits >> 8;
846
847         aty_st_8(DAC_REGS, tmpB, par);
848         aty_st_8(DAC_REGS + 2, tmpA, par);
849
850         tmpB = locationAddr + 1;
851         tmpA = (u8) program_bits;
852
853         aty_st_8(DAC_REGS, tmpB, par);
854         aty_st_8(DAC_REGS + 2, tmpA, par);
855
856         tmpB = locationAddr + 2;
857         tmpA = 0x77;
858
859         aty_st_8(DAC_REGS, tmpB, par);
860         aty_st_8(DAC_REGS + 2, tmpA, par);
861
862         udelay(400);            /* delay for 400 us */
863         tmpA = tmpC & (~(1 | 8));
864         tmpB = 1;
865
866         aty_st_8(DAC_REGS, tmpB, par);
867         aty_st_8(DAC_REGS + 2, tmpA, par);
868
869         (void) aty_ld_8(DAC_REGS, par); /* Clear DAC Counter */
870         aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, par);
871         return;
872 }
873
874 const struct aty_pll_ops aty_pll_att20c408 = {
875         .var_to_pll     = aty_var_to_pll_408,
876         .pll_to_var     = aty_pll_408_to_var,
877         .set_pll        = aty_set_pll_408,
878 };
879
880
881     /*
882      *  Unsupported DAC and Clock Chip
883      */
884
885 static int aty_set_dac_unsupported(const struct fb_info *info,
886                                    const union aty_pll *pll, u32 bpp,
887                                    u32 accel)
888 {
889         struct atyfb_par *par = (struct atyfb_par *) info->par;
890
891         aty_st_le32(BUS_CNTL, 0x890e20f1, par);
892         aty_st_le32(DAC_CNTL, 0x47052100, par);
893         /* new in 2.2.3p1 from Geert. ???????? */
894         aty_st_le32(BUS_CNTL, 0x590e10ff, par);
895         aty_st_le32(DAC_CNTL, 0x47012100, par);
896         return 0;
897 }
898
899 static int dummy(void)
900 {
901         return 0;
902 }
903
904 const struct aty_dac_ops aty_dac_unsupported = {
905         .set_dac        = aty_set_dac_unsupported,
906 };
907
908 const struct aty_pll_ops aty_pll_unsupported = {
909         .var_to_pll     = (void *) dummy,
910         .pll_to_var     = (void *) dummy,
911         .set_pll        = (void *) dummy,
912 };