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