ICS1562.c revision 7706df26
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c,v 1.2 1998/07/25 16:55:56 dawes Exp $ */ 2 3#ifdef HAVE_CONFIG_H 4#include "config.h" 5#endif 6 7#define BASE_FREQ 14.31818 8#define MAX_FREQ 230000 9 10#define reorder(a) ( \ 11 (a & 0x80) >> 7 | \ 12 (a & 0x40) >> 5 | \ 13 (a & 0x20) >> 3 | \ 14 (a & 0x10) >> 1 | \ 15 (a & 0x08) << 1 | \ 16 (a & 0x04) << 3 | \ 17 (a & 0x02) << 5 | \ 18 (a & 0x01) << 7 ) 19 20#define CHECK_MIN(m,a,r,n) do { \ 21 diff = f - (BASE_FREQ * 1e3 * (n)) / (r << p); \ 22 if (diff < 0) diff = -diff; \ 23 if (diff < min_diff) { \ 24 min_diff = diff; \ 25 best_m = m; \ 26 best_a = a; \ 27 best_r = r; \ 28 } \ 29 } while(0) 30 31 32static void Set_1562_PLL(int f, int p, int m, int a, int r, unsigned char *bits) 33{ 34 bits[0] = 0x80; /* N1 = 4, not used for PLL */ 35 bits[1] = reorder(p) >> 4; 36 bits[2] = 0x00; /* N2 = 1 */ 37 if (f <= 120000) 38 bits[3] = 0x20; /* V = 100 */ 39 else if (f <= 200000) 40 bits[3] = 0xa0; /* V = 101 */ 41 else 42 bits[3] = 0x60; /* V = 110 */ 43 bits[3] |= 0x05; /* P = 10, phase detector on */ 44 bits[4] = reorder(m); 45 bits[5] = reorder(a); 46 bits[6] = reorder(r); 47 48#ifdef DEBUG 49 { 50 int i; 51 for(i=0; i<7; i++) 52 ErrorF("%02x ", bits[i]); 53 ErrorF("\n"); 54 } 55#endif 56} 57 58void ICS1562_CalcClockBits(long f, unsigned char *bits); 59 60void ICS1562_CalcClockBits(long f, unsigned char *bits) 61{ 62 int n,r, a,m, p, r0,r1,n0,n1; 63 int best_m=34, best_a=1, best_r=30; 64 double diff, min_diff; 65 double ff, ffp; 66 67 if (f > MAX_FREQ) 68 f = MAX_FREQ; 69 70 if (f >= MAX_FREQ/2) 71 p=0; 72 else if (f >= MAX_FREQ/4) 73 p=1; 74 else 75 p=2; 76 77 ff = f / 1e3 / BASE_FREQ; 78 ffp = ff * (1 << p); 79 min_diff = 999999999; 80 81 r0 = (int)(7/ffp); 82 if (r0 < 1) r0 = 1; 83 r1 = (int)(449/ffp); 84 if (r1 > 0x7f+1) r1 = 0x7f+1; 85 if (r1 < r0) r1 = r0; 86 87 for (r=r0; r<r1; r++) { 88 n0 = (int)(ffp * r); 89 if (n0 < 7) n0 = 7; 90 n1 = (int)(ffp * (r+1)); 91 if (n1 > 448) n1 = 448; 92 for (n=n0; n<n1; n++) { 93 m = ((n+3)/7) - 1; 94 if (m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7); 95 if (++m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7); 96 m = (n/6) - 1; 97 a = n - (m+1)*6; 98 if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a); 99 m++; 100 a = n - (m+1)*6; 101 if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a); 102 } 103 } 104 105 if (best_a) n = (best_m+1)*6+best_a; 106 else n = (best_m+1)*7; 107 108#ifdef DEBUG 109 ErrorF("%8.3f %f %f p=%d m=%d a=%d r=%d %d/%d\n" 110 ,f/1e3 111 ,min_diff,(BASE_FREQ * (n)) / (best_r << p) 112 ,p ,best_m, best_a, best_r-1 113 ,n,best_r 114 ); 115#endif 116 117 Set_1562_PLL(f, p, best_m, best_a, best_r-1, bits); 118} 119