radeonfb.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:81k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/video/radeonfb.c
  3.  * framebuffer driver for ATI Radeon chipset video boards
  4.  *
  5.  * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
  6.  *
  7.  *
  8.  * ChangeLog:
  9.  * 2000-08-03 initial version 0.0.1
  10.  * 2000-09-10 more bug fixes, public release 0.0.5
  11.  * 2001-02-19 mode bug fixes, 0.0.7
  12.  * 2001-07-05 fixed scrolling issues, engine initialization,
  13.  * and minor mode tweaking, 0.0.9
  14.  * 2001-09-07 Radeon VE support, Nick Kurshev
  15.  * blanking, pan_display, and cmap fixes, 0.1.0
  16.  * 2001-10-10 Radeon 7500 and 8500 support, and experimental
  17.  * flat panel support, 0.1.1
  18.  * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
  19.  * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3
  20.  * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt
  21.  * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4
  22.  *
  23.  * Special thanks to ATI DevRel team for their hardware donations.
  24.  *
  25.  */
  26. #define RADEON_VERSION "0.1.4"
  27. #include <linux/config.h>
  28. #include <linux/module.h>
  29. #include <linux/kernel.h>
  30. #include <linux/errno.h>
  31. #include <linux/string.h>
  32. #include <linux/mm.h>
  33. #include <linux/tty.h>
  34. #include <linux/slab.h>
  35. #include <linux/delay.h>
  36. #include <linux/fb.h>
  37. #include <linux/console.h>
  38. #include <linux/selection.h>
  39. #include <linux/ioport.h>
  40. #include <linux/init.h>
  41. #include <linux/pci.h>
  42. #include <linux/vmalloc.h>
  43. #include <asm/io.h>
  44. #if defined(__powerpc__)
  45. #include <asm/prom.h>
  46. #include <asm/pci-bridge.h>
  47. #include <video/macmodes.h>
  48. #ifdef CONFIG_NVRAM
  49. #include <linux/nvram.h>
  50. #endif
  51. #ifdef CONFIG_PMAC_BACKLIGHT
  52. #include <asm/backlight.h>
  53. #endif
  54. #ifdef CONFIG_BOOTX_TEXT
  55. #include <asm/btext.h>
  56. #endif
  57. #ifdef CONFIG_ADB_PMU
  58. #include <linux/adb.h>
  59. #include <linux/pmu.h>
  60. #endif
  61. #endif /* __powerpc__ */
  62. #include <video/fbcon.h> 
  63. #include <video/fbcon-cfb8.h>
  64. #include <video/fbcon-cfb16.h>
  65. #include <video/fbcon-cfb24.h>
  66. #include <video/fbcon-cfb32.h>
  67. #include "radeon.h"
  68. #define DEBUG 0
  69. #if DEBUG
  70. #define RTRACE printk
  71. #else
  72. #define RTRACE if(0) printk
  73. #endif
  74. enum radeon_chips {
  75. RADEON_QD, /* Radeon R100 */
  76. RADEON_QE, /* Radeon R100 */
  77. RADEON_QF, /* Radeon R100 */
  78. RADEON_QG, /* Radeon R100 */
  79. RADEON_QY, /* Radeon RV100 (VE) */
  80. RADEON_QZ, /* Radeon RV100 (VE) */
  81. RADEON_QL, /* Radeon R200 (8500) */
  82. RADEON_QW, /* Radeon RV200 (7500) */
  83. RADEON_LW, /* Radeon Mobility M7 */
  84. RADEON_LY, /* Radeon Mobility M6 */
  85. RADEON_LZ /* Radeon Mobility M6 */
  86. };
  87. enum radeon_montype
  88. {
  89. MT_NONE,
  90. MT_CRT, /* CRT */
  91. MT_LCD, /* LCD */
  92. MT_DFP, /* DVI */
  93. MT_CTV, /* composite TV */
  94. MT_STV /* S-Video out */
  95. };
  96. static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
  97. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
  98. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
  99. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
  100. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
  101. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
  102. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
  103. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
  104. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
  105. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
  106. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
  107. { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
  108. { 0, }
  109. };
  110. MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
  111. typedef struct {
  112. u16 reg;
  113. u32 val;
  114. } reg_val;
  115. /* these common regs are cleared before mode setting so they do not
  116.  * interfere with anything
  117.  */
  118. reg_val common_regs[] = {
  119. { OVR_CLR, 0 },
  120. { OVR_WID_LEFT_RIGHT, 0 },
  121. { OVR_WID_TOP_BOTTOM, 0 },
  122. { OV0_SCALE_CNTL, 0 },
  123. { SUBPIC_CNTL, 0 },
  124. { VIPH_CONTROL, 0 },
  125. { I2C_CNTL_1, 0 },
  126. { GEN_INT_CNTL, 0 },
  127. { CAP0_TRIG_CNTL, 0 },
  128. };
  129. #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
  130. typedef struct {
  131.         u8 clock_chip_type;
  132.         u8 struct_size;
  133.         u8 accelerator_entry;
  134.         u8 VGA_entry;
  135.         u16 VGA_table_offset;
  136.         u16 POST_table_offset;
  137.         u16 XCLK;
  138.         u16 MCLK;
  139.         u8 num_PLL_blocks;
  140.         u8 size_PLL_blocks;
  141.         u16 PCLK_ref_freq;
  142.         u16 PCLK_ref_divider;
  143.         u32 PCLK_min_freq;
  144.         u32 PCLK_max_freq;
  145.         u16 MCLK_ref_freq;
  146.         u16 MCLK_ref_divider;
  147.         u32 MCLK_min_freq;
  148.         u32 MCLK_max_freq;
  149.         u16 XCLK_ref_freq;
  150.         u16 XCLK_ref_divider;
  151.         u32 XCLK_min_freq;
  152.         u32 XCLK_max_freq;
  153. } __attribute__ ((packed)) PLL_BLOCK;
  154. struct pll_info {
  155. int ppll_max;
  156. int ppll_min;
  157. int xclk;
  158. int ref_div;
  159. int ref_clk;
  160. };
  161. struct ram_info {
  162. int ml;
  163. int mb;
  164. int trcd;
  165. int trp;
  166. int twr;
  167. int cl;
  168. int tr2w;
  169. int loop_latency;
  170. int rloop;
  171. };
  172. struct radeon_regs {
  173. /* CRTC regs */
  174. u32 crtc_h_total_disp;
  175. u32 crtc_h_sync_strt_wid;
  176. u32 crtc_v_total_disp;
  177. u32 crtc_v_sync_strt_wid;
  178. u32 crtc_pitch;
  179. u32 crtc_gen_cntl;
  180. u32 crtc_ext_cntl;
  181. u32 dac_cntl;
  182. u32 flags;
  183. u32 pix_clock;
  184. int xres, yres;
  185. /* DDA regs */
  186. u32 dda_config;
  187. u32 dda_on_off;
  188. /* PLL regs */
  189. u32 ppll_div_3;
  190. u32 ppll_ref_div;
  191. /* Flat panel regs */
  192. u32 fp_crtc_h_total_disp;
  193. u32 fp_crtc_v_total_disp;
  194. u32 fp_gen_cntl;
  195. u32 fp_h_sync_strt_wid;
  196. u32 fp_horz_stretch;
  197. u32 fp_panel_cntl;
  198. u32 fp_v_sync_strt_wid;
  199. u32 fp_vert_stretch;
  200. u32 lvds_gen_cntl;
  201. u32 lvds_pll_cntl;
  202. u32 tmds_crc;
  203. u32 tmds_transmitter_cntl;
  204. #if defined(__BIG_ENDIAN)
  205. u32 surface_cntl;
  206. #endif
  207. };
  208. struct radeonfb_info {
  209. struct fb_info info;
  210. struct radeon_regs state;
  211. struct radeon_regs init_state;
  212. char name[17];
  213. char ram_type[12];
  214. u32 mmio_base_phys;
  215. u32 fb_base_phys;
  216. u32 mmio_base;
  217. u32 fb_base;
  218. struct pci_dev *pdev;
  219. unsigned char *EDID;
  220. unsigned char *bios_seg;
  221. struct display disp;
  222. int currcon;
  223. struct display *currcon_display;
  224. struct { u8 red, green, blue, pad; } palette[256];
  225. int chipset;
  226. int video_ram;
  227. u8 rev;
  228. int pitch, bpp, depth;
  229. int xres, yres, pixclock;
  230. int use_default_var;
  231. int got_dfpinfo;
  232. int hasCRTC2;
  233. int crtDisp_type;
  234. int dviDisp_type;
  235. int panel_xres, panel_yres;
  236. int clock;
  237. int hOver_plus, hSync_width, hblank;
  238. int vOver_plus, vSync_width, vblank;
  239. int hAct_high, vAct_high, interlaced;
  240. int synct, misc;
  241. u32 dp_gui_master_cntl;
  242. struct pll_info pll;
  243. int pll_output_freq, post_div, fb_div;
  244. struct ram_info ram;
  245.         u32 hack_crtc_ext_cntl;
  246.         u32 hack_crtc_v_sync_strt_wid;
  247. #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
  248.         union {
  249. #if defined(FBCON_HAS_CFB16)
  250.                 u_int16_t cfb16[16];
  251. #endif
  252. #if defined(FBCON_HAS_CFB24)
  253.                 u_int32_t cfb24[16];
  254. #endif  
  255. #if defined(FBCON_HAS_CFB32)
  256.                 u_int32_t cfb32[16];
  257. #endif  
  258.         } con_cmap;
  259. #endif  
  260. #ifdef CONFIG_PMAC_PBOOK
  261. unsigned char *save_framebuffer;
  262. int pm_reg;
  263. #endif
  264. struct radeonfb_info *next;
  265. };
  266. static struct fb_var_screeninfo radeonfb_default_var = {
  267.         640, 480, 640, 480, 0, 0, 8, 0,
  268.         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
  269.         0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
  270.         0, FB_VMODE_NONINTERLACED
  271. };
  272. /*
  273.  * IO macros
  274.  */
  275. #define INREG8(addr) readb((rinfo->mmio_base)+addr)
  276. #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
  277. #define INREG(addr) readl((rinfo->mmio_base)+addr)
  278. #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
  279. #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); 
  280. OUTREG(CLOCK_CNTL_DATA, val)
  281. #define OUTPLLP(addr,val,mask)  
  282. do {
  283. unsigned int _tmp = INPLL(addr);
  284. _tmp &= (mask);
  285. _tmp |= (val);
  286. OUTPLL(addr, _tmp);
  287. } while (0)
  288. #define OUTREGP(addr,val,mask)  
  289. do {
  290. unsigned int _tmp = INREG(addr);
  291. _tmp &= (mask);
  292. _tmp |= (val);
  293. OUTREG(addr, _tmp);
  294. } while (0)
  295. static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
  296. {
  297. OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
  298. return (INREG(CLOCK_CNTL_DATA));
  299. }
  300. #define INPLL(addr) _INPLL(rinfo, addr)
  301. #define PRIMARY_MONITOR(rinfo) ((rinfo->dviDisp_type != MT_NONE) &&
  302.  (rinfo->dviDisp_type != MT_STV) &&
  303.  (rinfo->dviDisp_type != MT_CTV) ?
  304.  rinfo->dviDisp_type : rinfo->crtDisp_type)
  305. static char *GET_MON_NAME(int type)
  306. {
  307. char *pret = NULL;
  308. switch (type) {
  309. case MT_NONE:
  310. pret = "no";
  311. break;
  312. case MT_CRT:
  313. pret = "CRT";
  314. break;
  315. case MT_DFP:
  316. pret = "DFP";
  317. break;
  318. case MT_LCD:
  319. pret = "LCD";
  320. break;
  321. case MT_CTV:
  322. pret = "CTV";
  323. break;
  324. case MT_STV:
  325. pret = "STV";
  326. break;
  327. }
  328. return pret;
  329. }
  330. /*
  331.  * 2D engine routines
  332.  */
  333. static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
  334. {
  335. int i;
  336. /* initiate flush */
  337. OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
  338.         ~RB2D_DC_FLUSH_ALL);
  339. for (i=0; i < 2000000; i++) {
  340. if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
  341. break;
  342. }
  343. }
  344. static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
  345. {
  346. int i;
  347. for (i=0; i<2000000; i++)
  348. if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
  349. return;
  350. }
  351. static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
  352. {
  353. int i;
  354. /* ensure FIFO is empty before waiting for idle */
  355. _radeon_fifo_wait (rinfo, 64);
  356. for (i=0; i<2000000; i++) {
  357. if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
  358. radeon_engine_flush (rinfo);
  359. return;
  360. }
  361. }
  362. }
  363. #define radeon_engine_idle() _radeon_engine_idle(rinfo)
  364. #define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
  365. /*
  366.  * helper routines
  367.  */
  368. static __inline__ u32 radeon_get_dstbpp(u16 depth)
  369. {
  370. switch (depth) {
  371. case 8:
  372. return DST_8BPP;
  373. case 15:
  374. return DST_15BPP;
  375. case 16:
  376. return DST_16BPP;
  377. case 32:
  378. return DST_32BPP;
  379. default:
  380. return 0;
  381. }
  382. }
  383. static inline int var_to_depth(const struct fb_var_screeninfo *var)
  384. {
  385. if (var->bits_per_pixel != 16)
  386. return var->bits_per_pixel;
  387. return (var->green.length == 6) ? 16 : 15;
  388. }
  389. static void _radeon_engine_reset(struct radeonfb_info *rinfo)
  390. {
  391. u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
  392. radeon_engine_flush (rinfo);
  393. clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
  394. mclk_cntl = INPLL(MCLK_CNTL);
  395. OUTPLL(MCLK_CNTL, (mclk_cntl |
  396.    FORCEON_MCLKA |
  397.    FORCEON_MCLKB |
  398.    FORCEON_YCLKA |
  399.    FORCEON_YCLKB |
  400.    FORCEON_MC |
  401.    FORCEON_AIC));
  402. rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
  403. OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
  404. SOFT_RESET_CP |
  405. SOFT_RESET_HI |
  406. SOFT_RESET_SE |
  407. SOFT_RESET_RE |
  408. SOFT_RESET_PP |
  409. SOFT_RESET_E2 |
  410. SOFT_RESET_RB |
  411. SOFT_RESET_HDP);
  412. INREG(RBBM_SOFT_RESET);
  413. OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
  414. ~(SOFT_RESET_CP |
  415.   SOFT_RESET_HI |
  416.   SOFT_RESET_SE |
  417.   SOFT_RESET_RE |
  418.   SOFT_RESET_PP |
  419.   SOFT_RESET_E2 |
  420.   SOFT_RESET_RB |
  421.   SOFT_RESET_HDP));
  422. INREG(RBBM_SOFT_RESET);
  423. OUTPLL(MCLK_CNTL, mclk_cntl);
  424. OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
  425. OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
  426. return;
  427. }
  428. #define radeon_engine_reset() _radeon_engine_reset(rinfo)
  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. static __inline__ int round_div(int num, int den)
  451. {
  452.         return (num + (den / 2)) / den;
  453. }
  454. static __inline__ int min_bits_req(int val)
  455. {
  456.         int bits_req = 0;
  457.                 
  458.         if (val == 0)
  459.                 bits_req = 1;
  460.                         
  461.         while (val) {
  462.                 val >>= 1;
  463.                 bits_req++;
  464.         }       
  465.         return (bits_req);
  466. }
  467. static __inline__ int _max(int val1, int val2)
  468. {
  469.         if (val1 >= val2)
  470.                 return val1;
  471.         else
  472.                 return val2;
  473. }                       
  474. /*
  475.  * globals
  476.  */
  477.         
  478. static char fontname[40] __initdata;
  479. static char *mode_option __initdata;
  480. static char noaccel __initdata = 0;
  481. static int panel_yres __initdata = 0;
  482. static char force_dfp __initdata = 0;
  483. static struct radeonfb_info *board_list = NULL;
  484. #ifdef FBCON_HAS_CFB8
  485. static struct display_switch fbcon_radeon8;
  486. #endif
  487. /*
  488.  * prototypes
  489.  */
  490. static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
  491.                              struct fb_info *info);
  492. static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
  493.                              struct fb_info *info);
  494. static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
  495.                              struct fb_info *info);
  496. static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
  497.                               struct fb_info *info);
  498. static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
  499.                               struct fb_info *info);
  500. static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
  501.                                  struct fb_info *info);
  502. static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
  503.                            unsigned long arg, int con, struct fb_info *info);
  504. static int radeonfb_switch (int con, struct fb_info *info);
  505. static int radeonfb_updatevar (int con, struct fb_info *info);
  506. static void radeonfb_blank (int blank, struct fb_info *info);
  507. static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
  508. static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
  509.                              unsigned *blue, unsigned *transp,
  510.                              struct fb_info *info);
  511. static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
  512.                              unsigned blue, unsigned transp, struct fb_info *info);
  513. static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
  514. static void radeon_save_state (struct radeonfb_info *rinfo,
  515.                                struct radeon_regs *save);
  516. static void radeon_engine_init (struct radeonfb_info *rinfo);
  517. static void radeon_load_video_mode (struct radeonfb_info *rinfo,
  518.                                     struct fb_var_screeninfo *mode);
  519. static void radeon_write_mode (struct radeonfb_info *rinfo,
  520.                                struct radeon_regs *mode);
  521. static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
  522. static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
  523. static int radeon_init_disp_var (struct radeonfb_info *rinfo);
  524. static int radeonfb_pci_register (struct pci_dev *pdev,
  525.                                  const struct pci_device_id *ent);
  526. static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
  527. static char *radeon_find_rom(struct radeonfb_info *rinfo);
  528. static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
  529. static void radeon_get_moninfo (struct radeonfb_info *rinfo);
  530. static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
  531. static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
  532. static void radeon_get_EDID(struct radeonfb_info *rinfo);
  533. static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
  534. static void radeon_update_default_var(struct radeonfb_info *rinfo);
  535. #ifdef CONFIG_ALL_PPC
  536. static int radeon_read_OF (struct radeonfb_info *rinfo);
  537. static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
  538. extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
  539. #ifdef CONFIG_PMAC_PBOOK
  540. int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
  541. static struct pmu_sleep_notifier radeon_sleep_notifier = {
  542. radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
  543. };
  544. static int radeon_set_backlight_enable(int on, int level, void *data);
  545. static int radeon_set_backlight_level(int level, void *data);
  546. static struct backlight_controller radeon_backlight_controller = {
  547. radeon_set_backlight_enable,
  548. radeon_set_backlight_level
  549. };
  550. #endif /* CONFIG_PMAC_PBOOK */
  551. #endif /* CONFIG_ALL_PPC */
  552. static struct fb_ops radeon_fb_ops = {
  553. fb_get_fix: radeonfb_get_fix,
  554. fb_get_var: radeonfb_get_var,
  555. fb_set_var: radeonfb_set_var,
  556. fb_get_cmap: radeonfb_get_cmap,
  557. fb_set_cmap: radeonfb_set_cmap,
  558. fb_pan_display: radeonfb_pan_display,
  559. fb_ioctl: radeonfb_ioctl,
  560. };
  561. static struct pci_driver radeonfb_driver = {
  562. name: "radeonfb",
  563. id_table: radeonfb_pci_table,
  564. probe: radeonfb_pci_register,
  565. remove: __devexit_p(radeonfb_pci_unregister),
  566. };
  567. int __init radeonfb_init (void)
  568. {
  569. return pci_module_init (&radeonfb_driver);
  570. }
  571. void __exit radeonfb_exit (void)
  572. {
  573. pci_unregister_driver (&radeonfb_driver);
  574. }
  575. int __init radeonfb_setup (char *options)
  576. {
  577.         char *this_opt;
  578.         if (!options || !*options)
  579.                 return 0;
  580.  
  581. while ((this_opt = strsep (&options, ",")) != NULL) {
  582. if (!*this_opt)
  583. continue;
  584.                 if (!strncmp (this_opt, "font:", 5)) {
  585.                         char *p;
  586.                         int i;
  587.         
  588.                         p = this_opt + 5;
  589.                         for (i=0; i<sizeof (fontname) - 1; i++)
  590.                                 if (!*p || *p == ' ' || *p == ',')
  591.                                         break;
  592.                         memcpy(fontname, this_opt + 5, i);
  593.                 } else if (!strncmp(this_opt, "noaccel", 7)) {
  594. noaccel = 1;
  595. } else if (!strncmp(this_opt, "dfp", 3)) {
  596. force_dfp = 1;
  597. } else if (!strncmp(this_opt, "panel_yres:", 11)) {
  598. panel_yres = simple_strtoul((this_opt+11), NULL, 0);
  599.                 } else
  600. mode_option = this_opt;
  601.         }
  602. return 0;
  603. }
  604. #ifdef MODULE
  605. module_init(radeonfb_init);
  606. module_exit(radeonfb_exit);
  607. #endif
  608. MODULE_AUTHOR("Ani Joshi");
  609. MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
  610. MODULE_LICENSE("GPL");
  611. static int radeonfb_pci_register (struct pci_dev *pdev,
  612.   const struct pci_device_id *ent)
  613. {
  614. struct radeonfb_info *rinfo;
  615. u32 tmp;
  616. int i, j;
  617. RTRACE("radeonfb_pci_register BEGINn");
  618. rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
  619. if (!rinfo) {
  620. printk ("radeonfb: could not allocate memoryn");
  621. return -ENODEV;
  622. }
  623. memset (rinfo, 0, sizeof (struct radeonfb_info));
  624. rinfo->pdev = pdev;
  625. /* enable device */
  626. {
  627. int err;
  628. if ((err = pci_enable_device(pdev))) {
  629. printk("radeonfb: cannot enable devicen");
  630. kfree (rinfo);
  631. return -ENODEV;
  632. }
  633. }
  634. /* set base addrs */
  635. rinfo->fb_base_phys = pci_resource_start (pdev, 0);
  636. rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
  637. /* request the mem regions */
  638. if (!request_mem_region (rinfo->fb_base_phys,
  639.  pci_resource_len(pdev, 0), "radeonfb")) {
  640. printk ("radeonfb: cannot reserve FB regionn");
  641. kfree (rinfo);
  642. return -ENODEV;
  643. }
  644. if (!request_mem_region (rinfo->mmio_base_phys,
  645.  pci_resource_len(pdev, 2), "radeonfb")) {
  646. printk ("radeonfb: cannot reserve MMIO regionn");
  647. release_mem_region (rinfo->fb_base_phys,
  648.     pci_resource_len(pdev, 0));
  649. kfree (rinfo);
  650. return -ENODEV;
  651. }
  652. /* map the regions */
  653. rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
  654.          RADEON_REGSIZE);
  655. if (!rinfo->mmio_base) {
  656. printk ("radeonfb: cannot map MMIOn");
  657. release_mem_region (rinfo->mmio_base_phys,
  658.     pci_resource_len(pdev, 2));
  659. release_mem_region (rinfo->fb_base_phys,
  660.     pci_resource_len(pdev, 0));
  661. kfree (rinfo);
  662. return -ENODEV;
  663. }
  664. rinfo->chipset = pdev->device;
  665. /* chipset */
  666. switch (pdev->device) {
  667. case PCI_DEVICE_ID_RADEON_QD:
  668. strcpy(rinfo->name, "Radeon QD ");
  669. break;
  670. case PCI_DEVICE_ID_RADEON_QE:
  671. strcpy(rinfo->name, "Radeon QE ");
  672. break;
  673. case PCI_DEVICE_ID_RADEON_QF:
  674. strcpy(rinfo->name, "Radeon QF ");
  675. break;
  676. case PCI_DEVICE_ID_RADEON_QG:
  677. strcpy(rinfo->name, "Radeon QG ");
  678. break;
  679. case PCI_DEVICE_ID_RADEON_QY:
  680. strcpy(rinfo->name, "Radeon QY VE ");
  681. rinfo->hasCRTC2 = 1;
  682. break;
  683. case PCI_DEVICE_ID_RADEON_QZ:
  684. strcpy(rinfo->name, "Radeon QZ VE ");
  685. rinfo->hasCRTC2 = 1;
  686. break;
  687. case PCI_DEVICE_ID_RADEON_QW:
  688. strcpy(rinfo->name, "Radeon 7500 QW ");
  689. rinfo->hasCRTC2 = 1;
  690. break;
  691. case PCI_DEVICE_ID_RADEON_QL:
  692. strcpy(rinfo->name, "Radeon 8500 QL ");
  693. rinfo->hasCRTC2 = 1;
  694. break;
  695. case PCI_DEVICE_ID_RADEON_LW:
  696. strcpy(rinfo->name, "Radeon M7 LW ");
  697. rinfo->hasCRTC2 = 1;
  698. break;
  699. case PCI_DEVICE_ID_RADEON_LY:
  700. strcpy(rinfo->name, "Radeon M6 LY ");
  701. rinfo->hasCRTC2 = 1;
  702. break;
  703. case PCI_DEVICE_ID_RADEON_LZ:
  704. strcpy(rinfo->name, "Radeon M6 LZ ");
  705. rinfo->hasCRTC2 = 1;
  706. break;
  707. default:
  708. return -ENODEV;
  709. }
  710. /* framebuffer size */
  711. tmp = INREG(CONFIG_MEMSIZE);
  712. /* mem size is bits [28:0], mask off the rest */
  713. rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
  714. /* ram type */
  715. tmp = INREG(MEM_SDRAM_MODE_REG);
  716. switch ((MEM_CFG_TYPE & tmp) >> 30) {
  717. case 0:
  718. /* SDR SGRAM (2:1) */
  719. strcpy(rinfo->ram_type, "SDR SGRAM");
  720. rinfo->ram.ml = 4;
  721. rinfo->ram.mb = 4;
  722. rinfo->ram.trcd = 1;
  723. rinfo->ram.trp = 2;
  724. rinfo->ram.twr = 1;
  725. rinfo->ram.cl = 2;
  726. rinfo->ram.loop_latency = 16;
  727. rinfo->ram.rloop = 16;
  728. break;
  729. case 1:
  730. /* DDR SGRAM */
  731. strcpy(rinfo->ram_type, "DDR SGRAM");
  732. rinfo->ram.ml = 4;
  733. rinfo->ram.mb = 4;
  734. rinfo->ram.trcd = 3;
  735. rinfo->ram.trp = 3;
  736. rinfo->ram.twr = 2;
  737. rinfo->ram.cl = 3;
  738. rinfo->ram.tr2w = 1;
  739. rinfo->ram.loop_latency = 16;
  740. rinfo->ram.rloop = 16;
  741. break;
  742. default:
  743. /* 64-bit SDR SGRAM */
  744. strcpy(rinfo->ram_type, "SDR SGRAM 64");
  745. rinfo->ram.ml = 4;
  746. rinfo->ram.mb = 8;
  747. rinfo->ram.trcd = 3;
  748. rinfo->ram.trp = 3;
  749. rinfo->ram.twr = 1;
  750. rinfo->ram.cl = 3;
  751. rinfo->ram.tr2w = 1;
  752. rinfo->ram.loop_latency = 17;
  753. rinfo->ram.rloop = 17;
  754. break;
  755. }
  756. rinfo->bios_seg = radeon_find_rom(rinfo);
  757. radeon_get_pllinfo(rinfo, rinfo->bios_seg);
  758. RTRACE("radeonfb: probed %s %dk videoramn", (rinfo->ram_type), (rinfo->video_ram/1024));
  759. #if !defined(__powerpc__)
  760. radeon_get_moninfo(rinfo);
  761. #else
  762. switch (pdev->device) {
  763. case PCI_DEVICE_ID_RADEON_LW:
  764. case PCI_DEVICE_ID_RADEON_LY:
  765. case PCI_DEVICE_ID_RADEON_LZ:
  766. rinfo->dviDisp_type = MT_LCD;
  767. break;
  768. default:
  769. radeon_get_moninfo(rinfo);
  770. break;
  771. }
  772. #endif
  773. radeon_get_EDID(rinfo);
  774. if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
  775.     (rinfo->crtDisp_type == MT_DFP)) {
  776. if (!radeon_get_dfpinfo(rinfo)) {
  777. iounmap ((void*)rinfo->mmio_base);
  778. release_mem_region (rinfo->mmio_base_phys,
  779.     pci_resource_len(pdev, 2));
  780. release_mem_region (rinfo->fb_base_phys,
  781.     pci_resource_len(pdev, 0));
  782. kfree (rinfo);
  783. return -ENODEV;
  784. }
  785. }
  786. rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
  787.      rinfo->video_ram);
  788. if (!rinfo->fb_base) {
  789. printk ("radeonfb: cannot map FBn");
  790. iounmap ((void*)rinfo->mmio_base);
  791. release_mem_region (rinfo->mmio_base_phys,
  792.     pci_resource_len(pdev, 2));
  793. release_mem_region (rinfo->fb_base_phys,
  794.     pci_resource_len(pdev, 0));
  795. kfree (rinfo);
  796. return -ENODEV;
  797. }
  798. /* XXX turn off accel for now, blts aren't working right */
  799. noaccel = 1;
  800. /* currcon not yet configured, will be set by first switch */
  801. rinfo->currcon = -1;
  802. /* set all the vital stuff */
  803. radeon_set_fbinfo (rinfo);
  804. /* save current mode regs before we switch into the new one
  805.  * so we can restore this upon __exit
  806.  */
  807. radeon_save_state (rinfo, &rinfo->init_state);
  808. /* init palette */
  809. for (i=0; i<16; i++) {
  810. j = color_table[i];
  811. rinfo->palette[i].red = default_red[j];
  812. rinfo->palette[i].green = default_grn[j];
  813. rinfo->palette[i].blue = default_blu[j];
  814. }
  815. pci_set_drvdata(pdev, rinfo);
  816. rinfo->next = board_list;
  817. board_list = rinfo;
  818. if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
  819. printk ("radeonfb: could not register framebuffern");
  820. iounmap ((void*)rinfo->fb_base);
  821. iounmap ((void*)rinfo->mmio_base);
  822. release_mem_region (rinfo->mmio_base_phys,
  823.     pci_resource_len(pdev, 2));
  824. release_mem_region (rinfo->fb_base_phys,
  825.     pci_resource_len(pdev, 0));
  826. kfree (rinfo);
  827. return -ENODEV;
  828. }
  829. if (!noaccel) {
  830. /* initialize the engine */
  831. radeon_engine_init (rinfo);
  832. }
  833. #ifdef CONFIG_PMAC_BACKLIGHT
  834. if (rinfo->dviDisp_type == MT_LCD)
  835. register_backlight_controller(&radeon_backlight_controller,
  836.       rinfo, "ati");
  837. #endif
  838. #ifdef CONFIG_PMAC_PBOOK
  839. if (rinfo->dviDisp_type == MT_LCD) {
  840. rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
  841. pmu_register_sleep_notifier(&radeon_sleep_notifier);
  842. }
  843. #endif
  844. printk ("radeonfb: ATI %s %s %d MBn", rinfo->name, rinfo->ram_type,
  845. (rinfo->video_ram/(1024*1024)));
  846. if (rinfo->hasCRTC2) {
  847. printk("radeonfb: DVI port %s monitor connectedn",
  848. GET_MON_NAME(rinfo->dviDisp_type));
  849. printk("radeonfb: CRT port %s monitor connectedn",
  850. GET_MON_NAME(rinfo->crtDisp_type));
  851. } else {
  852. printk("radeonfb: CRT port %s monitor connectedn",
  853. GET_MON_NAME(rinfo->crtDisp_type));
  854. }
  855. RTRACE("radeonfb_pci_register ENDn");
  856. return 0;
  857. }
  858. static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
  859. {
  860.         struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
  861.  
  862.         if (!rinfo)
  863.                 return;
  864.  
  865. /* restore original state */
  866.         radeon_write_mode (rinfo, &rinfo->init_state);
  867.  
  868.         unregister_framebuffer ((struct fb_info *) rinfo);
  869.                 
  870.         iounmap ((void*)rinfo->mmio_base);
  871.         iounmap ((void*)rinfo->fb_base);
  872.  
  873. release_mem_region (rinfo->mmio_base_phys,
  874.     pci_resource_len(pdev, 2));
  875. release_mem_region (rinfo->fb_base_phys,
  876.     pci_resource_len(pdev, 0));
  877.         
  878.         kfree (rinfo);
  879. }
  880. static char *radeon_find_rom(struct radeonfb_info *rinfo)
  881. {       
  882. #if defined(__i386__)
  883.         u32  segstart;
  884.         char *rom_base;
  885.         char *rom;
  886.         int  stage;
  887.         int  i,j;       
  888.         char aty_rom_sig[] = "761295520";
  889.         char *radeon_sig[] = {
  890.           "RG6",
  891.           "RADEON"
  892.         };
  893.                                                 
  894.         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
  895.                         
  896.                 stage = 1;
  897.                 
  898.                 rom_base = (char *)ioremap(segstart, 0x1000);
  899.                 if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
  900.                         stage = 2;
  901.                 
  902.                     
  903.                 if (stage != 2) {
  904.                         iounmap(rom_base);
  905.                         continue;
  906.                 }
  907.                                               
  908.                 rom = rom_base;
  909.                      
  910.                 for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
  911.                         if (aty_rom_sig[0] == *rom)
  912.                                 if (strncmp(aty_rom_sig, rom,
  913.                                                 strlen(aty_rom_sig)) == 0)
  914.                                         stage = 3;
  915.                         rom++;
  916.                 }
  917.                 if (stage != 3) {
  918.                         iounmap(rom_base);
  919.                         continue;
  920.                 }
  921.                 rom = rom_base;
  922.         
  923.                 for (i = 0; (i < 512) && (stage != 4); i++) {
  924.                     for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) {
  925.                         if (radeon_sig[j][0] == *rom)
  926.                                 if (strncmp(radeon_sig[j], rom,
  927.                                             strlen(radeon_sig[j])) == 0) {
  928.                                               stage = 4;
  929.                                               break;
  930.                                             }
  931.                     }                           
  932.                         rom++;
  933.                 }       
  934.                 if (stage != 4) {
  935.                         iounmap(rom_base);
  936.                         continue;
  937.                 }       
  938.                 
  939.                 return rom_base;
  940.         }
  941. #endif          
  942.         return NULL;
  943. }
  944. static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
  945. {
  946.         void *bios_header;
  947.         void *header_ptr;
  948.         u16 bios_header_offset, pll_info_offset;
  949.         PLL_BLOCK pll;
  950. if (bios_seg) {
  951.         bios_header = bios_seg + 0x48L;
  952.         header_ptr  = bios_header;
  953.         
  954.          bios_header_offset = readw(header_ptr);
  955.         bios_header = bios_seg + bios_header_offset;
  956.          bios_header += 0x30;
  957.         
  958.          header_ptr = bios_header;
  959.          pll_info_offset = readw(header_ptr);
  960.          header_ptr = bios_seg + pll_info_offset;
  961.         
  962.          memcpy_fromio(&pll, header_ptr, 50);
  963.         
  964.          rinfo->pll.xclk = (u32)pll.XCLK;
  965.          rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
  966.          rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
  967.          rinfo->pll.ppll_min = pll.PCLK_min_freq;
  968.          rinfo->pll.ppll_max = pll.PCLK_max_freq;
  969. printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOSn",
  970. rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
  971. } else {
  972. #ifdef CONFIG_ALL_PPC
  973. if (radeon_read_OF(rinfo)) {
  974. unsigned int tmp, Nx, M, ref_div, xclk;
  975. tmp = INPLL(M_SPLL_REF_FB_DIV);
  976. ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
  977. Nx = (tmp & 0xff00) >> 8;
  978. M = (tmp & 0xff);
  979. xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
  980. (2 * M)));
  981. rinfo->pll.xclk = xclk;
  982. rinfo->pll.ref_div = ref_div;
  983. rinfo->pll.ppll_min = 12000;
  984. rinfo->pll.ppll_max = 35000;
  985. printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OFn",
  986. rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
  987. return;
  988. }
  989. #endif
  990. /* no BIOS or BIOS not found, use defaults */
  991. switch (rinfo->chipset) {
  992. case PCI_DEVICE_ID_RADEON_QW:
  993. rinfo->pll.ppll_max = 35000;
  994. rinfo->pll.ppll_min = 12000;
  995. rinfo->pll.xclk = 23000;
  996. rinfo->pll.ref_div = 12;
  997. rinfo->pll.ref_clk = 2700;
  998. break;
  999. case PCI_DEVICE_ID_RADEON_QL:
  1000. rinfo->pll.ppll_max = 35000;
  1001. rinfo->pll.ppll_min = 12000;
  1002. rinfo->pll.xclk = 27500;
  1003. rinfo->pll.ref_div = 12;
  1004. rinfo->pll.ref_clk = 2700;
  1005. break;
  1006. case PCI_DEVICE_ID_RADEON_QD:
  1007. case PCI_DEVICE_ID_RADEON_QE:
  1008. case PCI_DEVICE_ID_RADEON_QF:
  1009. case PCI_DEVICE_ID_RADEON_QG:
  1010. default:
  1011. rinfo->pll.ppll_max = 35000;
  1012. rinfo->pll.ppll_min = 12000;
  1013. rinfo->pll.xclk = 16600;
  1014. rinfo->pll.ref_div = 67;
  1015. rinfo->pll.ref_clk = 2700;
  1016. break;
  1017. }
  1018. printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaultsn",
  1019. rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
  1020. }
  1021. }
  1022. static void radeon_get_moninfo (struct radeonfb_info *rinfo)
  1023. {
  1024. unsigned int tmp;
  1025. if (force_dfp) {
  1026. rinfo->dviDisp_type = MT_DFP;
  1027. return;
  1028. }
  1029. tmp = INREG(RADEON_BIOS_4_SCRATCH);
  1030. if (rinfo->hasCRTC2) {
  1031. /* primary DVI port */
  1032. if (tmp & 0x08)
  1033. rinfo->dviDisp_type = MT_DFP;
  1034. else if (tmp & 0x4)
  1035. rinfo->dviDisp_type = MT_LCD;
  1036. else if (tmp & 0x200)
  1037. rinfo->dviDisp_type = MT_CRT;
  1038. else if (tmp & 0x10)
  1039. rinfo->dviDisp_type = MT_CTV;
  1040. else if (tmp & 0x20)
  1041. rinfo->dviDisp_type = MT_STV;
  1042. /* secondary CRT port */
  1043. if (tmp & 0x2)
  1044. rinfo->crtDisp_type = MT_CRT;
  1045. else if (tmp & 0x800)
  1046. rinfo->crtDisp_type = MT_DFP;
  1047. else if (tmp & 0x400)
  1048. rinfo->crtDisp_type = MT_LCD;
  1049. else if (tmp & 0x1000)
  1050. rinfo->crtDisp_type = MT_CTV;
  1051. else if (tmp & 0x2000)
  1052. rinfo->crtDisp_type = MT_STV;
  1053. } else {
  1054. rinfo->dviDisp_type = MT_NONE;
  1055. tmp = INREG(FP_GEN_CNTL);
  1056. if (tmp & FP_EN_TMDS)
  1057. rinfo->crtDisp_type = MT_DFP;
  1058. else
  1059. rinfo->crtDisp_type = MT_CRT;
  1060. }
  1061. }
  1062. static void radeon_get_EDID(struct radeonfb_info *rinfo)
  1063. {
  1064. #ifdef CONFIG_ALL_PPC
  1065. if (!radeon_get_EDID_OF(rinfo))
  1066. RTRACE("radeonfb: could not retrieve EDID from OFn");
  1067. #else
  1068. /* XXX use other methods later */
  1069. #endif
  1070. }
  1071. #ifdef CONFIG_ALL_PPC
  1072. static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
  1073. {
  1074. struct device_node *dp;
  1075. unsigned char *pedid = NULL;
  1076. dp = pci_device_to_OF_node(rinfo->pdev);
  1077. pedid = (unsigned char *) get_property(dp, "DFP,EDID", 0);
  1078. if (!pedid)
  1079. pedid = (unsigned char *) get_property(dp, "LCD,EDID", 0);
  1080. if (!pedid)
  1081. pedid = (unsigned char *) get_property(dp, "EDID", 0);
  1082. if (pedid) {
  1083. rinfo->EDID = pedid;
  1084. return 1;
  1085. } else
  1086. return 0;
  1087. }
  1088. #endif /* CONFIG_ALL_PPC */
  1089. static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
  1090. {
  1091. unsigned char *block = rinfo->EDID;
  1092. if (!block)
  1093. return 0;
  1094. /* jump to the detailed timing block section */
  1095. block += 54;
  1096. rinfo->clock = (block[0] + (block[1] << 8));
  1097. rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
  1098. rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
  1099. rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
  1100. rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
  1101. rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
  1102. rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
  1103. rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
  1104. rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
  1105. rinfo->interlaced = ((block[17] & 0x80) >> 7);
  1106. rinfo->synct = ((block[17] & 0x18) >> 3);
  1107. rinfo->misc = ((block[17] & 0x06) >> 1);
  1108. rinfo->hAct_high = rinfo->vAct_high = 0;
  1109. if (rinfo->synct == 3) {
  1110. if (rinfo->misc & 2)
  1111. rinfo->hAct_high = 1;
  1112. if (rinfo->misc & 1)
  1113. rinfo->vAct_high = 1;
  1114. }
  1115. printk("radeonfb: detected DFP panel size from EDID: %dx%dn",
  1116. rinfo->panel_xres, rinfo->panel_yres);
  1117. rinfo->got_dfpinfo = 1;
  1118. return 1;
  1119. }
  1120. static void radeon_update_default_var(struct radeonfb_info *rinfo)
  1121. {
  1122. struct fb_var_screeninfo *var = &radeonfb_default_var;
  1123. var->xres = rinfo->panel_xres;
  1124. var->yres = rinfo->panel_yres;
  1125. var->xres_virtual = rinfo->panel_xres;
  1126. var->yres_virtual = rinfo->panel_yres;
  1127. var->xoffset = var->yoffset = 0;
  1128. var->bits_per_pixel = 8;
  1129. var->pixclock = 100000000 / rinfo->clock;
  1130. var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
  1131. var->right_margin = rinfo->hOver_plus;
  1132. var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
  1133. var->lower_margin = rinfo->vOver_plus;
  1134. var->hsync_len = rinfo->hSync_width;
  1135. var->vsync_len = rinfo->vSync_width;
  1136. var->sync = 0;
  1137. if (rinfo->synct == 3) {
  1138. if (rinfo->hAct_high)
  1139. var->sync |= FB_SYNC_HOR_HIGH_ACT;
  1140. if (rinfo->vAct_high)
  1141. var->sync |= FB_SYNC_VERT_HIGH_ACT;
  1142. }
  1143. var->vmode = 0;
  1144. if (rinfo->interlaced)
  1145. var->vmode |= FB_VMODE_INTERLACED;
  1146. rinfo->use_default_var = 1;
  1147. }
  1148. static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
  1149. {
  1150. char *fpbiosstart, *tmp, *tmp0;
  1151. char stmp[30];
  1152. int i;
  1153. if (!rinfo->bios_seg)
  1154. return 0;
  1155. if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
  1156. printk("radeonfb: Failed to detect DFP panel info using BIOSn");
  1157. return 0;
  1158. }
  1159. if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
  1160. printk("radeonfb: Failed to detect DFP panel info using BIOSn");
  1161. return 0;
  1162. }
  1163. for(i=0; i<24; i++)
  1164. stmp[i] = readb(tmp+i+1);
  1165. stmp[24] = 0;
  1166. printk("radeonfb: panel ID string: %sn", stmp);
  1167. rinfo->panel_xres = readw(tmp + 25);
  1168. rinfo->panel_yres = readw(tmp + 27);
  1169. printk("radeonfb: detected DFP panel size from BIOS: %dx%dn",
  1170. rinfo->panel_xres, rinfo->panel_yres);
  1171. for(i=0; i<20; i++) {
  1172. tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
  1173. if (tmp0 == 0)
  1174. break;
  1175. if ((readw(tmp0) == rinfo->panel_xres) &&
  1176.     (readw(tmp0+2) == rinfo->panel_yres)) {
  1177. rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
  1178. rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
  1179. rinfo->hSync_width = readb(tmp0+23) * 8;
  1180. rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
  1181. rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
  1182. rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
  1183. rinfo->clock = readw(tmp0+9);
  1184. rinfo->got_dfpinfo = 1;
  1185. return 1;
  1186. }
  1187. }
  1188. return 0;
  1189. }
  1190. static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
  1191. {
  1192. unsigned int tmp;
  1193. unsigned short a, b;
  1194. if (radeon_get_dfpinfo_BIOS(rinfo))
  1195. radeon_update_default_var(rinfo);
  1196. if (radeon_dfp_parse_EDID(rinfo))
  1197. radeon_update_default_var(rinfo);
  1198. if (!rinfo->got_dfpinfo) {
  1199. /*
  1200.  * it seems all else has failed now and we
  1201.  * resort to probing registers for our DFP info
  1202.          */
  1203. if (panel_yres) {
  1204. rinfo->panel_yres = panel_yres;
  1205. } else {
  1206. tmp = INREG(FP_VERT_STRETCH);
  1207. tmp &= 0x00fff000;
  1208. rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
  1209. }
  1210. switch (rinfo->panel_yres) {
  1211. case 480:
  1212. rinfo->panel_xres = 640;
  1213. break;
  1214. case 600:
  1215. rinfo->panel_xres = 800;
  1216. break;
  1217. case 768:
  1218. #if defined(__powerpc__)
  1219. if (rinfo->dviDisp_type == MT_LCD)
  1220. rinfo->panel_xres = 1152;
  1221. else
  1222. #endif
  1223. rinfo->panel_xres = 1024;
  1224. break;
  1225. case 1024:
  1226. rinfo->panel_xres = 1280;
  1227. break;
  1228. case 1050:
  1229. rinfo->panel_xres = 1400;
  1230. break;
  1231. case 1200:
  1232. rinfo->panel_xres = 1600;
  1233. break;
  1234. default:
  1235. printk("radeonfb: Failed to detect DFP panel sizen");
  1236. return 0;
  1237. }
  1238. printk("radeonfb: detected DFP panel size from registers: %dx%dn",
  1239. rinfo->panel_xres, rinfo->panel_yres);
  1240. tmp = INREG(FP_CRTC_H_TOTAL_DISP);
  1241. a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
  1242. b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
  1243. rinfo->hblank = (a - b + 1) * 8;
  1244. tmp = INREG(FP_H_SYNC_STRT_WID);
  1245. rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
  1246. FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
  1247. rinfo->hOver_plus *= 8;
  1248. rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
  1249. FP_H_SYNC_WID_SHIFT);
  1250. rinfo->hSync_width *= 8;
  1251. tmp = INREG(FP_CRTC_V_TOTAL_DISP);
  1252. a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
  1253. b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
  1254. rinfo->vblank = a - b /* + 24 */ ;
  1255. tmp = INREG(FP_V_SYNC_STRT_WID);
  1256. rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
  1257. - b + 1;
  1258. rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
  1259. FP_V_SYNC_WID_SHIFT);
  1260. return 1;
  1261. }
  1262. return 1;
  1263. }
  1264. #ifdef CONFIG_ALL_PPC
  1265. static int radeon_read_OF (struct radeonfb_info *rinfo)
  1266. {
  1267. struct device_node *dp;
  1268. unsigned int *xtal;
  1269. dp = pci_device_to_OF_node(rinfo->pdev);
  1270. xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
  1271. rinfo->pll.ref_clk = *xtal / 10;
  1272. if (*xtal)
  1273. return 1;
  1274. else
  1275. return 0;
  1276. }
  1277. #endif
  1278. static void radeon_engine_init (struct radeonfb_info *rinfo)
  1279. {
  1280. u32 temp;
  1281. /* disable 3D engine */
  1282. OUTREG(RB3D_CNTL, 0);
  1283. radeon_engine_reset ();
  1284. radeon_fifo_wait (1);
  1285. OUTREG(DSTCACHE_MODE, 0);
  1286. /* XXX */
  1287. rinfo->pitch = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6;
  1288. radeon_fifo_wait (1);
  1289. temp = INREG(DEFAULT_PITCH_OFFSET);
  1290. OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | 
  1291.       (rinfo->pitch << 0x16)));
  1292. radeon_fifo_wait (1);
  1293. OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
  1294. radeon_fifo_wait (1);
  1295. OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
  1296.  DEFAULT_SC_BOTTOM_MAX));
  1297. temp = radeon_get_dstbpp(rinfo->depth);
  1298. rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
  1299. radeon_fifo_wait (1);
  1300. OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
  1301.     GMC_BRUSH_SOLID_COLOR |
  1302.     GMC_SRC_DATATYPE_COLOR));
  1303. radeon_fifo_wait (7);
  1304. /* clear line drawing regs */
  1305. OUTREG(DST_LINE_START, 0);
  1306. OUTREG(DST_LINE_END, 0);
  1307. /* set brush color regs */
  1308. OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
  1309. OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
  1310. /* set source color regs */
  1311. OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
  1312. OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
  1313. /* default write mask */
  1314. OUTREG(DP_WRITE_MSK, 0xffffffff);
  1315. radeon_engine_idle ();
  1316. }
  1317. static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
  1318. {
  1319. struct fb_info *info;
  1320. info = &rinfo->info;
  1321. strcpy (info->modename, rinfo->name);
  1322.         info->node = -1;
  1323.         info->flags = FBINFO_FLAG_DEFAULT;
  1324.         info->fbops = &radeon_fb_ops;
  1325.         info->display_fg = NULL;
  1326.         strncpy (info->fontname, fontname, sizeof (info->fontname));
  1327.         info->fontname[sizeof (info->fontname) - 1] = 0;
  1328.         info->changevar = NULL;
  1329.         info->switch_con = radeonfb_switch;
  1330.         info->updatevar = radeonfb_updatevar;
  1331.         info->blank = radeonfb_blank;
  1332.         if (radeon_init_disp (rinfo) < 0)
  1333.                 return -1;   
  1334.         return 0;
  1335. }
  1336. static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
  1337. {
  1338.         struct fb_info *info;
  1339.         struct display *disp;
  1340.         info = &rinfo->info;
  1341.         disp = &rinfo->disp;
  1342.         
  1343.         disp->var = radeonfb_default_var;
  1344. #if defined(__powerpc__)
  1345. if (rinfo->dviDisp_type == MT_LCD) {
  1346. if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &disp->var))
  1347. disp->var = radeonfb_default_var;
  1348. }
  1349. #endif
  1350. rinfo->depth = var_to_depth(&disp->var);
  1351. rinfo->bpp = disp->var.bits_per_pixel;
  1352.         info->disp = disp;
  1353.         radeon_set_dispsw (rinfo, disp);
  1354. if (noaccel)
  1355.         disp->scrollmode = SCROLL_YREDRAW;
  1356. else
  1357. disp->scrollmode = 0;
  1358.         
  1359.         rinfo->currcon_display = disp;
  1360.         if ((radeon_init_disp_var (rinfo)) < 0)
  1361.                 return -1;
  1362.         
  1363.         return 0;
  1364. }
  1365. static int radeon_init_disp_var (struct radeonfb_info *rinfo)
  1366. {
  1367. #ifndef MODULE
  1368.         if (mode_option)
  1369.                 fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
  1370.                               NULL, 0, NULL, 8);
  1371.         else
  1372. #endif
  1373. #if defined(__powerpc__)
  1374. if (rinfo->dviDisp_type == MT_LCD) {
  1375. if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &rinfo->disp.var))
  1376. rinfo->disp.var = radeonfb_default_var;
  1377. }
  1378. else
  1379. #endif
  1380. if (rinfo->use_default_var)
  1381. /* We will use the modified default far */
  1382. rinfo->disp.var = radeonfb_default_var;
  1383. else
  1384.                 fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
  1385.                               NULL, 0, NULL, 0);
  1386. if (noaccel)
  1387. rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
  1388. else
  1389. rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
  1390.  
  1391.         return 0;
  1392. }
  1393. static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
  1394. {
  1395.         int accel;  
  1396.                 
  1397.         accel = disp->var.accel_flags & FB_ACCELF_TEXT;
  1398.                 
  1399.         disp->dispsw_data = NULL;
  1400.         
  1401.         disp->screen_base = (char*)rinfo->fb_base;
  1402.         disp->type = FB_TYPE_PACKED_PIXELS;
  1403.         disp->type_aux = 0;
  1404.         disp->ypanstep = 1;
  1405.         disp->ywrapstep = 0;
  1406.         disp->can_soft_blank = 1;
  1407.         disp->inverse = 0;
  1408.         switch (disp->var.bits_per_pixel) {
  1409. #ifdef FBCON_HAS_CFB8
  1410.                 case 8:
  1411.                         disp->dispsw = &fbcon_cfb8;
  1412.                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
  1413.                         disp->line_length = disp->var.xres_virtual;
  1414.                         break;
  1415. #endif
  1416. #ifdef FBCON_HAS_CFB16
  1417.                 case 16:
  1418.                         disp->dispsw = &fbcon_cfb16;
  1419.                         disp->dispsw_data = &rinfo->con_cmap.cfb16;
  1420.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1421.                         disp->line_length = disp->var.xres_virtual * 2;
  1422.                         break;
  1423. #endif  
  1424. #ifdef FBCON_HAS_CFB32       
  1425.                 case 24:
  1426.                         disp->dispsw = &fbcon_cfb24;
  1427.                         disp->dispsw_data = &rinfo->con_cmap.cfb24;
  1428.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1429.                         disp->line_length = disp->var.xres_virtual * 4;
  1430.                         break;
  1431. #endif
  1432. #ifdef FBCON_HAS_CFB32
  1433.                 case 32:
  1434.                         disp->dispsw = &fbcon_cfb32;
  1435.                         disp->dispsw_data = &rinfo->con_cmap.cfb32;
  1436.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1437.                         disp->line_length = disp->var.xres_virtual * 4;
  1438.                         break;   
  1439. #endif
  1440.                 default:
  1441.                         printk ("radeonfb: setting fbcon_dummy renderern");
  1442.                         disp->dispsw = &fbcon_dummy;
  1443.         }
  1444.                 
  1445.         return;
  1446. }
  1447.                         
  1448. static void do_install_cmap(int con, struct fb_info *info)
  1449. {
  1450.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1451.                 
  1452.         if (con != rinfo->currcon)
  1453.                 return;
  1454.                 
  1455.         if (fb_display[con].cmap.len)
  1456.                 fb_set_cmap(&fb_display[con].cmap, 1, radeon_setcolreg, info);
  1457.         else {
  1458. int size = radeon_get_cmap_len(&fb_display[con].var);
  1459.                 fb_set_cmap(fb_default_cmap(size), 1, radeon_setcolreg, info);
  1460.         }
  1461. }
  1462. static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
  1463.                                 struct fb_var_screeninfo *var,
  1464.                                 struct fb_var_screeninfo *v,
  1465.                                 int nom, int den)
  1466. {
  1467.         static struct {
  1468.                 int xres, yres;
  1469.         } modes[] = {
  1470.                 {1600, 1280},
  1471.                 {1280, 1024},
  1472.                 {1024, 768},
  1473.                 {800, 600},
  1474.                 {640, 480},
  1475.                 {-1, -1}
  1476.         };
  1477.         int i;
  1478.                 
  1479.         /* use highest possible virtual resolution */
  1480.         if (v->xres_virtual == -1 && v->yres_virtual == -1) {
  1481.                 printk("radeonfb: using max availabe virtual resolutionn");
  1482.                 for (i=0; modes[i].xres != -1; i++) {
  1483.                         if (modes[i].xres * nom / den * modes[i].yres <
  1484.                             rinfo->video_ram / 2)
  1485.                                 break;
  1486.                 }
  1487.                 if (modes[i].xres == -1) {
  1488.                         printk("radeonfb: could not find virtual resolution that fits into video memory!n");
  1489.                         return -EINVAL;
  1490.                 }
  1491.                 v->xres_virtual = modes[i].xres;  
  1492.                 v->yres_virtual = modes[i].yres;
  1493.                 
  1494.                 printk("radeonfb: virtual resolution set to max of %dx%dn",
  1495.                         v->xres_virtual, v->yres_virtual);
  1496.         } else if (v->xres_virtual == -1) {
  1497.                 v->xres_virtual = (rinfo->video_ram * den /   
  1498.                                 (nom * v->yres_virtual * 2)) & ~15;
  1499.         } else if (v->yres_virtual == -1) {
  1500.                 v->xres_virtual = (v->xres_virtual + 15) & ~15;
  1501.                 v->yres_virtual = rinfo->video_ram * den /
  1502.                         (nom * v->xres_virtual *2);
  1503.         } else {
  1504.                 if (v->xres_virtual * nom / den * v->yres_virtual >
  1505.                         rinfo->video_ram) {
  1506.                         return -EINVAL;
  1507.                 }
  1508.         }
  1509.                 
  1510.         if (v->xres_virtual * nom / den >= 8192) {
  1511.                 v->xres_virtual = 8192 * den / nom - 16;
  1512.         }       
  1513.         
  1514.         if (v->xres_virtual < v->xres)
  1515.                 return -EINVAL;
  1516.                 
  1517.         if (v->yres_virtual < v->yres)
  1518.                 return -EINVAL;
  1519.                                 
  1520.         return 0;
  1521. }
  1522.                         
  1523. /*
  1524.  * fb ops
  1525.  */
  1526. static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
  1527.                              struct fb_info *info)
  1528. {
  1529.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1530.         struct display *disp;  
  1531.         
  1532.         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
  1533.         memset (fix, 0, sizeof (struct fb_fix_screeninfo));
  1534. strcpy (fix->id, rinfo->name);
  1535.         
  1536.         fix->smem_start = rinfo->fb_base_phys;
  1537.         fix->smem_len = rinfo->video_ram;
  1538.         fix->type = disp->type;
  1539.         fix->type_aux = disp->type_aux;
  1540.         fix->visual = disp->visual;
  1541.         fix->xpanstep = 8;
  1542.         fix->ypanstep = 1;
  1543.         fix->ywrapstep = 0;
  1544.         
  1545.         fix->line_length = disp->line_length;
  1546.  
  1547.         fix->mmio_start = rinfo->mmio_base_phys;
  1548.         fix->mmio_len = RADEON_REGSIZE;
  1549. if (noaccel)
  1550.         fix->accel = FB_ACCEL_NONE;
  1551. else
  1552. fix->accel = 40; /* XXX */
  1553.         
  1554.         return 0;
  1555. }
  1556. static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
  1557.                              struct fb_info *info)
  1558. {
  1559.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1560.         
  1561.         *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
  1562.         
  1563.         return 0;
  1564. }
  1565. static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
  1566.                              struct fb_info *info)
  1567. {
  1568.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1569.         struct display *disp;
  1570.         struct fb_var_screeninfo v;
  1571.         int nom, den, accel;
  1572.         unsigned chgvar = 0;
  1573.         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
  1574.         accel = var->accel_flags & FB_ACCELF_TEXT;
  1575.         if (con >= 0) {
  1576.                 chgvar = ((disp->var.xres != var->xres) ||
  1577.                           (disp->var.yres != var->yres) ||
  1578.                           (disp->var.xres_virtual != var->xres_virtual) ||
  1579.                           (disp->var.yres_virtual != var->yres_virtual) ||
  1580.                           (disp->var.bits_per_pixel != var->bits_per_pixel) ||
  1581.                           memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
  1582.                           memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
  1583.                           memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
  1584.         }
  1585.         memcpy (&v, var, sizeof (v));
  1586.         switch (v.bits_per_pixel) {
  1587. case 0 ... 8:
  1588. v.bits_per_pixel = 8;
  1589. break;
  1590. case 9 ... 16:
  1591. v.bits_per_pixel = 16;
  1592. break;
  1593. case 17 ... 24:
  1594. v.bits_per_pixel = 24;
  1595. break;
  1596. case 25 ... 32:
  1597. v.bits_per_pixel = 32;
  1598. break;
  1599. default:
  1600. return -EINVAL;
  1601. }
  1602. switch (var_to_depth(&v)) {
  1603. #ifdef FBCON_HAS_CFB8
  1604.                 case 8:
  1605.                         nom = den = 1;
  1606.                         disp->line_length = v.xres_virtual;
  1607.                         disp->visual = FB_VISUAL_PSEUDOCOLOR; 
  1608.                         v.red.offset = v.green.offset = v.blue.offset = 0;
  1609.                         v.red.length = v.green.length = v.blue.length = 8;
  1610.                         v.transp.offset = v.transp.length = 0;
  1611.                         break;
  1612. #endif
  1613.                         
  1614. #ifdef FBCON_HAS_CFB16
  1615. case 15:
  1616. nom = 2;
  1617. den = 1;
  1618. disp->line_length = v.xres_virtual * 2;
  1619. disp->visual = FB_VISUAL_DIRECTCOLOR;
  1620. v.red.offset = 10;
  1621. v.green.offset = 5;
  1622. v.red.offset = 0;
  1623. v.red.length = v.green.length = v.blue.length = 5;
  1624. v.transp.offset = v.transp.length = 0;
  1625. break;
  1626.                 case 16:
  1627.                         nom = 2;
  1628.                         den = 1;
  1629.                         disp->line_length = v.xres_virtual * 2;
  1630.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1631.                         v.red.offset = 11;
  1632.                         v.green.offset = 5;
  1633.                         v.blue.offset = 0;
  1634.                         v.red.length = 5;
  1635.                         v.green.length = 6;
  1636.                         v.blue.length = 5;
  1637.                         v.transp.offset = v.transp.length = 0;
  1638.                         break;  
  1639. #endif
  1640.                         
  1641. #ifdef FBCON_HAS_CFB24
  1642.                 case 24:
  1643.                         nom = 4;
  1644.                         den = 1;
  1645.                         disp->line_length = v.xres_virtual * 3;
  1646.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1647.                         v.red.offset = 16;
  1648.                         v.green.offset = 8;
  1649.                         v.blue.offset = 0;
  1650.                         v.red.length = v.blue.length = v.green.length = 8;
  1651.                         v.transp.offset = v.transp.length = 0;
  1652.                         break;
  1653. #endif
  1654. #ifdef FBCON_HAS_CFB32
  1655.                 case 32:
  1656.                         nom = 4;
  1657.                         den = 1;
  1658.                         disp->line_length = v.xres_virtual * 4;
  1659.                         disp->visual = FB_VISUAL_DIRECTCOLOR;
  1660.                         v.red.offset = 16;
  1661.                         v.green.offset = 8;
  1662.                         v.blue.offset = 0;
  1663.                         v.red.length = v.blue.length = v.green.length = 8;
  1664.                         v.transp.offset = 24;
  1665.                         v.transp.length = 8;
  1666.                         break;
  1667. #endif
  1668.                 default:
  1669.                         printk ("radeonfb: mode %dx%dx%d rejected, color depth invalidn",
  1670.                                 var->xres, var->yres, var->bits_per_pixel);
  1671.                         return -EINVAL;
  1672.         }
  1673.         if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
  1674.                 return -EINVAL;  
  1675.                 
  1676.         if (v.xoffset < 0)
  1677.                 v.xoffset = 0;
  1678.         if (v.yoffset < 0)
  1679.                 v.yoffset = 0;
  1680.          
  1681.         if (v.xoffset > v.xres_virtual - v.xres)
  1682.                 v.xoffset = v.xres_virtual - v.xres - 1;
  1683.                         
  1684.         if (v.yoffset > v.yres_virtual - v.yres)
  1685.                 v.yoffset = v.yres_virtual - v.yres - 1;
  1686.          
  1687.         v.red.msb_right = v.green.msb_right = v.blue.msb_right =
  1688.                           v.transp.offset = v.transp.length =
  1689.                           v.transp.msb_right = 0;
  1690.                         
  1691.         switch (v.activate & FB_ACTIVATE_MASK) {
  1692.                 case FB_ACTIVATE_TEST:
  1693.                         return 0;
  1694.                 case FB_ACTIVATE_NXTOPEN:
  1695.                 case FB_ACTIVATE_NOW:
  1696.                         break;
  1697.                 default:
  1698.                         return -EINVAL;
  1699.         }
  1700.         
  1701.         memcpy (&disp->var, &v, sizeof (v));
  1702.         
  1703.         if (chgvar) {     
  1704.                 radeon_set_dispsw(rinfo, disp);
  1705.                 if (noaccel)
  1706.                         disp->scrollmode = SCROLL_YREDRAW;
  1707.                 else
  1708.                         disp->scrollmode = 0;
  1709.                 
  1710.                 if (info && info->changevar)
  1711.                         info->changevar(con);
  1712.         }
  1713.          
  1714.         radeon_load_video_mode (rinfo, &v);
  1715.                 
  1716.         do_install_cmap(con, info);
  1717.   
  1718.         return 0;
  1719. }
  1720. static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
  1721.                               struct fb_info *info)
  1722. {
  1723.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1724.         struct display *disp;
  1725.                 
  1726.         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
  1727.         
  1728.         if (con == rinfo->currcon) {
  1729.                 int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
  1730.                 return rc;
  1731.         } else if (disp->cmap.len)
  1732.                 fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
  1733.         else
  1734.                 fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
  1735.                               cmap, kspc ? 0 : 2);
  1736.                         
  1737.         return 0;
  1738. }
  1739. static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
  1740.                               struct fb_info *info)
  1741. {
  1742.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1743.         struct display *disp;
  1744.         unsigned int cmap_len;
  1745.                 
  1746.         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
  1747.   
  1748.         cmap_len = radeon_get_cmap_len (&disp->var);
  1749.         if (disp->cmap.len != cmap_len) {
  1750.                 int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
  1751.                 if (err)
  1752.                         return err;
  1753.         }
  1754.  
  1755.         if (con == rinfo->currcon) {
  1756.                 int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
  1757.                 return rc;
  1758.         } else
  1759.                 fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
  1760.         
  1761.         return 0;
  1762. }               
  1763. static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
  1764.                                  struct fb_info *info)
  1765. {
  1766.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1767.         u32 offset, xoffset, yoffset;
  1768.                 
  1769.         xoffset = (var->xoffset + 7) & ~7;
  1770.         yoffset = var->yoffset;
  1771.                 
  1772.         if ((xoffset + var->xres > var->xres_virtual) || (yoffset+var->yres >
  1773.                 var->yres_virtual))
  1774.                 return -EINVAL;
  1775.                 
  1776.         offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
  1777.          
  1778.         OUTREG(CRTC_OFFSET, offset);
  1779.         
  1780.         return 0;
  1781. }
  1782. static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
  1783.                            unsigned long arg, int con, struct fb_info *info)
  1784. {
  1785. return -EINVAL;
  1786. }
  1787. static int radeonfb_switch (int con, struct fb_info *info)
  1788. {
  1789.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1790.         struct display *disp;
  1791.         struct fb_cmap *cmap;
  1792.         int switchmode = 0;
  1793.         
  1794.         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
  1795.                 
  1796.         if (rinfo->currcon >= 0) {
  1797.                 cmap = &(rinfo->currcon_display->cmap);
  1798.                 if (cmap->len)
  1799.                         fb_get_cmap (cmap, 1, radeon_getcolreg, info);
  1800.         }   
  1801.                 
  1802. switchmode = (con != rinfo->currcon);
  1803. rinfo->currcon = con;
  1804. rinfo->currcon_display = disp;
  1805. disp->var.activate = FB_ACTIVATE_NOW;
  1806.         
  1807.         if (switchmode) {
  1808.                 radeonfb_set_var (&disp->var, con, info);
  1809.                 radeon_set_dispsw (rinfo, disp);
  1810.                 do_install_cmap(con, info);
  1811.         }       
  1812.         /* XXX absurd hack for X to restore console */
  1813.         {   
  1814. OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
  1815. CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
  1816.                 OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
  1817.         }
  1818.         return 0;
  1819. }
  1820. static int radeonfb_updatevar (int con, struct fb_info *info)
  1821. {
  1822.         int rc;
  1823.                 
  1824.         rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
  1825.                                                          con, info);
  1826.         
  1827.         return rc;
  1828. }
  1829. static void radeonfb_blank (int blank, struct fb_info *info)
  1830. {
  1831.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1832.         u32 val = INREG(CRTC_EXT_CNTL);
  1833. u32 val2 = INREG(LVDS_GEN_CNTL);
  1834. #ifdef CONFIG_PMAC_BACKLIGHT
  1835. if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
  1836. set_backlight_enable(!blank);
  1837. return;
  1838. }
  1839. #endif
  1840.                         
  1841.         /* reset it */
  1842.         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
  1843.                  CRTC_VSYNC_DIS);
  1844. val2 &= ~(LVDS_DISPLAY_DIS);
  1845.         switch (blank) {
  1846.                 case VESA_NO_BLANKING:
  1847.                         break;
  1848.                 case VESA_VSYNC_SUSPEND:
  1849.                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
  1850.                         break;
  1851.                 case VESA_HSYNC_SUSPEND:
  1852.                         val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
  1853.                         break;
  1854.                 case VESA_POWERDOWN:
  1855.                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | 
  1856.                                 CRTC_HSYNC_DIS);
  1857. val2 |= (LVDS_DISPLAY_DIS);
  1858.                         break;
  1859.         }
  1860. switch (rinfo->dviDisp_type) {
  1861. case MT_LCD:
  1862. OUTREG(LVDS_GEN_CNTL, val2);
  1863. break;
  1864. case MT_CRT:
  1865. default:
  1866.         OUTREG(CRTC_EXT_CNTL, val);
  1867. break;
  1868. }
  1869. }
  1870. static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
  1871. {
  1872.         int rc = 256;            /* reasonable default */
  1873.         
  1874.         switch (var_to_depth(var)) {
  1875.                 case 15:
  1876.                         rc = 32;
  1877.                         break;
  1878. case 16:
  1879. rc = 64;
  1880. break;
  1881.         }
  1882.                 
  1883.         return rc;
  1884. }
  1885. static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
  1886.                              unsigned *blue, unsigned *transp,
  1887.                              struct fb_info *info)
  1888. {
  1889.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1890. if (regno > 255)
  1891. return 1;
  1892.      
  1893.   *red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red; 
  1894.      *green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
  1895.      *blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
  1896.      *transp = 0;
  1897. return 0;
  1898. }                            
  1899. static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
  1900.                              unsigned blue, unsigned transp, struct fb_info *info)
  1901. {
  1902.         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
  1903. u32 pindex;
  1904. if (regno > 255)
  1905. return 1;
  1906. red >>= 8;
  1907. green >>= 8;
  1908. blue >>= 8;
  1909. rinfo->palette[regno].red = red;
  1910. rinfo->palette[regno].green = green;
  1911. rinfo->palette[regno].blue = blue;
  1912.         /* default */
  1913.         pindex = regno;
  1914.         
  1915. if (rinfo->bpp == 16) {
  1916. pindex = regno * 8;
  1917. if (rinfo->depth == 16 && regno > 63)
  1918. return 1;
  1919. if (rinfo->depth == 15 && regno > 31)
  1920. return 1;
  1921. /* For 565, the green component is mixed one order below */
  1922. if (rinfo->depth == 16) {
  1923.                 OUTREG(PALETTE_INDEX, pindex>>1);
  1924.                   OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
  1925.                          (green << 8) | (rinfo->palette[regno>>1].blue));
  1926.                  green = rinfo->palette[regno<<1].green;
  1927.          }
  1928. }
  1929. if (rinfo->depth != 16 || regno < 32) {
  1930. OUTREG(PALETTE_INDEX, pindex);
  1931. OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
  1932. }
  1933.   if (regno < 16) {
  1934.          switch (rinfo->depth) {
  1935. #ifdef FBCON_HAS_CFB16
  1936.         case 15:
  1937.          rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
  1938.                             regno;   
  1939.         break;
  1940.         case 16:
  1941.          rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
  1942.                             regno;   
  1943.         break;
  1944. #endif
  1945. #ifdef FBCON_HAS_CFB24
  1946.                         case 24:
  1947.                                 rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
  1948.                                 break;
  1949. #endif
  1950. #ifdef FBCON_HAS_CFB32
  1951.          case 32: {
  1952.              u32 i;    
  1953.    
  1954.            i = (regno << 8) | regno;
  1955.              rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
  1956.          break;
  1957.          }
  1958. #endif
  1959. }
  1960.         }
  1961. return 0;
  1962. }
  1963. static void radeon_save_state (struct radeonfb_info *rinfo,
  1964.                                struct radeon_regs *save)
  1965. {
  1966. /* CRTC regs */
  1967. save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
  1968. save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
  1969. save->dac_cntl = INREG(DAC_CNTL);
  1970.         save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
  1971.         save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
  1972.         save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
  1973.         save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
  1974. save->crtc_pitch = INREG(CRTC_PITCH);
  1975. #if defined(__BIG_ENDIAN)
  1976. save->surface_cntl = INREG(SURFACE_CNTL);
  1977. #endif
  1978. /* FP regs */
  1979. save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
  1980. save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
  1981. save->fp_gen_cntl = INREG(FP_GEN_CNTL);
  1982. save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
  1983. save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
  1984. save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
  1985. save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
  1986. save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
  1987. save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
  1988. save->tmds_crc = INREG(TMDS_CRC);
  1989. save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
  1990. }
  1991. static void radeon_load_video_mode (struct radeonfb_info *rinfo,
  1992.                                     struct fb_var_screeninfo *mode)
  1993. {
  1994. struct radeon_regs newmode;
  1995. int hTotal, vTotal, hSyncStart, hSyncEnd,
  1996.     hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
  1997. u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
  1998. u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
  1999. u32 dotClock = 1000000000 / mode->pixclock,
  2000.     sync, h_sync_pol, v_sync_pol;
  2001. int freq = dotClock / 10;  /* x 100 */
  2002.         int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
  2003.         int useable_precision, roff, ron;
  2004.         int min_bits, format = 0;
  2005. int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
  2006. int primary_mon = PRIMARY_MONITOR(rinfo);
  2007. int depth = var_to_depth(mode);
  2008. rinfo->xres = mode->xres;
  2009. rinfo->yres = mode->yres;
  2010. rinfo->pixclock = mode->pixclock;
  2011. hSyncStart = mode->xres + mode->right_margin;
  2012. hSyncEnd = hSyncStart + mode->hsync_len;
  2013. hTotal = hSyncEnd + mode->left_margin;
  2014. vSyncStart = mode->yres + mode->lower_margin;
  2015. vSyncEnd = vSyncStart + mode->vsync_len;
  2016. vTotal = vSyncEnd + mode->upper_margin;
  2017. if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
  2018. if (rinfo->panel_xres < mode->xres)
  2019. rinfo->xres = mode->xres = rinfo->panel_xres;
  2020. if (rinfo->panel_yres < mode->yres)
  2021. rinfo->yres = mode->yres = rinfo->panel_yres;
  2022. hTotal = mode->xres + rinfo->hblank;
  2023. hSyncStart = mode->xres + rinfo->hOver_plus;
  2024. hSyncEnd = hSyncStart + rinfo->hSync_width;
  2025. vTotal = mode->yres + rinfo->vblank;
  2026. vSyncStart = mode->yres + rinfo->vOver_plus;
  2027. vSyncEnd = vSyncStart + rinfo->vSync_width;
  2028. }
  2029. sync = mode->sync;
  2030. h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
  2031. v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
  2032. RTRACE("hStart = %d, hEnd = %d, hTotal = %dn",
  2033. hSyncStart, hSyncEnd, hTotal);
  2034. RTRACE("vStart = %d, vEnd = %d, vTotal = %dn",
  2035. vSyncStart, vSyncEnd, vTotal);
  2036. hsync_wid = (hSyncEnd - hSyncStart) / 8;
  2037. vsync_wid = vSyncEnd - vSyncStart;
  2038. if (hsync_wid == 0)
  2039. hsync_wid = 1;
  2040. else if (hsync_wid > 0x3f) /* max */
  2041. hsync_wid = 0x3f;
  2042. if (vsync_wid == 0)
  2043. vsync_wid = 1;
  2044. else if (vsync_wid > 0x1f) /* max */
  2045. vsync_wid = 0x1f;
  2046. hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
  2047. vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
  2048. cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
  2049. format = radeon_get_dstbpp(depth);
  2050. bytpp = mode->bits_per_pixel >> 3;
  2051. if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
  2052. hsync_fudge = hsync_fudge_fp[format-1];
  2053. else
  2054. hsync_fudge = hsync_adj_tab[format-1];
  2055. hsync_start = hSyncStart - 8 + hsync_fudge;
  2056. newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
  2057. (format << 8);
  2058. if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
  2059. newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
  2060. newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
  2061.    CRTC_INTERLACE_EN);
  2062. } else {
  2063. newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
  2064. CRTC_CRT_ON;
  2065. }
  2066. newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
  2067.    DAC_8BIT_EN;
  2068. newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
  2069.      (((mode->xres / 8) - 1) << 16));
  2070. newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
  2071. (hsync_wid << 16) | (h_sync_pol << 23));
  2072. newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
  2073.     ((mode->yres - 1) << 16);
  2074. newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
  2075.  (vsync_wid << 16) | (v_sync_pol  << 23));
  2076. newmode.crtc_pitch = (mode->xres >> 3);
  2077. newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
  2078. #if defined(__BIG_ENDIAN)
  2079. newmode.surface_cntl = SURF_TRANSLATION_DIS;
  2080. switch (mode->bits_per_pixel) {
  2081. case 16:
  2082. newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
  2083. break;
  2084. case 24:
  2085. case 32:
  2086. newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
  2087. break;
  2088. }
  2089. #endif
  2090. rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
  2091. & ~(0x3f)) / 64;
  2092. RTRACE("h_total_disp = 0x%xt   hsync_strt_wid = 0x%xn",
  2093. newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
  2094. RTRACE("v_total_disp = 0x%xt   vsync_strt_wid = 0x%xn",
  2095. newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
  2096. newmode.xres = mode->xres;
  2097. newmode.yres = mode->yres;
  2098. rinfo->bpp = mode->bits_per_pixel;
  2099. rinfo->depth = depth;
  2100. rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
  2101. rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
  2102. if (freq > rinfo->pll.ppll_max)
  2103. freq = rinfo->pll.ppll_max;
  2104. if (freq*12 < rinfo->pll.ppll_min)
  2105. freq = rinfo->pll.ppll_min / 12;
  2106. {
  2107. struct {
  2108. int divider;
  2109. int bitvalue;
  2110. } *post_div,
  2111.   post_divs[] = {
  2112. { 1,  0 },
  2113. { 2,  1 },
  2114. { 4,  2 },
  2115. { 8,  3 },
  2116. { 3,  4 },
  2117. { 16, 5 },
  2118. { 6,  6 },
  2119. { 12, 7 },
  2120. { 0,  0 },
  2121. };
  2122. for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
  2123. rinfo->pll_output_freq = post_div->divider * freq;
  2124. if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
  2125.     rinfo->pll_output_freq <= rinfo->pll.ppll_max)
  2126. break;
  2127. }
  2128. rinfo->post_div = post_div->divider;
  2129. rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
  2130.   rinfo->pll.ref_clk);
  2131. newmode.ppll_ref_div = rinfo->pll.ref_div;
  2132. newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
  2133. }
  2134. RTRACE("post div = 0x%xn", rinfo->post_div);
  2135. RTRACE("fb_div = 0x%xn", rinfo->fb_div);
  2136. RTRACE("ppll_div_3 = 0x%xn", newmode.ppll_div_3);
  2137. /* DDA */
  2138. vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
  2139.       rinfo->pll.ref_div * rinfo->post_div);
  2140. xclk_freq = rinfo->pll.xclk;
  2141. xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
  2142. min_bits = min_bits_req(xclk_per_trans);
  2143. useable_precision = min_bits + 1;
  2144. xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
  2145.    vclk_freq * mode->bits_per_pixel);
  2146. ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
  2147.        2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
  2148.        xclk_per_trans) << (11 - useable_precision);
  2149. roff = xclk_per_trans_precise * (32 - 4);
  2150. RTRACE("ron = %d, roff = %dn", ron, roff);
  2151. RTRACE("vclk_freq = %d, per = %dn", vclk_freq, xclk_per_trans_precise);
  2152. if ((ron + rinfo->ram.rloop) >= roff) {
  2153. printk("radeonfb: error ron out of rangen");
  2154. return;
  2155. }
  2156. newmode.dda_config = (xclk_per_trans_precise |
  2157.       (useable_precision << 16) |
  2158.       (rinfo->ram.rloop << 20));
  2159. newmode.dda_on_off = (ron << 16) | roff;
  2160. if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
  2161. unsigned int hRatio, vRatio;
  2162. if (mode->xres > rinfo->panel_xres)
  2163. mode->xres = rinfo->panel_xres;
  2164. if (mode->yres > rinfo->panel_yres)
  2165. mode->yres = rinfo->panel_yres;
  2166. newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
  2167.    << HORZ_PANEL_SHIFT);
  2168. newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
  2169.    << VERT_PANEL_SHIFT);
  2170. if (mode->xres != rinfo->panel_xres) {
  2171. hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
  2172.    rinfo->panel_xres);
  2173. newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
  2174.    (newmode.fp_horz_stretch &
  2175.     (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
  2176.      HORZ_AUTO_RATIO_INC)));
  2177. newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
  2178.     HORZ_STRETCH_ENABLE);
  2179. }
  2180. newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
  2181. if (mode->yres != rinfo->panel_yres) {
  2182. vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
  2183.    rinfo->panel_yres);
  2184. newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
  2185.    (newmode.fp_vert_stretch &
  2186.    (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
  2187. newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
  2188.     VERT_STRETCH_ENABLE);
  2189. }
  2190. newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
  2191. newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
  2192.        ~(FP_SEL_CRTC2 |
  2193.  FP_RMX_HVSYNC_CONTROL_EN |
  2194.  FP_DFP_SYNC_SEL |
  2195.  FP_CRT_SYNC_SEL |
  2196.  FP_CRTC_LOCK_8DOT |
  2197.  FP_USE_SHADOW_EN |
  2198.  FP_CRTC_USE_SHADOW_VEND |
  2199.  FP_CRT_SYNC_ALT));
  2200. newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
  2201. FP_CRTC_DONT_SHADOW_HEND);
  2202. newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
  2203. newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
  2204. newmode.tmds_crc = rinfo->init_state.tmds_crc;
  2205. newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
  2206. if (primary_mon == MT_LCD) {
  2207. newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
  2208. newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
  2209. } else {
  2210. /* DFP */
  2211. newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
  2212. newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
  2213.  ICHCSEL) & ~(TMDS_PLLRST);
  2214. newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
  2215. }
  2216. newmode.fp_crtc_h_total_disp = newmode.crtc_h_total_disp;
  2217. newmode.fp_crtc_v_total_disp = newmode.crtc_v_total_disp;
  2218. newmode.fp_h_sync_strt_wid = newmode.crtc_h_sync_strt_wid;
  2219. newmode.fp_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
  2220. }
  2221. /* do it! */
  2222. radeon_write_mode (rinfo, &newmode);
  2223. #if defined(CONFIG_BOOTX_TEXT)
  2224. btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
  2225.      rinfo->depth, rinfo->pitch*64);
  2226. #endif
  2227. return;
  2228. }
  2229. static void radeon_write_mode (struct radeonfb_info *rinfo,
  2230.                                struct radeon_regs *mode)
  2231. {
  2232. int i;
  2233. int primary_mon = PRIMARY_MONITOR(rinfo);
  2234. /* blank screen */
  2235. OUTREGP(CRTC_EXT_CNTL, CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS,
  2236. ~(CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS));
  2237. for (i=0; i<9; i++)
  2238. OUTREG(common_regs[i].reg, common_regs[i].val);
  2239. OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
  2240. OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
  2241. CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
  2242. OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
  2243. OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
  2244. OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
  2245. OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
  2246. OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
  2247. OUTREG(CRTC_OFFSET, 0);
  2248. OUTREG(CRTC_OFFSET_CNTL, 0);
  2249. OUTREG(CRTC_PITCH, mode->crtc_pitch);
  2250. #if defined(__BIG_ENDIAN)
  2251. OUTREG(SURFACE_CNTL, mode->surface_cntl);
  2252. #endif
  2253. while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
  2254.        PPLL_DIV_SEL_MASK) {
  2255. OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
  2256. }
  2257. OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
  2258. while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
  2259.        (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
  2260. OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
  2261. }
  2262. while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
  2263.        (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
  2264. OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
  2265. }
  2266. while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
  2267.        (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
  2268. OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
  2269. }
  2270. OUTPLL(HTOTAL_CNTL, 0);
  2271. OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
  2272. OUTREG(DDA_CONFIG, mode->dda_config);
  2273. OUTREG(DDA_ON_OFF, mode->dda_on_off);
  2274. if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
  2275. OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
  2276. OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
  2277. OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
  2278. OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
  2279. OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
  2280. OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
  2281. OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
  2282. OUTREG(TMDS_CRC, mode->tmds_crc);
  2283. OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
  2284. if (primary_mon == MT_LCD) {
  2285. unsigned int tmp = INREG(LVDS_GEN_CNTL);
  2286. mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
  2287. mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
  2288. if ((tmp & (LVDS_ON | LVDS_BLON)) ==
  2289.     (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
  2290. OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
  2291. } else {
  2292. if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
  2293. udelay(1000);
  2294. OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
  2295. } else {
  2296. OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
  2297.        LVDS_BLON);
  2298. udelay(1000);
  2299. OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
  2300. }
  2301. }
  2302. }
  2303. }
  2304. /* unblank screen */
  2305. OUTREG8(CRTC_EXT_CNTL + 1, 0);
  2306. return;
  2307. }
  2308. #ifdef CONFIG_PMAC_BACKLIGHT
  2309. static int backlight_conv[] = {
  2310. 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
  2311. 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
  2312. };
  2313. #define BACKLIGHT_LVDS_OFF
  2314. #undef BACKLIGHT_DAC_OFF
  2315. /* We turn off the LCD completely instead of just dimming the backlight.
  2316.  * This provides some greater power saving and the display is useless
  2317.  * without backlight anyway.
  2318.  */
  2319. static int radeon_set_backlight_enable(int on, int level, void *data)
  2320. {
  2321. struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
  2322. unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
  2323. lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
  2324. if (on && (level > BACKLIGHT_OFF)) {
  2325. lvds_gen_cntl |= LVDS_DIGON;
  2326. if (!lvds_gen_cntl & LVDS_ON) {
  2327. lvds_gen_cntl &= ~LVDS_BLON;
  2328. OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
  2329. (void)INREG(LVDS_GEN_CNTL);
  2330. mdelay(10);
  2331. lvds_gen_cntl |= LVDS_BLON;
  2332. OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
  2333. }
  2334. lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
  2335. lvds_gen_cntl |= (backlight_conv[level] <<
  2336.   LVDS_BL_MOD_LEVEL_SHIFT);
  2337. lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
  2338. lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
  2339. } else {
  2340. lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
  2341. lvds_gen_cntl |= (backlight_conv[0] <<
  2342.   LVDS_BL_MOD_LEVEL_SHIFT);
  2343. lvds_gen_cntl |= LVDS_DISPLAY_DIS;
  2344. OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
  2345. udelay(10);
  2346. lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
  2347. }
  2348. OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
  2349. rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
  2350. rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
  2351. return 0;
  2352. }
  2353. static int radeon_set_backlight_level(int level, void *data)
  2354. {
  2355. return radeon_set_backlight_enable(1, level, data);
  2356. }
  2357. #endif /* CONFIG_PMAC_BACKLIGHT */
  2358. #ifdef CONFIG_PMAC_PBOOK
  2359. static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
  2360. {
  2361. u16 pwr_cmd;
  2362. if (!rinfo->pm_reg)
  2363. return;
  2364. /* Set the chip into appropriate suspend mode (we use D2,
  2365.  * D3 would require a compete re-initialization of the chip,
  2366.  * including PCI config registers, clocks, AGP conf, ...)
  2367.  */
  2368. if (suspend) {
  2369. /* Make sure CRTC2 is reset.  Remove that the day
  2370.  * we decide to actually use CRTC2 and replace it with
  2371.  * real code for disabling the CRTC2 output during sleep.
  2372.  */
  2373. pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
  2374.      &pwr_cmd);
  2375. /* Switch PCI power managment to D2 */
  2376. pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
  2377.       (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK)
  2378.       | 2);
  2379. pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
  2380.      &pwr_cmd);
  2381. } else {
  2382. /* Switch back PCI powermanagment to D0 */
  2383. mdelay(100);
  2384. pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
  2385. mdelay(100);
  2386. pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
  2387.      &pwr_cmd);
  2388. mdelay(100);
  2389. }
  2390. }
  2391. /*
  2392.  * Save the contents of the framebuffer when we go to sleep,
  2393.  * and restore it when we wake up again.
  2394.  */
  2395. int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
  2396. {
  2397. struct radeonfb_info *rinfo;
  2398. for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
  2399. struct fb_fix_screeninfo fix;
  2400. int nb;
  2401. switch (rinfo->chipset) {
  2402. case PCI_DEVICE_ID_RADEON_LW:
  2403. case PCI_DEVICE_ID_RADEON_LY:
  2404. case PCI_DEVICE_ID_RADEON_LZ:
  2405. break;
  2406. default:
  2407. return PBOOK_SLEEP_REFUSE;
  2408. }
  2409. radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
  2410. nb = fb_display[fg_console].var.yres * fix.line_length;
  2411. switch (when) {
  2412. case PBOOK_SLEEP_REQUEST:
  2413. #if 0
  2414. rinfo->save_framebuffer = vmalloc(nb);
  2415. if (rinfo->save_framebuffer == NULL)
  2416. return PBOOK_SLEEP_REFUSE;
  2417. #endif
  2418. break;
  2419. case PBOOK_SLEEP_REJECT:
  2420. #if 0
  2421. if (rinfo->save_framebuffer) {
  2422. vfree(rinfo->save_framebuffer);
  2423. rinfo->save_framebuffer = 0;
  2424. }
  2425. #endif
  2426. break;
  2427. case PBOOK_SLEEP_NOW:
  2428. radeon_engine_idle();
  2429. radeon_engine_reset();
  2430. radeon_engine_idle();
  2431. #if 0
  2432. /* Backup framebuffer content */
  2433. if (rinfo->save_framebuffer)
  2434. memcpy_fromio(rinfo->save_framebuffer,
  2435.       (void *)rinfo->fb_base,
  2436.       nb);
  2437. #endif
  2438. /* Blank display and LCD */
  2439. radeonfb_blank(VESA_POWERDOWN+1,
  2440.        (struct fb_info *)rinfo);
  2441. /* Sleep */
  2442. radeon_set_suspend(rinfo, 1);
  2443. break;
  2444. case PBOOK_WAKE:
  2445. /* Wakeup */
  2446. radeon_set_suspend(rinfo, 0);
  2447. radeon_engine_reset();
  2448. if (!noaccel) {
  2449. radeon_engine_init(rinfo);
  2450. radeon_engine_reset();
  2451. }
  2452. #if 0
  2453. /* Restore framebuffer content */
  2454. if (rinfo->save_framebuffer) {
  2455. memcpy_toio((void *)rinfo->fb_base,
  2456.     rinfo->save_framebuffer,
  2457.     nb);
  2458. vfree(rinfo->save_framebuffer);
  2459. rinfo->save_framebuffer = 0;
  2460. }
  2461. #endif
  2462. if (rinfo->currcon_display) {
  2463. radeonfb_set_var(&rinfo->currcon_display->var, rinfo->currcon,
  2464.  (struct fb_info *) rinfo);
  2465. radeon_set_dispsw(rinfo, rinfo->currcon_display);
  2466. do_install_cmap(rinfo->currcon,
  2467. (struct fb_info *)rinfo);
  2468. }
  2469. radeonfb_blank(0, (struct fb_info *)rinfo);
  2470. break;
  2471. }
  2472. }
  2473. return PBOOK_SLEEP_OK;
  2474. }
  2475. #endif /* CONFIG_PMAC_PBOOK */
  2476. /*
  2477.  * text console acceleration
  2478.  */
  2479. static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
  2480.        int dsty, int dstx, int height, int width)
  2481. {
  2482. struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
  2483. u32 dp_cntl = DST_LAST_PEL;
  2484. srcx *= fontwidth(p);
  2485. srcy *= fontheight(p);
  2486. dstx *= fontwidth(p);
  2487. dsty *= fontheight(p);
  2488. width *= fontwidth(p);
  2489. height *= fontheight(p);
  2490. if (srcy < dsty) {
  2491. srcy += height - 1;
  2492. dsty += height - 1;
  2493. } else
  2494. dp_cntl |= DST_Y_TOP_TO_BOTTOM;
  2495. if (srcx < dstx) {
  2496. srcx += width - 1;
  2497. dstx += width - 1;
  2498. } else
  2499. dp_cntl |= DST_X_LEFT_TO_RIGHT;
  2500. radeon_fifo_wait(6);
  2501. OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
  2502.     GMC_BRUSH_NONE |
  2503.     GMC_SRC_DATATYPE_COLOR |
  2504.     ROP3_S |
  2505.     DP_SRC_SOURCE_MEMORY));
  2506. OUTREG(DP_WRITE_MSK, 0xffffffff);
  2507. OUTREG(DP_CNTL, dp_cntl);
  2508. OUTREG(SRC_Y_X, (srcy << 16) | srcx);
  2509. OUTREG(DST_Y_X, (dsty << 16) | dstx);
  2510. OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
  2511. }
  2512. static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
  2513.        int srcy, int srcx, int height, int width)
  2514. {
  2515. struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
  2516. u32 clr;
  2517. clr = attr_bgcol_ec(p, conp);
  2518. clr |= (clr << 8);
  2519. clr |= (clr << 16);
  2520. srcx *= fontwidth(p);
  2521. srcy *= fontheight(p);
  2522. width *= fontwidth(p);
  2523. height *= fontheight(p);
  2524. radeon_fifo_wait(6);
  2525. OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
  2526.     GMC_BRUSH_SOLID_COLOR |
  2527.     GMC_SRC_DATATYPE_COLOR |
  2528.     ROP3_P));
  2529. OUTREG(DP_BRUSH_FRGD_CLR, clr);
  2530. OUTREG(DP_WRITE_MSK, 0xffffffff);
  2531. OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
  2532. OUTREG(DST_Y_X, (srcy << 16) | srcx);
  2533. OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
  2534. }
  2535. #ifdef FBCON_HAS_CFB8
  2536. static struct display_switch fbcon_radeon8 = {
  2537. setup: fbcon_cfb8_setup,
  2538. bmove: fbcon_radeon_bmove,
  2539. clear: fbcon_radeon_clear,
  2540. putc: fbcon_cfb8_putc,
  2541. putcs: fbcon_cfb8_putcs,
  2542. revc: fbcon_cfb8_revc,
  2543. clear_margins: fbcon_cfb8_clear_margins,
  2544. fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
  2545. };
  2546. #endif