Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
#include "pci.h"
6
#include "vga.h"
7
 
8
/*
9
 * Tvp3026 Viewpoint Video Interface Palette.
10
 * Assumes hooked up to an S3 chip of some kind.
11
 * Why is register access different from the
12
 * Tvp302[05]?
13
 */
14
enum {
15
	Index		= 0x00,		/* Index register */
16
	Data		= 0x0A,		/* Data register */
17
 
18
	Id		= 0x3F,		/* ID Register */
19
	Tvp3026		= 0x26,
20
};
21
 
22
static uchar
23
tvp3026io(uchar reg, uchar data)
24
{
25
	uchar crt55;
26
 
27
	crt55 = vgaxi(Crtx, 0x55) & 0xFC;
28
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
29
	vgao(dacxreg[reg & 0x03], data);
30
 
31
	return crt55;
32
}
33
 
34
static uchar
35
tvp3026i(uchar reg)
36
{
37
	uchar crt55, r;
38
 
39
	crt55 = vgaxi(Crtx, 0x55) & 0xFC;
40
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
41
	r = vgai(dacxreg[reg & 0x03]);
42
	vgaxo(Crtx, 0x55, crt55);
43
 
44
	return r;
45
}
46
 
47
uchar
48
tvp3026xi(uchar index)
49
{
50
	uchar crt55, r;
51
 
52
	crt55 = tvp3026io(Index, index);
53
	vgaxo(Crtx, 0x55, crt55|((Data>>2) & 0x03));
54
	r = vgai(dacxreg[Data & 0x03]);
55
	vgaxo(Crtx, 0x55, crt55);
56
 
57
	return r;
58
}
59
 
60
static void
61
tvp3026o(uchar reg, uchar data)
62
{
63
	uchar crt55;
64
 
65
	crt55 = tvp3026io(reg, data);
66
	vgaxo(Crtx, 0x55, crt55);
67
}
68
 
69
void
70
tvp3026xo(uchar index, uchar data)
71
{
72
	uchar crt55;
73
 
74
	crt55 = tvp3026io(Index, index);
75
	vgaxo(Crtx, 0x55, crt55|((Data>>2) & 0x03));
76
	vgao(dacxreg[Data & 0x03], data);
77
	vgaxo(Crtx, 0x55, crt55);
78
}
79
 
80
static void
81
options(Vga*, Ctlr* ctlr)
82
{
83
	ctlr->flag |= Hclk2|Hextsid|Henhanced|Foptions;
84
}
85
 
86
static void
87
init(Vga* vga, Ctlr* ctlr)
88
{
89
	ulong grade;
90
	char *p;
91
 
92
	/*
93
	 * Work out the part speed-grade from name. Name can have,
94
	 * e.g. '-135' on the end  for 135MHz part.
95
	 */
96
	grade = 110000000;
97
	if(p = strrchr(ctlr->name, '-'))
98
		grade = strtoul(p+1, 0, 0) * 1000000;
99
 
100
	/*
101
	 * If we don't already have a desired pclk,
102
	 * take it from the mode.
103
	 * Check it's within range.
104
	 */
105
	if(vga->f[0] == 0)
106
		vga->f[0] = vga->mode->frequency;
107
	if(vga->f[0] > grade)
108
		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
109
 
110
	/*
111
	 * Determine whether to use clock-doubler or not.
112
	 */
113
	if((ctlr->flag & Uclk2) == 0 && vga->mode->z == 8 && vga->f[0] > 85000000)
114
		resyncinit(vga, ctlr, Uclk2, 0);
115
 
116
	ctlr->flag |= Finit;
117
}
118
 
119
static void
120
load(Vga* vga, Ctlr* ctlr)
121
{
122
	uchar x;
123
 
124
	/*
125
	 * General Control:
126
	 *	output sync polarity
127
	 * It's important to set this properly and to turn off the
128
	 * VGA controller H and V syncs. Can't be set in VGA mode.
129
	 */
130
	x = 0x00;
131
	if((vga->misc & 0x40) == 0)
132
		x |= 0x01;
133
	if((vga->misc & 0x80) == 0)
134
		x |= 0x02;
135
	tvp3026xo(0x1D, x);
136
	vga->misc |= 0xC0;
137
	vgao(MiscW, vga->misc);
138
 
139
	ctlr->flag |= Fload;
140
}
141
 
142
static void
143
dump(Vga*, Ctlr* ctlr)
144
{
145
	int i;
146
	ulong clock[4], f;
147
 
148
	printitem(ctlr->name, "direct");
149
	for(i = 0; i < 16; i++)
150
		printreg(tvp3026i(i));
151
 
152
	printitem(ctlr->name, "index");
153
	for(i = 0; i < 64; i++)
154
		printreg(tvp3026xi(i));
155
 
156
	printitem(ctlr->name, "PCLK");
157
	for(i = 0; i < 3; i++){
158
		tvp3026xo(0x2C, (i<<4)|(i<<2)|i);
159
		printreg(clock[i] = tvp3026xi(0x2D));
160
	}
161
	f = (RefFreq*(65-clock[1]))/(65-(clock[0] & 0x3F));
162
	f >>= clock[2] & 0x03;
163
	Bprint(&stdout, "%23ld", f);
164
 
165
	printitem(ctlr->name, "MCLK");
166
	for(i = 0; i < 3; i++){
167
		tvp3026xo(0x2C, (i<<4)|(i<<2)|i);
168
		printreg(clock[i] = tvp3026xi(0x2E));
169
	}
170
	f = (RefFreq*(65-clock[1]))/(65-(clock[0] & 0x3F));
171
	f >>= clock[2] & 0x03;
172
	Bprint(&stdout, "%23ld", f);
173
 
174
	printitem(ctlr->name, "LCLK");
175
	for(i = 0; i < 3; i++){
176
		tvp3026xo(0x2C, (i<<4)|(i<<2)|i);
177
		printreg(clock[i] = tvp3026xi(0x2F));
178
	}
179
	Bprint(&stdout, "\n");
180
}
181
 
182
Ctlr tvp3026 = {
183
	"tvp3026",			/* name */
184
	0,				/* snarf */
185
	options,			/* options */
186
	init,				/* init */
187
	0,				/* load */
188
	dump,				/* dump */
189
};