1 /*
2 * Chrontel
3 * CH9294 Dual Enhanced Graphics Clock Generator.
4 */
5 #include <u.h>
6 #include <libc.h>
7 #include <bio.h>
8
9 #include "pci.h"
10 #include "vga.h"
11
12 typedef struct {
13 char* name[2];
14 ulong frequency[16];
15 } Pattern;
16
17 static Pattern patterns[] = {
18 { "e", "E", /* Tseng */
19 50350000, 56644000, 65000000, 72000000, 80000000, 89800000, 63000000, 75000000,
20 VgaFreq0, VgaFreq1, 31500000, 36000000, 40000000, 44900000, 50000000, 65000000,
21 },
22 { "g", "G", /* S3, IIT */
23 VgaFreq0, VgaFreq1, 40000000, 72000000, 50000000, 77000000, 36000000, 44900000,
24 130000000, 120000000, 80000000, 31500000, 110000000, 65000000, 75000000, 94500000,
25 },
26 { "k", "K", /* Avance Logic */
27 50350000, 56644000, 89800000, 72000000, 75000000, 65000000, 63000000, 80000000,
28 57272000, 85000000, 94000000, 96000000, 100000000, 108000000, 110000000, 77000000,
29 },
30
31 { 0,
32 },
33 };
34
35 static void
init(Vga * vga,Ctlr * ctlr)36 init(Vga* vga, Ctlr* ctlr)
37 {
38 Pattern *pattern;
39 char *p;
40 int f, fmin, index, divisor, maxdivisor;
41
42 if(ctlr->flag & Finit)
43 return;
44
45 if(vga->f[0] == 0)
46 vga->f[0] = vga->mode->frequency;
47
48 if((p = strchr(ctlr->name, '-')) == 0)
49 error("%s: unknown pattern\n", ctlr->name);
50 p++;
51
52 for(pattern = patterns; pattern->name[0]; pattern++){
53 if(strcmp(pattern->name[0], p) == 0)
54 break;
55 if(pattern->name[1] && strcmp(pattern->name[1], p) == 0)
56 break;
57 }
58 if(pattern->name[0] == 0)
59 error("%s: unknown pattern\n", ctlr->name);
60
61 maxdivisor = 1;
62 if(vga->ctlr && (vga->ctlr->flag & Hclkdiv))
63 maxdivisor = 8;
64 fmin = vga->f[0];
65 for(index = 0; index < 16; index++){
66 for(divisor = 1; divisor <= maxdivisor; divisor <<= 1){
67 f = vga->f[0] - pattern->frequency[index]/divisor;
68 if(f < 0)
69 f = -f;
70 if(f < fmin){
71 /*vga->f = pattern->frequency[index];*/
72 fmin = f;
73 vga->d[0] = divisor;
74 vga->i[0] = index;
75 }
76 }
77 }
78
79 if(fmin > (vga->f[0]*5)/100)
80 error("%s: can't find frequency %ld\n", ctlr->name, vga->f[0]);
81 ctlr->flag |= Finit;
82 }
83
84 Ctlr ch9294 = {
85 "ch9294", /* name */
86 0, /* snarf */
87 0, /* options */
88 init, /* init */
89 0, /* load */
90 0, /* dump */
91 };
92