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 /*