Rev 74 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
74 | giacomo | 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 "vgapci.h" |
||
18 | #include "endianess.h" |
||
19 | #include "r128_reg.h" |
||
20 | |||
21 | #include <kernel/log.h> |
||
22 | |||
23 | static enum { Rage128=0, Radeon } chiptype; /* r128io needs to know */ |
||
24 | static int dac6bits; |
||
25 | #include "r128io.h" |
||
26 | |||
27 | #ifdef __PPC |
||
28 | #define NO_BIOS |
||
29 | #else |
||
30 | #undef NO_BIOS |
||
31 | #endif |
||
32 | |||
33 | typedef int Bool; |
||
34 | |||
35 | static int r128_ramtype; |
||
36 | static int BusCntl, CRTOnly, HasPanelRegs; |
||
37 | |||
38 | typedef struct { |
||
39 | uint16_t reference_freq; |
||
40 | uint16_t reference_div; |
||
41 | uint32_t min_pll_freq; |
||
42 | uint32_t max_pll_freq; |
||
43 | uint16_t xclk; |
||
44 | } R128PLLRec, *R128PLLPtr; |
||
45 | |||
46 | typedef struct { |
||
47 | /* Common registers */ |
||
48 | uint32_t ovr_clr; |
||
49 | uint32_t ovr_wid_left_right; |
||
50 | uint32_t ovr_wid_top_bottom; |
||
51 | uint32_t ov0_scale_cntl; |
||
52 | uint32_t mpp_tb_config; |
||
53 | uint32_t mpp_gp_config; |
||
54 | uint32_t subpic_cntl; |
||
55 | uint32_t viph_control; |
||
56 | uint32_t i2c_cntl_1; |
||
57 | uint32_t gen_int_cntl; |
||
58 | uint32_t cap0_trig_cntl; |
||
59 | uint32_t cap1_trig_cntl; |
||
60 | uint32_t bus_cntl; |
||
61 | uint32_t bus_cntl1; |
||
62 | uint32_t mem_cntl; |
||
63 | uint32_t config_cntl; |
||
64 | uint32_t mem_vga_wp_sel; |
||
65 | uint32_t mem_vga_rp_sel; |
||
66 | uint32_t surface_cntl; |
||
67 | uint32_t dac_cntl2; |
||
68 | uint32_t crtc_more_cntl; |
||
69 | uint32_t dac_ext_cntl; |
||
70 | uint32_t grph_buf_cntl; |
||
71 | uint32_t vga_buf_cntl; |
||
72 | |||
73 | /* Other registers to save for VT switches */ |
||
74 | uint32_t dp_datatype; |
||
75 | uint32_t gen_reset_cntl; |
||
76 | uint32_t clock_cntl_index; |
||
77 | uint32_t amcgpio_en_reg; |
||
78 | uint32_t amcgpio_mask; |
||
79 | /* CRTC registers */ |
||
80 | uint32_t crtc_gen_cntl; |
||
81 | uint32_t crtc_ext_cntl; |
||
82 | uint32_t dac_cntl; |
||
83 | uint32_t crtc_h_total_disp; |
||
84 | uint32_t crtc_h_sync_strt_wid; |
||
85 | uint32_t crtc_v_total_disp; |
||
86 | uint32_t crtc_v_sync_strt_wid; |
||
87 | uint32_t crtc_offset; |
||
88 | uint32_t crtc_offset_cntl; |
||
89 | uint32_t crtc_pitch; |
||
90 | /* CRTC2 registers */ |
||
91 | uint32_t crtc2_gen_cntl; |
||
92 | /* Flat panel registers */ |
||
93 | uint32_t fp_crtc_h_total_disp; |
||
94 | uint32_t fp_crtc_v_total_disp; |
||
95 | uint32_t fp_gen_cntl; |
||
96 | uint32_t fp_h_sync_strt_wid; |
||
97 | uint32_t fp_horz_stretch; |
||
98 | uint32_t fp_panel_cntl; |
||
99 | uint32_t fp_v_sync_strt_wid; |
||
100 | uint32_t fp_vert_stretch; |
||
101 | uint32_t lvds_gen_cntl; |
||
102 | uint32_t tmds_crc; |
||
103 | /* Computed values for PLL */ |
||
104 | uint32_t dot_clock_freq; |
||
105 | uint32_t pll_output_freq; |
||
106 | int feedback_div; |
||
107 | int post_div; |
||
108 | /* PLL registers */ |
||
109 | uint32_t ppll_ref_div; |
||
110 | uint32_t ppll_div_3; |
||
111 | uint32_t htotal_cntl; |
||
112 | /* DDA register */ |
||
113 | uint32_t dda_config; |
||
114 | uint32_t dda_on_off; |
||
115 | uint32_t vga_dda_config; |
||
116 | uint32_t vga_dda_on_off; |
||
117 | /* Pallet */ |
||
118 | Bool palette_valid; |
||
119 | uint32_t palette[256]; |
||
120 | } R128SaveRec, *R128SavePtr; |
||
121 | |||
122 | typedef struct { /* All values in XCLKS */ |
||
123 | int ML; /* Memory Read Latency */ |
||
124 | int MB; /* Memory Burst Length */ |
||
125 | int Trcd; /* RAS to CAS delay */ |
||
126 | int Trp; /* RAS percentage */ |
||
127 | int Twr; /* Write Recovery */ |
||
128 | int CL; /* CAS Latency */ |
||
129 | int Tr2w; /* Read to Write Delay */ |
||
130 | int Rloop; /* Loop Latency */ |
||
131 | int Rloop_fudge; /* Add to ML to get Rloop */ |
||
132 | char *name; |
||
133 | } R128RAMRec, *R128RAMPtr; |
||
134 | |||
135 | #define R128_TOTAL_REGS (VGA_TOTAL_REGS + sizeof(R128SaveRec)) |
||
136 | static int R128MinBits(int val) |
||
137 | { |
||
138 | int bits; |
||
139 | |||
140 | if (!val) return 1; |
||
141 | for (bits = 0; val; val >>= 1, ++bits); |
||
142 | return bits; |
||
143 | } |
||
144 | static int R128Div(int n, int d) |
||
145 | { |
||
146 | return (n + (d / 2)) / d; |
||
147 | } |
||
148 | static R128PLLRec pll; |
||
149 | |||
150 | static R128RAMRec ram[] = { /* Memory Specifications |
||
151 | From RAGE 128 Software Development |
||
152 | Manual (Technical Reference Manual P/N |
||
153 | SDK-G04000 Rev 0.01), page 3-21. */ |
||
154 | { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, |
||
155 | { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, |
||
156 | { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, |
||
157 | { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, |
||
158 | }; |
||
159 | |||
160 | static unsigned R128INPLL(int addr) |
||
161 | { |
||
162 | OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); |
||
163 | return INREG(R128_CLOCK_CNTL_DATA); |
||
164 | } |
||
165 | |||
166 | static void R128WaitForVerticalSync(void) |
||
167 | { |
||
168 | volatile int i; |
||
169 | |||
170 | OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); |
||
171 | for (i = 0; i < R128_TIMEOUT; i++) { |
||
172 | if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; |
||
173 | } |
||
174 | } |
||
175 | |||
176 | /* Blank screen. */ |
||
177 | static void R128Blank(void) |
||
178 | { |
||
179 | OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS); |
||
180 | } |
||
181 | |||
182 | /* Unblank screen. */ |
||
183 | static void R128Unblank(void) |
||
184 | { |
||
185 | OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS); |
||
186 | } |
||
187 | |||
188 | static void R128RestoreCommonRegisters(R128SavePtr restore) |
||
189 | { |
||
190 | OUTREG(R128_OVR_CLR, restore->ovr_clr); |
||
191 | OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); |
||
192 | OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); |
||
193 | OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); |
||
194 | OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); |
||
195 | OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); |
||
196 | OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); |
||
197 | OUTREG(R128_VIPH_CONTROL, restore->viph_control); |
||
198 | OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); |
||
199 | OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); |
||
200 | OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); |
||
201 | OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); |
||
202 | OUTREG(R128_BUS_CNTL, restore->bus_cntl); |
||
203 | OUTREG(R128_BUS_CNTL1, restore->bus_cntl1); |
||
204 | OUTREG(R128_CONFIG_CNTL, restore->config_cntl); |
||
205 | OUTREG(R128_MEM_VGA_WP_SEL, restore->mem_vga_wp_sel); |
||
206 | OUTREG(R128_MEM_VGA_RP_SEL, restore->mem_vga_rp_sel); |
||
207 | |||
208 | if(chiptype == Rage128) { |
||
209 | OUTREG(RADEON_SURFACE_CNTL, restore->surface_cntl); |
||
210 | OUTREG(RADEON_DAC_CNTL2, restore->dac_cntl2); |
||
211 | OUTREG(RADEON_CRTC_MORE_CNTL,restore->crtc_more_cntl); |
||
212 | OUTREG(RADEON_DAC_EXT_CNTL, restore->dac_ext_cntl); |
||
213 | OUTREG(RADEON_GRPH_BUF_CNTL, restore->grph_buf_cntl); |
||
214 | OUTREG(RADEON_VGA_BUF_CNTL, restore->vga_buf_cntl); |
||
215 | } |
||
216 | |||
217 | } |
||
218 | |||
219 | /* Write CRTC registers. */ |
||
220 | static void R128RestoreCrtcRegisters(R128SavePtr restore) |
||
221 | { |
||
222 | OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl); |
||
223 | |||
224 | OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl, |
||
225 | R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS); |
||
226 | |||
227 | OUTREGP(R128_DAC_CNTL, restore->dac_cntl, |
||
228 | R128_DAC_RANGE_CNTL | R128_DAC_BLANKING); |
||
229 | |||
230 | OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); |
||
231 | OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); |
||
232 | OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); |
||
233 | OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); |
||
234 | OUTREG(R128_CRTC_OFFSET, restore->crtc_offset); |
||
235 | OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); |
||
236 | OUTREG(R128_CRTC_PITCH, restore->crtc_pitch); |
||
237 | } |
||
238 | |||
239 | /* Write flat panel registers */ |
||
240 | #if 0 |
||
241 | static void R128RestoreFPRegisters(R128SavePtr restore) |
||
242 | { |
||
243 | uint32_t tmp; |
||
244 | |||
245 | OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); |
||
246 | OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); |
||
247 | OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); |
||
248 | OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl); |
||
249 | OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); |
||
250 | OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); |
||
251 | OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); |
||
252 | OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); |
||
253 | OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); |
||
254 | OUTREG(R128_TMDS_CRC, restore->tmds_crc); |
||
255 | |||
256 | tmp = INREG(R128_LVDS_GEN_CNTL); |
||
257 | if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == |
||
258 | (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { |
||
259 | OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); |
||
260 | } else { |
||
261 | if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { |
||
262 | OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON); |
||
263 | // usleep(R128PTR(pScrn)->PanelPwrDly * 1000); |
||
264 | OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); |
||
265 | } else { |
||
266 | OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); |
||
267 | // usleep(R128PTR(pScrn)->PanelPwrDly * 1000); |
||
268 | OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); |
||
269 | } |
||
270 | } |
||
271 | } |
||
272 | #endif |
||
273 | static void R128PLLWaitForReadUpdateComplete(void) |
||
274 | { |
||
275 | while (INPLL(R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R); |
||
276 | } |
||
277 | |||
278 | static void R128PLLWriteUpdate(void) |
||
279 | { |
||
280 | OUTPLLP(R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff); |
||
281 | } |
||
282 | |||
283 | /* Write PLL registers. */ |
||
284 | static void RADEONRestorePLLRegisters(R128SavePtr restore) |
||
285 | { |
||
286 | OUTPLLP(R128_VCLK_ECP_CNTL, |
||
287 | RADEON_VCLK_SRC_SEL_CPUCLK, |
||
288 | ~(RADEON_VCLK_SRC_SEL_MASK)); |
||
289 | |||
290 | OUTPLLP(R128_PPLL_CNTL, |
||
291 | R128_PPLL_RESET |
||
292 | | R128_PPLL_ATOMIC_UPDATE_EN |
||
293 | | R128_PPLL_VGA_ATOMIC_UPDATE_EN, |
||
294 | ~(R128_PPLL_RESET |
||
295 | | R128_PPLL_ATOMIC_UPDATE_EN |
||
296 | | R128_PPLL_VGA_ATOMIC_UPDATE_EN)); |
||
297 | |||
298 | OUTREGP(R128_CLOCK_CNTL_INDEX, |
||
299 | R128_PLL_DIV_SEL, |
||
300 | ~(R128_PLL_DIV_SEL)); |
||
301 | |||
302 | OUTPLLP(R128_PPLL_REF_DIV, |
||
303 | restore->ppll_ref_div, |
||
304 | ~R128_PPLL_REF_DIV_MASK); |
||
305 | |||
306 | OUTPLLP(R128_PPLL_DIV_3, |
||
307 | restore->ppll_div_3, |
||
308 | ~R128_PPLL_FB3_DIV_MASK); |
||
309 | |||
310 | OUTPLLP(R128_PPLL_DIV_3, |
||
311 | restore->ppll_div_3, |
||
312 | ~R128_PPLL_POST3_DIV_MASK); |
||
313 | |||
314 | R128PLLWriteUpdate(); |
||
315 | R128PLLWaitForReadUpdateComplete(); |
||
316 | |||
317 | OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); |
||
318 | |||
319 | OUTPLLP(R128_PPLL_CNTL, |
||
320 | 0, |
||
321 | ~(R128_PPLL_RESET |
||
322 | | R128_PPLL_SLEEP |
||
323 | | R128_PPLL_ATOMIC_UPDATE_EN |
||
324 | | R128_PPLL_VGA_ATOMIC_UPDATE_EN)); |
||
325 | |||
326 | sleep(1); /* Let the clock to lock */ |
||
327 | |||
328 | OUTPLLP(R128_VCLK_ECP_CNTL, |
||
329 | RADEON_VCLK_SRC_SEL_PPLLCLK, |
||
330 | ~(RADEON_VCLK_SRC_SEL_MASK)); |
||
331 | } |
||
332 | |||
333 | static void R128RestorePLLRegisters(R128SavePtr restore) |
||
334 | { |
||
335 | OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff); |
||
336 | |||
337 | OUTPLLP( |
||
338 | R128_PPLL_CNTL, |
||
339 | R128_PPLL_RESET |
||
340 | | R128_PPLL_ATOMIC_UPDATE_EN, |
||
341 | 0xffff); |
||
342 | |||
343 | R128PLLWaitForReadUpdateComplete(); |
||
344 | OUTPLLP(R128_PPLL_REF_DIV, |
||
345 | restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK); |
||
346 | R128PLLWriteUpdate(); |
||
347 | |||
348 | R128PLLWaitForReadUpdateComplete(); |
||
349 | OUTPLLP(R128_PPLL_DIV_3, |
||
350 | restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK); |
||
351 | R128PLLWriteUpdate(); |
||
352 | OUTPLLP(R128_PPLL_DIV_3, |
||
353 | restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK); |
||
354 | R128PLLWriteUpdate(); |
||
355 | |||
356 | R128PLLWaitForReadUpdateComplete(); |
||
357 | OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); |
||
358 | R128PLLWriteUpdate(); |
||
359 | |||
360 | OUTPLLP( R128_PPLL_CNTL, 0, ~R128_PPLL_RESET); |
||
361 | |||
362 | } |
||
363 | |||
364 | /* Write DDA registers. */ |
||
365 | static void R128RestoreDDARegisters(R128SavePtr restore) |
||
366 | { |
||
367 | OUTREG(R128_DDA_CONFIG, restore->dda_config); |
||
368 | OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); |
||
369 | // OUTREG(R128_VGA_DDA_CONFIG, restore->vga_dda_config); |
||
370 | // OUTREG(R128_VGA_DDA_ON_OFF, restore->vga_dda_on_off); |
||
371 | } |
||
372 | |||
373 | /* Write palette data. */ |
||
374 | static void R128RestorePalette( R128SavePtr restore) |
||
375 | { |
||
376 | int i; |
||
377 | |||
378 | if (!restore->palette_valid) return; |
||
379 | |||
380 | /* Select palette 0 (main CRTC) if using FP-enabled chip */ |
||
381 | // if (info->HasPanelRegs) PAL_SELECT(0); |
||
382 | |||
383 | OUTPAL_START(0); |
||
384 | for (i = 0; i < 256; i++) OUTPAL_NEXT_uint32_t(restore->palette[i]); |
||
385 | } |
||
386 | |||
387 | /* Write out state to define a new video mode. */ |
||
388 | static void R128RestoreMode(R128SavePtr restore) |
||
389 | { |
||
390 | R128Blank(); |
||
391 | |||
392 | OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); |
||
393 | OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); |
||
394 | OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); |
||
395 | #if 0 /* works without, and it causes problems with it */ |
||
396 | OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); |
||
397 | #endif |
||
398 | OUTREG(R128_DP_DATATYPE, restore->dp_datatype); |
||
399 | |||
400 | R128RestoreCommonRegisters( restore); |
||
401 | R128RestoreCrtcRegisters( restore); |
||
402 | // if (info->HasPanelRegs) |
||
403 | // R128RestoreFPRegisters(restore); |
||
404 | // if (!info->HasPanelRegs || info->CRTOnly) |
||
405 | switch(chiptype) { |
||
406 | case Rage128: |
||
407 | R128RestorePLLRegisters(restore); |
||
408 | break; |
||
409 | case Radeon: |
||
410 | RADEONRestorePLLRegisters(restore); |
||
411 | break; |
||
412 | } |
||
413 | |||
414 | if(chiptype == Rage128) { |
||
415 | R128RestoreDDARegisters(restore); |
||
416 | } |
||
417 | R128RestorePalette(restore); |
||
418 | } |
||
419 | |||
420 | /* Read common registers. */ |
||
421 | static void R128SaveCommonRegisters(R128SavePtr save) |
||
422 | { |
||
423 | save->ovr_clr = INREG(R128_OVR_CLR); |
||
424 | save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); |
||
425 | save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); |
||
426 | save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); |
||
427 | save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); |
||
428 | save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); |
||
429 | save->subpic_cntl = INREG(R128_SUBPIC_CNTL); |
||
430 | save->viph_control = INREG(R128_VIPH_CONTROL); |
||
431 | save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); |
||
432 | save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); |
||
433 | save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); |
||
434 | save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); |
||
435 | save->bus_cntl = INREG(R128_BUS_CNTL); |
||
436 | save->bus_cntl1 = INREG(R128_BUS_CNTL1); |
||
437 | save->mem_cntl = INREG(R128_MEM_CNTL); |
||
438 | save->config_cntl = INREG(R128_CONFIG_CNTL); |
||
439 | save->mem_vga_wp_sel = INREG(R128_MEM_VGA_WP_SEL); |
||
440 | save->mem_vga_rp_sel = INREG(R128_MEM_VGA_RP_SEL); |
||
441 | |||
442 | if(chiptype==Radeon) { |
||
443 | save->surface_cntl = INREG(RADEON_SURFACE_CNTL); |
||
444 | save->dac_cntl2 = INREG(RADEON_DAC_CNTL2); |
||
445 | save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); |
||
446 | save->dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL); |
||
447 | save->grph_buf_cntl = INREG(RADEON_GRPH_BUF_CNTL); |
||
448 | save->vga_buf_cntl = INREG(RADEON_VGA_BUF_CNTL); |
||
449 | } |
||
450 | } |
||
451 | |||
452 | /* Read CRTC registers. */ |
||
453 | static void R128SaveCrtcRegisters(R128SavePtr save) |
||
454 | { |
||
455 | save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); |
||
456 | save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); |
||
457 | save->dac_cntl = INREG(R128_DAC_CNTL); |
||
458 | save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); |
||
459 | save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); |
||
460 | save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); |
||
461 | save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); |
||
462 | save->crtc_offset = INREG(R128_CRTC_OFFSET); |
||
463 | save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); |
||
464 | save->crtc_pitch = INREG(R128_CRTC_PITCH); |
||
465 | } |
||
466 | |||
467 | #if 0 |
||
468 | /* Read flat panel registers */ |
||
469 | static void R128SaveFPRegisters(R128SavePtr save) |
||
470 | { |
||
471 | save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); |
||
472 | save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); |
||
473 | save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); |
||
474 | save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); |
||
475 | save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); |
||
476 | save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); |
||
477 | save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); |
||
478 | save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); |
||
479 | save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); |
||
480 | save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); |
||
481 | save->tmds_crc = INREG(R128_TMDS_CRC); |
||
482 | } |
||
483 | #endif |
||
484 | |||
485 | /* Read PLL registers. */ |
||
486 | static void R128SavePLLRegisters(R128SavePtr save) |
||
487 | { |
||
488 | save->ppll_ref_div = INPLL(R128_PPLL_REF_DIV); |
||
489 | save->ppll_div_3 = INPLL(R128_PPLL_DIV_3); |
||
490 | save->htotal_cntl = INPLL(R128_HTOTAL_CNTL); |
||
491 | } |
||
492 | |||
493 | /* Read DDA registers. */ |
||
494 | static void R128SaveDDARegisters(R128SavePtr save) |
||
495 | { |
||
496 | save->dda_config = INREG(R128_DDA_CONFIG); |
||
497 | save->dda_on_off = INREG(R128_DDA_ON_OFF); |
||
498 | save->vga_dda_config = INREG(R128_VGA_DDA_CONFIG); |
||
499 | save->vga_dda_on_off = INREG(R128_VGA_DDA_ON_OFF); |
||
500 | } |
||
501 | |||
502 | /* Read palette data. */ |
||
503 | static void R128SavePalette(R128SavePtr save) |
||
504 | { |
||
505 | int i; |
||
506 | |||
507 | /* Select palette 0 (main CRTC) if using FP-enabled chip */ |
||
508 | // if (info->HasPanelRegs) PAL_SELECT(0); |
||
509 | |||
510 | INPAL_START(0); |
||
511 | for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); |
||
512 | save->palette_valid = 1; |
||
513 | } |
||
514 | |||
515 | /* Save state that defines current video mode. */ |
||
516 | static void R128SaveMode(R128SavePtr save) |
||
517 | { |
||
518 | R128SaveCommonRegisters(save); |
||
519 | R128SaveCrtcRegisters(save); |
||
520 | // if (R128PTR(pScrn)->HasPanelRegs) |
||
521 | // R128SaveFPRegisters(save); |
||
522 | R128SavePLLRegisters(save); |
||
523 | if(chiptype == Rage128) |
||
524 | R128SaveDDARegisters(save); |
||
525 | R128SavePalette(save); |
||
526 | |||
527 | save->dp_datatype = INREG(R128_DP_DATATYPE); |
||
528 | save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); |
||
529 | save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); |
||
530 | save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); |
||
531 | save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); |
||
532 | } |
||
533 | |||
534 | static void R128InitCommonRegisters(R128SavePtr save) |
||
535 | { |
||
536 | save->ovr_clr = 0; |
||
537 | save->ovr_wid_left_right = 0; |
||
538 | save->ovr_wid_top_bottom = 0; |
||
539 | save->ov0_scale_cntl = 0; |
||
540 | save->mpp_tb_config = 0; |
||
541 | save->mpp_gp_config = 0; |
||
542 | save->subpic_cntl = 0; |
||
543 | save->viph_control = 0; |
||
544 | save->i2c_cntl_1 = 0; |
||
545 | save->gen_int_cntl = 0; |
||
546 | save->cap0_trig_cntl = 0; |
||
547 | save->cap1_trig_cntl = 0; |
||
548 | save->mem_vga_wp_sel = 0; |
||
549 | save->mem_vga_rp_sel = 0; |
||
550 | save->config_cntl = INREG(R128_CONFIG_CNTL); |
||
551 | save->bus_cntl = BusCntl; |
||
552 | save->bus_cntl1 = INREG(R128_BUS_CNTL1); |
||
553 | if(chiptype == Radeon) { |
||
554 | if(save->bus_cntl & RADEON_BUS_READ_BURST) |
||
555 | save->bus_cntl |=RADEON_BUS_RD_DISCARD_EN; |
||
556 | } |
||
557 | |||
558 | save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); |
||
559 | save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); |
||
560 | |||
561 | /* |
||
562 | * If bursts are enabled, turn on discards and aborts |
||
563 | */ |
||
564 | if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) |
||
565 | save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; |
||
566 | } |
||
567 | |||
568 | /* Define CRTC registers for requested video mode. */ |
||
569 | static Bool R128InitCrtcRegisters(R128SavePtr save, |
||
570 | ModeTiming *mode, ModeInfo *info) |
||
571 | { |
||
572 | int format; |
||
573 | int hsync_start; |
||
574 | int hsync_wid; |
||
575 | int hsync_fudge; |
||
576 | int vsync_wid; |
||
577 | int bytpp; |
||
578 | int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; |
||
579 | int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; |
||
580 | int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; |
||
581 | |||
582 | dac6bits=0; |
||
583 | |||
584 | switch (info->bitsPerPixel) { |
||
585 | case 4: format = 1; bytpp = 0; dac6bits = 1; break; |
||
586 | case 8: format = 2; bytpp = 1; dac6bits = 1; break; |
||
587 | case 16: |
||
588 | if(info->greenWeight==5) |
||
589 | format = 3; else format = 4; |
||
590 | bytpp = 2; |
||
591 | break; |
||
592 | case 24: format = 5; bytpp = 3; break; /* RGB */ |
||
593 | case 32: format = 6; bytpp = 4; break; /* xRGB */ |
||
594 | default: |
||
595 | return 0; |
||
596 | } |
||
597 | |||
598 | if (HasPanelRegs) |
||
599 | if (CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1]; |
||
600 | else hsync_fudge = hsync_fudge_fp[format-1]; |
||
601 | else |
||
602 | hsync_fudge = hsync_fudge_default[format-1]; |
||
603 | |||
604 | save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN |
||
605 | | R128_CRTC_EN |
||
606 | | (format << 8) |
||
607 | | ((mode->flags & DOUBLESCAN) |
||
608 | ? R128_CRTC_DBL_SCAN_EN |
||
609 | : 0) |
||
610 | | ((mode->flags & INTERLACED) |
||
611 | ? R128_CRTC_INTERLACE_EN |
||
612 | : 0)); |
||
613 | |||
614 | save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN | R128_VGA_MEM_PS_EN; |
||
615 | if(chiptype == Radeon) save->crtc_ext_cntl |= R128_CRTC_CRT_ON; |
||
616 | save->dac_cntl = (R128_DAC_MASK_ALL |
||
617 | | R128_DAC_VGA_ADR_EN |
||
618 | | (dac6bits ? 0 : R128_DAC_8BIT_EN)); |
||
619 | |||
620 | save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) |
||
621 | | (((mode->CrtcHDisplay / 8) - 1) << 16)); |
||
622 | |||
623 | hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; |
||
624 | if (!hsync_wid) hsync_wid = 1; |
||
625 | if (hsync_wid > 0x3f) hsync_wid = 0x3f; |
||
626 | |||
627 | hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; |
||
628 | |||
629 | save->crtc_h_sync_strt_wid = ((hsync_start & 0xfff) |
||
630 | | (hsync_wid << 16) |
||
631 | | ((mode->flags & NHSYNC) |
||
632 | ? R128_CRTC_H_SYNC_POL |
||
633 | : 0)); |
||
634 | |||
635 | #if 1 |
||
636 | /* This works for double scan mode. */ |
||
637 | save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) |
||
638 | | ((mode->CrtcVDisplay - 1) << 16)); |
||
639 | #else |
||
640 | /* This is what cce/nbmode.c example code |
||
641 | does -- is this correct? */ |
||
642 | save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) |
||
643 | | ((mode->CrtcVDisplay |
||
644 | * ((mode->Flags & DOUBLESCAN) ? 2 : 1) - 1) |
||
645 | << 16)); |
||
646 | #endif |
||
647 | |||
648 | vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; |
||
649 | if (!vsync_wid) vsync_wid = 1; |
||
650 | if (vsync_wid > 0x1f) vsync_wid = 0x1f; |
||
651 | |||
652 | save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) |
||
653 | | (vsync_wid << 16) |
||
654 | | ((mode->flags & NVSYNC) |
||
655 | ? R128_CRTC_V_SYNC_POL |
||
656 | : 0)); |
||
657 | save->crtc_offset = 0; |
||
658 | save->crtc_offset_cntl = 0; |
||
659 | save->crtc_pitch = info->width / 8; |
||
660 | |||
661 | save->config_cntl |= R128_CFG_VGA_RAM_EN; |
||
662 | |||
663 | if(chiptype == Radeon) { |
||
664 | save->crtc_pitch |= save->crtc_pitch<<16; |
||
665 | save->surface_cntl = RADEON_SURF_TRANSLATION_DIS; |
||
666 | |||
667 | save->dac_cntl2 = INREG(RADEON_DAC_CNTL2); |
||
668 | save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); |
||
669 | save->dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL); |
||
670 | save->grph_buf_cntl = INREG(RADEON_GRPH_BUF_CNTL); |
||
671 | save->vga_buf_cntl = INREG(RADEON_VGA_BUF_CNTL); |
||
672 | |||
673 | } |
||
674 | |||
675 | #ifdef __PPC |
||
676 | /* Change the endianness of the aperture */ |
||
677 | switch (info->bitsPerPixel) { |
||
678 | case 15: |
||
679 | case 16: save->config_cntl |= APER_0_BIG_ENDIAN_16BPP_SWAP; break; |
||
680 | case 32: save->config_cntl |= APER_0_BIG_ENDIAN_32BPP_SWAP; break; |
||
681 | default: break; |
||
682 | } |
||
683 | #endif |
||
684 | |||
685 | return 1; |
||
686 | } |
||
687 | |||
688 | #if 0 |
||
689 | /* Define CRTC registers for requested video mode. */ |
||
690 | static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, |
||
691 | ModeTiming *mode, ModeInfo *info) |
||
692 | { |
||
693 | #if 0 |
||
694 | int xres = mode->CrtcHDisplay; |
||
695 | int yres = mode->CrtcVDisplay; |
||
696 | float Hratio, Vratio; |
||
697 | |||
698 | if (CRTOnly) { |
||
699 | save->crtc_ext_cntl |= R128_CRTC_CRT_ON; |
||
700 | save->crtc2_gen_cntl = 0; |
||
701 | save->fp_gen_cntl = orig->fp_gen_cntl; |
||
702 | save->fp_gen_cntl &= ~(R128_FP_FPON | |
||
703 | R128_FP_CRTC_USE_SHADOW_VEND | |
||
704 | R128_FP_CRTC_HORZ_DIV2_EN | |
||
705 | R128_FP_CRTC_HOR_CRT_DIV2_DIS | |
||
706 | R128_FP_USE_SHADOW_EN); |
||
707 | save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 | |
||
708 | R128_FP_CRTC_DONT_SHADOW_VPAR); |
||
709 | save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON; |
||
710 | save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON | |
||
711 | R128_LVDS_BLON); |
||
712 | return; |
||
713 | } |
||
714 | |||
715 | |||
716 | if (xres > info->PanelXRes) xres = info->PanelXRes; |
||
717 | if (yres > info->PanelYRes) yres = info->PanelYRes; |
||
718 | |||
719 | Hratio = (float)xres/(float)info->PanelXRes; |
||
720 | Vratio = (float)yres/(float)info->PanelYRes; |
||
721 | |||
722 | save->fp_horz_stretch = |
||
723 | (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) |
||
724 | & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | |
||
725 | (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | |
||
726 | R128_HORZ_FP_LOOP_STRETCH | |
||
727 | R128_HORZ_STRETCH_RESERVED))); |
||
728 | save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; |
||
729 | if (Hratio == 1.0) save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | |
||
730 | R128_HORZ_STRETCH_ENABLE); |
||
731 | else save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | |
||
732 | R128_HORZ_STRETCH_ENABLE); |
||
733 | |||
734 | save->fp_vert_stretch = |
||
735 | (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) |
||
736 | & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | |
||
737 | (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | |
||
738 | R128_VERT_STRETCH_RESERVED))); |
||
739 | save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; |
||
740 | if (Vratio == 1.0) save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | |
||
741 | R128_VERT_STRETCH_BLEND); |
||
742 | else save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | |
||
743 | R128_VERT_STRETCH_BLEND); |
||
744 | |||
745 | save->fp_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 | |
||
746 | R128_FP_CRTC_USE_SHADOW_VEND | |
||
747 | R128_FP_CRTC_HORZ_DIV2_EN | |
||
748 | R128_FP_CRTC_HOR_CRT_DIV2_DIS | |
||
749 | R128_FP_USE_SHADOW_EN)); |
||
750 | if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) { |
||
751 | save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR | |
||
752 | R128_FP_TDMS_EN); |
||
753 | } |
||
754 | |||
755 | save->fp_panel_cntl = orig->fp_panel_cntl; |
||
756 | save->lvds_gen_cntl = orig->lvds_gen_cntl; |
||
757 | |||
758 | save->tmds_crc = orig->tmds_crc; |
||
759 | |||
760 | /* Disable CRT output by disabling CRT output and setting the CRT |
||
761 | DAC to use CRTC2, which we set to 0's. In the future, we will |
||
762 | want to use the dual CRTC capabilities of the R128 to allow both |
||
763 | the flat panel and external CRT to either simultaneously display |
||
764 | the same image or display two different images. */ |
||
765 | save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON; |
||
766 | save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2; |
||
767 | save->crtc2_gen_cntl = 0; |
||
768 | |||
769 | /* WARNING: Be careful about turning on the flat panel */ |
||
770 | #if 1 |
||
771 | save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON); |
||
772 | #else |
||
773 | save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); |
||
774 | save->fp_gen_cntl |= (R128_FP_FPON); |
||
775 | #endif |
||
776 | |||
777 | save->fp_crtc_h_total_disp = save->crtc_h_total_disp; |
||
778 | save->fp_crtc_v_total_disp = save->crtc_v_total_disp; |
||
779 | save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; |
||
780 | save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; |
||
781 | #endif |
||
782 | } |
||
783 | #endif |
||
784 | |||
785 | /* Define PLL registers for requested video mode. */ |
||
786 | static void RADEONInitPLLRegisters(R128SavePtr save, R128PLLPtr pll, |
||
787 | double dot_clock) |
||
788 | { |
||
789 | unsigned long freq = dot_clock * 100; |
||
790 | struct { |
||
791 | int divider; |
||
792 | int bitvalue; |
||
793 | } *post_div, |
||
794 | post_divs[] = { |
||
795 | /* From RAGE 128 VR/RAGE 128 GL Register |
||
796 | Reference Manual (Technical Reference |
||
797 | Manual P/N RRG-G04100-C Rev. 0.04), page |
||
798 | 3-17 (PLL_DIV_[3:0]). */ |
||
799 | { 1, 0 }, /* VCLK_SRC */ |
||
800 | { 2, 1 }, /* VCLK_SRC/2 */ |
||
801 | { 4, 2 }, /* VCLK_SRC/4 */ |
||
802 | { 8, 3 }, /* VCLK_SRC/8 */ |
||
803 | |||
804 | { 3, 4 }, /* VCLK_SRC/3 */ |
||
805 | { 16, 5 }, |
||
806 | { 6, 6 }, /* VCLK_SRC/6 */ |
||
807 | { 12, 7 }, /* VCLK_SRC/12 */ |
||
808 | { 0, 0 } |
||
809 | }; |
||
810 | |||
811 | if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; |
||
812 | if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; |
||
813 | |||
814 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { |
||
815 | save->pll_output_freq = post_div->divider * freq; |
||
816 | if (save->pll_output_freq >= pll->min_pll_freq |
||
817 | && save->pll_output_freq <= pll->max_pll_freq) break; |
||
818 | } |
||
819 | |||
820 | save->dot_clock_freq = freq; |
||
821 | save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq, |
||
822 | pll->reference_freq); |
||
823 | save->post_div = post_div->divider; |
||
824 | |||
825 | save->ppll_ref_div = pll->reference_div; |
||
826 | save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); |
||
827 | save->htotal_cntl = 0; |
||
828 | } |
||
829 | |||
830 | static void R128InitPLLRegisters(R128SavePtr save, R128PLLPtr pll, |
||
831 | double dot_clock) |
||
832 | { |
||
833 | unsigned long freq = dot_clock * 100; |
||
834 | struct { |
||
835 | int divider; |
||
836 | int bitvalue; |
||
837 | } *post_div, |
||
838 | post_divs[] = { |
||
839 | /* From RAGE 128 VR/RAGE 128 GL Register |
||
840 | Reference Manual (Technical Reference |
||
841 | Manual P/N RRG-G04100-C Rev. 0.04), page |
||
842 | 3-17 (PLL_DIV_[3:0]). */ |
||
843 | { 1, 0 }, /* VCLK_SRC */ |
||
844 | { 2, 1 }, /* VCLK_SRC/2 */ |
||
845 | { 4, 2 }, /* VCLK_SRC/4 */ |
||
846 | { 8, 3 }, /* VCLK_SRC/8 */ |
||
847 | |||
848 | { 3, 4 }, /* VCLK_SRC/3 */ |
||
849 | /* bitvalue = 5 is reserved */ |
||
850 | { 6, 6 }, /* VCLK_SRC/6 */ |
||
851 | { 12, 7 }, /* VCLK_SRC/12 */ |
||
852 | { 0, 0 } |
||
853 | }; |
||
854 | |||
855 | if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; |
||
856 | if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; |
||
857 | |||
858 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { |
||
859 | save->pll_output_freq = post_div->divider * freq; |
||
860 | if (save->pll_output_freq >= pll->min_pll_freq |
||
861 | && save->pll_output_freq <= pll->max_pll_freq) break; |
||
862 | } |
||
863 | |||
864 | save->dot_clock_freq = freq; |
||
865 | save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq, |
||
866 | pll->reference_freq); |
||
867 | save->post_div = post_div->divider; |
||
868 | |||
869 | save->ppll_ref_div = pll->reference_div; |
||
870 | save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); |
||
871 | save->htotal_cntl = 0; |
||
872 | } |
||
873 | |||
874 | /* Define DDA registers for requested video mode. */ |
||
875 | static Bool R128InitDDARegisters(R128SavePtr save, |
||
876 | R128PLLPtr pll, ModeInfo *info) |
||
877 | { |
||
878 | int DisplayFifoWidth = 128; |
||
879 | int DisplayFifoDepth = 32; |
||
880 | int XclkFreq; |
||
881 | int VclkFreq; |
||
882 | int XclksPerTransfer; |
||
883 | int XclksPerTransferPrecise; |
||
884 | int UseablePrecision; |
||
885 | int Roff; |
||
886 | int Ron; |
||
887 | |||
888 | XclkFreq = pll->xclk; |
||
889 | |||
890 | VclkFreq = R128Div(pll->reference_freq * save->feedback_div, |
||
891 | pll->reference_div * save->post_div); |
||
892 | |||
893 | XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth, |
||
894 | VclkFreq * (info->bytesPerPixel * 8)); |
||
895 | |||
896 | UseablePrecision = R128MinBits(XclksPerTransfer) + 1; |
||
897 | |||
898 | XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth) |
||
899 | << (11 - UseablePrecision), |
||
900 | VclkFreq * (info->bytesPerPixel * 8)); |
||
901 | |||
902 | Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); |
||
903 | |||
904 | Ron = (4 * ram[r128_ramtype].MB |
||
905 | + 3 * (((ram[r128_ramtype].Trcd - 2)>0)?(ram[r128_ramtype].Trcd - 2):0) |
||
906 | + 2 * ram[r128_ramtype].Trp |
||
907 | + ram[r128_ramtype].Twr |
||
908 | + ram[r128_ramtype].CL |
||
909 | + ram[r128_ramtype].Tr2w |
||
910 | + XclksPerTransfer) << (11 - UseablePrecision); |
||
911 | |||
912 | if (Ron + ram[r128_ramtype].Rloop >= Roff) { |
||
913 | return 0; |
||
914 | } |
||
915 | |||
916 | save->dda_config = (XclksPerTransferPrecise |
||
917 | | (UseablePrecision << 16) |
||
918 | | (ram[r128_ramtype].Rloop << 20)); |
||
919 | |||
920 | save->dda_on_off = (Ron << 16) | Roff; |
||
921 | |||
922 | return 1; |
||
923 | } |
||
924 | |||
925 | |||
926 | /* Define initial palette for requested video mode. This doesn't do |
||
927 | anything for XFree86 4.0. */ |
||
928 | static void R128InitPalette(R128SavePtr save) |
||
929 | { |
||
930 | int i; |
||
931 | save->palette_valid = 1; |
||
932 | for(i=0;i<256;i++) save->palette[i]=i | (i<<8) | (i<<16); |
||
933 | } |
||
934 | |||
935 | /* Define registers for a requested video mode. */ |
||
936 | static Bool R128Init(ModeTiming *mode, ModeInfo *info, R128SavePtr save) |
||
937 | { |
||
938 | double dot_clock = mode->pixelClock/1000.0; |
||
939 | |||
940 | R128InitCommonRegisters(save); |
||
941 | if (!R128InitCrtcRegisters(save, mode, info)) return 0; |
||
942 | #if 0 |
||
943 | if (HasPanelRegs) |
||
944 | R128InitFPRegisters(&info->SavedReg, save, mode, info); |
||
945 | #endif |
||
946 | switch(chiptype) { |
||
947 | case Rage128: |
||
948 | R128InitPLLRegisters(save, &pll, dot_clock); |
||
949 | break; |
||
950 | case Radeon: |
||
951 | RADEONInitPLLRegisters(save, &pll, dot_clock); |
||
952 | break; |
||
953 | } |
||
954 | |||
955 | if (!R128InitDDARegisters(save, &pll, info)) |
||
956 | return 0; |
||
957 | // if (!info->PaletteSavedOnVT) |
||
958 | R128InitPalette(save); |
||
959 | |||
960 | return 1; |
||
961 | } |
||
962 | |||
963 | static int r128_init(int, int, int); |
||
964 | static void r128_unlock(void); |
||
965 | static void r128_lock(void); |
||
966 | |||
967 | static int r128_memory; |
||
968 | static int r128_is_linear, r128_linear_base, r128_mmio_base; |
||
969 | |||
970 | static CardSpecs *cardspecs; |
||
971 | |||
972 | static void r128_setpage(int page) |
||
973 | { |
||
974 | page*=2; |
||
975 | OUTREG(R128_MEM_VGA_WP_SEL, page | ((page+1)<<16)); |
||
976 | OUTREG(R128_MEM_VGA_RP_SEL, page | ((page+1)<<16)); |
||
977 | |||
978 | } |
||
979 | |||
980 | static int __svgalib_r128_inlinearmode(void) |
||
981 | { |
||
982 | return r128_is_linear; |
||
983 | } |
||
984 | |||
985 | /* Fill in chipset specific mode information */ |
||
986 | |||
987 | static void r128_getmodeinfo(int mode, vga_modeinfo *modeinfo) |
||
988 | { |
||
989 | |||
990 | if(modeinfo->colors==16)return; |
||
991 | |||
992 | modeinfo->maxpixels = r128_memory*1024/modeinfo->bytesperpixel; |
||
993 | modeinfo->maxlogicalwidth = 4088; |
||
994 | modeinfo->startaddressrange = r128_memory * 1024 - 1; |
||
995 | modeinfo->haveblit = 0; |
||
996 | modeinfo->flags &= ~HAVE_RWPAGE; |
||
997 | modeinfo->flags |= HAVE_EXT_SET; |
||
998 | |||
999 | if (modeinfo->bytesperpixel >= 1) { |
||
1000 | if(r128_linear_base)modeinfo->flags |= CAPABLE_LINEAR; |
||
1001 | if (__svgalib_r128_inlinearmode()) |
||
1002 | modeinfo->flags |= IS_LINEAR | LINEAR_MODE; |
||
1003 | } |
||
1004 | } |
||
1005 | |||
1006 | /* Read and save chipset-specific registers */ |
||
1007 | |||
1008 | static int r128_saveregs(unsigned char regs[]) |
||
1009 | { |
||
1010 | r128_unlock(); |
||
1011 | R128SaveMode((R128SavePtr)(regs+VGA_TOTAL_REGS)); |
||
1012 | return R128_TOTAL_REGS - VGA_TOTAL_REGS; |
||
1013 | } |
||
1014 | |||
1015 | /* Set chipset-specific registers */ |
||
1016 | |||
1017 | static void r128_setregs(const unsigned char regs[], int mode) |
||
1018 | { |
||
1019 | r128_unlock(); |
||
1020 | |||
1021 | R128RestoreMode((R128SavePtr)(regs+VGA_TOTAL_REGS)); |
||
1022 | |||
1023 | R128Unblank(); |
||
1024 | } |
||
1025 | /* Return nonzero if mode is available */ |
||
1026 | |||
1027 | static int r128_modeavailable(int mode) |
||
1028 | { |
||
1029 | struct info *info; |
||
1030 | ModeTiming *modetiming; |
||
1031 | ModeInfo *modeinfo; |
||
1032 | |||
1033 | modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); |
||
1034 | |||
1035 | if (IS_IN_STANDARD_VGA_DRIVER(mode)) |
||
1036 | return __svgalib_vga_driverspecs.modeavailable(mode); |
||
1037 | |||
1038 | info = &__svgalib_infotable[mode]; |
||
1039 | if (r128_memory * 1024 < info->ydim * info->xbytes) |
||
1040 | return 0; |
||
1041 | |||
1042 | modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); |
||
1043 | |||
1044 | modetiming = malloc(sizeof(ModeTiming)); |
||
1045 | if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) { |
||
1046 | free(modetiming); |
||
1047 | free(modeinfo); |
||
1048 | return 0; |
||
1049 | } |
||
1050 | free(modetiming); |
||
1051 | free(modeinfo); |
||
1052 | |||
1053 | return SVGADRV; |
||
1054 | } |
||
1055 | |||
1056 | /* Local, called by r128_setmode(). */ |
||
1057 | |||
1058 | static void r128_initializemode(unsigned char *moderegs, |
||
1059 | ModeTiming * modetiming, ModeInfo * modeinfo, int mode) |
||
1060 | { /* long k; */ |
||
1061 | __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo); |
||
1062 | |||
1063 | R128Init(modetiming, modeinfo, (R128SavePtr)(moderegs+VGA_TOTAL_REGS)); |
||
1064 | |||
1065 | return ; |
||
1066 | } |
||
1067 | |||
1068 | |||
1069 | static int r128_setmode(int mode, int prv_mode) |
||
1070 | { |
||
1071 | unsigned char *moderegs; |
||
1072 | ModeTiming *modetiming; |
||
1073 | ModeInfo *modeinfo; |
||
1074 | |||
1075 | if (IS_IN_STANDARD_VGA_DRIVER(mode)) { |
||
1076 | return __svgalib_vga_driverspecs.setmode(mode, prv_mode); |
||
1077 | } |
||
1078 | if (!r128_modeavailable(mode)) |
||
1079 | return 1; |
||
1080 | |||
1081 | modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); |
||
1082 | |||
1083 | modetiming = malloc(sizeof(ModeTiming)); |
||
1084 | if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) { |
||
1085 | free(modetiming); |
||
1086 | free(modeinfo); |
||
1087 | return 1; |
||
1088 | } |
||
1089 | |||
1090 | moderegs = malloc(R128_TOTAL_REGS); |
||
1091 | |||
1092 | r128_initializemode(moderegs, modetiming, modeinfo, mode); |
||
1093 | free(modetiming); |
||
1094 | |||
1095 | __svgalib_setregs(moderegs); /* Set standard regs. */ |
||
1096 | r128_setregs(moderegs, mode); /* Set extended regs. */ |
||
1097 | free(moderegs); |
||
1098 | |||
1099 | free(modeinfo); |
||
1100 | return 0; |
||
1101 | } |
||
1102 | |||
1103 | |||
1104 | /* Unlock chipset-specific registers */ |
||
1105 | static void r128_unlock(void) |
||
1106 | { |
||
1107 | __svgalib_outcrtc(0x11, __svgalib_incrtc(0x11) & 0x7f); |
||
1108 | } |
||
1109 | |||
1110 | static void r128_lock(void) |
||
1111 | { |
||
1112 | } |
||
1113 | |||
1114 | /* Indentify chipset, initialize and return non-zero if detected */ |
||
1115 | int r128_test(void) |
||
1116 | { |
||
1117 | return r128_init(0,0,0); |
||
1118 | return 1; |
||
1119 | } |
||
1120 | |||
1121 | |||
1122 | /* Set display start address (not for 16 color modes) */ |
||
1123 | /* Cirrus supports any address in video memory (up to 2Mb) */ |
||
1124 | |||
1125 | static void r128_setdisplaystart(int address) |
||
1126 | { |
||
1127 | int naddress=address >> 2; |
||
1128 | __svgalib_outcrtc(0x0c,(naddress>>8)&0xff); |
||
1129 | __svgalib_outcrtc(0x0d,(naddress)&0xff); |
||
1130 | OUTREG(R128_CRTC_OFFSET, address); |
||
1131 | } |
||
1132 | |||
1133 | /* Set logical scanline length (usually multiple of 8) */ |
||
1134 | /* Cirrus supports multiples of 8, up to 4088 */ |
||
1135 | |||
1136 | static void r128_setlogicalwidth(int width) |
||
1137 | { |
||
1138 | int offset = width >> 3; |
||
1139 | |||
1140 | if(CI.bytesperpixel>1) { |
||
1141 | offset = offset/CI.bytesperpixel; |
||
1142 | } |
||
1143 | __svgalib_outcrtc(0x13,offset&0xff); |
||
1144 | OUTREG(R128_CRTC_PITCH, offset); |
||
1145 | } |
||
1146 | |||
1147 | static int r128_linear(int op, int param) |
||
1148 | { |
||
1149 | if (op==LINEAR_ENABLE){r128_is_linear=1; return 0;}; |
||
1150 | if (op==LINEAR_DISABLE){r128_is_linear=0; return 0;}; |
||
1151 | if (op==LINEAR_QUERY_BASE) return r128_linear_base; |
||
1152 | if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */ |
||
1153 | else return -1; /* Unknown function. */ |
||
1154 | } |
||
1155 | |||
1156 | static int r128_match_programmable_clock(int clock) |
||
1157 | { |
||
1158 | return clock ; |
||
1159 | } |
||
1160 | |||
1161 | static int r128_map_clock(int bpp, int clock) |
||
1162 | { |
||
1163 | return clock ; |
||
1164 | } |
||
1165 | |||
1166 | static int r128_map_horizontal_crtc(int bpp, int pixelclock, int htiming) |
||
1167 | { |
||
1168 | return htiming; |
||
1169 | } |
||
1170 | |||
1171 | static unsigned int cur_colors[16*2]; |
||
1172 | |||
1173 | static int r128_cursor( int cmd, int p1, int p2, int p3, int p4, void *p5) { |
||
1174 | int i, j; |
||
1175 | unsigned long *b3; |
||
1176 | unsigned long l1, l2; |
||
1177 | |||
1178 | switch(cmd){ |
||
1179 | case CURSOR_INIT: |
||
1180 | return 1; |
||
1181 | case CURSOR_HIDE: |
||
1182 | OUTREG(R128_CRTC_GEN_CNTL,INREG(R128_CRTC_GEN_CNTL) & ~R128_CRTC_CUR_EN ); |
||
1183 | break; |
||
1184 | case CURSOR_SHOW: |
||
1185 | OUTREG(R128_CRTC_GEN_CNTL,INREG(R128_CRTC_GEN_CNTL) | R128_CRTC_CUR_EN ); |
||
1186 | break; |
||
1187 | case CURSOR_POSITION: |
||
1188 | OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | 0); |
||
1189 | OUTREG(R128_CUR_HORZ_VERT_POSN, p2|(p1<<16)); |
||
1190 | break; |
||
1191 | case CURSOR_SELECT: |
||
1192 | i=r128_memory*1024-(p1+1)*4096; |
||
1193 | OUTREG(R128_CUR_OFFSET,i); |
||
1194 | OUTREG(R128_CUR_CLR0,cur_colors[p1*2]); |
||
1195 | OUTREG(R128_CUR_CLR1,cur_colors[p1*2+1]); |
||
1196 | break; |
||
1197 | case CURSOR_IMAGE: |
||
1198 | i=r128_memory*1024-(p1+1)*4096; |
||
1199 | b3=(unsigned long *)p5; |
||
1200 | switch(p2) { |
||
1201 | case 0: |
||
1202 | cur_colors[p1*2]=p3; |
||
1203 | cur_colors[p1*2+1]=p4; |
||
1204 | |||
1205 | for(j=0;j<32;j++) { |
||
1206 | l1=*(b3+j); /* source */ |
||
1207 | l2=*(b3+32+j); /* mask */ |
||
1208 | l1=BE32(l1); |
||
1209 | l2=BE32(l2); |
||
1210 | *(unsigned long *)(LINEAR_POINTER+i+16*j)=~l2; |
||
1211 | *(unsigned long *)(LINEAR_POINTER+i+16*j+4)=0xffffffff; |
||
1212 | *(unsigned long *)(LINEAR_POINTER+i+16*j+8)=l1&l2; |
||
1213 | *(unsigned long *)(LINEAR_POINTER+i+16*j+12)=0; |
||
1214 | *(unsigned long *)(LINEAR_POINTER+i+512+16*j)=0xffffffff; |
||
1215 | *(unsigned long *)(LINEAR_POINTER+i+512+16*j+4)=0xffffffff; |
||
1216 | *(unsigned long *)(LINEAR_POINTER+i+512+16*j+8)=0; |
||
1217 | *(unsigned long *)(LINEAR_POINTER+i+512+16*j+12)=0; |
||
1218 | } |
||
1219 | break; |
||
1220 | } |
||
1221 | break; |
||
1222 | } |
||
1223 | return 0; |
||
1224 | } |
||
1225 | |||
1226 | static Emulation r128_emul = |
||
1227 | { |
||
1228 | 0, |
||
1229 | 0, |
||
1230 | 0, |
||
1231 | 0, |
||
1232 | 0, |
||
1233 | 0, |
||
1234 | 0, /* screenoff */ |
||
1235 | 0, /* screenon */ |
||
1236 | R128WaitForVerticalSync, /* waitretrace */ |
||
1237 | }; |
||
1238 | |||
1239 | static int r128_ext_set( unsigned what, va_list params ) |
||
1240 | { |
||
1241 | int param2; |
||
1242 | param2 = va_arg(params, int); |
||
1243 | |||
1244 | switch (what) { |
||
1245 | case VGA_EXT_AVAILABLE: |
||
1246 | switch (param2) { |
||
1247 | case VGA_AVAIL_SET: |
||
1248 | return VGA_EXT_AVAILABLE | VGA_EXT_SET | VGA_EXT_CLEAR | VGA_EXT_RESET; |
||
1249 | case VGA_AVAIL_ACCEL: |
||
1250 | return 0; |
||
1251 | case VGA_AVAIL_FLAGS: |
||
1252 | return VGA_CLUT8; |
||
1253 | } |
||
1254 | break; |
||
1255 | case VGA_EXT_SET: |
||
1256 | if (param2 & VGA_CLUT8) OUTREGP( R128_DAC_CNTL, R128_DAC_8BIT_EN, R128_DAC_MASK_ALL ); |
||
1257 | return 1; |
||
1258 | break; |
||
1259 | } |
||
1260 | return 0; |
||
1261 | } |
||
1262 | |||
1263 | /* Function table (exported) */ |
||
1264 | |||
1265 | DriverSpecs __svgalib_r128_driverspecs = |
||
1266 | { |
||
1267 | r128_saveregs, |
||
1268 | r128_setregs, |
||
1269 | r128_unlock, |
||
1270 | r128_lock, |
||
1271 | r128_test, |
||
1272 | r128_init, |
||
1273 | r128_setpage, |
||
1274 | NULL, |
||
1275 | NULL, |
||
1276 | r128_setmode, |
||
1277 | r128_modeavailable, |
||
1278 | r128_setdisplaystart, |
||
1279 | r128_setlogicalwidth, |
||
1280 | r128_getmodeinfo, |
||
1281 | 0, /* old blit funcs */ |
||
1282 | 0, |
||
1283 | 0, |
||
1284 | 0, |
||
1285 | 0, |
||
1286 | r128_ext_set, /* ext_set */ |
||
1287 | 0, /* accel */ |
||
1288 | r128_linear, |
||
1289 | 0, /* accelspecs, filled in during init. */ |
||
1290 | &r128_emul, /* Emulation */ |
||
1291 | r128_cursor, |
||
1292 | }; |
||
1293 | |||
1294 | #define VENDOR_ID 0x1002 |
||
1295 | |||
1296 | /* Initialize chipset (called after detection) */ |
||
1297 | static int r128_init(int force, int par1, int par2) |
||
1298 | { |
||
1299 | unsigned long buf[64]; |
||
1300 | int found=0, id, NOBIOS=0; |
||
1301 | unsigned char *BIOS_POINTER; |
||
115 | giacomo | 1302 | char chipnames[2][9]; |
1303 | |||
1304 | sprintf(chipnames[0],"Rage 128"); |
||
1305 | sprintf(chipnames[1],"Radeon"); |
||
74 | giacomo | 1306 | |
1307 | if (force) { |
||
1308 | r128_memory = par1; |
||
1309 | chiptype = par2; |
||
1310 | } else { |
||
1311 | |||
1312 | }; |
||
1313 | |||
1314 | found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0); |
||
1315 | |||
1316 | if(found) return 0; |
||
1317 | |||
1318 | chiptype=-1; |
||
1319 | id=(buf[0]>>16)&0xffff; |
||
1320 | |||
1321 | if( (id==0x4c45) || |
||
1322 | (id==0x4c56) || |
||
1323 | (id==0x4d46) || |
||
1324 | (id==0x4d4c) || |
||
1325 | ((id>>8)==0x50) || |
||
1326 | ((id>>8)==0x52) || |
||
1327 | ((id>>8)==0x53) || |
||
1328 | ((id>>8)==0x54)) |
||
1329 | chiptype=Rage128; |
||
1330 | |||
1331 | if( (id==0x4242) || |
||
1332 | (id==0x4c57) || |
||
1333 | (id==0x4c59) || |
||
1334 | (id==0x4c5a) || |
||
1335 | ((id>>8)==0x51)) |
||
1336 | chiptype = Radeon; |
||
1337 | |||
1338 | if(chiptype==-1) return 0; |
||
1339 | |||
1340 | r128_linear_base=buf[4]&0xffffff00; |
||
1341 | r128_mmio_base=buf[6]&0xffffff00; |
||
1342 | |||
1343 | MMIO_POINTER = (void *)r128_mmio_base; |
||
1344 | |||
1345 | r128_memory = INREG(R128_CONFIG_MEMSIZE) / 1024; |
||
1346 | BusCntl = INREG(R128_BUS_CNTL); |
||
1347 | HasPanelRegs = 0; |
||
1348 | CRTOnly = 1; |
||
1349 | r128_ramtype = 1; |
||
1350 | |||
1351 | #ifndef __PPC |
||
1352 | if(__svgalib_secondary) |
||
1353 | #endif |
||
1354 | NOBIOS=1; |
||
1355 | |||
1356 | if(NOBIOS) { |
||
1357 | int x_mpll_ref_fb_div, xclk_cntl, Nx, M; |
||
1358 | int PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12}; |
||
1359 | |||
1360 | switch(chiptype) { |
||
1361 | case Rage128: |
||
1362 | pll.reference_freq = 2950; |
||
1363 | pll.min_pll_freq = 12500; |
||
1364 | pll.max_pll_freq = 25000; |
||
1365 | pll.reference_div = INPLL(R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK; |
||
1366 | |||
1367 | x_mpll_ref_fb_div = INPLL(R128_X_MPLL_REF_FB_DIV); |
||
1368 | xclk_cntl = INPLL(R128_XCLK_CNTL) & 0x7; |
||
1369 | Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8; |
||
1370 | M = (x_mpll_ref_fb_div & 0x0000FF); |
||
1371 | pll.xclk = R128Div((2 * Nx * pll.reference_freq), |
||
1372 | (M * PostDivSet[xclk_cntl])); |
||
1373 | break; |
||
1374 | case Radeon: |
||
1375 | pll.reference_freq = 2700; |
||
1376 | pll.min_pll_freq = 12500; |
||
1377 | pll.max_pll_freq = 35000; |
||
1378 | pll.reference_div = 67; |
||
1379 | pll.xclk = 16667; |
||
1380 | break; |
||
1381 | } |
||
1382 | } else |
||
1383 | #define R128_BIOS16(x) (*(unsigned short *)(BIOS_POINTER + x)) |
||
1384 | #define R128_BIOS32(x) (*(unsigned int *)(BIOS_POINTER + x)) |
||
1385 | { |
||
1386 | uint16_t bios_header; |
||
1387 | uint16_t pll_info_block; |
||
1388 | BIOS_POINTER = (void *)0xc0000; |
||
1389 | bios_header = R128_BIOS16(0x48); |
||
1390 | pll_info_block = R128_BIOS16(bios_header + 0x30); |
||
1391 | pll.reference_freq = R128_BIOS16(pll_info_block + 0x0e); |
||
1392 | pll.reference_div = R128_BIOS16(pll_info_block + 0x10); |
||
1393 | pll.min_pll_freq = R128_BIOS32(pll_info_block + 0x12); |
||
1394 | pll.max_pll_freq = R128_BIOS32(pll_info_block + 0x16); |
||
1395 | pll.xclk = R128_BIOS16(pll_info_block + 0x08); |
||
1396 | } |
||
1397 | #if 1 |
||
1398 | printk(KERN_INFO "pll: %i %i %i %i %i\n",pll.reference_freq,pll.reference_div, |
||
1399 | pll.min_pll_freq, pll.max_pll_freq, pll.xclk); |
||
1400 | #endif |
||
1401 | |||
1402 | r128_mapio(); |
||
1403 | |||
1404 | if (__svgalib_driver_report) { |
||
1405 | printk(KERN_INFO "Using ATI %s driver, %iKB.\n",chipnames[chiptype],r128_memory); |
||
1406 | }; |
||
1407 | |||
1408 | __svgalib_modeinfo_linearset |= IS_LINEAR; |
||
1409 | |||
1410 | cardspecs = malloc(sizeof(CardSpecs)); |
||
1411 | cardspecs->videoMemory = r128_memory; |
||
1412 | cardspecs->maxPixelClock4bpp = 75000; |
||
1413 | cardspecs->maxPixelClock8bpp = 250000; |
||
1414 | cardspecs->maxPixelClock16bpp = 250000; |
||
1415 | cardspecs->maxPixelClock24bpp = 250000; |
||
1416 | cardspecs->maxPixelClock32bpp = 250000; |
||
1417 | cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE; |
||
1418 | cardspecs->maxHorizontalCrtc = 4080; |
||
1419 | cardspecs->maxPixelClock4bpp = 0; |
||
1420 | cardspecs->nClocks =0; |
||
1421 | cardspecs->mapClock = r128_map_clock; |
||
1422 | cardspecs->mapHorizontalCrtc = r128_map_horizontal_crtc; |
||
1423 | cardspecs->matchProgrammableClock=r128_match_programmable_clock; |
||
1424 | __svgalib_driverspecs = &__svgalib_r128_driverspecs; |
||
1425 | __svgalib_banked_mem_base=0xa0000; |
||
1426 | __svgalib_banked_mem_size=0x10000; |
||
1427 | __svgalib_linear_mem_base=r128_linear_base; |
||
1428 | __svgalib_linear_mem_size=r128_memory*0x400; |
||
1429 | __svgalib_mmio_base=r128_mmio_base; |
||
1430 | __svgalib_mmio_size=16*1024; |
||
1431 | if(chiptype==Radeon) { |
||
1432 | __svgalib_banked_mem_base=r128_linear_base; |
||
1433 | __svgalib_r128_driverspecs.__svgalib_setpage = __svgalib_emul_setpage; |
||
1434 | } |
||
1435 | |||
1436 | sleep(4); |
||
1437 | |||
1438 | return 1; |
||
1439 | } |