/* $XFree86: xc/programs/Xserver/hw/xfree86/common_hw/S3gendac.c,v 3.23.2.2 1997/05/11 02:56:20 dawes Exp $ */ /* * Progaming of the S3 gendac programable clocks, from the S3 Gendac * programing documentation by S3 Inc. * Jon Tombs * Also used for GenDAC and GenDAC-like chips on non-S3 chipsets. */ /* $XConsortium: S3gendac.c /main/16 1996/10/25 14:11:48 kaleb $ */ #include #include "Xfuncproto.h" #include "S3gendac.h" #include "compiler.h" #define NO_OSLIB_PROTOTYPES #include "xf86.h" #include "xf86_OSlib.h" #include "xf86_HWlib.h" #define CLK_MCLK 10 #define PLL_S3GENDAC 1 #define PLL_S3TRIO 2 #define PLL_ET4000GENDAC 3 #define PLL_ARK2000GENDAC 4 #define PLL_ET6000 5 extern int vgaIOBase; static void setS3gendacpll( #if NeedFunctionPrototypes int reg, unsigned char data1, unsigned char data2 #endif ); static void settriopll( #if NeedFunctionPrototypes int reg, unsigned char data1, unsigned char data2 #endif ); static void setET4000gendacpll( #if NeedFunctionPrototypes int reg, unsigned char data1, unsigned char data2 #endif ); static void setET6000pll( #if NeedFunctionPrototypes int reg, unsigned char data1, unsigned char data2 #endif ); static void setARK2000gendacpll( #if NeedFunctionPrototypes int reg, unsigned char data1, unsigned char data2 #endif ); static int commonSetClock( #if NeedFunctionPrototypes long freq, int clock, int min_m, int min_n1, int max_n1, int min_n2, int max_n2, int pll_type, long freq_min, long freq_max #endif ); int S3gendacSetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_S3GENDAC, 100000, 250000); } int ET4000gendacSetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_ET4000GENDAC, 100000, 270000); } int ET6000SetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_ET6000, 100000, 270000); } int ET4000gendacSetpixmuxClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 2, 3, PLL_ET4000GENDAC, 100000, 270000); } int ARK2000gendacSetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_ARK2000GENDAC, 100000, 270000); } int ICS5342SetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 1, 3, PLL_S3GENDAC, 100000, 270000); } int S3TrioSetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_S3TRIO, 135000, 270000); } int S3Trio64V2SetClock(freq, clk) long freq; int clk; { return commonSetClock(freq, clk, 1, 1, 31, 0, 4, PLL_S3TRIO, 170000, 340000); } int S3ViRGE_VXSetClock(freq, clk) long freq; int clk; { if (clk != CLK_MCLK) return commonSetClock(freq, clk, 0, 0, 31, 0, 4, PLL_S3TRIO, 220000, 440000); else return commonSetClock(freq, clk, 0, 0, 31, 0, 3, PLL_S3TRIO, 220000, 440000); } int S3AuroraSetClock(freq, clk) long freq; int clk; { if (clk == CLK_MCLK) return commonSetClock(freq, clk, 1, 1, 31, 0, 3, PLL_S3TRIO, 135000, 270000); else return commonSetClock(freq, clk, 1, 1, 63, 0, 3, PLL_S3TRIO, 135000, 270000); } int #if NeedFunctionPrototypes commonCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2, long freq_min, long freq_max, unsigned char * mdiv, unsigned char * ndiv) #else commonCalcClock(freq, min_m, min_n1, max_n1, min_n2, max_n2, freq_min, freq_max, mdiv, ndiv) long freq; int min_m, min_n1, max_n1, min_n2, max_n2; long freq_min, freq_max; unsigned char *mdiv, *ndiv; #endif { double ffreq, ffreq_min, ffreq_max; double div, diff, best_diff; unsigned int m; unsigned char n1, n2; unsigned char best_n1=16+2, best_n2=2, best_m=125+2; ffreq = freq / 1000.0 / BASE_FREQ; ffreq_min = freq_min / 1000.0 / BASE_FREQ; ffreq_max = freq_max / 1000.0 / BASE_FREQ; if (ffreq < ffreq_min / (1<= %1.3f MHz]\n", ffreq*BASE_FREQ, ffreq_min*BASE_FREQ / (1< ffreq_max / (1< 127+2) continue; div = (double)(m) / (double)(n1); if ((div >= ffreq_min) && (div <= ffreq_max)) { diff = ffreq - div / (1<> 5))) / 100; return rtn; }