1219b2ee8SDavid du Colombier /*
2219b2ee8SDavid du Colombier * Integrated Circuit Systems, Inc.
3219b2ee8SDavid du Colombier * ICS2494[A] Dual Video/Memory Clock Generator.
4219b2ee8SDavid du Colombier */
5219b2ee8SDavid du Colombier #include <u.h>
6219b2ee8SDavid du Colombier #include <libc.h>
77dd7cddfSDavid du Colombier #include <bio.h>
8219b2ee8SDavid du Colombier
9*9a747e4fSDavid du Colombier #include "pci.h"
10219b2ee8SDavid du Colombier #include "vga.h"
11219b2ee8SDavid du Colombier
12219b2ee8SDavid du Colombier typedef struct {
13219b2ee8SDavid du Colombier char* name[2];
14219b2ee8SDavid du Colombier ulong frequency[16];
15219b2ee8SDavid du Colombier } Pattern;
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier static Pattern patterns[] = {
18219b2ee8SDavid du Colombier { "237", "304",
19219b2ee8SDavid du Colombier 50350000, 56644000, 65000000, 72000000, 80000000, 89800000, 63000000, 75000000,
20219b2ee8SDavid du Colombier 25175000, 28322000, 31500000, 36000000, 40000000, 44900000, 50000000, 65000000,
21219b2ee8SDavid du Colombier },
22219b2ee8SDavid du Colombier
23219b2ee8SDavid du Colombier { "324", 0,
24219b2ee8SDavid du Colombier 50350000, 56644000, 65000000, 72000000, 80000000, 89800000, 63000000, 75000000,
25219b2ee8SDavid du Colombier 83078000, 93463000, 100000000, 104000000, 108000000, 120000000, 130000000, 134700000,
26219b2ee8SDavid du Colombier },
27219b2ee8SDavid du Colombier
28219b2ee8SDavid du Colombier { 0,
29219b2ee8SDavid du Colombier },
30219b2ee8SDavid du Colombier };
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)33219b2ee8SDavid du Colombier init(Vga* vga, Ctlr* ctlr)
34219b2ee8SDavid du Colombier {
35219b2ee8SDavid du Colombier Pattern *pattern;
36219b2ee8SDavid du Colombier char *p;
377dd7cddfSDavid du Colombier int f, index, divisor, maxdivisor;
38219b2ee8SDavid du Colombier
39219b2ee8SDavid du Colombier if(ctlr->flag & Finit)
40219b2ee8SDavid du Colombier return;
41219b2ee8SDavid du Colombier
427dd7cddfSDavid du Colombier if(vga->f[0] == 0)
437dd7cddfSDavid du Colombier vga->f[0] = vga->mode->frequency;
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier if((p = strchr(ctlr->name, '-')) == 0)
46219b2ee8SDavid du Colombier error("%s: unknown pattern\n", ctlr->name);
47219b2ee8SDavid du Colombier p++;
48219b2ee8SDavid du Colombier
49219b2ee8SDavid du Colombier for(pattern = patterns; pattern->name[0]; pattern++){
50219b2ee8SDavid du Colombier if(strcmp(pattern->name[0], p) == 0)
51219b2ee8SDavid du Colombier break;
52219b2ee8SDavid du Colombier if(pattern->name[1] && strcmp(pattern->name[1], p) == 0)
53219b2ee8SDavid du Colombier break;
54219b2ee8SDavid du Colombier }
55219b2ee8SDavid du Colombier if(pattern->name[0] == 0)
56219b2ee8SDavid du Colombier error("%s: unknown pattern\n", ctlr->name);
57219b2ee8SDavid du Colombier
587dd7cddfSDavid du Colombier maxdivisor = 1;
597dd7cddfSDavid du Colombier if(vga->ctlr && (vga->ctlr->flag & Hclkdiv))
607dd7cddfSDavid du Colombier maxdivisor = 8;
61219b2ee8SDavid du Colombier for(index = 0; index < 16; index++){
627dd7cddfSDavid du Colombier for(divisor = 1; divisor <= maxdivisor; divisor <<= 1){
637dd7cddfSDavid du Colombier f = vga->f[0] - pattern->frequency[index]/divisor;
64219b2ee8SDavid du Colombier if(f < 0)
65219b2ee8SDavid du Colombier f = -f;
66219b2ee8SDavid du Colombier if(f < 1000000){
67219b2ee8SDavid du Colombier /*vga->f = pattern->frequency[index];*/
687dd7cddfSDavid du Colombier vga->d[0] = divisor;
697dd7cddfSDavid du Colombier vga->i[0] = index;
70219b2ee8SDavid du Colombier
71219b2ee8SDavid du Colombier ctlr->flag |= Finit;
72219b2ee8SDavid du Colombier return;
73219b2ee8SDavid du Colombier }
74219b2ee8SDavid du Colombier }
75219b2ee8SDavid du Colombier }
767dd7cddfSDavid du Colombier error("%s: can't find frequency %ld\n", ctlr->name, vga->f[0]);
77219b2ee8SDavid du Colombier }
78219b2ee8SDavid du Colombier
79219b2ee8SDavid du Colombier Ctlr ics2494 = {
80219b2ee8SDavid du Colombier "ics2494", /* name */
81219b2ee8SDavid du Colombier 0, /* snarf */
82219b2ee8SDavid du Colombier 0, /* options */
83219b2ee8SDavid du Colombier init, /* init */
84219b2ee8SDavid du Colombier 0, /* load */
85219b2ee8SDavid du Colombier 0, /* dump */
86219b2ee8SDavid du Colombier };
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier Ctlr ics2494a = {
89219b2ee8SDavid du Colombier "ics2494a", /* name */
90219b2ee8SDavid du Colombier 0, /* snarf */
91219b2ee8SDavid du Colombier 0, /* options */
92219b2ee8SDavid du Colombier init, /* init */
93219b2ee8SDavid du Colombier 0, /* load */
94219b2ee8SDavid du Colombier 0, /* dump */
95219b2ee8SDavid du Colombier };
96