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