1 /*
2 Rage 128 chipset driver
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/mman.h>
10 #include <errno.h>
11 #include "vga.h"
12 #include "libvga.h"
13 #include "driver.h"
14 #include "timing.h"
15 #include "vgaregs.h"
16 #include "interface.h"
17 #include "accel.h"
18 #include "vgapci.h"
19 #include "r128_reg.h"
20
21 typedef unsigned int CARD32;
22 typedef unsigned short CARD16;
23 typedef int Bool;
24
25 static int r128_ramtype;
26 static int BusCntl, CRTOnly, HasPanelRegs;
27
28 typedef struct {
29 CARD16 reference_freq;
30 CARD16 reference_div;
31 CARD32 min_pll_freq;
32 CARD32 max_pll_freq;
33 CARD16 xclk;
34 } R128PLLRec, *R128PLLPtr;
35
36 typedef struct {
37 /* Common registers */
38 CARD32 ovr_clr;
39 CARD32 ovr_wid_left_right;
40 CARD32 ovr_wid_top_bottom;
41 CARD32 ov0_scale_cntl;
42 CARD32 mpp_tb_config;
43 CARD32 mpp_gp_config;
44 CARD32 subpic_cntl;
45 CARD32 viph_control;
46 CARD32 i2c_cntl_1;
47 CARD32 gen_int_cntl;
48 CARD32 cap0_trig_cntl;
49 CARD32 cap1_trig_cntl;
50 CARD32 bus_cntl;
51 CARD32 config_cntl;
52 CARD32 mem_vga_wp_sel;
53 CARD32 mem_vga_rp_sel;
54 /* Other registers to save for VT switches */
55 CARD32 dp_datatype;
56 CARD32 gen_reset_cntl;
57 CARD32 clock_cntl_index;
58 CARD32 amcgpio_en_reg;
59 CARD32 amcgpio_mask;
60 /* CRTC registers */
61 CARD32 crtc_gen_cntl;
62 CARD32 crtc_ext_cntl;
63 CARD32 dac_cntl;
64 CARD32 crtc_h_total_disp;
65 CARD32 crtc_h_sync_strt_wid;
66 CARD32 crtc_v_total_disp;
67 CARD32 crtc_v_sync_strt_wid;
68 CARD32 crtc_offset;
69 CARD32 crtc_offset_cntl;
70 CARD32 crtc_pitch;
71 /* CRTC2 registers */
72 CARD32 crtc2_gen_cntl;
73 /* Flat panel registers */
74 CARD32 fp_crtc_h_total_disp;
75 CARD32 fp_crtc_v_total_disp;
76 CARD32 fp_gen_cntl;
77 CARD32 fp_h_sync_strt_wid;
78 CARD32 fp_horz_stretch;
79 CARD32 fp_panel_cntl;
80 CARD32 fp_v_sync_strt_wid;
81 CARD32 fp_vert_stretch;
82 CARD32 lvds_gen_cntl;
83 CARD32 tmds_crc;
84 /* Computed values for PLL */
85 CARD32 dot_clock_freq;
86 CARD32 pll_output_freq;
87 int feedback_div;
88 int post_div;
89 /* PLL registers */
90 CARD32 ppll_ref_div;
91 CARD32 ppll_div_3;
92 CARD32 htotal_cntl;
93 /* DDA register */
94 CARD32 dda_config;
95 CARD32 dda_on_off;
96 CARD32 vga_dda_config;
97 CARD32 vga_dda_on_off;
98 /* Pallet */
99 Bool palette_valid;
100 CARD32 palette[256];
101 } R128SaveRec, *R128SavePtr;
102
103 typedef struct { /* All values in XCLKS */
104 int ML; /* Memory Read Latency */
105 int MB; /* Memory Burst Length */
106 int Trcd; /* RAS to CAS delay */
107 int Trp; /* RAS percentage */
108 int Twr; /* Write Recovery */
109 int CL; /* CAS Latency */
110 int Tr2w; /* Read to Write Delay */
111 int Rloop; /* Loop Latency */
112 int Rloop_fudge; /* Add to ML to get Rloop */
113 char *name;
114 } R128RAMRec, *R128RAMPtr;
115
116 #define R128_TOTAL_REGS (VGA_TOTAL_REGS + sizeof(R128SaveRec))
R128MinBits(int val)117 static int R128MinBits(int val)
118 {
119 int bits;
120
121 if (!val) return 1;
122 for (bits = 0; val; val >>= 1, ++bits);
123 return bits;
124 }
R128Div(int n,int d)125 static int R128Div(int n, int d)
126 {
127 return (n + (d / 2)) / d;
128 }
129 static R128PLLRec pll;
130
131 static R128RAMRec ram[] = { /* Memory Specifications
132 From RAGE 128 Software Development
133 Manual (Technical Reference Manual P/N
134 SDK-G04000 Rev 0.01), page 3-21. */
135 { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" },
136 { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" },
137 { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" },
138 { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
139 };
140
R128INPLL(int addr)141 unsigned R128INPLL(int addr)
142 {
143 OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
144 return INREG(R128_CLOCK_CNTL_DATA);
145 }
146
R128WaitForVerticalSync(void)147 void R128WaitForVerticalSync(void)
148 {
149 int i;
150
151 OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK);
152 for (i = 0; i < R128_TIMEOUT; i++) {
153 if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break;
154 }
155 }
156
157 /* Blank screen. */
R128Blank(void)158 static void R128Blank(void)
159 {
160 OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);
161 }
162
163 /* Unblank screen. */
R128Unblank(void)164 static void R128Unblank(void)
165 {
166 OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);
167 }
168
R128RestoreCommonRegisters(R128SavePtr restore)169 static void R128RestoreCommonRegisters(R128SavePtr restore)
170 {
171 OUTREG(R128_OVR_CLR, restore->ovr_clr);
172 OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right);
173 OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom);
174 OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl);
175 OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config );
176 OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config );
177 OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl);
178 OUTREG(R128_VIPH_CONTROL, restore->viph_control);
179 OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1);
180 OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl);
181 OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl);
182 OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl);
183 OUTREG(R128_BUS_CNTL, restore->bus_cntl);
184 OUTREG(R128_CONFIG_CNTL, restore->config_cntl);
185 OUTREG(R128_MEM_VGA_WP_SEL, restore->mem_vga_wp_sel);
186 OUTREG(R128_MEM_VGA_RP_SEL, restore->mem_vga_rp_sel);
187
188 }
189
190 /* Write CRTC registers. */
R128RestoreCrtcRegisters(R128SavePtr restore)191 static void R128RestoreCrtcRegisters(R128SavePtr restore)
192 {
193 OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
194
195 OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl,
196 R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS);
197
198 OUTREGP(R128_DAC_CNTL, restore->dac_cntl,
199 R128_DAC_RANGE_CNTL | R128_DAC_BLANKING);
200
201 OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp);
202 OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
203 OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp);
204 OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
205 OUTREG(R128_CRTC_OFFSET, restore->crtc_offset);
206 OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
207 OUTREG(R128_CRTC_PITCH, restore->crtc_pitch);
208 }
209
210 /* Write flat panel registers */
R128RestoreFPRegisters(R128SavePtr restore)211 static void R128RestoreFPRegisters(R128SavePtr restore)
212 {
213 CARD32 tmp;
214
215 OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
216 OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
217 OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
218 OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl);
219 OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid);
220 OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch);
221 OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
222 OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
223 OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch);
224 OUTREG(R128_TMDS_CRC, restore->tmds_crc);
225
226 tmp = INREG(R128_LVDS_GEN_CNTL);
227 if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
228 (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
229 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
230 } else {
231 if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
232 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON);
233 // usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
234 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
235 } else {
236 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
237 // usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
238 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
239 }
240 }
241 }
242
R128PLLWaitForReadUpdateComplete(void)243 static void R128PLLWaitForReadUpdateComplete(void)
244 {
245 while (INPLL(R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R);
246 }
247
R128PLLWriteUpdate(void)248 static void R128PLLWriteUpdate(void)
249 {
250 OUTPLLP(R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff);
251 }
252
253 /* Write PLL registers. */
R128RestorePLLRegisters(R128SavePtr restore)254 static void R128RestorePLLRegisters(R128SavePtr restore)
255 {
256 OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff);
257
258 OUTPLLP(
259 R128_PPLL_CNTL,
260 R128_PPLL_RESET
261 | R128_PPLL_ATOMIC_UPDATE_EN,
262 0xffff);
263
264 R128PLLWaitForReadUpdateComplete();
265 OUTPLLP(R128_PPLL_REF_DIV,
266 restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK);
267 R128PLLWriteUpdate();
268
269 R128PLLWaitForReadUpdateComplete();
270 OUTPLLP(R128_PPLL_DIV_3,
271 restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK);
272 R128PLLWriteUpdate();
273 OUTPLLP(R128_PPLL_DIV_3,
274 restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK);
275 R128PLLWriteUpdate();
276
277 R128PLLWaitForReadUpdateComplete();
278 OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl);
279 R128PLLWriteUpdate();
280
281 OUTPLLP( R128_PPLL_CNTL, 0, ~R128_PPLL_RESET);
282
283 }
284
285 /* Write DDA registers. */
R128RestoreDDARegisters(R128SavePtr restore)286 static void R128RestoreDDARegisters(R128SavePtr restore)
287 {
288 OUTREG(R128_DDA_CONFIG, restore->dda_config);
289 OUTREG(R128_DDA_ON_OFF, restore->dda_on_off);
290 // OUTREG(R128_VGA_DDA_CONFIG, restore->vga_dda_config);
291 // OUTREG(R128_VGA_DDA_ON_OFF, restore->vga_dda_on_off);
292 }
293
294 /* Write palette data. */
R128RestorePalette(R128SavePtr restore)295 static void R128RestorePalette( R128SavePtr restore)
296 {
297 int i;
298
299 if (!restore->palette_valid) return;
300
301 /* Select palette 0 (main CRTC) if using FP-enabled chip */
302 // if (info->HasPanelRegs) PAL_SELECT(0);
303
304 OUTPAL_START(0);
305 for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]);
306 }
307
308 /* Write out state to define a new video mode. */
R128RestoreMode(R128SavePtr restore)309 static void R128RestoreMode(R128SavePtr restore)
310 {
311 R128Blank();
312
313 OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask);
314 OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg);
315 OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
316 OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
317 OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
318
319 R128RestoreCommonRegisters( restore);
320 R128RestoreCrtcRegisters( restore);
321 // if (info->HasPanelRegs)
322 // R128RestoreFPRegisters(restore);
323 // if (!info->HasPanelRegs || info->CRTOnly)
324 R128RestorePLLRegisters(restore);
325 R128RestoreDDARegisters(restore);
326 R128RestorePalette(restore);
327 }
328
329 /* Read common registers. */
R128SaveCommonRegisters(R128SavePtr save)330 static void R128SaveCommonRegisters(R128SavePtr save)
331 {
332 save->ovr_clr = INREG(R128_OVR_CLR);
333 save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT);
334 save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM);
335 save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL);
336 save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG);
337 save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG);
338 save->subpic_cntl = INREG(R128_SUBPIC_CNTL);
339 save->viph_control = INREG(R128_VIPH_CONTROL);
340 save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1);
341 save->gen_int_cntl = INREG(R128_GEN_INT_CNTL);
342 save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL);
343 save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL);
344 save->bus_cntl = INREG(R128_BUS_CNTL);
345 save->config_cntl = INREG(R128_CONFIG_CNTL);
346 save->mem_vga_wp_sel = INREG(R128_MEM_VGA_WP_SEL);
347 save->mem_vga_rp_sel = INREG(R128_MEM_VGA_RP_SEL);
348 }
349
350 /* Read CRTC registers. */
R128SaveCrtcRegisters(R128SavePtr save)351 static void R128SaveCrtcRegisters(R128SavePtr save)
352 {
353 save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL);
354 save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL);
355 save->dac_cntl = INREG(R128_DAC_CNTL);
356 save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP);
357 save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID);
358 save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP);
359 save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
360 save->crtc_offset = INREG(R128_CRTC_OFFSET);
361 save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL);
362 save->crtc_pitch = INREG(R128_CRTC_PITCH);
363 }
364
365 /* Read flat panel registers */
R128SaveFPRegisters(R128SavePtr save)366 static void R128SaveFPRegisters(R128SavePtr save)
367 {
368 save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL);
369 save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP);
370 save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP);
371 save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL);
372 save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID);
373 save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH);
374 save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL);
375 save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID);
376 save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH);
377 save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL);
378 save->tmds_crc = INREG(R128_TMDS_CRC);
379 }
380
381 /* Read PLL registers. */
R128SavePLLRegisters(R128SavePtr save)382 static void R128SavePLLRegisters(R128SavePtr save)
383 {
384 save->ppll_ref_div = INPLL(R128_PPLL_REF_DIV);
385 save->ppll_div_3 = INPLL(R128_PPLL_DIV_3);
386 save->htotal_cntl = INPLL(R128_HTOTAL_CNTL);
387 }
388
389 /* Read DDA registers. */
R128SaveDDARegisters(R128SavePtr save)390 static void R128SaveDDARegisters(R128SavePtr save)
391 {
392 save->dda_config = INREG(R128_DDA_CONFIG);
393 save->dda_on_off = INREG(R128_DDA_ON_OFF);
394 save->vga_dda_config = INREG(R128_VGA_DDA_CONFIG);
395 save->vga_dda_on_off = INREG(R128_VGA_DDA_ON_OFF);
396 }
397
398 /* Read palette data. */
R128SavePalette(R128SavePtr save)399 static void R128SavePalette(R128SavePtr save)
400 {
401 int i;
402
403 /* Select palette 0 (main CRTC) if using FP-enabled chip */
404 // if (info->HasPanelRegs) PAL_SELECT(0);
405
406 INPAL_START(0);
407 for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
408 save->palette_valid = 1;
409 }
410
411 /* Save state that defines current video mode. */
R128SaveMode(R128SavePtr save)412 static void R128SaveMode(R128SavePtr save)
413 {
414 R128SaveCommonRegisters(save);
415 R128SaveCrtcRegisters(save);
416 // if (R128PTR(pScrn)->HasPanelRegs)
417 // R128SaveFPRegisters(save);
418 R128SavePLLRegisters(save);
419 R128SaveDDARegisters(save);
420 R128SavePalette(save);
421
422 save->dp_datatype = INREG(R128_DP_DATATYPE);
423 save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
424 save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
425 save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG);
426 save->amcgpio_mask = INREG(R128_AMCGPIO_MASK);
427 }
428
R128InitCommonRegisters(R128SavePtr save)429 static void R128InitCommonRegisters(R128SavePtr save)
430 {
431 save->ovr_clr = 0;
432 save->ovr_wid_left_right = 0;
433 save->ovr_wid_top_bottom = 0;
434 save->ov0_scale_cntl = 0;
435 save->mpp_tb_config = 0;
436 save->mpp_gp_config = 0;
437 save->subpic_cntl = 0;
438 save->viph_control = 0;
439 save->i2c_cntl_1 = 0;
440 save->gen_int_cntl = 0;
441 save->cap0_trig_cntl = 0;
442 save->cap1_trig_cntl = 0;
443 save->mem_vga_wp_sel = 0;
444 save->mem_vga_rp_sel = 0;
445 save->bus_cntl = BusCntl;
446 /*
447 * If bursts are enabled, turn on discards and aborts
448 */
449 if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST))
450 save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN;
451 }
452
453 /* Define CRTC registers for requested video mode. */
R128InitCrtcRegisters(R128SavePtr save,ModeTiming * mode,ModeInfo * info)454 static Bool R128InitCrtcRegisters(R128SavePtr save,
455 ModeTiming *mode, ModeInfo *info)
456 {
457 int format;
458 int hsync_start;
459 int hsync_wid;
460 int hsync_fudge;
461 int vsync_wid;
462 int bytpp;
463 int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
464 int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 };
465 int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 };
466 int dac6bits;
467
468 dac6bits=0;
469
470 switch (info->bitsPerPixel) {
471 case 4: format = 1; bytpp = 0; dac6bits = 1; break;
472 case 8: format = 2; bytpp = 1; dac6bits = 1; break;
473 case 16:
474 if(info->greenWeight==5)
475 format = 3; else format = 4;
476 bytpp = 2;
477 break;
478 case 24: format = 5; bytpp = 3; break; /* RGB */
479 case 32: format = 6; bytpp = 4; break; /* xRGB */
480 default:
481 return 0;
482 }
483
484 if (HasPanelRegs)
485 if (CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1];
486 else hsync_fudge = hsync_fudge_fp[format-1];
487 else
488 hsync_fudge = hsync_fudge_default[format-1];
489
490 save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN
491 | R128_CRTC_EN
492 | (format << 8)
493 | ((mode->flags & DOUBLESCAN)
494 ? R128_CRTC_DBL_SCAN_EN
495 : 0)
496 | ((mode->flags & INTERLACED)
497 ? R128_CRTC_INTERLACE_EN
498 : 0));
499
500 save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN | R128_VGA_MEM_PS_EN;
501 save->dac_cntl = (R128_DAC_MASK_ALL
502 | R128_DAC_VGA_ADR_EN
503 | (dac6bits ? 0 : R128_DAC_8BIT_EN));
504
505 save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
506 | (((mode->CrtcHDisplay / 8) - 1) << 16));
507
508 hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
509 if (!hsync_wid) hsync_wid = 1;
510 if (hsync_wid > 0x3f) hsync_wid = 0x3f;
511
512 hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge;
513
514 save->crtc_h_sync_strt_wid = ((hsync_start & 0xfff)
515 | (hsync_wid << 16)
516 | ((mode->flags & NHSYNC)
517 ? R128_CRTC_H_SYNC_POL
518 : 0));
519
520 #if 1
521 /* This works for double scan mode. */
522 save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
523 | ((mode->CrtcVDisplay - 1) << 16));
524 #else
525 /* This is what cce/nbmode.c example code
526 does -- is this correct? */
527 save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
528 | ((mode->CrtcVDisplay
529 * ((mode->Flags & DOUBLESCAN) ? 2 : 1) - 1)
530 << 16));
531 #endif
532
533 vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
534 if (!vsync_wid) vsync_wid = 1;
535 if (vsync_wid > 0x1f) vsync_wid = 0x1f;
536
537 save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
538 | (vsync_wid << 16)
539 | ((mode->flags & NVSYNC)
540 ? R128_CRTC_V_SYNC_POL
541 : 0));
542 save->crtc_offset = 0;
543 save->crtc_offset_cntl = 0;
544 save->crtc_pitch = info->width / 8;
545
546 save->config_cntl |= R128_CFG_VGA_RAM_EN;
547
548 #if 0
549 /* Change the endianness of the aperture */
550 switch (info->bitsPerPixel) {
551 case 15:
552 case 16: save->config_cntl |= APER_0_BIG_ENDIAN_16BPP_SWAP; break;
553 case 32: save->config_cntl |= APER_0_BIG_ENDIAN_32BPP_SWAP; break;
554 default: break;
555 }
556 #endif
557
558 return 1;
559 }
560
561 /* Define CRTC registers for requested video mode. */
R128InitFPRegisters(R128SavePtr orig,R128SavePtr save,ModeTiming * mode,ModeInfo * info)562 static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
563 ModeTiming *mode, ModeInfo *info)
564 {
565 #if 0
566 int xres = mode->CrtcHDisplay;
567 int yres = mode->CrtcVDisplay;
568 float Hratio, Vratio;
569
570 if (CRTOnly) {
571 save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
572 save->crtc2_gen_cntl = 0;
573 save->fp_gen_cntl = orig->fp_gen_cntl;
574 save->fp_gen_cntl &= ~(R128_FP_FPON |
575 R128_FP_CRTC_USE_SHADOW_VEND |
576 R128_FP_CRTC_HORZ_DIV2_EN |
577 R128_FP_CRTC_HOR_CRT_DIV2_DIS |
578 R128_FP_USE_SHADOW_EN);
579 save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
580 R128_FP_CRTC_DONT_SHADOW_VPAR);
581 save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON;
582 save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON |
583 R128_LVDS_BLON);
584 return;
585 }
586
587
588 if (xres > info->PanelXRes) xres = info->PanelXRes;
589 if (yres > info->PanelYRes) yres = info->PanelYRes;
590
591 Hratio = (float)xres/(float)info->PanelXRes;
592 Vratio = (float)yres/(float)info->PanelYRes;
593
594 save->fp_horz_stretch =
595 (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
596 & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) |
597 (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE |
598 R128_HORZ_FP_LOOP_STRETCH |
599 R128_HORZ_STRETCH_RESERVED)));
600 save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
601 if (Hratio == 1.0) save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND |
602 R128_HORZ_STRETCH_ENABLE);
603 else save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND |
604 R128_HORZ_STRETCH_ENABLE);
605
606 save->fp_vert_stretch =
607 (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
608 & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) |
609 (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
610 R128_VERT_STRETCH_RESERVED)));
611 save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
612 if (Vratio == 1.0) save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE |
613 R128_VERT_STRETCH_BLEND);
614 else save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE |
615 R128_VERT_STRETCH_BLEND);
616
617 save->fp_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 |
618 R128_FP_CRTC_USE_SHADOW_VEND |
619 R128_FP_CRTC_HORZ_DIV2_EN |
620 R128_FP_CRTC_HOR_CRT_DIV2_DIS |
621 R128_FP_USE_SHADOW_EN));
622 if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) {
623 save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR |
624 R128_FP_TDMS_EN);
625 }
626
627 save->fp_panel_cntl = orig->fp_panel_cntl;
628 save->lvds_gen_cntl = orig->lvds_gen_cntl;
629
630 save->tmds_crc = orig->tmds_crc;
631
632 /* Disable CRT output by disabling CRT output and setting the CRT
633 DAC to use CRTC2, which we set to 0's. In the future, we will
634 want to use the dual CRTC capabilities of the R128 to allow both
635 the flat panel and external CRT to either simultaneously display
636 the same image or display two different images. */
637 save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON;
638 save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
639 save->crtc2_gen_cntl = 0;
640
641 /* WARNING: Be careful about turning on the flat panel */
642 #if 1
643 save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
644 #else
645 save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
646 save->fp_gen_cntl |= (R128_FP_FPON);
647 #endif
648
649 save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
650 save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
651 save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
652 save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
653 #endif
654 }
655
656 /* Define PLL registers for requested video mode. */
R128InitPLLRegisters(R128SavePtr save,R128PLLPtr pll,double dot_clock)657 static void R128InitPLLRegisters(R128SavePtr save, R128PLLPtr pll,
658 double dot_clock)
659 {
660 unsigned long freq = dot_clock * 100;
661 struct {
662 int divider;
663 int bitvalue;
664 } *post_div,
665 post_divs[] = {
666 /* From RAGE 128 VR/RAGE 128 GL Register
667 Reference Manual (Technical Reference
668 Manual P/N RRG-G04100-C Rev. 0.04), page
669 3-17 (PLL_DIV_[3:0]). */
670 { 1, 0 }, /* VCLK_SRC */
671 { 2, 1 }, /* VCLK_SRC/2 */
672 { 4, 2 }, /* VCLK_SRC/4 */
673 { 8, 3 }, /* VCLK_SRC/8 */
674
675 { 3, 4 }, /* VCLK_SRC/3 */
676 /* bitvalue = 5 is reserved */
677 { 6, 6 }, /* VCLK_SRC/6 */
678 { 12, 7 }, /* VCLK_SRC/12 */
679 { 0, 0 }
680 };
681
682 if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
683 if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
684
685 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
686 save->pll_output_freq = post_div->divider * freq;
687 if (save->pll_output_freq >= pll->min_pll_freq
688 && save->pll_output_freq <= pll->max_pll_freq) break;
689 }
690
691 save->dot_clock_freq = freq;
692 save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq,
693 pll->reference_freq);
694 save->post_div = post_div->divider;
695
696 save->ppll_ref_div = pll->reference_div;
697 save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
698 save->htotal_cntl = 0;
699 }
700
701 /* Define DDA registers for requested video mode. */
R128InitDDARegisters(R128SavePtr save,R128PLLPtr pll,ModeInfo * info)702 static Bool R128InitDDARegisters(R128SavePtr save,
703 R128PLLPtr pll, ModeInfo *info)
704 {
705 int DisplayFifoWidth = 128;
706 int DisplayFifoDepth = 32;
707 int XclkFreq;
708 int VclkFreq;
709 int XclksPerTransfer;
710 int XclksPerTransferPrecise;
711 int UseablePrecision;
712 int Roff;
713 int Ron;
714
715 XclkFreq = pll->xclk;
716
717 VclkFreq = R128Div(pll->reference_freq * save->feedback_div,
718 pll->reference_div * save->post_div);
719
720 XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth,
721 VclkFreq * (info->bytesPerPixel * 8));
722
723 UseablePrecision = R128MinBits(XclksPerTransfer) + 1;
724
725 XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth)
726 << (11 - UseablePrecision),
727 VclkFreq * (info->bytesPerPixel * 8));
728
729 Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4);
730
731 Ron = (4 * ram[r128_ramtype].MB
732 + 3 * (((ram[r128_ramtype].Trcd - 2)>0)?(ram[r128_ramtype].Trcd - 2):0)
733 + 2 * ram[r128_ramtype].Trp
734 + ram[r128_ramtype].Twr
735 + ram[r128_ramtype].CL
736 + ram[r128_ramtype].Tr2w
737 + XclksPerTransfer) << (11 - UseablePrecision);
738
739 if (Ron + ram[r128_ramtype].Rloop >= Roff) {
740 return 0;
741 }
742
743 save->dda_config = (XclksPerTransferPrecise
744 | (UseablePrecision << 16)
745 | (ram[r128_ramtype].Rloop << 20));
746
747 save->dda_on_off = (Ron << 16) | Roff;
748
749 return 1;
750 }
751
752
753 /* Define initial palette for requested video mode. This doesn't do
754 anything for XFree86 4.0. */
R128InitPalette(R128SavePtr save)755 static void R128InitPalette(R128SavePtr save)
756 {
757 int i;
758 save->palette_valid = 1;
759 for(i=0;i<256;i++) save->palette[i]=i | (i<<8) | (i<<16);
760 }
761
762 /* Define registers for a requested video mode. */
R128Init(ModeTiming * mode,ModeInfo * info,R128SavePtr save)763 static Bool R128Init(ModeTiming *mode, ModeInfo *info, R128SavePtr save)
764 {
765 double dot_clock = mode->pixelClock/1000.0;
766
767 R128InitCommonRegisters(save);
768 if (!R128InitCrtcRegisters(save, mode, info)) return 0;
769 #if 0
770 if (HasPanelRegs)
771 R128InitFPRegisters(&info->SavedReg, save, mode, info);
772 #endif
773 R128InitPLLRegisters(save, &pll, dot_clock);
774 if (!R128InitDDARegisters(save, &pll, info))
775 return 0;
776 // if (!info->PaletteSavedOnVT)
777 R128InitPalette(save);
778
779 return 1;
780 }
781
782 static int r128_init(int, int, int);
783 static void r128_unlock(void);
784 static void r128_lock(void);
785
786 void __svgalib_skaccel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels);
787
788 static int r128_memory, r128_chiptype;
789 static int r128_is_linear, r128_linear_base, r128_mmio_base;
790
791 static CardSpecs *cardspecs;
792
r128_setpage(int page)793 static void r128_setpage(int page)
794 {
795 page*=2;
796 OUTREG(R128_MEM_VGA_WP_SEL, page | ((page+1)<<16));
797 OUTREG(R128_MEM_VGA_RP_SEL, page | ((page+1)<<16));
798
799 }
800
__svgalib_r128_inlinearmode(void)801 static int __svgalib_r128_inlinearmode(void)
802 {
803 return r128_is_linear;
804 }
805
806 /* Fill in chipset specific mode information */
807
r128_getmodeinfo(int mode,vga_modeinfo * modeinfo)808 static void r128_getmodeinfo(int mode, vga_modeinfo *modeinfo)
809 {
810
811 if(modeinfo->colors==16)return;
812
813 modeinfo->maxpixels = r128_memory*1024/modeinfo->bytesperpixel;
814 modeinfo->maxlogicalwidth = 4088;
815 modeinfo->startaddressrange = r128_memory * 1024 - 1;
816 modeinfo->haveblit = 0;
817 modeinfo->flags &= ~HAVE_RWPAGE;
818
819 if (modeinfo->bytesperpixel >= 1) {
820 if(r128_linear_base)modeinfo->flags |= CAPABLE_LINEAR;
821 if (__svgalib_r128_inlinearmode())
822 modeinfo->flags |= IS_LINEAR;
823 }
824 }
825
826 /* Read and save chipset-specific registers */
827
r128_saveregs(unsigned char regs[])828 static int r128_saveregs(unsigned char regs[])
829 {
830 int i;
831
832 r128_unlock();
833 R128SaveMode((R128SavePtr)(regs+VGA_TOTAL_REGS));
834 return R128_TOTAL_REGS - VGA_TOTAL_REGS;
835 }
836
837 /* Set chipset-specific registers */
838
r128_setregs(const unsigned char regs[],int mode)839 static void r128_setregs(const unsigned char regs[], int mode)
840 {
841 r128_unlock();
842
843 R128RestoreMode((R128SavePtr)(regs+VGA_TOTAL_REGS));
844
845 R128Unblank();
846 }
847 /* Return nonzero if mode is available */
848
r128_modeavailable(int mode)849 static int r128_modeavailable(int mode)
850 {
851 struct info *info;
852 ModeTiming *modetiming;
853 ModeInfo *modeinfo;
854
855 modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
856
857 if (IS_IN_STANDARD_VGA_DRIVER(mode))
858 return __svgalib_vga_driverspecs.modeavailable(mode);
859
860 info = &__svgalib_infotable[mode];
861 if (r128_memory * 1024 < info->ydim * info->xbytes)
862 return 0;
863
864 modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
865
866 modetiming = malloc(sizeof(ModeTiming));
867 if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
868 free(modetiming);
869 free(modeinfo);
870 return 0;
871 }
872 free(modetiming);
873 free(modeinfo);
874
875 return SVGADRV;
876 }
877
878 /* Local, called by r128_setmode(). */
879
r128_initializemode(unsigned char * moderegs,ModeTiming * modetiming,ModeInfo * modeinfo,int mode)880 static void r128_initializemode(unsigned char *moderegs,
881 ModeTiming * modetiming, ModeInfo * modeinfo, int mode)
882 { /* long k; */
883 __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);
884
885 R128Init(modetiming, modeinfo, (R128SavePtr)(moderegs+VGA_TOTAL_REGS));
886
887 return ;
888 }
889
890
r128_setmode(int mode,int prv_mode)891 static int r128_setmode(int mode, int prv_mode)
892 {
893 unsigned char *moderegs;
894 ModeTiming *modetiming;
895 ModeInfo *modeinfo;
896
897 if (IS_IN_STANDARD_VGA_DRIVER(mode)) {
898 return __svgalib_vga_driverspecs.setmode(mode, prv_mode);
899 }
900 if (!r128_modeavailable(mode))
901 return 1;
902
903 modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
904
905 modetiming = malloc(sizeof(ModeTiming));
906 if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
907 free(modetiming);
908 free(modeinfo);
909 return 1;
910 }
911
912 moderegs = malloc(R128_TOTAL_REGS);
913
914 r128_initializemode(moderegs, modetiming, modeinfo, mode);
915 free(modetiming);
916
917 __svgalib_setregs(moderegs); /* Set standard regs. */
918 r128_setregs(moderegs, mode); /* Set extended regs. */
919 free(moderegs);
920
921 __svgalib_InitializeAcceleratorInterface(modeinfo);
922
923
924 free(modeinfo);
925 return 0;
926 }
927
928
929 /* Unlock chipset-specific registers */
930
r128_unlock(void)931 static void r128_unlock(void)
932 {
933 int vgaIOBase, temp;
934
935 vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
936 outb(vgaIOBase + 4, 0x11);
937 temp = inb(vgaIOBase + 5);
938 outb(vgaIOBase + 5, temp & 0x7F);
939
940 }
941
r128_lock(void)942 static void r128_lock(void)
943 {
944 int vgaIOBase, temp;
945
946 vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
947 outb(vgaIOBase + 4, 0x11);
948 temp = inb(vgaIOBase + 5);
949 outb(vgaIOBase + 5, temp & 0x7F);
950 }
951
952
953 #define VENDOR_ID 0x1002
954
955 /* Indentify chipset, initialize and return non-zero if detected */
956
r128_test(void)957 static int r128_test(void)
958 {
959 int found, id;
960 unsigned long buf[64];
961
962 found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0);
963
964 if(found) return 0;
965 id=(buf[0]>>16)&0xffff;
966 if((id>=0x5350) || (id<=0x4fff)) return 0;
967
968 r128_init(0,0,0);
969 return 1;
970 }
971
972
973 /* Set display start address (not for 16 color modes) */
974 /* Cirrus supports any address in video memory (up to 2Mb) */
975
r128_setdisplaystart(int address)976 static void r128_setdisplaystart(int address)
977 {
978 int naddress=address >> 2;
979 __svgalib_outcrtc(0x0c,(naddress>>8)&0xff);
980 __svgalib_outcrtc(0x0d,(naddress)&0xff);
981 OUTREG(R128_CRTC_OFFSET, address);
982 }
983
984 /* Set logical scanline length (usually multiple of 8) */
985 /* Cirrus supports multiples of 8, up to 4088 */
986
r128_setlogicalwidth(int width)987 static void r128_setlogicalwidth(int width)
988 {
989 int offset = width >> 3;
990
991 if(CI.bytesperpixel>1) {
992 offset = offset/CI.bytesperpixel;
993 }
994 __svgalib_outcrtc(0x13,offset&0xff);
995 OUTREG(R128_CRTC_PITCH, offset);
996 }
997
r128_linear(int op,int param)998 static int r128_linear(int op, int param)
999 {
1000 if (op==LINEAR_ENABLE){r128_is_linear=1; return 0;};
1001 if (op==LINEAR_DISABLE){r128_is_linear=0; return 0;};
1002 if (op==LINEAR_QUERY_BASE) return r128_linear_base;
1003 if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */
1004 else return -1; /* Unknown function. */
1005 }
1006
r128_match_programmable_clock(int clock)1007 static int r128_match_programmable_clock(int clock)
1008 {
1009 return clock ;
1010 }
1011
r128_map_clock(int bpp,int clock)1012 static int r128_map_clock(int bpp, int clock)
1013 {
1014 return clock ;
1015 }
1016
r128_map_horizontal_crtc(int bpp,int pixelclock,int htiming)1017 static int r128_map_horizontal_crtc(int bpp, int pixelclock, int htiming)
1018 {
1019 return htiming;
1020 }
1021
1022 /* Function table (exported) */
1023
1024 DriverSpecs __svgalib_r128_driverspecs =
1025 {
1026 r128_saveregs,
1027 r128_setregs,
1028 r128_unlock,
1029 r128_lock,
1030 r128_test,
1031 r128_init,
1032 r128_setpage,
1033 NULL,
1034 NULL,
1035 r128_setmode,
1036 r128_modeavailable,
1037 r128_setdisplaystart,
1038 r128_setlogicalwidth,
1039 r128_getmodeinfo,
1040 0, /* old blit funcs */
1041 0,
1042 0,
1043 0,
1044 0,
1045 0, /* ext_set */
1046 0, /* accel */
1047 r128_linear,
1048 0, /* accelspecs, filled in during init. */
1049 NULL, /* Emulation */
1050 };
1051
1052 /* Initialize chipset (called after detection) */
1053
r128_init(int force,int par1,int par2)1054 static int r128_init(int force, int par1, int par2)
1055 {
1056 unsigned long buf[64];
1057 int found=0;
1058 unsigned char *BIOS_POINTER;
1059
1060 r128_unlock();
1061 if (force) {
1062 r128_memory = par1;
1063 r128_chiptype = par2;
1064 } else {
1065
1066 };
1067
1068 found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0);
1069
1070 if(found) return 0;
1071 r128_chiptype=(buf[0]>>16)&0xffff;
1072 if((r128_chiptype>=0x5350) || (r128_chiptype<=0x4fff)) return 0;
1073
1074 r128_linear_base=buf[4]&0xffffff00;
1075 r128_mmio_base=buf[6]&0xffffff00;
1076
1077 MMIO_POINTER = mmap(0, 16*1024, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd,
1078 r128_mmio_base);
1079 BIOS_POINTER = mmap(0, 64*1024, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd,
1080 0xc0000);
1081
1082 r128_memory = INREG(R128_CONFIG_MEMSIZE) / 1024;
1083 BusCntl = INREG(R128_BUS_CNTL);
1084 HasPanelRegs = 0;
1085 CRTOnly = 1;
1086 r128_ramtype = 1;
1087 #if 0
1088 pll.reference_freq = 2700;
1089 pll.min_pll_freq = 12500;
1090 pll.max_pll_freq = 40000;
1091 pll.reference_div = INPLL(R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK;
1092 pll.xclk = 14000;
1093 #else
1094 #define R128_BIOS16(x) (*(unsigned short *)(BIOS_POINTER + x))
1095 #define R128_BIOS32(x) (*(unsigned int *)(BIOS_POINTER + x))
1096 {
1097 CARD16 bios_header = R128_BIOS16(0x48);
1098 CARD16 pll_info_block = R128_BIOS16(bios_header + 0x30);
1099 pll.reference_freq = R128_BIOS16(pll_info_block + 0x0e);
1100 pll.reference_div = R128_BIOS16(pll_info_block + 0x10);
1101 pll.min_pll_freq = R128_BIOS32(pll_info_block + 0x12);
1102 pll.max_pll_freq = R128_BIOS32(pll_info_block + 0x16);
1103 pll.xclk = R128_BIOS16(pll_info_block + 0x08);
1104 #if 0
1105 printf("pll: %i %i %i %i %i\n",pll.reference_freq,pll.reference_div,
1106 pll.min_pll_freq, pll.max_pll_freq, pll.xclk);
1107 #endif
1108 }
1109 #endif
1110
1111 munmap(MMIO_POINTER, 16*1024);
1112 munmap(BIOS_POINTER, 64*1024);
1113
1114 if (__svgalib_driver_report) {
1115 printf("Using Rage 128 driver, %iKB.\n",r128_memory);
1116 };
1117
1118 cardspecs = malloc(sizeof(CardSpecs));
1119 cardspecs->videoMemory = r128_memory;
1120 cardspecs->maxPixelClock4bpp = 75000;
1121 cardspecs->maxPixelClock8bpp = 160000;
1122 cardspecs->maxPixelClock16bpp = 160000;
1123 cardspecs->maxPixelClock24bpp = 160000;
1124 cardspecs->maxPixelClock32bpp = 160000;
1125 cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE;
1126 cardspecs->maxHorizontalCrtc = 2040;
1127 cardspecs->maxPixelClock4bpp = 0;
1128 cardspecs->nClocks =0;
1129 cardspecs->mapClock = r128_map_clock;
1130 cardspecs->mapHorizontalCrtc = r128_map_horizontal_crtc;
1131 cardspecs->matchProgrammableClock=r128_match_programmable_clock;
1132 __svgalib_driverspecs = &__svgalib_r128_driverspecs;
1133 __svgalib_banked_mem_base=0xa0000;
1134 __svgalib_banked_mem_size=0x10000;
1135 __svgalib_linear_mem_base=r128_linear_base;
1136 __svgalib_linear_mem_size=r128_memory*0x400;
1137 __svgalib_mmio_base=r128_mmio_base;
1138 __svgalib_mmio_size=16*1024;
1139 return 0;
1140 }
1141