ti3026clk.c
来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 292 行
C
292 行
/* $XFree86: xc/programs/Xserver/hw/xfree86/common_hw/Ti3026clk.c,v 3.11 1996/12/23 06:44:22 dawes Exp $ *//* * Copyright 1995 The XFree86 Project, Inc * * programming the on-chip clock on the Ti3026, derived from the * S3 gendac code by Jon Tombs * Harald Koenig <koenig@tat.physik.uni-tuebingen.de> *//* $XConsortium: Ti3026clk.c /main/10 1996/10/19 18:00:22 kaleb $ */#include "Xfuncproto.h"#include "Ti302X.h" #include "compiler.h"#define NO_OSLIB_PROTOTYPES#include "xf86_OSlib.h"#include <math.h>void (* dacOutTi3026IndReg)(unsigned char,unsigned char,unsigned char) = NULL;unsigned char (* dacInTi3026IndReg)(unsigned char) = NULL;#if NeedFunctionPrototypesstatic voids3ProgramTi3026Clock(int clk, unsigned char n, unsigned char m, unsigned char p, unsigned char ln, unsigned char lm, unsigned char lp, unsigned char lq, char which)#elsestatic voids3ProgramTi3026Clock(clk, n, m, p, ln, lm, lp, lq, which)int clk;unsigned char n;unsigned char m;unsigned char p;unsigned char ln;unsigned char lm;unsigned char lp;unsigned char lq;char which;#endif{ int tmp; /* * Reset the clock data index */ (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x00); if (clk != TI_MCLK_PLL_DATA) { if (which == TI_BOTH_CLOCKS) { /* * If we are using the Ti PLL clock output the clock frequency */ (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (n & 0x3f) | 0x80); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (m & 0x3f) ); tmp = (*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA) & 0x40; (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (p & 3) | tmp | 0xb0); /* wait until PLL is locked */ for (tmp=0; tmp<10000; tmp++) if ((*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA) & 0x40) break; } /* * And now set up the loop clock for RCLK */ (*dacOutTi3026IndReg)(TI_LOOP_CLOCK_PLL_DATA, 0x00, ln); (*dacOutTi3026IndReg)(TI_LOOP_CLOCK_PLL_DATA, 0x00, lm); (*dacOutTi3026IndReg)(TI_LOOP_CLOCK_PLL_DATA, 0x00, lp); (*dacOutTi3026IndReg)(TI_MCLK_LCLK_CONTROL, 0xc8, (lq & 0x0f) | 0x10); if (which == TI_BOTH_CLOCKS) { /* select pixel clock PLL as dot clock soure */ (*dacOutTi3026IndReg)(TI_INPUT_CLOCK_SELECT, 0x00, TI_ICLK_PLL); } } else { int pn, pm, pp, csr; /* select pixel clock PLL as dot clock soure */ csr = (*dacInTi3026IndReg)(TI_INPUT_CLOCK_SELECT); (*dacOutTi3026IndReg)(TI_INPUT_CLOCK_SELECT, 0x00, TI_ICLK_PLL); /* save the old dot clock PLL settings */ (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x00); pn = (*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA); (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x01); pm = (*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA); (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x02); pp = (*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA); /* programm dot clock PLL to new MCLK frequency */ (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x00); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (n & 0x3f) | 0x80); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (m & 0x3f) ); tmp = (*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA) & 0x40; (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, (p & 3) | tmp | 0xb0); /* wait until PLL is locked */ for (tmp=0; tmp<10000; tmp++) if ((*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA) & 0x40) break; /* switch to output dot clock on the MCLK terminal */ (*dacOutTi3026IndReg)(0x39, 0xe7, 0x00); (*dacOutTi3026IndReg)(0x39, 0xe7, 0x08); /* Set MCLK */ (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x00); (*dacOutTi3026IndReg)(TI_MCLK_PLL_DATA, 0x00, (n & 0x3f) | 0x80); (*dacOutTi3026IndReg)(TI_MCLK_PLL_DATA, 0x00, (m & 0x3f)); (*dacOutTi3026IndReg)(TI_MCLK_PLL_DATA, 0x00, (p & 3) | 0xb0); /* wait until PLL is locked */ for (tmp=0; tmp<10000; tmp++) if ((*dacInTi3026IndReg)(TI_MCLK_PLL_DATA) & 0x40) break; /* switch to output MCLK on the MCLK terminal */ (*dacOutTi3026IndReg)(0x39, 0xe7, 0x10); (*dacOutTi3026IndReg)(0x39, 0xe7, 0x18); /* restore dot clock PLL */ (*dacOutTi3026IndReg)(TI_PLL_CONTROL, 0x00, 0x00); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, pn); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, pm); (*dacOutTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA, 0x00, pp); /* wait until PLL is locked */ for (tmp=0; tmp<10000; tmp++) if ((*dacInTi3026IndReg)(TI_PIXEL_CLOCK_PLL_DATA) & 0x40) break; (*dacOutTi3026IndReg)(TI_INPUT_CLOCK_SELECT, 0x00, csr); }}#if NeedFunctionPrototypesstatic void Ti30XXSetClock(long freq, int clk, int bpp, char which, int buswidth)#elsestatic voidTi30XXSetClock(freq, clk, bpp, which, buswidth)long freq;int clk;int bpp;char which;int buswidth;#endif{ double ffreq; int n, p, m; int ln, lp, lm, lq, lk, z; int best_n=32, best_m=32; double diff, mindiff; #define FREQ_MIN 13767 /* ~110000 / 8 */#define FREQ_MAX 220000 if (freq < FREQ_MIN) ffreq = FREQ_MIN / 1000.0; else if (freq > FREQ_MAX) ffreq = FREQ_MAX / 1000.0; else ffreq = freq / 1000.0; /* work out suitable timings */ /* pick the right p value */ for(p=0; p<4 && ffreq < 110.0; p++) ffreq *= 2; /* now 110.0 <= ffreq <= 220.0 */ ffreq /= TI_REF_FREQ; /* now 7.6825 <= ffreq <= 15.3650 */ /* the remaining formula is ffreq = (65-m)*8 / (65-n) */ mindiff = ffreq; for (n=62; n >= 40; n--) { m = 65 - (int)(ffreq * (65-n) / 8.0 + 0.5); if (m < 1) m = 1; else if (m > 62) m = 62; diff = ((65-m) * 8) / (65.0-n) - ffreq; if (diff<0) diff = -diff; if (diff < mindiff) { mindiff = diff; best_n = n; best_m = m; } }#ifdef DEBUG ErrorF("clk %d, asked %d, setting to %f, n %02x %d, m %02x %d, p %d\n", clk, freq, 8.0/(1 << p)*((65.0-best_m)/(65-best_n)) * TI_REF_FREQ, best_n, best_n, best_m, best_m, p);#endif if (bpp == 3) {#if 0 /* TI_MUX1_3026T_888_P5 */ lk = buswidth / 8 / bpp; lm = 63; if (buswidth == 64) /* Ti3026 */ ln = 60; else /* Ti3030 */ ln = 55;#else /* TI_MUX1_3026T_888_P8 */ lk = buswidth / 8 / bpp; lm = 62; if (buswidth == 64) /* Ti3026 */ ln = 57; else /* Ti3030 */ ln = 49;#endif } else { lk = buswidth / 8 / bpp; ln = 65 - 4 * lk; lm = 61; } z = 110000.0 / (65-lm) / freq * (100 * (65-ln)) / lk ; if (z > 1600) { lp = 3; lq = (z-1600) / 1600 + 1; /* smallest q greater (z-16)/16 */ } else { /* largest p less then log2(z) */ for (lp=0; z > (200 << lp); lp++) ; lq = 0; }#ifdef DEBUG ErrorF("bpp %d lk %2d ln %2d lm %2d lz %4d lp %2d lq %2d\n", bpp,lk,ln,lm,z,lp,lq);#endif if (bpp == 3) { if (buswidth == 64) { /* Ti3026 */ ln = (ln & 0x3f) | 0x80; lm = (lm & 0x3f) | 0x80; lp = (lp & 0x03) | 0xf8; } else { /* Ti3030 */ ln = (ln & 0x3f) | 0xc0; lm = (lm & 0x3f) | 0x80; lp = (lp & 0x03) | 0xf8; } } else { ln = (ln & 0x3f) | 0x80; lm = (lm & 0x3f) ; lp = (lp & 0x03) | 0xf0; } s3ProgramTi3026Clock(clk, best_n, best_m, p, ln, lm, lp, lq, which);}#if NeedFunctionPrototypesvoid Ti3026SetClock(long freq, int clk, int bpp, char which)#elsevoidTi3026SetClock(freq, clk, bpp, which)long freq;int clk;int bpp;char which;#endif{ Ti30XXSetClock(freq, clk, bpp, which, 64);}#if NeedFunctionPrototypesvoid Ti3030SetClock(long freq, int clk, int bpp, char which)#elsevoidTi3030SetClock(freq, clk, bpp, which)long freq;int clk;int bpp;char which;#endif{ Ti30XXSetClock(freq, clk, bpp, which, 128);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?