87 lines
1.9 KiB
C
87 lines
1.9 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
|
|
#include <u.h>
|
|
#include <lib9.h>
|
|
#include <bio.h>
|
|
|
|
#include "pci.h"
|
|
#include "vga.h"
|
|
|
|
#define SCALE(f) ((f)/1) /* could be /10 */
|
|
|
|
static void
|
|
init(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
int f;
|
|
uint32_t d, dmax, fmin, fvco, n, nmax, p;
|
|
|
|
if(ctlr->flag & Finit)
|
|
return;
|
|
|
|
if(vga->f[0] == 0)
|
|
vga->f[0] = vga->mode->frequency;
|
|
|
|
/*
|
|
* Look for values of n, d and p that give
|
|
* the least error for
|
|
* Fvco = RefFreq*((n+2)*8)/(d+2)
|
|
* Fpll = Fvco/2**p
|
|
* N and d are 7-bits, p is 2-bits. Constraints:
|
|
* RefFreq/(n+2) > 1MHz
|
|
* 110MHz <= Fvco <= 220MHz
|
|
* n, d >= 1
|
|
* Should try to minimise n, d.
|
|
*
|
|
* There's nothing like brute force and ignorance.
|
|
*/
|
|
fmin = vga->f[0];
|
|
vga->d[0] = 6;
|
|
vga->n[0] = 5;
|
|
vga->p[0] = 2;
|
|
dmax = (RefFreq/1000000)-2;
|
|
for(d = 1; d < dmax; d++){
|
|
/*
|
|
* Calculate an upper bound on n
|
|
* to satisfy the condition
|
|
* Fvco <= 220MHz
|
|
* This will hopefully prevent arithmetic
|
|
* overflow.
|
|
*/
|
|
nmax = ((220000000+RefFreq)*(d+2))/(RefFreq*8) - 2;
|
|
for(n = 1; n < nmax; n++){
|
|
fvco = SCALE(RefFreq)*((n+2)*8)/(d+2);
|
|
if(fvco < SCALE(110000000) || fvco > SCALE(220000000))
|
|
continue;
|
|
for(p = 1; p < 4; p++){
|
|
f = SCALE(vga->f[0]) - (fvco>>p);
|
|
if(f < 0)
|
|
f = -f;
|
|
if(f < fmin){
|
|
fmin = f;
|
|
vga->d[0] = d;
|
|
vga->n[0] = n;
|
|
vga->p[0] = p;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ctlr->flag |= Finit;
|
|
}
|
|
|
|
Ctlr tvp3025clock = {
|
|
"tvp3025clock", /* name */
|
|
0, /* snarf */
|
|
0, /* options */
|
|
init, /* init */
|
|
0, /* load */
|
|
0, /* dump */
|
|
};
|