Mercurial > mplayer.hg
comparison drivers/radeon/radeonfb.c @ 2132:94617874ed1c
Imported some XFree86-CVS stuff
author | nick |
---|---|
date | Mon, 08 Oct 2001 08:22:32 +0000 |
parents | db1880f741d4 |
children | 96d1926373a1 |
comparison
equal
deleted
inserted
replaced
2131:b42efb0ddb82 | 2132:94617874ed1c |
---|---|
86 #define DEBUG 0 | 86 #define DEBUG 0 |
87 | 87 |
88 #if DEBUG | 88 #if DEBUG |
89 #define RTRACE printk | 89 #define RTRACE printk |
90 #else | 90 #else |
91 #define RTRACE if(0) printk | 91 #define RTRACE(...) ((void)0) |
92 #endif | 92 #endif |
93 | 93 |
94 | 94 |
95 | 95 |
96 enum radeon_chips { | 96 enum radeon_chips { |
155 typedef struct { | 155 typedef struct { |
156 u16 reg; | 156 u16 reg; |
157 u32 val; | 157 u32 val; |
158 } reg_val; | 158 } reg_val; |
159 | 159 |
160 | |
161 /* these common regs are cleared before mode setting so they do not | |
162 * interfere with anything | |
163 */ | |
164 reg_val common_regs[] = { | |
165 { OVR_CLR, 0 }, | |
166 { OVR_WID_LEFT_RIGHT, 0 }, | |
167 { OVR_WID_TOP_BOTTOM, 0 }, | |
168 { OV0_SCALE_CNTL, 0 }, | |
169 { SUBPIC_CNTL, 0 }, | |
170 { VIPH_CONTROL, 0 }, | |
171 { I2C_CNTL_1, 0 }, | |
172 { GEN_INT_CNTL, 0 }, | |
173 { CAP0_TRIG_CNTL, 0 }, | |
174 }; | |
175 | 160 |
176 #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0])) | 161 #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0])) |
177 | 162 |
178 typedef struct { | 163 typedef struct { |
179 u8 clock_chip_type; | 164 u8 clock_chip_type; |
222 int rloop; | 207 int rloop; |
223 }; | 208 }; |
224 | 209 |
225 | 210 |
226 struct radeon_regs { | 211 struct radeon_regs { |
212 /* Common registers */ | |
213 u32 ovr_clr; | |
214 u32 ovr_wid_left_right; | |
215 u32 ovr_wid_top_bottom; | |
216 u32 ov0_scale_cntl; | |
217 u32 mpp_tb_config; | |
218 u32 mpp_gp_config; | |
219 u32 subpic_cntl; | |
220 u32 viph_control; | |
221 u32 i2c_cntl_1; | |
222 u32 gen_int_cntl; | |
223 u32 cap0_trig_cntl; | |
224 u32 cap1_trig_cntl; | |
225 u32 bus_cntl; | |
226 /* Other registers to save for VT switches */ | |
227 u32 dp_datatype; | |
228 u32 rbbm_soft_reset; | |
229 u32 clock_cntl_index; | |
230 u32 amcgpio_en_reg; | |
231 u32 amcgpio_mask; | |
232 /* CRTC registers */ | |
233 u32 crtc_gen_cntl; | |
234 u32 crtc_ext_cntl; | |
235 u32 dac_cntl; | |
227 u32 crtc_h_total_disp; | 236 u32 crtc_h_total_disp; |
228 u32 crtc_h_sync_strt_wid; | 237 u32 crtc_h_sync_strt_wid; |
229 u32 crtc_v_total_disp; | 238 u32 crtc_v_total_disp; |
230 u32 crtc_v_sync_strt_wid; | 239 u32 crtc_v_sync_strt_wid; |
240 u32 crtc_offset; | |
241 u32 crtc_offset_cntl; | |
231 u32 crtc_pitch; | 242 u32 crtc_pitch; |
243 /* CRTC2 registers */ | |
244 u32 crtc2_gen_cntl; | |
245 u32 dac2_cntl; | |
246 u32 disp_output_cntl; | |
247 u32 crtc2_h_total_disp; | |
248 u32 crtc2_h_sync_strt_wid; | |
249 u32 crtc2_v_total_disp; | |
250 u32 crtc2_v_sync_strt_wid; | |
251 u32 crtc2_offset; | |
252 u32 crtc2_offset_cntl; | |
253 u32 crtc2_pitch; | |
254 /* Flat panel registers */ | |
255 u32 fp_crtc_h_total_disp; | |
256 u32 fp_crtc_v_total_disp; | |
257 u32 fp_gen_cntl; | |
258 u32 fp_h_sync_strt_wid; | |
259 u32 fp_horz_stretch; | |
260 u32 fp_panel_cntl; | |
261 u32 fp_v_sync_strt_wid; | |
262 u32 fp_vert_stretch; | |
263 u32 lvds_gen_cntl; | |
264 u32 lvds_pll_cntl; | |
265 u32 tmds_crc; | |
266 /* DDA registers */ | |
267 u32 dda_config; | |
268 u32 dda_on_off; | |
269 | |
270 /* Computed values for PLL */ | |
271 u32 dot_clock_freq; | |
272 u32 pll_output_freq; | |
273 int feedback_div; | |
274 int post_div; | |
275 /* PLL registers */ | |
276 u32 ppll_ref_div; | |
277 u32 ppll_div_3; | |
278 u32 htotal_cntl; | |
279 /* Computed values for PLL2 */ | |
280 u32 dot_clock_freq_2; | |
281 u32 pll_output_freq_2; | |
282 int feedback_div_2; | |
283 int post_div_2; | |
284 /* PLL2 registers */ | |
285 u32 p2pll_ref_div; | |
286 u32 p2pll_div_0; | |
287 u32 htotal_cntl2; | |
288 /* Pallet */ | |
289 int palette_valid; | |
290 u32 palette[256]; | |
291 u32 palette2[256]; | |
292 | |
232 u32 flags; | 293 u32 flags; |
233 u32 pix_clock; | 294 u32 pix_clock; |
234 int xres, yres; | 295 int xres, yres; |
235 int bpp; | 296 int bpp; |
236 u32 crtc_gen_cntl; | |
237 u32 crtc_ext_cntl; | |
238 #if defined(__BIG_ENDIAN) | 297 #if defined(__BIG_ENDIAN) |
239 u32 surface_cntl; | 298 u32 surface_cntl; |
240 #endif | 299 #endif |
241 u32 dac_cntl; | |
242 u32 dda_config; | |
243 u32 dda_on_off; | |
244 u32 ppll_div_3; | |
245 u32 ppll_ref_div; | |
246 }; | 300 }; |
247 | 301 |
248 | 302 |
249 struct radeonfb_info { | 303 struct radeonfb_info { |
250 struct fb_info info; | 304 struct fb_info info; |
258 int hasCRTC2; | 312 int hasCRTC2; |
259 int crtDispType; | 313 int crtDispType; |
260 int dviDispType; | 314 int dviDispType; |
261 int hasTVout; | 315 int hasTVout; |
262 int isM7; | 316 int isM7; |
317 int isM6; | |
263 int isR200; | 318 int isR200; |
264 int theatre_num; | 319 int theatre_num; |
320 /* Computed values for FPs */ | |
321 int PanelXRes; | |
322 int PanelYRes; | |
323 int HOverPlus; | |
324 int HSyncWidth; | |
325 int HBlank; | |
326 int VOverPlus; | |
327 int VSyncWidth; | |
328 int VBlank; | |
329 int PanelPwrDly; | |
265 | 330 |
266 u32 mmio_base_phys; | 331 u32 mmio_base_phys; |
267 u32 fb_base_phys; | 332 u32 fb_base_phys; |
268 | 333 |
269 u32 mmio_base; | 334 u32 mmio_base; |
270 u32 fb_base; | 335 u32 fb_base; |
336 | |
337 u32 MemCntl; | |
338 u32 BusCntl; | |
271 | 339 |
272 struct pci_dev *pdev; | 340 struct pci_dev *pdev; |
273 | 341 |
274 struct display disp; | 342 struct display disp; |
275 int currcon; | 343 int currcon; |
288 struct pll_info pll; | 356 struct pll_info pll; |
289 int pll_output_freq, post_div, fb_div; | 357 int pll_output_freq, post_div, fb_div; |
290 | 358 |
291 struct ram_info ram; | 359 struct ram_info ram; |
292 | 360 |
293 u32 hack_crtc_ext_cntl; | |
294 u32 hack_crtc_v_sync_strt_wid; | |
295 #ifdef CONFIG_MTRR | 361 #ifdef CONFIG_MTRR |
296 struct { int vram; int vram_valid; } mtrr; | 362 struct { int vram; int vram_valid; } mtrr; |
297 #endif | 363 #endif |
298 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32) | 364 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32) |
299 union { | 365 union { |
308 #endif | 374 #endif |
309 } con_cmap; | 375 } con_cmap; |
310 #endif | 376 #endif |
311 }; | 377 }; |
312 | 378 |
379 #define SINGLE_MONITOR(rinfo) (rinfo->crtDispType == MT_NONE || rinfo->dviDispType == MT_NONE) | |
380 /*#define DUAL_MONITOR(rinfo) (rinfo->crtDispType != MT_NONE && rinfo->dviDispType != MT_NONE)*/ | |
381 /* Disable DUAL monitor support for now */ | |
382 #define DUAL_MONITOR(rinfo) (0) | |
383 #define PRIMARY_MONITOR(rinfo) (rinfo->dviDispType != MT_NONE && rinfo->dviDispType != MT_STV && rinfo->dviDispType != MT_CTV ? rinfo->dviDispType : rinfo->crtDispType) | |
313 | 384 |
314 static struct fb_var_screeninfo radeonfb_default_var = { | 385 static struct fb_var_screeninfo radeonfb_default_var = { |
315 640, 480, 640, 480, 0, 0, 8, 0, | 386 640, 480, 640, 480, 0, 0, 8, 0, |
316 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, | 387 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, |
317 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2, | 388 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2, |
352 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f); | 423 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f); |
353 return (INREG(CLOCK_CNTL_DATA)); | 424 return (INREG(CLOCK_CNTL_DATA)); |
354 } | 425 } |
355 | 426 |
356 #define INPLL(addr) _INPLL(rinfo, addr) | 427 #define INPLL(addr) _INPLL(rinfo, addr) |
428 | |
429 static __inline__ u8 radeon_get_post_div_bitval(int post_div) | |
430 { | |
431 switch (post_div) { | |
432 case 1: | |
433 return 0x00; | |
434 case 2: | |
435 return 0x01; | |
436 case 3: | |
437 return 0x04; | |
438 case 4: | |
439 return 0x02; | |
440 case 6: | |
441 return 0x06; | |
442 case 8: | |
443 return 0x03; | |
444 case 12: | |
445 return 0x07; | |
446 default: | |
447 return 0x02; | |
448 } | |
449 } | |
450 | |
451 | |
452 | |
453 static __inline__ int round_div(int num, int den) | |
454 { | |
455 return (num + (den / 2)) / den; | |
456 } | |
457 | |
458 | |
459 | |
460 static __inline__ int min_bits_req(int val) | |
461 { | |
462 int bits_req = 0; | |
463 | |
464 if (val == 0) | |
465 bits_req = 1; | |
466 | |
467 while (val) { | |
468 val >>= 1; | |
469 bits_req++; | |
470 } | |
471 | |
472 return (bits_req); | |
473 } | |
474 | |
475 | |
476 static __inline__ int _max(int val1, int val2) | |
477 { | |
478 if (val1 >= val2) | |
479 return val1; | |
480 else | |
481 return val2; | |
482 } | |
357 | 483 |
358 | 484 |
359 /* | 485 /* |
360 * 2D engine routines | 486 * 2D engine routines |
361 */ | 487 */ |
475 | 601 |
476 return; | 602 return; |
477 } | 603 } |
478 | 604 |
479 #define radeon_engine_reset() _radeon_engine_reset(rinfo) | 605 #define radeon_engine_reset() _radeon_engine_reset(rinfo) |
480 | |
481 | |
482 static __inline__ u8 radeon_get_post_div_bitval(int post_div) | |
483 { | |
484 switch (post_div) { | |
485 case 1: | |
486 return 0x00; | |
487 case 2: | |
488 return 0x01; | |
489 case 3: | |
490 return 0x04; | |
491 case 4: | |
492 return 0x02; | |
493 case 6: | |
494 return 0x06; | |
495 case 8: | |
496 return 0x03; | |
497 case 12: | |
498 return 0x07; | |
499 default: | |
500 return 0x02; | |
501 } | |
502 } | |
503 | |
504 | |
505 | |
506 static __inline__ int round_div(int num, int den) | |
507 { | |
508 return (num + (den / 2)) / den; | |
509 } | |
510 | |
511 | |
512 | |
513 static __inline__ int min_bits_req(int val) | |
514 { | |
515 int bits_req = 0; | |
516 | |
517 if (val == 0) | |
518 bits_req = 1; | |
519 | |
520 while (val) { | |
521 val >>= 1; | |
522 bits_req++; | |
523 } | |
524 | |
525 return (bits_req); | |
526 } | |
527 | |
528 | |
529 static __inline__ int _max(int val1, int val2) | |
530 { | |
531 if (val1 >= val2) | |
532 return val1; | |
533 else | |
534 return val2; | |
535 } | |
536 | |
537 | |
538 | 606 |
539 /* | 607 /* |
540 * globals | 608 * globals |
541 */ | 609 */ |
542 | 610 |
581 unsigned *blue, unsigned *transp, | 649 unsigned *blue, unsigned *transp, |
582 struct fb_info *info); | 650 struct fb_info *info); |
583 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, | 651 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, |
584 unsigned blue, unsigned transp, struct fb_info *info); | 652 unsigned blue, unsigned transp, struct fb_info *info); |
585 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp); | 653 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp); |
654 static void radeon_save_mode (struct radeonfb_info *rinfo, | |
655 struct radeon_regs *save); | |
586 static void radeon_save_state (struct radeonfb_info *rinfo, | 656 static void radeon_save_state (struct radeonfb_info *rinfo, |
587 struct radeon_regs *save); | 657 struct radeon_regs *save); |
588 static void radeon_engine_init (struct radeonfb_info *rinfo); | 658 static void radeon_engine_init (struct radeonfb_info *rinfo); |
589 static void radeon_load_video_mode (struct radeonfb_info *rinfo, | 659 static int radeon_load_video_mode (struct radeonfb_info *rinfo, |
590 struct fb_var_screeninfo *mode); | 660 struct fb_var_screeninfo *mode); |
591 static void radeon_write_mode (struct radeonfb_info *rinfo, | 661 static void radeon_write_mode (struct radeonfb_info *rinfo, |
662 struct radeon_regs *mode); | |
663 static void radeon_write_state (struct radeonfb_info *rinfo, | |
592 struct radeon_regs *mode); | 664 struct radeon_regs *mode); |
593 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo); | 665 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo); |
594 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo); | 666 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo); |
595 static int radeon_init_disp_var (struct radeonfb_info *rinfo); | 667 static int radeon_init_disp_var (struct radeonfb_info *rinfo); |
596 static int radeonfb_pci_register (struct pci_dev *pdev, | 668 static int radeonfb_pci_register (struct pci_dev *pdev, |
955 rinfo->hasCRTC2 = 1; | 1027 rinfo->hasCRTC2 = 1; |
956 strcpy(rinfo->name, "Radeon VE QZ "); | 1028 strcpy(rinfo->name, "Radeon VE QZ "); |
957 break; | 1029 break; |
958 case PCI_DEVICE_ID_RADEON_LY: | 1030 case PCI_DEVICE_ID_RADEON_LY: |
959 rinfo->hasCRTC2 = 1; | 1031 rinfo->hasCRTC2 = 1; |
1032 rinfo->isM6 = 1; | |
960 strcpy(rinfo->name, "Radeon M6 LY "); | 1033 strcpy(rinfo->name, "Radeon M6 LY "); |
961 break; | 1034 break; |
962 case PCI_DEVICE_ID_RADEON_LZ: | 1035 case PCI_DEVICE_ID_RADEON_LZ: |
963 rinfo->hasCRTC2 = 1; | 1036 rinfo->hasCRTC2 = 1; |
1037 rinfo->isM6 = 1; | |
964 strcpy(rinfo->name, "Radeon M6 LZ "); | 1038 strcpy(rinfo->name, "Radeon M6 LZ "); |
965 break; | 1039 break; |
966 case PCI_DEVICE_ID_RADEON_LW: | 1040 case PCI_DEVICE_ID_RADEON_LW: |
967 /* Note: Only difference between VE,M6 and M7 is initialization CRTC2 | 1041 /* Note: Only difference between VE,M6 and M7 is initialization CRTC2 |
968 registers in dual monitor configuration!!! */ | 1042 registers in dual monitor configuration!!! */ |
994 | 1068 |
995 /* mem size is bits [28:0], mask off the rest */ | 1069 /* mem size is bits [28:0], mask off the rest */ |
996 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; | 1070 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; |
997 | 1071 |
998 /* ram type */ | 1072 /* ram type */ |
999 tmp = INREG(MEM_SDRAM_MODE_REG); | 1073 rinfo->MemCntl = INREG(MEM_SDRAM_MODE_REG); |
1000 switch ((MEM_CFG_TYPE & tmp) >> 30) { | 1074 switch ((MEM_CFG_TYPE & rinfo->MemCntl) >> 30) { |
1001 case 0: | 1075 case 0: |
1002 /* SDR SGRAM (2:1) */ | 1076 /* SDR SGRAM (2:1) */ |
1003 strcpy(rinfo->ram_type, "SDR SGRAM"); | 1077 strcpy(rinfo->ram_type, "SDR SGRAM"); |
1004 rinfo->ram.ml = 4; | 1078 rinfo->ram.ml = 4; |
1005 rinfo->ram.mb = 4; | 1079 rinfo->ram.mb = 4; |
1038 rinfo->ram.loop_latency = 17; | 1112 rinfo->ram.loop_latency = 17; |
1039 rinfo->ram.rloop = 17; | 1113 rinfo->ram.rloop = 17; |
1040 | 1114 |
1041 break; | 1115 break; |
1042 } | 1116 } |
1117 /* Bus type */ | |
1118 rinfo->BusCntl = INREG(BUS_CNTL); | |
1043 | 1119 |
1044 bios_seg = radeon_find_rom(rinfo); | 1120 bios_seg = radeon_find_rom(rinfo); |
1045 radeon_get_pllinfo(rinfo, bios_seg); | 1121 radeon_get_pllinfo(rinfo, bios_seg); |
1046 | 1122 |
1047 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n", | 1123 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n", |
1200 | 1276 |
1201 if (!rinfo) | 1277 if (!rinfo) |
1202 return; | 1278 return; |
1203 | 1279 |
1204 /* restore original state */ | 1280 /* restore original state */ |
1205 radeon_write_mode (rinfo, &rinfo->init_state); | 1281 radeon_write_state (rinfo, &rinfo->init_state); |
1206 | 1282 |
1207 unregister_framebuffer ((struct fb_info *) rinfo); | 1283 unregister_framebuffer ((struct fb_info *) rinfo); |
1208 #ifdef CONFIG_MTRR | 1284 #ifdef CONFIG_MTRR |
1209 if (rinfo->mtrr.vram_valid) | 1285 if (rinfo->mtrr.vram_valid) |
1210 mtrr_del(rinfo->mtrr.vram, rinfo->fb_base_phys, | 1286 mtrr_del(rinfo->mtrr.vram, rinfo->fb_base_phys, |
1323 rinfo->pll.ppll_min = 12000; | 1399 rinfo->pll.ppll_min = 12000; |
1324 rinfo->pll.xclk = 16600; | 1400 rinfo->pll.xclk = 16600; |
1325 rinfo->pll.ref_div = 67; | 1401 rinfo->pll.ref_div = 67; |
1326 rinfo->pll.ref_clk = 2700; | 1402 rinfo->pll.ref_clk = 2700; |
1327 } | 1403 } |
1404 } | |
1405 | |
1406 static void radeon_init_common_regs(struct radeonfb_info *rinfo, | |
1407 struct radeon_regs *save) | |
1408 { | |
1409 RTRACE("radeonfb: radeon_init_common_regs is called\n"); | |
1410 save->ovr_clr = 0; | |
1411 save->ovr_wid_left_right= 0; | |
1412 save->ovr_wid_top_bottom= 0; | |
1413 save->ov0_scale_cntl = 0; | |
1414 save->mpp_tb_config = 0; | |
1415 save->mpp_gp_config = 0; | |
1416 save->subpic_cntl = 0; | |
1417 save->viph_control = 0; | |
1418 save->i2c_cntl_1 = 0; | |
1419 save->rbbm_soft_reset = 0; | |
1420 save->cap0_trig_cntl = 0; | |
1421 save->cap1_trig_cntl = 0; | |
1422 save->bus_cntl = rinfo->BusCntl; | |
1423 /* | |
1424 * If bursts are enabled, turn on discards | |
1425 * Radeon doesn't have write bursts | |
1426 | |
1427 * XXX: Disabled by NK since on Radeon VE it causes | |
1428 * mode corruption. | |
1429 if (save->bus_cntl & (BUS_READ_BURST)) | |
1430 save->bus_cntl |= BUS_RD_DISCARD_EN; | |
1431 */ | |
1432 } | |
1433 #if 0 | |
1434 static int radeon_init_crtc_regs(struct radeonfb_info *rinfo, | |
1435 struct radeon_regs *save, | |
1436 struct fb_var_screeninfo *mode) | |
1437 { | |
1438 int format; | |
1439 int hsync_start; | |
1440 int hsync_wid; | |
1441 int hsync_fudge; | |
1442 int vsync_wid; | |
1443 int bytpp; | |
1444 int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; | |
1445 int hsync_fudge_fp[] = { 0x02, 0x02, 0x00, 0x00, 0x05, 0x05 }; | |
1446 int prim_mon; | |
1447 int hTotal, vTotal, hSyncStart, hSyncEnd; | |
1448 int vSyncStart, vSyncEnd; | |
1449 RTRACE("radeonfb: radeon_init_crtc_regs is called\n"); | |
1450 | |
1451 switch (mode->bits_per_pixel) { | |
1452 case 8: format = 2; bytpp = 1; break; | |
1453 case 16: format = 4; bytpp = 2; break; /* 565 */ | |
1454 case 24: format = 5; bytpp = 3; break; /* RGB */ | |
1455 case 32: format = 6; bytpp = 4; break; /* xRGB */ | |
1456 default: | |
1457 printk("radeonfb: Unsupported pixel depth (%d)\n", mode->bits_per_pixel); | |
1458 return 0; | |
1459 } | |
1460 prim_mon = PRIMARY_MONITOR(rinfo); | |
1461 if ((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) | |
1462 hsync_fudge = hsync_fudge_fp[format-1]; | |
1463 else | |
1464 hsync_fudge = hsync_fudge_default[format-1]; | |
1465 | |
1466 save->crtc_gen_cntl = (CRTC_EXT_DISP_EN | |
1467 | CRTC_EN | |
1468 | (format << 8) | |
1469 /* | CRTC_DBL_SCAN_EN*/); | |
1470 | |
1471 if((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) | |
1472 { | |
1473 save->crtc_ext_cntl = VGA_ATI_LINEAR | | |
1474 XCRT_CNT_EN; | |
1475 save->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | | |
1476 CRTC_INTERLACE_EN); | |
1477 } | |
1478 else | |
1479 save->crtc_ext_cntl = VGA_ATI_LINEAR | | |
1480 XCRT_CNT_EN | | |
1481 CRTC_CRT_ON; | |
1482 | |
1483 save->dac_cntl = (DAC_MASK_ALL | |
1484 | DAC_VGA_ADR_EN | |
1485 | DAC_8BIT_EN); | |
1486 | |
1487 rinfo->xres = mode->xres; | |
1488 rinfo->yres = mode->yres; | |
1489 rinfo->pixclock = mode->pixclock; | |
1490 | |
1491 hSyncStart = mode->xres + mode->right_margin; | |
1492 hSyncEnd = hSyncStart + mode->hsync_len; | |
1493 hTotal = hSyncEnd + mode->left_margin; | |
1494 | |
1495 vSyncStart = mode->yres + mode->lower_margin; | |
1496 vSyncEnd = vSyncStart + mode->vsync_len; | |
1497 vTotal = vSyncEnd + mode->upper_margin; | |
1498 | |
1499 if(((prim_mon == MT_DFP) || (prim_mon == MT_LCD))) | |
1500 { | |
1501 if(rinfo->PanelXRes < mode->xres) | |
1502 rinfo->xres = mode->xres = rinfo->PanelXRes; | |
1503 if(rinfo->PanelYRes < mode->yres) | |
1504 rinfo->yres = mode->yres = rinfo->PanelYRes; | |
1505 hTotal = mode->xres + rinfo->HBlank + mode->left_margin; | |
1506 hSyncStart = mode->xres + rinfo->HOverPlus + mode->right_margin; | |
1507 hSyncEnd = hSyncStart + rinfo->HSyncWidth + mode->hsync_len; | |
1508 vTotal = mode->yres + rinfo->VBlank + mode->upper_margin; | |
1509 vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin; | |
1510 vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len; | |
1511 } | |
1512 | |
1513 save->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | |
1514 | ((((mode->xres / 8) - 1) & 0x1ff) << 16)); | |
1515 | |
1516 hsync_wid = (hSyncEnd - hSyncStart) / 8; | |
1517 if (!hsync_wid) hsync_wid = 1; | |
1518 if (hsync_wid > 0x3f) hsync_wid = 0x3f; | |
1519 hsync_start = hSyncStart - 8 + hsync_fudge; | |
1520 | |
1521 save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | |
1522 | (hsync_wid << 16) | |
1523 | ((mode->sync & FB_SYNC_HOR_HIGH_ACT) | |
1524 ? 0 | |
1525 : CRTC_H_SYNC_POL)); | |
1526 | |
1527 /* This works for double scan mode. */ | |
1528 save->crtc_v_total_disp = (((vTotal - 1) & 0xffff) | |
1529 | ((mode->yres - 1) << 16)); | |
1530 | |
1531 vsync_wid = vSyncEnd - vSyncStart; | |
1532 if (!vsync_wid) vsync_wid = 1; | |
1533 if (vsync_wid > 0x1f) vsync_wid = 0x1f; | |
1534 | |
1535 save->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | |
1536 | (vsync_wid << 16) | |
1537 | ((mode->sync & FB_SYNC_VERT_HIGH_ACT) | |
1538 ? 0 | |
1539 : CRTC_V_SYNC_POL)); | |
1540 | |
1541 save->crtc_offset = 0; | |
1542 save->crtc_offset_cntl = 0; | |
1543 | |
1544 save->crtc_pitch = ((mode->xres * bytpp) + | |
1545 ((mode->bits_per_pixel) - 1)) / | |
1546 (mode->bits_per_pixel); | |
1547 save->crtc_pitch |= save->crtc_pitch << 16; | |
1548 | |
1549 save->xres = mode->xres; | |
1550 save->yres = mode->yres; | |
1551 | |
1552 RTRACE("radeonfb: radeon_init_crtc_regs returns SUCCESS\n"); | |
1553 return 1; | |
1554 } | |
1555 #endif | |
1556 static int radeon_init_crtc_regs(struct radeonfb_info *rinfo, | |
1557 struct radeon_regs *save, | |
1558 struct fb_var_screeninfo *mode) | |
1559 { | |
1560 int hTotal, vTotal, hSyncStart, hSyncEnd, | |
1561 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync; | |
1562 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; | |
1563 u8 hsync_fudge_fp[] = { 2, 2, 0, 0, 5, 5 }; | |
1564 u32 sync, h_sync_pol, v_sync_pol; | |
1565 int format = 0; | |
1566 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid; | |
1567 int prim_mon; | |
1568 | |
1569 prim_mon = PRIMARY_MONITOR(rinfo); | |
1570 | |
1571 rinfo->xres = mode->xres; | |
1572 rinfo->yres = mode->yres; | |
1573 rinfo->pixclock = mode->pixclock; | |
1574 | |
1575 hSyncStart = mode->xres + mode->right_margin; | |
1576 hSyncEnd = hSyncStart + mode->hsync_len; | |
1577 hTotal = hSyncEnd + mode->left_margin; | |
1578 | |
1579 vSyncStart = mode->yres + mode->lower_margin; | |
1580 vSyncEnd = vSyncStart + mode->vsync_len; | |
1581 vTotal = vSyncEnd + mode->upper_margin; | |
1582 | |
1583 sync = mode->sync; | |
1584 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | |
1585 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; | |
1586 | |
1587 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n", | |
1588 hSyncStart, hSyncEnd, hTotal); | |
1589 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n", | |
1590 vSyncStart, vSyncEnd, vTotal); | |
1591 | |
1592 hsync_wid = (hSyncEnd - hSyncStart) / 8; | |
1593 vsync_wid = vSyncEnd - vSyncStart; | |
1594 if (hsync_wid == 0) | |
1595 hsync_wid = 1; | |
1596 else if (hsync_wid > 0x3f) /* max */ | |
1597 hsync_wid = 0x3f; | |
1598 vsync_wid = mode->vsync_len; | |
1599 if (vsync_wid == 0) | |
1600 vsync_wid = 1; | |
1601 else if (vsync_wid > 0x1f) /* max */ | |
1602 vsync_wid = 0x1f; | |
1603 | |
1604 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | |
1605 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; | |
1606 | |
1607 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; | |
1608 | |
1609 switch (mode->bits_per_pixel) { | |
1610 case 8: | |
1611 format = DST_8BPP; | |
1612 bytpp = 1; | |
1613 break; | |
1614 case 16: | |
1615 format = DST_16BPP; | |
1616 bytpp = 2; | |
1617 break; | |
1618 case 24: | |
1619 format = DST_24BPP; | |
1620 bytpp = 3; | |
1621 break; | |
1622 case 32: | |
1623 format = DST_32BPP; | |
1624 bytpp = 4; | |
1625 break; | |
1626 } | |
1627 | |
1628 if ((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) | |
1629 hsync_fudge = hsync_fudge_fp[format-1]; | |
1630 else | |
1631 hsync_fudge = hsync_adj_tab[format-1]; | |
1632 | |
1633 hsync_start = hSyncStart - 8 + hsync_fudge; | |
1634 save->crtc_gen_cntl = (CRTC_EXT_DISP_EN | |
1635 | CRTC_EN | |
1636 | (format << 8) | |
1637 /* | CRTC_DBL_SCAN_EN*/); | |
1638 | |
1639 if((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) | |
1640 { | |
1641 save->crtc_ext_cntl = VGA_ATI_LINEAR | | |
1642 XCRT_CNT_EN; | |
1643 save->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | | |
1644 CRTC_INTERLACE_EN); | |
1645 } | |
1646 else | |
1647 save->crtc_ext_cntl = VGA_ATI_LINEAR | | |
1648 XCRT_CNT_EN | | |
1649 CRTC_CRT_ON; | |
1650 | |
1651 save->dac_cntl = (DAC_MASK_ALL | |
1652 | DAC_VGA_ADR_EN | |
1653 | DAC_8BIT_EN); | |
1654 | |
1655 save->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | | |
1656 ((((mode->xres / 8) - 1) & 0x1ff) << 16)); | |
1657 | |
1658 save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | | |
1659 (hsync_wid << 16) | (h_sync_pol << 23)); | |
1660 | |
1661 save->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | | |
1662 ((mode->yres - 1) << 16); | |
1663 | |
1664 save->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | | |
1665 (vsync_wid << 16) | (v_sync_pol << 23)); | |
1666 | |
1667 save->crtc_pitch = (mode->xres >> 3); | |
1668 | |
1669 #if defined(__BIG_ENDIAN) | |
1670 save->surface_cntl = SURF_TRANSLATION_DIS; | |
1671 switch (mode->bits_per_pixel) { | |
1672 case 16: | |
1673 save->surface_cntl |= NONSURF_AP0_SWP_16BPP; | |
1674 break; | |
1675 case 24: | |
1676 case 32: | |
1677 save->surface_cntl |= NONSURF_AP0_SWP_32BPP; | |
1678 break; | |
1679 } | |
1680 #endif | |
1681 | |
1682 rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f) | |
1683 & ~(0x3f)) / 64; | |
1684 | |
1685 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n", | |
1686 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid); | |
1687 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n", | |
1688 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid); | |
1689 | |
1690 save->xres = mode->xres; | |
1691 save->yres = mode->yres; | |
1692 | |
1693 save->crtc_offset = 0; | |
1694 save->crtc_offset_cntl = 0; | |
1695 | |
1696 rinfo->bpp = mode->bits_per_pixel; | |
1697 return 0; | |
1698 } | |
1699 | |
1700 static int radeon_init_crtc2_regs(struct radeonfb_info *rinfo, | |
1701 struct radeon_regs *save, | |
1702 struct fb_var_screeninfo *mode) | |
1703 { | |
1704 int format; | |
1705 int hsync_start; | |
1706 int hsync_wid; | |
1707 int hsync_fudge; | |
1708 int vsync_wid; | |
1709 int bytpp; | |
1710 int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; | |
1711 int hTotal, vTotal, hSyncStart, hSyncEnd; | |
1712 int vSyncStart, vSyncEnd; | |
1713 RTRACE("radeonfb: radeon_init_crtc2_regs is called\n"); | |
1714 | |
1715 switch (mode->bits_per_pixel) { | |
1716 case 8: format = 2; bytpp = 1; break; | |
1717 case 16: format = 4; bytpp = 2; break; /* 565 */ | |
1718 case 24: format = 5; bytpp = 3; break; /* RGB */ | |
1719 case 32: format = 6; bytpp = 4; break; /* xRGB */ | |
1720 default: | |
1721 printk("radeonfb: Unsupported pixel depth (%d)\n", mode->bits_per_pixel); | |
1722 return 0; | |
1723 } | |
1724 | |
1725 hsync_fudge = hsync_fudge_default[format-1]; | |
1726 | |
1727 save->crtc2_gen_cntl = (CRTC2_EN | |
1728 | CRTC2_CRT2_ON | |
1729 | (format << 8) | |
1730 /*| CRTC2_DBL_SCAN_EN*/); | |
1731 | |
1732 if(!rinfo->isM7) | |
1733 save->dac2_cntl = rinfo->init_state.dac2_cntl | |
1734 /*| DAC2_DAC2_CLK_SEL*/ | |
1735 | DAC2_DAC_CLK_SEL; | |
1736 else | |
1737 { | |
1738 save->disp_output_cntl = | |
1739 ((rinfo->init_state.disp_output_cntl & | |
1740 (u32)~DISP_DAC_SOURCE_MASK) | |
1741 | DISP_DAC_SOURCE_CRTC2); | |
1742 } | |
1743 | |
1744 hSyncStart = mode->xres + mode->right_margin; | |
1745 hSyncEnd = hSyncStart + mode->hsync_len; | |
1746 hTotal = hSyncEnd + mode->left_margin; | |
1747 | |
1748 vSyncStart = mode->yres + mode->lower_margin; | |
1749 vSyncEnd = vSyncStart + mode->vsync_len; | |
1750 vTotal = vSyncEnd + mode->upper_margin; | |
1751 | |
1752 save->crtc2_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | |
1753 | ((((mode->xres / 8) - 1) & 0x1ff) << 16)); | |
1754 | |
1755 hsync_wid = (hSyncEnd - hSyncStart) / 8; | |
1756 if (!hsync_wid) hsync_wid = 1; | |
1757 if (hsync_wid > 0x3f) hsync_wid = 0x3f; | |
1758 hsync_start = hSyncStart - 8 + hsync_fudge; | |
1759 | |
1760 save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff) | |
1761 | (hsync_wid << 16) | |
1762 | ((mode->sync & FB_SYNC_HOR_HIGH_ACT) | |
1763 ? 0 | |
1764 : CRTC_H_SYNC_POL)); | |
1765 | |
1766 /* This works for double scan mode. */ | |
1767 save->crtc2_v_total_disp = (((vTotal - 1) & 0xffff) | |
1768 | ((mode->yres - 1) << 16)); | |
1769 | |
1770 vsync_wid = vSyncEnd - vSyncStart; | |
1771 if (!vsync_wid) vsync_wid = 1; | |
1772 if (vsync_wid > 0x1f) vsync_wid = 0x1f; | |
1773 | |
1774 save->crtc2_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | |
1775 | (vsync_wid << 16) | |
1776 | ((mode->sync & FB_SYNC_VERT_HIGH_ACT) | |
1777 ? 0 | |
1778 : CRTC2_V_SYNC_POL)); | |
1779 | |
1780 save->crtc2_offset = 0; | |
1781 save->crtc2_offset_cntl = 0; | |
1782 | |
1783 save->crtc2_pitch = ((mode->xres * bytpp) + | |
1784 ((mode->bits_per_pixel) -1)) / | |
1785 (mode->bits_per_pixel); | |
1786 save->crtc2_pitch |= save->crtc2_pitch << 16; | |
1787 | |
1788 RTRACE("radeonfb: radeon_init_crtc2_regs returns SUCCESS\n"); | |
1789 return 1; | |
1790 } | |
1791 | |
1792 static void radeon_init_fp_regs(struct radeonfb_info *rinfo, | |
1793 struct radeon_regs *save, | |
1794 struct fb_var_screeninfo *mode) | |
1795 { | |
1796 float Hratio, Vratio; | |
1797 int prim_mon; | |
1798 RTRACE("radeonfb: radeon_init_fp_regs is called\n"); | |
1799 if(rinfo->PanelXRes == 0 || rinfo->PanelYRes == 0) | |
1800 { | |
1801 Hratio = 1; | |
1802 Vratio = 1; | |
1803 } | |
1804 else | |
1805 { | |
1806 if (mode->xres > rinfo->PanelXRes) mode->xres = rinfo->PanelXRes; | |
1807 if (mode->yres > rinfo->PanelYRes) mode->yres = rinfo->PanelYRes; | |
1808 | |
1809 Hratio = (float)mode->xres/(float)rinfo->PanelXRes; | |
1810 Vratio = (float)mode->yres/(float)rinfo->PanelYRes; | |
1811 } | |
1812 | |
1813 if (Hratio == 1.0) | |
1814 { | |
1815 save->fp_horz_stretch = rinfo->init_state.fp_horz_stretch; | |
1816 save->fp_horz_stretch &= ~(HORZ_STRETCH_BLEND | | |
1817 HORZ_STRETCH_ENABLE); | |
1818 } | |
1819 else | |
1820 { | |
1821 save->fp_horz_stretch = | |
1822 ((((unsigned long)(Hratio * HORZ_STRETCH_RATIO_MAX + | |
1823 0.5)) & HORZ_STRETCH_RATIO_MASK)) | | |
1824 (rinfo->init_state.fp_horz_stretch & (HORZ_PANEL_SIZE | | |
1825 HORZ_FP_LOOP_STRETCH | | |
1826 HORZ_AUTO_RATIO_INC)); | |
1827 save->fp_horz_stretch |= (HORZ_STRETCH_BLEND | | |
1828 HORZ_STRETCH_ENABLE); | |
1829 } | |
1830 save->fp_horz_stretch &= ~HORZ_AUTO_RATIO; | |
1831 | |
1832 if (Vratio == 1.0) | |
1833 { | |
1834 save->fp_vert_stretch = rinfo->init_state.fp_vert_stretch; | |
1835 save->fp_vert_stretch &= ~(VERT_STRETCH_ENABLE| | |
1836 VERT_STRETCH_BLEND); | |
1837 } | |
1838 else | |
1839 { | |
1840 save->fp_vert_stretch = | |
1841 (((((unsigned long)(Vratio * VERT_STRETCH_RATIO_MAX + | |
1842 0.5)) & VERT_STRETCH_RATIO_MASK)) | | |
1843 (rinfo->init_state.fp_vert_stretch & (VERT_PANEL_SIZE | | |
1844 VERT_STRETCH_RESERVED))); | |
1845 save->fp_vert_stretch |= (VERT_STRETCH_ENABLE | | |
1846 VERT_STRETCH_BLEND); | |
1847 } | |
1848 save->fp_vert_stretch &= ~VERT_AUTO_RATIO_EN; | |
1849 | |
1850 save->fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32) | |
1851 ~(FP_SEL_CRTC2 | | |
1852 FP_RMX_HVSYNC_CONTROL_EN | | |
1853 FP_DFP_SYNC_SEL | | |
1854 FP_CRT_SYNC_SEL | | |
1855 FP_CRTC_LOCK_8DOT | | |
1856 FP_USE_SHADOW_EN | | |
1857 FP_CRTC_USE_SHADOW_VEND | | |
1858 FP_CRT_SYNC_ALT)); | |
1859 save->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | | |
1860 FP_CRTC_DONT_SHADOW_HEND ); | |
1861 | |
1862 save->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl; | |
1863 save->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl; | |
1864 save->tmds_crc = rinfo->init_state.tmds_crc; | |
1865 | |
1866 /* Disable CRT output by disabling CRT output for DFP*/ | |
1867 save->crtc_ext_cntl &= ~CRTC_CRT_ON; | |
1868 prim_mon = PRIMARY_MONITOR(rinfo); | |
1869 if(prim_mon == MT_LCD) | |
1870 { | |
1871 save->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); | |
1872 save->fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN); | |
1873 } | |
1874 else if(prim_mon == MT_DFP) | |
1875 save->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN); | |
1876 | |
1877 save->fp_crtc_h_total_disp = rinfo->init_state.fp_crtc_h_total_disp; | |
1878 save->fp_crtc_v_total_disp = rinfo->init_state.fp_crtc_v_total_disp; | |
1879 save->fp_h_sync_strt_wid = rinfo->init_state.fp_h_sync_strt_wid; | |
1880 save->fp_v_sync_strt_wid = rinfo->init_state.fp_v_sync_strt_wid; | |
1881 } | |
1882 | |
1883 static void radeon_init_pll_regs(struct radeonfb_info *rinfo, | |
1884 struct radeon_regs *save, | |
1885 struct fb_var_screeninfo *mode) | |
1886 { | |
1887 u32 dot_clock = 1000000000 / mode->pixclock; | |
1888 u32 freq = dot_clock / 10; /* x 100 */ | |
1889 struct { | |
1890 int divider; | |
1891 int bitvalue; | |
1892 } *post_div, post_divs[] = { | |
1893 { 1, 0 }, | |
1894 { 2, 1 }, | |
1895 { 4, 2 }, | |
1896 { 8, 3 }, | |
1897 { 3, 4 }, | |
1898 { 16, 5 }, | |
1899 { 6, 6 }, | |
1900 { 12, 7 }, | |
1901 { 0, 0 }, | |
1902 }; | |
1903 if (freq > rinfo->pll.ppll_max) freq = rinfo->pll.ppll_max; | |
1904 if (freq*12 < rinfo->pll.ppll_min) freq = rinfo->pll.ppll_min / 12; | |
1905 | |
1906 for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | |
1907 rinfo->pll_output_freq = post_div->divider * freq; | |
1908 if (rinfo->pll_output_freq >= rinfo->pll.ppll_min && | |
1909 rinfo->pll_output_freq <= rinfo->pll.ppll_max) break; | |
1910 } | |
1911 | |
1912 rinfo->post_div = post_div->divider; | |
1913 rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq, | |
1914 rinfo->pll.ref_clk); | |
1915 save->ppll_ref_div = rinfo->pll.ref_div; | |
1916 save->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16); | |
1917 save->htotal_cntl = 0; | |
1918 | |
1919 RTRACE("post div = 0x%x\n", rinfo->post_div); | |
1920 RTRACE("fb_div = 0x%x\n", rinfo->fb_div); | |
1921 RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3); | |
1922 } | |
1923 | |
1924 static void radeon_init_pll2_regs(struct radeonfb_info *rinfo, | |
1925 struct radeon_regs *save, | |
1926 struct fb_var_screeninfo *mode) | |
1927 { | |
1928 u32 dot_clock = 1000000000 / mode->pixclock; | |
1929 u32 freq = dot_clock * 100; | |
1930 struct { | |
1931 int divider; | |
1932 int bitvalue; | |
1933 } *post_div, | |
1934 post_divs[] = { | |
1935 /* From RAGE 128 VR/RAGE 128 GL Register | |
1936 Reference Manual (Technical Reference | |
1937 Manual P/N RRG-G04100-C Rev. 0.04), page | |
1938 3-17 (PLL_DIV_[3:0]). */ | |
1939 { 1, 0 }, /* VCLK_SRC */ | |
1940 { 2, 1 }, /* VCLK_SRC/2 */ | |
1941 { 4, 2 }, /* VCLK_SRC/4 */ | |
1942 { 8, 3 }, /* VCLK_SRC/8 */ | |
1943 { 3, 4 }, /* VCLK_SRC/3 */ | |
1944 { 16, 5 }, /* VCLK_SRC/16 */ | |
1945 { 6, 6 }, /* VCLK_SRC/6 */ | |
1946 { 12, 7 }, /* VCLK_SRC/12 */ | |
1947 { 0, 0 } | |
1948 }; | |
1949 RTRACE("radeonfb: radeon_init_pll2_regs is called\n"); | |
1950 | |
1951 if (freq > rinfo->pll.ppll_max) freq = rinfo->pll.ppll_max; | |
1952 if (freq*12 < rinfo->pll.ppll_min) freq = rinfo->pll.ppll_min/12; | |
1953 | |
1954 for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | |
1955 save->pll_output_freq_2 = post_div->divider * freq; | |
1956 if (save->pll_output_freq_2 >= rinfo->pll.ppll_min | |
1957 && save->pll_output_freq_2 <= rinfo->pll.ppll_max) break; | |
1958 } | |
1959 | |
1960 save->dot_clock_freq_2 = freq; | |
1961 save->feedback_div_2 = round_div(rinfo->pll.ref_div | |
1962 * save->pll_output_freq_2, | |
1963 rinfo->pll.ref_clk); | |
1964 save->post_div_2 = post_div->divider; | |
1965 | |
1966 save->p2pll_ref_div = rinfo->pll.ref_div; | |
1967 save->p2pll_div_0 = (save->feedback_div_2 | (post_div->bitvalue<<16)); | |
1968 save->htotal_cntl2 = 0; | |
1969 } | |
1970 | |
1971 static int radeon_init_dda_regs(struct radeonfb_info *rinfo, | |
1972 struct radeon_regs *save, | |
1973 struct fb_var_screeninfo *mode) | |
1974 { | |
1975 int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise; | |
1976 int useable_precision, roff, ron; | |
1977 int min_bits; | |
1978 const int DispFifoWidth=128,DispFifoDepth=32; | |
1979 /* DDA */ | |
1980 vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div, | |
1981 rinfo->pll.ref_div * rinfo->post_div); | |
1982 xclk_freq = rinfo->pll.xclk; | |
1983 | |
1984 xclk_per_trans = round_div(xclk_freq * DispFifoWidth, | |
1985 vclk_freq * mode->bits_per_pixel); | |
1986 | |
1987 min_bits = min_bits_req(xclk_per_trans); | |
1988 useable_precision = min_bits + 1; | |
1989 | |
1990 xclk_per_trans_precise = round_div((xclk_freq * DispFifoWidth) | |
1991 << (11 - useable_precision), | |
1992 vclk_freq * mode->bits_per_pixel); | |
1993 | |
1994 ron = (4 * rinfo->ram.mb + | |
1995 3 * _max(rinfo->ram.trcd - 2, 0) + | |
1996 2 * rinfo->ram.trp + | |
1997 rinfo->ram.twr + | |
1998 rinfo->ram.cl + | |
1999 rinfo->ram.tr2w + | |
2000 xclk_per_trans) << (11 - useable_precision); | |
2001 roff = xclk_per_trans_precise * (DispFifoDepth - 4); | |
2002 | |
2003 RTRACE("ron = %d, roff = %d\n", ron, roff); | |
2004 RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise); | |
2005 | |
2006 if ((ron + rinfo->ram.rloop) >= roff) { | |
2007 printk("radeonfb: error ron out of range\n"); | |
2008 return -1; | |
2009 } | |
2010 | |
2011 save->dda_config = (xclk_per_trans_precise | | |
2012 (useable_precision << 16) | | |
2013 (rinfo->ram.rloop << 20)); | |
2014 save->dda_on_off = (ron << 16) | roff; | |
2015 return 0; | |
2016 } | |
2017 | |
2018 /* | |
2019 static void radeon_init_palette(struct radeon_regs *save) | |
2020 { | |
2021 save->palette_valid = 0; | |
2022 } | |
2023 */ | |
2024 | |
2025 static int radeon_init_mode(struct radeonfb_info *rinfo, | |
2026 struct radeon_regs *save, | |
2027 struct fb_var_screeninfo *mode) | |
2028 { | |
2029 int prim_mon; | |
2030 RTRACE("radeonfb: radeon_init_mode is called\n"); | |
2031 if(DUAL_MONITOR(rinfo)) | |
2032 { | |
2033 if (!radeon_init_crtc2_regs(rinfo, save, mode)) | |
2034 return 0; | |
2035 radeon_init_pll2_regs(rinfo, save, mode); | |
2036 } | |
2037 radeon_init_common_regs(rinfo, save); | |
2038 if(!radeon_init_crtc_regs(rinfo, save, mode)) | |
2039 return 0; | |
2040 if(mode->pixclock) | |
2041 { | |
2042 radeon_init_pll_regs(rinfo, save, mode); | |
2043 if (!radeon_init_dda_regs(rinfo, save, mode)) | |
2044 return 0; | |
2045 } | |
2046 else | |
2047 { | |
2048 save->ppll_ref_div = rinfo->init_state.ppll_ref_div; | |
2049 save->ppll_div_3 = rinfo->init_state.ppll_div_3; | |
2050 save->htotal_cntl = rinfo->init_state.htotal_cntl; | |
2051 save->dda_config = rinfo->init_state.dda_config; | |
2052 save->dda_on_off = rinfo->init_state.dda_on_off; | |
2053 } | |
2054 /* radeon_init_palete here */ | |
2055 prim_mon = PRIMARY_MONITOR(rinfo); | |
2056 if (((prim_mon == MT_DFP) || (prim_mon == MT_LCD))) | |
2057 { | |
2058 radeon_init_fp_regs(rinfo, save, mode); | |
2059 } | |
2060 | |
2061 RTRACE("radeonfb: radeon_init_mode returns SUCCESS\n"); | |
2062 return 1; | |
1328 } | 2063 } |
1329 | 2064 |
1330 static void radeon_engine_init (struct radeonfb_info *rinfo) | 2065 static void radeon_engine_init (struct radeonfb_info *rinfo) |
1331 { | 2066 { |
1332 u32 temp; | 2067 u32 temp; |
1572 struct fb_info *info) | 2307 struct fb_info *info) |
1573 { | 2308 { |
1574 struct radeonfb_info *rinfo = (struct radeonfb_info *) info; | 2309 struct radeonfb_info *rinfo = (struct radeonfb_info *) info; |
1575 struct display *disp; | 2310 struct display *disp; |
1576 struct fb_var_screeninfo v; | 2311 struct fb_var_screeninfo v; |
1577 int nom, den, accel; | 2312 int nom, den, accel, err; |
1578 unsigned chgvar = 0; | 2313 unsigned chgvar = 0; |
1579 | 2314 |
1580 disp = (con < 0) ? rinfo->info.disp : &fb_display[con]; | 2315 disp = (con < 0) ? rinfo->info.disp : &fb_display[con]; |
1581 | 2316 |
1582 accel = var->accel_flags & FB_ACCELF_TEXT; | 2317 accel = var->accel_flags & FB_ACCELF_TEXT; |
1695 | 2430 |
1696 if (info && info->changevar) | 2431 if (info && info->changevar) |
1697 info->changevar(con); | 2432 info->changevar(con); |
1698 } | 2433 } |
1699 | 2434 |
1700 radeon_load_video_mode (rinfo, &v); | 2435 err = radeon_load_video_mode (rinfo, &v); |
1701 | 2436 if(err) return err; |
1702 do_install_cmap(con, info); | 2437 do_install_cmap(con, info); |
1703 | 2438 |
1704 return 0; | 2439 return 0; |
1705 } | 2440 } |
1706 | 2441 |
1890 | 2625 |
1891 radeonfb_set_var (&disp->var, con, info); | 2626 radeonfb_set_var (&disp->var, con, info); |
1892 radeon_set_dispsw (rinfo, disp); | 2627 radeon_set_dispsw (rinfo, disp); |
1893 do_install_cmap(con, info); | 2628 do_install_cmap(con, info); |
1894 } | 2629 } |
1895 | |
1896 /* XXX absurd hack for X to restore console */ | |
1897 { | |
1898 OUTREG(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl); | |
1899 OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid); | |
1900 } | |
1901 | |
1902 return 0; | 2630 return 0; |
1903 } | 2631 } |
1904 | 2632 |
1905 | 2633 |
1906 | 2634 |
2078 } | 2806 } |
2079 #endif | 2807 #endif |
2080 return 0; | 2808 return 0; |
2081 } | 2809 } |
2082 | 2810 |
2083 | 2811 static void radeon_save_common_regs(struct radeonfb_info *rinfo, |
2084 | |
2085 static void radeon_save_state (struct radeonfb_info *rinfo, | |
2086 struct radeon_regs *save) | 2812 struct radeon_regs *save) |
2087 { | 2813 { |
2088 save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL); | 2814 RTRACE("radeonfb: radeon_save_common_regs is called\n"); |
2089 save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL); | 2815 save->ovr_clr = INREG(OVR_CLR); |
2090 save->dac_cntl = INREG(DAC_CNTL); | 2816 save->ovr_wid_left_right= INREG(OVR_WID_LEFT_RIGHT); |
2091 save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP); | 2817 save->ovr_wid_top_bottom= INREG(OVR_WID_TOP_BOTTOM); |
2092 save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID); | 2818 save->ov0_scale_cntl = INREG(OV0_SCALE_CNTL); |
2093 save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP); | 2819 save->mpp_tb_config = INREG(MPP_TB_CONFIG); |
2094 save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); | 2820 save->mpp_gp_config = INREG(MPP_GP_CONFIG); |
2095 save->crtc_pitch = INREG(CRTC_PITCH); | 2821 save->subpic_cntl = INREG(SUBPIC_CNTL); |
2096 } | 2822 save->viph_control = INREG(VIPH_CONTROL); |
2097 | 2823 save->i2c_cntl_1 = INREG(I2C_CNTL_1); |
2098 | 2824 save->gen_int_cntl = INREG(GEN_INT_CNTL); |
2099 | 2825 save->cap0_trig_cntl = INREG(CAP0_TRIG_CNTL); |
2100 static void radeon_load_video_mode (struct radeonfb_info *rinfo, | 2826 save->cap1_trig_cntl = INREG(CAP1_TRIG_CNTL); |
2827 save->bus_cntl = INREG(BUS_CNTL); | |
2828 } | |
2829 | |
2830 static void radeon_save_crtc_regs(struct radeonfb_info *rinfo, | |
2831 struct radeon_regs *save) | |
2832 { | |
2833 RTRACE("radeonfb: radeon_save_crtc_regs is called\n"); | |
2834 save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL); | |
2835 save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL); | |
2836 save->dac_cntl = INREG(DAC_CNTL); | |
2837 save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP); | |
2838 save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID); | |
2839 save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP); | |
2840 save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); | |
2841 save->crtc_offset = INREG(CRTC_OFFSET); | |
2842 save->crtc_offset_cntl = INREG(CRTC_OFFSET_CNTL); | |
2843 save->crtc_pitch = INREG(CRTC_PITCH); | |
2844 } | |
2845 | |
2846 static void radeon_save_crtc2_regs(struct radeonfb_info *rinfo, | |
2847 struct radeon_regs *save) | |
2848 { | |
2849 RTRACE("radeonfb: radeon_save_crtc2_regs is called\n"); | |
2850 save->dac2_cntl = INREG(DAC_CNTL2); | |
2851 save->disp_output_cntl = INREG(DISP_OUTPUT_CNTL); | |
2852 | |
2853 save->crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL); | |
2854 save->crtc2_h_total_disp = INREG(CRTC2_H_TOTAL_DISP); | |
2855 save->crtc2_h_sync_strt_wid = INREG(CRTC2_H_SYNC_STRT_WID); | |
2856 save->crtc2_v_total_disp = INREG(CRTC2_V_TOTAL_DISP); | |
2857 save->crtc2_v_sync_strt_wid = INREG(CRTC2_V_SYNC_STRT_WID); | |
2858 save->crtc2_offset = INREG(CRTC2_OFFSET); | |
2859 save->crtc2_offset_cntl = INREG(CRTC2_OFFSET_CNTL); | |
2860 save->crtc2_pitch = INREG(CRTC2_PITCH); | |
2861 } | |
2862 | |
2863 static void radeon_save_fp_regs(struct radeonfb_info *rinfo, | |
2864 struct radeon_regs *save) | |
2865 { | |
2866 RTRACE("radeonfb: radeon_save_fp_regs is called\n"); | |
2867 save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP); | |
2868 save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP); | |
2869 save->fp_gen_cntl = INREG(FP_GEN_CNTL); | |
2870 save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID); | |
2871 save->fp_horz_stretch = INREG(FP_HORZ_STRETCH); | |
2872 save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID); | |
2873 save->fp_vert_stretch = INREG(FP_VERT_STRETCH); | |
2874 save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL); | |
2875 save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL); | |
2876 save->tmds_crc = INREG(TMDS_CRC); | |
2877 } | |
2878 | |
2879 static void radeon_save_pll_regs(struct radeonfb_info *rinfo, | |
2880 struct radeon_regs *save) | |
2881 { | |
2882 RTRACE("radeonfb: radeon_save_pll_regs is called\n"); | |
2883 save->ppll_ref_div = INPLL(PPLL_REF_DIV); | |
2884 save->ppll_div_3 = INPLL(PPLL_DIV_3); | |
2885 save->htotal_cntl = INPLL(HTOTAL_CNTL); | |
2886 } | |
2887 | |
2888 static void radeon_save_pll2_regs(struct radeonfb_info *rinfo, | |
2889 struct radeon_regs *save) | |
2890 { | |
2891 RTRACE("radeonfb: radeon_save_pll2_regs is called\n"); | |
2892 save->p2pll_ref_div = INPLL(P2PLL_REF_DIV); | |
2893 save->p2pll_div_0 = INPLL(P2PLL_DIV_0); | |
2894 save->htotal_cntl2 = INPLL(HTOTAL2_CNTL); | |
2895 } | |
2896 | |
2897 static void radeon_save_dda_regs(struct radeonfb_info *rinfo, | |
2898 struct radeon_regs *save) | |
2899 { | |
2900 RTRACE("radeonfb: radeon_save_dda_regs is called\n"); | |
2901 save->dda_config = INREG(DDA_CONFIG); | |
2902 save->dda_on_off = INREG(DDA_ON_OFF); | |
2903 } | |
2904 | |
2905 #if 0 | |
2906 static void radeon_save_palette(struct radeonfb_info *rinfo, | |
2907 struct radeon_regs *save) | |
2908 { | |
2909 int i; | |
2910 RTRACE("radeonfb: radeon_save_palette is called\n"); | |
2911 PAL_SELECT(1); | |
2912 INPAL_START(0); | |
2913 for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT(); | |
2914 PAL_SELECT(0); | |
2915 INPAL_START(0); | |
2916 for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); | |
2917 } | |
2918 #endif | |
2919 | |
2920 static void radeon_write_common_regs(struct radeonfb_info *rinfo, | |
2921 struct radeon_regs *restore) | |
2922 { | |
2923 RTRACE("radeonfb: radeon_write_common_regs is called\n"); | |
2924 OUTREG(OVR_CLR, restore->ovr_clr); | |
2925 OUTREG(OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); | |
2926 OUTREG(OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); | |
2927 OUTREG(OV0_SCALE_CNTL, restore->ov0_scale_cntl); | |
2928 OUTREG(MPP_TB_CONFIG, restore->mpp_tb_config ); | |
2929 OUTREG(MPP_GP_CONFIG, restore->mpp_gp_config ); | |
2930 OUTREG(SUBPIC_CNTL, restore->subpic_cntl); | |
2931 OUTREG(VIPH_CONTROL, restore->viph_control); | |
2932 OUTREG(I2C_CNTL_1, restore->i2c_cntl_1); | |
2933 OUTREG(GEN_INT_CNTL, restore->gen_int_cntl); | |
2934 OUTREG(CAP0_TRIG_CNTL, restore->cap0_trig_cntl); | |
2935 OUTREG(CAP1_TRIG_CNTL, restore->cap1_trig_cntl); | |
2936 OUTREG(BUS_CNTL, restore->bus_cntl); | |
2937 } | |
2938 | |
2939 static void radeon_write_crtc_regs(struct radeonfb_info *rinfo, | |
2940 struct radeon_regs *restore) | |
2941 { | |
2942 RTRACE("radeonfb: radeon_write_crtc_regs is called\n"); | |
2943 OUTREG(CRTC_GEN_CNTL, restore->crtc_gen_cntl); | |
2944 | |
2945 OUTREGP(CRTC_EXT_CNTL, restore->crtc_ext_cntl, | |
2946 CRTC_VSYNC_DIS | | |
2947 CRTC_HSYNC_DIS | | |
2948 CRTC_DISPLAY_DIS); | |
2949 | |
2950 OUTREGP(DAC_CNTL, restore->dac_cntl, | |
2951 DAC_RANGE_CNTL | | |
2952 DAC_BLANKING); | |
2953 | |
2954 OUTREG(CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); | |
2955 OUTREG(CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); | |
2956 OUTREG(CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); | |
2957 OUTREG(CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); | |
2958 OUTREG(CRTC_OFFSET, restore->crtc_offset); | |
2959 OUTREG(CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); | |
2960 OUTREG(CRTC_PITCH, restore->crtc_pitch); | |
2961 } | |
2962 | |
2963 static void radeon_write_crtc2_regs(struct radeonfb_info *rinfo, | |
2964 struct radeon_regs *restore) | |
2965 { | |
2966 RTRACE("radeonfb: radeon_write_crtc2_regs is called\n"); | |
2967 /* OUTREG(CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);*/ | |
2968 OUTREGP(CRTC2_GEN_CNTL, restore->crtc2_gen_cntl, | |
2969 CRTC2_VSYNC_DIS | | |
2970 CRTC2_HSYNC_DIS | | |
2971 CRTC2_DISP_DIS); | |
2972 | |
2973 OUTREG(DAC_CNTL2, restore->dac2_cntl); | |
2974 OUTREG(DISP_OUTPUT_CNTL, restore->disp_output_cntl); | |
2975 | |
2976 OUTREG(CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp); | |
2977 OUTREG(CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid); | |
2978 OUTREG(CRTC2_V_TOTAL_DISP, restore->crtc2_v_total_disp); | |
2979 OUTREG(CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid); | |
2980 OUTREG(CRTC2_OFFSET, restore->crtc2_offset); | |
2981 OUTREG(CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl); | |
2982 OUTREG(CRTC2_PITCH, restore->crtc2_pitch); | |
2983 } | |
2984 | |
2985 static void radeon_write_fp_regs(struct radeonfb_info *rinfo, | |
2986 struct radeon_regs *restore) | |
2987 { | |
2988 int prim_mon; | |
2989 u32 tmp; | |
2990 RTRACE("radeonfb: radeon_write_fp_regs is called\n"); | |
2991 OUTREG(FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); | |
2992 OUTREG(FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); | |
2993 OUTREG(FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); | |
2994 OUTREG(FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); | |
2995 OUTREG(TMDS_CRC, restore->tmds_crc); | |
2996 OUTREG(FP_HORZ_STRETCH, restore->fp_horz_stretch); | |
2997 OUTREG(FP_VERT_STRETCH, restore->fp_vert_stretch); | |
2998 OUTREG(FP_GEN_CNTL, restore->fp_gen_cntl); | |
2999 prim_mon = PRIMARY_MONITOR(rinfo); | |
3000 if(prim_mon == MT_LCD) { | |
3001 tmp = INREG(LVDS_GEN_CNTL); | |
3002 if((tmp & (LVDS_ON | LVDS_BLON)) == | |
3003 (restore->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) { | |
3004 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); | |
3005 } | |
3006 } | |
3007 else { | |
3008 if (restore->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) { | |
3009 #if 0 | |
3010 /* TODO it later */ | |
3011 usleep(rinfo->PanelPwrDly * 1000); | |
3012 #endif | |
3013 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); | |
3014 } | |
3015 else { | |
3016 OUTREG(LVDS_GEN_CNTL, | |
3017 restore->lvds_gen_cntl | LVDS_BLON); | |
3018 #if 0 | |
3019 /* TODO it later */ | |
3020 usleep(rinfo->PanelPwrDly * 1000); | |
3021 #endif | |
3022 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); | |
3023 } | |
3024 } | |
3025 } | |
3026 | |
3027 static void radeon_write_pll_regs(struct radeonfb_info *rinfo, | |
3028 struct radeon_regs *restore) | |
3029 { | |
3030 RTRACE("radeonfb: radeon_write_pll_regs is called\n"); | |
3031 OUTPLLP(0x08, 0x00, ~(0x03)); | |
3032 while ( (INREG(CLOCK_CNTL_INDEX) & PLL_DIV_SEL) != PLL_DIV_SEL) { | |
3033 OUTREGP(CLOCK_CNTL_INDEX, PLL_DIV_SEL, 0xffff); | |
3034 } | |
3035 OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff); | |
3036 while ( (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) != | |
3037 (restore->ppll_ref_div & PPLL_REF_DIV_MASK)) { | |
3038 OUTPLLP(PPLL_REF_DIV, | |
3039 restore->ppll_ref_div, ~PPLL_REF_DIV_MASK); | |
3040 } | |
3041 while ( (INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) != | |
3042 (restore->ppll_div_3 & PPLL_FB3_DIV_MASK)) { | |
3043 OUTPLLP(PPLL_DIV_3,restore->ppll_div_3, ~PPLL_FB3_DIV_MASK); | |
3044 } | |
3045 while ( (INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) != | |
3046 (restore->ppll_div_3 & PPLL_POST3_DIV_MASK)) { | |
3047 OUTPLLP(PPLL_DIV_3,restore->ppll_div_3, ~PPLL_POST3_DIV_MASK); | |
3048 } | |
3049 OUTPLL(HTOTAL_CNTL, restore->htotal_cntl); | |
3050 OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET); | |
3051 OUTPLLP(0x08, 0x03, ~(0x03)); | |
3052 } | |
3053 | |
3054 | |
3055 static void radeon_write_pll2_regs(struct radeonfb_info *rinfo, | |
3056 struct radeon_regs *restore) | |
3057 { | |
3058 RTRACE("radeonfb: radeon_write_pll2_regs is called\n"); | |
3059 OUTPLLP(0x2d, 0x00, ~(0x03)); | |
3060 while (INREG(CLOCK_CNTL_INDEX) & ~(PLL2_DIV_SEL_MASK)) { | |
3061 OUTREGP(CLOCK_CNTL_INDEX, 0, PLL2_DIV_SEL_MASK); | |
3062 } | |
3063 OUTPLLP(P2PLL_CNTL,P2PLL_RESET,0xffff); | |
3064 while ( (INPLL(P2PLL_REF_DIV) & P2PLL_REF_DIV_MASK) != | |
3065 (restore->p2pll_ref_div & P2PLL_REF_DIV_MASK)) { | |
3066 OUTPLLP(P2PLL_REF_DIV, restore->p2pll_ref_div, ~P2PLL_REF_DIV_MASK); | |
3067 } | |
3068 while ( (INPLL(P2PLL_DIV_0) & P2PLL_FB0_DIV_MASK) != | |
3069 (restore->p2pll_div_0 & P2PLL_FB0_DIV_MASK)) { | |
3070 OUTPLLP(P2PLL_DIV_0, restore->p2pll_div_0, ~P2PLL_FB0_DIV_MASK); | |
3071 } | |
3072 while ( (INPLL(P2PLL_DIV_0) & P2PLL_POST0_DIV_MASK) != | |
3073 (restore->p2pll_div_0 & P2PLL_POST0_DIV_MASK)) { | |
3074 OUTPLLP(P2PLL_DIV_0,restore->p2pll_div_0, ~P2PLL_POST0_DIV_MASK); | |
3075 } | |
3076 OUTPLL(HTOTAL2_CNTL, restore->htotal_cntl2); | |
3077 OUTPLLP(P2PLL_CNTL, 0, ~(P2PLL_RESET | P2PLL_SLEEP)); | |
3078 OUTPLLP(0x2d, 0x03, ~(0x03)); | |
3079 } | |
3080 | |
3081 static void radeon_write_dda_regs(struct radeonfb_info *rinfo, | |
3082 struct radeon_regs *restore) | |
3083 { | |
3084 RTRACE("radeonfb: radeon_write_dda_regs is called\n"); | |
3085 OUTREG(DDA_CONFIG, restore->dda_config); | |
3086 OUTREG(DDA_ON_OFF, restore->dda_on_off); | |
3087 } | |
3088 | |
3089 #if 0 | |
3090 static void radeon_write_palette(struct radeonfb_info *rinfo, | |
3091 struct radeon_regs *restore) | |
3092 { | |
3093 int i; | |
3094 | |
3095 RTRACE("radeonfb: radeon_write_palette is called\n"); | |
3096 PAL_SELECT(1); | |
3097 OUTPAL_START(0); | |
3098 for (i = 0; i < 256; i++) { | |
3099 RADEONWaitForFifo(32); /* delay */ | |
3100 OUTPAL_NEXT_CARD32(restore->palette2[i]); | |
3101 } | |
3102 | |
3103 PAL_SELECT(0); | |
3104 OUTPAL_START(0); | |
3105 for (i = 0; i < 256; i++) { | |
3106 RADEONWaitForFifo(32); /* delay */ | |
3107 OUTPAL_NEXT_CARD32(restore->palette[i]); | |
3108 } | |
3109 } | |
3110 #endif | |
3111 | |
3112 static void radeon_save_mode (struct radeonfb_info *rinfo, | |
3113 struct radeon_regs *save) | |
3114 { | |
3115 int prim_mon; | |
3116 RTRACE("radeonfb: radeon_save_mode is called\n"); | |
3117 if(DUAL_MONITOR(rinfo)) { | |
3118 radeon_save_crtc2_regs(rinfo,save); | |
3119 radeon_save_pll2_regs(rinfo,save); | |
3120 } | |
3121 radeon_save_common_regs(rinfo,save); | |
3122 radeon_save_crtc_regs(rinfo,save); | |
3123 prim_mon = PRIMARY_MONITOR(rinfo); | |
3124 if(prim_mon == MT_LCD || prim_mon == MT_DFP) radeon_save_fp_regs(rinfo,save); | |
3125 radeon_save_pll_regs(rinfo,save); | |
3126 radeon_save_dda_regs(rinfo,save); | |
3127 /*radeon_save_palette(rinfo,save);*/ | |
3128 } | |
3129 | |
3130 static void radeon_save_state(struct radeonfb_info *rinfo, | |
3131 struct radeon_regs *save) | |
3132 { | |
3133 RTRACE("radeonfb: radeon_save_state is called\n"); | |
3134 save->dp_datatype = INREG(DP_DATATYPE); | |
3135 save->rbbm_soft_reset = INREG(RBBM_SOFT_RESET); | |
3136 save->clock_cntl_index = INREG(CLOCK_CNTL_INDEX); | |
3137 save->amcgpio_en_reg = INREG(AMCGPIO_EN_REG); | |
3138 save->amcgpio_mask = INREG(AMCGPIO_MASK); | |
3139 radeon_save_mode(rinfo,save); | |
3140 } | |
3141 | |
3142 static int radeon_load_video_mode (struct radeonfb_info *rinfo, | |
2101 struct fb_var_screeninfo *mode) | 3143 struct fb_var_screeninfo *mode) |
2102 { | 3144 { |
3145 /* | |
2103 struct radeon_regs newmode; | 3146 struct radeon_regs newmode; |
2104 int hTotal, vTotal, hSyncStart, hSyncEnd, | 3147 |
2105 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync; | 3148 RTRACE("radeonfb: radeon_load_video_mode is called\n"); |
2106 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; | 3149 if(!radeon_init_mode(rinfo, &newmode, mode)) return -1; |
2107 u32 dotClock = 1000000000 / mode->pixclock, | 3150 |
2108 sync, h_sync_pol, v_sync_pol; | 3151 radeonfb_blank(VESA_POWERDOWN,&rinfo->info); |
2109 int freq = dotClock / 10; /* x 100 */ | 3152 radeon_write_mode(rinfo, &newmode); |
2110 int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise; | 3153 radeonfb_blank(VESA_NO_BLANKING,&rinfo->info); |
2111 int useable_precision, roff, ron; | 3154 return 0; |
2112 int min_bits, format = 0; | 3155 */ |
2113 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid; | 3156 struct radeon_regs newmode; |
2114 | 3157 |
2115 rinfo->xres = mode->xres; | 3158 radeon_init_common_regs(rinfo,&newmode); |
2116 rinfo->yres = mode->yres; | 3159 radeon_init_crtc_regs(rinfo,&newmode,mode); |
2117 rinfo->pixclock = mode->pixclock; | 3160 radeon_init_pll_regs(rinfo,&newmode,mode); |
2118 | 3161 radeon_init_dda_regs(rinfo,&newmode,mode); |
2119 hSyncStart = mode->xres + mode->right_margin; | |
2120 hSyncEnd = hSyncStart + mode->hsync_len; | |
2121 hTotal = hSyncEnd + mode->left_margin; | |
2122 | |
2123 vSyncStart = mode->yres + mode->lower_margin; | |
2124 vSyncEnd = vSyncStart + mode->vsync_len; | |
2125 vTotal = vSyncEnd + mode->upper_margin; | |
2126 | |
2127 sync = mode->sync; | |
2128 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | |
2129 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; | |
2130 | |
2131 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n", | |
2132 hSyncStart, hSyncEnd, hTotal); | |
2133 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n", | |
2134 vSyncStart, vSyncEnd, vTotal); | |
2135 | |
2136 hsync_wid = (hSyncEnd - hSyncStart) / 8; | |
2137 vsync_wid = vSyncEnd - vSyncStart; | |
2138 if (hsync_wid == 0) | |
2139 hsync_wid = 1; | |
2140 else if (hsync_wid > 0x3f) /* max */ | |
2141 hsync_wid = 0x3f; | |
2142 vsync_wid = mode->vsync_len; | |
2143 if (vsync_wid == 0) | |
2144 vsync_wid = 1; | |
2145 else if (vsync_wid > 0x1f) /* max */ | |
2146 vsync_wid = 0x1f; | |
2147 | |
2148 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; | |
2149 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; | |
2150 | |
2151 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; | |
2152 | |
2153 switch (mode->bits_per_pixel) { | |
2154 case 8: | |
2155 format = DST_8BPP; | |
2156 bytpp = 1; | |
2157 break; | |
2158 case 16: | |
2159 format = DST_16BPP; | |
2160 bytpp = 2; | |
2161 break; | |
2162 case 24: | |
2163 format = DST_24BPP; | |
2164 bytpp = 3; | |
2165 break; | |
2166 case 32: | |
2167 format = DST_32BPP; | |
2168 bytpp = 4; | |
2169 break; | |
2170 } | |
2171 | |
2172 hsync_fudge = hsync_adj_tab[format-1]; | |
2173 hsync_start = hSyncStart - 8 + hsync_fudge; | |
2174 | |
2175 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | | |
2176 (format << 8); | |
2177 if(rinfo->hasCRTC2) | |
2178 /* HACKED: !!! Enable CRT port here !!! */ | |
2179 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON; | |
2180 else newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; | |
2181 newmode.dac_cntl = INREG(DAC_CNTL) | DAC_MASK_ALL | DAC_VGA_ADR_EN | | |
2182 DAC_8BIT_EN; | |
2183 | |
2184 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | | |
2185 ((((mode->xres / 8) - 1) & 0x1ff) << 16)); | |
2186 | |
2187 newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | | |
2188 (hsync_wid << 16) | (h_sync_pol << 23)); | |
2189 | |
2190 newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) | | |
2191 ((mode->yres - 1) << 16); | |
2192 | |
2193 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | | |
2194 (vsync_wid << 16) | (v_sync_pol << 23)); | |
2195 | |
2196 newmode.crtc_pitch = (mode->xres >> 3); | |
2197 | |
2198 #if defined(__BIG_ENDIAN) | |
2199 newmode.surface_cntl = SURF_TRANSLATION_DIS; | |
2200 switch (mode->bits_per_pixel) { | |
2201 case 16: | |
2202 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP; | |
2203 break; | |
2204 case 24: | |
2205 case 32: | |
2206 newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP; | |
2207 break; | |
2208 } | |
2209 #endif | |
2210 | |
2211 rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f) | |
2212 & ~(0x3f)) / 64; | |
2213 | |
2214 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n", | |
2215 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid); | |
2216 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n", | |
2217 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid); | |
2218 | |
2219 newmode.xres = mode->xres; | |
2220 newmode.yres = mode->yres; | |
2221 | |
2222 rinfo->bpp = mode->bits_per_pixel; | |
2223 rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl; | |
2224 rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid; | |
2225 | |
2226 if (freq > rinfo->pll.ppll_max) | |
2227 freq = rinfo->pll.ppll_max; | |
2228 if (freq*12 < rinfo->pll.ppll_min) | |
2229 freq = rinfo->pll.ppll_min / 12; | |
2230 | |
2231 { | |
2232 struct { | |
2233 int divider; | |
2234 int bitvalue; | |
2235 } *post_div, | |
2236 post_divs[] = { | |
2237 { 1, 0 }, | |
2238 { 2, 1 }, | |
2239 { 4, 2 }, | |
2240 { 8, 3 }, | |
2241 { 3, 4 }, | |
2242 { 16, 5 }, | |
2243 { 6, 6 }, | |
2244 { 12, 7 }, | |
2245 { 0, 0 }, | |
2246 }; | |
2247 | |
2248 for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | |
2249 rinfo->pll_output_freq = post_div->divider * freq; | |
2250 if (rinfo->pll_output_freq >= rinfo->pll.ppll_min && | |
2251 rinfo->pll_output_freq <= rinfo->pll.ppll_max) | |
2252 break; | |
2253 } | |
2254 | |
2255 rinfo->post_div = post_div->divider; | |
2256 rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq, | |
2257 rinfo->pll.ref_clk); | |
2258 newmode.ppll_ref_div = rinfo->pll.ref_div; | |
2259 newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16); | |
2260 } | |
2261 | |
2262 RTRACE("post div = 0x%x\n", rinfo->post_div); | |
2263 RTRACE("fb_div = 0x%x\n", rinfo->fb_div); | |
2264 RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3); | |
2265 | |
2266 /* DDA */ | |
2267 vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div, | |
2268 rinfo->pll.ref_div * rinfo->post_div); | |
2269 xclk_freq = rinfo->pll.xclk; | |
2270 | |
2271 xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel); | |
2272 | |
2273 min_bits = min_bits_req(xclk_per_trans); | |
2274 useable_precision = min_bits + 1; | |
2275 | |
2276 xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision), | |
2277 vclk_freq * mode->bits_per_pixel); | |
2278 | |
2279 ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) + | |
2280 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w + | |
2281 xclk_per_trans) << (11 - useable_precision); | |
2282 roff = xclk_per_trans_precise * (32 - 4); | |
2283 | |
2284 RTRACE("ron = %d, roff = %d\n", ron, roff); | |
2285 RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise); | |
2286 | |
2287 if ((ron + rinfo->ram.rloop) >= roff) { | |
2288 printk("radeonfb: error ron out of range\n"); | |
2289 return; | |
2290 } | |
2291 | |
2292 newmode.dda_config = (xclk_per_trans_precise | | |
2293 (useable_precision << 16) | | |
2294 (rinfo->ram.rloop << 20)); | |
2295 newmode.dda_on_off = (ron << 16) | roff; | |
2296 | |
2297 /* do it! */ | 3162 /* do it! */ |
2298 radeon_write_mode (rinfo, &newmode); | 3163 radeon_write_mode (rinfo, &newmode); |
2299 /* XXX absurd hack for X to restore console on VE */ | 3164 return 0; |
2300 if(rinfo->hasCRTC2 && rinfo->crtDispType == MT_CRT && | 3165 } |
2301 (rinfo->dviDispType == MT_NONE || rinfo->dviDispType == MT_STV)) { | |
2302 OUTREG(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl); | |
2303 OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid); | |
2304 } | |
2305 return; | |
2306 } | |
2307 | |
2308 | |
2309 /***** | |
2310 When changing mode with Dual-head card (VE/M6), care must | |
2311 be taken for the special order in setting registers. CRTC2 has | |
2312 to be set before changing CRTC_EXT register. | |
2313 Otherwise we may get a blank screen. | |
2314 *****/ | |
2315 | 3166 |
2316 static void radeon_write_mode (struct radeonfb_info *rinfo, | 3167 static void radeon_write_mode (struct radeonfb_info *rinfo, |
2317 struct radeon_regs *mode) | 3168 struct radeon_regs *mode) |
2318 { | 3169 { |
2319 int i; | 3170 /***** |
2320 | 3171 When changing mode with Dual-head card (VE/M6), care must |
2321 /* blank screen */ | 3172 be taken for the special order in setting registers. CRTC2 has |
2322 OUTREG8(CRTC_EXT_CNTL + 1, 4); | 3173 to be set before changing CRTC_EXT register. |
2323 | 3174 Otherwise we may get a blank screen. |
2324 for (i=0; i<9; i++) | 3175 *****/ |
2325 OUTREG(common_regs[i].reg, common_regs[i].val); | 3176 RTRACE("radeonfb: radeon_write_mode is called\n"); |
2326 | 3177 if(DUAL_MONITOR(rinfo)) { |
2327 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); | 3178 radeon_write_crtc2_regs(rinfo,mode); |
2328 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, | 3179 radeon_write_pll2_regs(rinfo,mode); |
2329 CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS); | 3180 } |
2330 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); | 3181 radeon_write_common_regs(rinfo,mode); |
2331 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); | 3182 radeon_write_dda_regs(rinfo,mode); |
2332 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); | 3183 radeon_write_crtc_regs(rinfo,mode); |
2333 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); | 3184 if(rinfo->crtDispType == MT_DFP || rinfo->crtDispType == MT_LCD) { |
2334 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); | 3185 radeon_write_fp_regs(rinfo,mode); |
2335 OUTREG(CRTC_OFFSET, 0); | 3186 } |
2336 OUTREG(CRTC_OFFSET_CNTL, 0); | 3187 radeon_write_pll_regs(rinfo,mode); |
2337 OUTREG(CRTC_PITCH, mode->crtc_pitch); | 3188 } |
2338 #if defined(__BIG_ENDIAN) | 3189 |
2339 /* XXX this code makes degradation of mplayer quality on Radeon VE */ | 3190 static void radeon_write_state (struct radeonfb_info *rinfo, |
2340 OUTREG(SURFACE_CNTL, mode->surface_cntl); | 3191 struct radeon_regs *restore) |
2341 #endif | 3192 { |
2342 /* Here we should restore FP registers for LCD & DFP monitors */ | 3193 RTRACE("radeonfb: radeon_write_state is called\n"); |
2343 | 3194 radeonfb_blank(VESA_POWERDOWN,&rinfo->info); |
2344 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) != | 3195 OUTREG(AMCGPIO_MASK, restore->amcgpio_mask); |
2345 PPLL_DIV_SEL_MASK) { | 3196 OUTREG(AMCGPIO_EN_REG, restore->amcgpio_en_reg); |
2346 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff); | 3197 OUTREG(CLOCK_CNTL_INDEX,restore->clock_cntl_index); |
2347 } | 3198 OUTREG(RBBM_SOFT_RESET, restore->rbbm_soft_reset); |
2348 | 3199 OUTREG(DP_DATATYPE, restore->dp_datatype); |
2349 OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff); | 3200 /* M6 card has trouble restoring text mode for its CRT. |
2350 | 3201 Needs this workaround.*/ |
2351 while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) != | 3202 if(rinfo->isM6) OUTREG(DAC_CNTL2, restore->dac2_cntl); |
2352 (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) { | 3203 radeon_write_mode(rinfo,restore); |
2353 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); | 3204 radeonfb_blank(VESA_NO_BLANKING,&rinfo->info); |
2354 } | |
2355 | |
2356 while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) != | |
2357 (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) { | |
2358 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); | |
2359 } | |
2360 | |
2361 while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) != | |
2362 (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) { | |
2363 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); | |
2364 } | |
2365 | |
2366 OUTPLL(HTOTAL_CNTL, 0); | |
2367 | |
2368 OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET); | |
2369 | |
2370 OUTREG(DDA_CONFIG, mode->dda_config); | |
2371 OUTREG(DDA_ON_OFF, mode->dda_on_off); | |
2372 | |
2373 /* unblank screen */ | |
2374 OUTREG8(CRTC_EXT_CNTL + 1, 0); | |
2375 | |
2376 return; | |
2377 } | 3205 } |
2378 | 3206 |
2379 #if 0 | 3207 #if 0 |
2380 | 3208 |
2381 /* | 3209 /* |