sstfb.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:61k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
  3.  *
  4.  *     Copyright (c) 2000-2002 Ghozlane Toumi <gtoumi@laposte.net>
  5.  *
  6.  *     Created 15 Jan 2000 by Ghozlane Toumi
  7.  *
  8.  * Contributions (and many thanks) :
  9.  *
  10.  * 03/2001 James Simmons   <jsimmons@linux-fbdev.org>
  11.  * 04/2001 Paul Mundt      <lethal@chaoticdreams.org>
  12.  * 05/2001 Urs Ganse       <ursg@uni.de>
  13.  *     (initial work on voodoo2 port, interlace)
  14.  * 09/2002 Helge Deller    <deller@gmx.de>
  15.  *     (enable driver on big-endian machines (hppa), ioctl fixes)
  16.  *
  17.  *
  18.  * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
  19.  */
  20. /*
  21.  * The voodoo1 has the following memory mapped adress space:
  22.  * 0x000000 - 0x3fffff : registers              (4Mb)
  23.  * 0x400000 - 0x7fffff : linear frame buffer    (4Mb)
  24.  * 0x800000 - 0xffffff : texture memory         (8Mb)
  25.  */
  26. /*
  27.  * misc notes, TODOs, toASKs, and deep thoughts
  28. -TODO: at one time or another test that the mode is acceptable by the monitor
  29. -ASK: I can choose different ordering for the color bitfields (rgba argb ...)
  30.       wich one should i use ? is there any preferred one ? It seems ARGB is
  31.       the one ...
  32. -TODO: check the error paths . if something get wrong, the error doesn't seem
  33.       to be very well handled...if handled at all.. not good.
  34. -TODO: in  set_var check the validity of timings (hsync vsync)...
  35. -TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
  36.        a nop command . so it's ok as long as the commands we pass don't go
  37.        through the fifo. warning: issuing a nop command seems to need pci_fifo
  38. -FIXME: in case of failure in the init sequence, be sure we return to a safe
  39.         state.
  40. -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
  41. -ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
  42. -TODO: change struct sst_info fb_info from static to array/dynamic
  43.  *
  44.  */
  45. /*
  46.  * debug info
  47.  * SST_DEBUG : enable debugging
  48.  * SST_DEBUG_REG : debug registers
  49.  *   0 :  no debug
  50.  *   1 : dac calls, [un]set_bits, FbiInit
  51.  *   2 : insane debug level (log every register read/write)
  52.  * SST_DEBUG_FUNC : functions
  53.  *   0 : no debug
  54.  *   1 : function call / debug ioctl
  55.  *   2 : variables
  56.  *   3 : flood . you don't want to do that. trust me.
  57.  * SST_DEBUG_VAR : debug display/var structs
  58.  *   0 : no debug
  59.  *   1 : dumps display, fb_var
  60.  * SST_DEBUG_IOCTL : enable sstfb specific ioctls
  61.  *   0 : disable
  62.  *   1 : enable debug ioctls :
  63.  *    toggle vga (0x46db) : toggle vga_pass_through
  64.  *    fill fb    (0x46dc) : fills fb
  65.  *    dump var   (0x46dd) : logs display[0-5].var
  66.  *    test disp  (0x46de) : draws a test motif
  67.  */
  68. /* #define SST_DEBUG */
  69. #undef SST_DEBUG
  70. #define SST_DEBUG_REG   0
  71. #define SST_DEBUG_FUNC  0
  72. #define SST_DEBUG_VAR   0
  73. #define SST_DEBUG_IOCTL 1
  74. /* #define EN_24_32_BPP  *//* enable 24/32 bpp functions for testing only */
  75. #undef EN_24_32_BPP
  76. /*
  77.   Default video mode .
  78.   0 800x600@60  took from glide
  79.   1 640x480@75  took from glide
  80.   2 1024x768@76 std fb.mode
  81.   3 640x480@60  glide default */
  82. #define DEFAULT_MODE 1
  83. /*
  84.  * Includes
  85.  */
  86. #include <linux/string.h>
  87. #include <linux/config.h>
  88. #include <linux/kernel.h>
  89. #include <linux/module.h>
  90. #include <linux/tty.h>
  91. #include <linux/fb.h>
  92. #include <linux/pci.h>
  93. #include <linux/delay.h>
  94. #include <linux/init.h>
  95. #include <linux/version.h>
  96. #include <linux/slab.h>
  97. #include <asm/io.h>
  98. #include <asm/ioctl.h>
  99. #include <asm/uaccess.h>
  100. #include <video/fbcon.h>
  101. #include <video/fbcon-cfb16.h>
  102. #ifdef  EN_24_32_BPP
  103. #  include <video/fbcon-cfb24.h>
  104. #  include <video/fbcon-cfb32.h>
  105. #endif
  106. #include "sstfb.h"
  107. /* void __Dump_regs(struct sstfb_info *);
  108. #define Dump_regs __Dump_regs(sst_info) */
  109. /********/
  110. /* initialized by setup */
  111. static int inverse; /* =0 */ /* invert colormap */
  112. static int vgapass; /* =0 */ /* enable Vga passthrough cable */
  113. static int mem;     /* =0 */ /* mem size in Mb , 0 = autodetect */
  114. static int clipping = 1; /* use clipping (slower, safer) */
  115. static int gfxclk;  /* =0 */ /* force FBI freq in Mhz . Dangerous */
  116. static int slowpci; /* =0 */ /* slow PCI settings */
  117. static int dev = -2; /* specify device (0..n) -2=all -1=none*/
  118. static char * mode_option ;
  119. /********/
  120. int sstfb_init(void);
  121. int sstfb_setup(char *options);
  122. static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id);
  123. static void __devexit sstfb_remove(struct pci_dev *pdev);
  124. /* Framebuffer API */
  125. static int sstfb_open(struct fb_info *info, int user);
  126. static int sstfb_release(struct fb_info *info, int user);
  127. static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
  128.                          int con, struct fb_info *info);
  129. static int sstfb_get_var(struct fb_var_screeninfo *var,
  130.                          int con, struct fb_info *info);
  131. static int sstfb_set_var(struct fb_var_screeninfo *var,
  132.                          int con, struct fb_info *info);
  133. static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
  134.                           int con, struct fb_info *info);
  135. static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
  136.                           int con, struct fb_info *info);
  137. static int sstfb_pan_display(struct fb_var_screeninfo *var,
  138.                              int con, struct fb_info *info);
  139. static int sstfb_ioctl(struct inode *inode, struct file *file,
  140.                        u_int cmd, u_long arg, int con,
  141.                        struct fb_info *info);
  142. /* Interface to the low level console driver */
  143. static int sstfbcon_switch(int con, struct fb_info *info);
  144. static int sstfbcon_updatevar(int con, struct fb_info *info);
  145. static void sstfbcon_blank(int blank, struct fb_info *info);
  146. /* Internal routines */
  147. static void sstfb_install_cmap(int con, struct fb_info *info);
  148. static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
  149.                            u_int *transp, struct fb_info *info);
  150. static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  151.                            u_int transp, struct fb_info *info);
  152. static int sstfb_set_par(const struct sstfb_par *par,
  153.                           struct sstfb_info *sst_info);
  154. static int sstfb_decode_var (const struct fb_var_screeninfo *var,
  155.                              struct sstfb_par *par,
  156.                              const struct sstfb_info *sst_info);
  157. static int sstfb_encode_var (struct fb_var_screeninfo *var,
  158.                              const struct sstfb_par *par,
  159.                              const struct sstfb_info *sst_info);
  160. static void sstfb_test16(struct sstfb_info *sst_info);
  161. #ifdef EN_24_32_BPP
  162. static void sstfb_test32(struct sstfb_info *sst_info);
  163. #endif
  164. /* Low level routines */
  165. static int sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize);
  166. static int __sst_wait_idle(u_long vbase);
  167. #define sst_wait_idle()  __sst_wait_idle(sst_info->mmio.vbase)
  168. static int sst_detect_dactype(struct sstfb_info *sst_info);
  169. static int sst_detect_att(struct sstfb_info *sst_info);
  170. static int sst_detect_ti(struct sstfb_info *sst_info);
  171. static int sst_detect_ics(struct sstfb_info *sst_info);
  172. static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t);
  173. static int sst_set_pll_att_ti(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
  174. static int sst_set_pll_ics(struct sstfb_info *sst_info, const struct pll_timing *t, const int clock);
  175. static void sst_set_vidmod_att_ti(struct sstfb_info *sst_info, const int bpp);
  176. static void sst_set_vidmod_ics(struct sstfb_info *sst_info, const int bpp);
  177. static int sst_init(struct sstfb_info *sst_info);
  178. static void sst_shutdown(struct sstfb_info *sst_info);
  179. static struct fb_ops sstfb_ops = {
  180. owner : THIS_MODULE,
  181. fb_open: sstfb_open,
  182. fb_release: sstfb_release,
  183. fb_get_fix: sstfb_get_fix,
  184. fb_get_var: sstfb_get_var,
  185. fb_set_var: sstfb_set_var,
  186. fb_get_cmap: sstfb_get_cmap,
  187. fb_set_cmap: sstfb_set_cmap,
  188. fb_pan_display: sstfb_pan_display,
  189. fb_ioctl: sstfb_ioctl,
  190. };
  191. enum {
  192. ID_VOODOO1 = 0,
  193. ID_VOODOO2 = 1,
  194. };
  195. #define IS_VOODOO2(info) ((info)->type == ID_VOODOO2 )
  196. static struct sst_spec voodoo_spec[] __devinitdata = {
  197. { name : "Voodoo Graphics",
  198. default_gfx_clock : 50000,
  199. max_gfxclk : 60, },
  200. { name : "Voodoo2",
  201. default_gfx_clock : 75000,
  202. max_gfxclk : 85, },
  203. };
  204. static struct pci_device_id sstfb_id_tbl[] __devinitdata = {
  205. { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO,
  206.   PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 },
  207. { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2,
  208.   PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 },
  209. { 0 },
  210. };
  211. static struct pci_driver sstfb_driver = {
  212. name: "sstfb",
  213. id_table: sstfb_id_tbl,
  214. probe:          sstfb_probe,
  215. remove: __devexit_p(sstfb_remove),
  216. };
  217. static struct fb_var_screeninfo sstfb_default =
  218. #if ( DEFAULT_MODE == 0 )
  219.     { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
  220.     800, 600, 800, 600, 0, 0, 16, 0,
  221.     {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
  222.     0, 0, -1, -1, 0,
  223.     25000, 86, 41, 23, 1, 127, 4,
  224.     0, FB_VMODE_NONINTERLACED };
  225. #endif
  226. #if ( DEFAULT_MODE == 1 )
  227.     {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
  228.     640, 480, 640, 480, 0, 0, 16, 0,
  229.     {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
  230.     0, 0, -1, -1, 0,
  231.     31746, 118, 17, 16, 1, 63, 3,
  232.     0, FB_VMODE_NONINTERLACED };
  233. #endif
  234. #if ( DEFAULT_MODE == 2 )
  235.     { /* 1024x768@76 took from my /etc/fb.modes */
  236.     1024, 768, 1024, 768,0, 0, 16,0,
  237.     {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
  238.     0, 0, -1, -1, 0,
  239.     11764, 208, 8, 36, 16, 120, 3 ,
  240.     0, FB_VMODE_NONINTERLACED };
  241. #endif
  242. #if ( DEFAULT_MODE == 3 )
  243.     { /* 640x480@60 , 16bpp glide default ?*/
  244.     640, 480, 640, 480, 0, 0, 16, 0,
  245.     {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
  246.     0, 0, -1, -1, 0,
  247.     39721 ,  38, 26 ,  25 ,18  , 96 ,2,
  248.     0, FB_VMODE_NONINTERLACED };
  249. #endif
  250. static struct dac_switch dacs[] __devinitdata = {
  251. { name: "TI TVP3409",
  252. detect: sst_detect_ti,
  253. set_pll: sst_set_pll_att_ti,
  254. set_vidmod: sst_set_vidmod_att_ti },
  255. { name: "AT&T ATT20C409",
  256. detect: sst_detect_att,
  257. set_pll: sst_set_pll_att_ti,
  258. set_vidmod: sst_set_vidmod_att_ti },
  259. { name: "ICS ICS5342",
  260. detect: sst_detect_ics,
  261. set_pll: sst_set_pll_ics,
  262. set_vidmod: sst_set_vidmod_ics },
  263. };
  264. /*
  265.  *
  266.  *  Definitions
  267.  *
  268.  */
  269. #if (SST_DEBUG_VAR > 0)
  270. /* debug info / dump a fb_var_screeninfo */
  271. static void sst_dbg_print_var(struct fb_var_screeninfo *var) {
  272. dprintk(" {%d, %d, %d, %d, %d, %d, %d, %d,n",
  273.         var->xres, var->yres, var->xres_virtual, var->yres_virtual,
  274.         var->xoffset, var->yoffset,
  275.         var->bits_per_pixel, var->grayscale);
  276. dprintk(" {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d},n",
  277.         var->red.offset, var->red.length, var->red.msb_right,
  278.         var->green.offset, var->green.length, var->green.msb_right,
  279.         var->blue.offset, var->blue.length, var->blue.msb_right,
  280.         var->transp.offset, var->transp.length,
  281.         var->transp.msb_right);
  282. dprintk(" %d, %d, %d, %d, %d,n",
  283.         var->nonstd, var->activate,
  284.         var->height, var->width, var->accel_flags);
  285. dprintk(" %d, %d, %d, %d, %d, %d, %d,n",
  286.         var->pixclock, var->left_margin, var->right_margin,
  287.         var->upper_margin, var->lower_margin,
  288.         var->hsync_len, var->vsync_len);
  289. dprintk(" %#x, %#x}n",var->sync, var->vmode);
  290. }
  291. #endif /* (SST_DEBUG_VAR > 0) */
  292. #if (SST_DEBUG_REG > 0)
  293. static void sst_dbg_print_read_reg (u32 reg, u32 val) {
  294. char * regname =NULL;
  295. switch (reg) {
  296. case FBIINIT0: regname="FbiInit0"; break;
  297. case FBIINIT1: regname="FbiInit1"; break;
  298. case FBIINIT2: regname="FbiInit2"; break;
  299. case FBIINIT3: regname="FbiInit3"; break;
  300. case FBIINIT4: regname="FbiInit4"; break;
  301. case FBIINIT5: regname="FbiInit5"; break;
  302. case FBIINIT6: regname="FbiInit6"; break;
  303. }
  304. if (regname == NULL)
  305. r_ddprintk("sst_read(%#x): %#xn", reg, val);
  306. else
  307. r_dprintk(" sst_read(%s): %#xn", regname, val);
  308. }
  309. static void sst_dbg_print_write_reg (u32 reg, u32 val) {
  310. char * regname = NULL;
  311. switch (reg) {
  312. case FBIINIT0: regname="FbiInit0"; break;
  313. case FBIINIT1: regname="FbiInit1"; break;
  314. case FBIINIT2: regname="FbiInit2"; break;
  315. case FBIINIT3: regname="FbiInit3"; break;
  316. case FBIINIT4: regname="FbiInit4"; break;
  317. case FBIINIT5: regname="FbiInit5"; break;
  318. case FBIINIT6: regname="FbiInit6"; break;
  319. }
  320. if (regname == NULL)
  321. r_ddprintk("sst_write(%#x, %#x)n", reg, val);
  322. else
  323. r_dprintk(" sst_write(%s, %#x)n", regname, val);
  324. }
  325. #else /*  (SST_DEBUG_REG > 0) */
  326. #  define sst_dbg_print_read_reg(reg, val) do {}while(0)
  327. #  define sst_dbg_print_write_reg(reg, val) do {}while(0)
  328. #endif /*  (SST_DEBUG_REG > 0) */
  329. /* register access */
  330. #define sst_read(reg) __sst_read(sst_info->mmio.vbase, reg)
  331. #define sst_write(reg,val) __sst_write(sst_info->mmio.vbase, reg, val)
  332. #define sst_set_bits(reg,val) __sst_set_bits(sst_info->mmio.vbase, reg, val)
  333. #define sst_unset_bits(reg,val) __sst_unset_bits(sst_info->mmio.vbase, reg, val)
  334. #define sst_dac_read(reg) __sst_dac_read(sst_info->mmio.vbase, reg)
  335. #define sst_dac_write(reg,val) __sst_dac_write(sst_info->mmio.vbase, reg, val)
  336. #define dac_i_read(reg) __dac_i_read(sst_info->mmio.vbase, reg)
  337. #define dac_i_write(reg,val) __dac_i_write(sst_info->mmio.vbase, reg, val)
  338. static inline u32 __sst_read(u_long vbase, u32 reg)
  339. {
  340. u32 ret;
  341. ret = readl(vbase + reg);
  342. sst_dbg_print_read_reg(reg, ret);
  343. return ret;
  344. }
  345. static inline void __sst_write(u_long vbase, u32 reg, u32 val)
  346. {
  347. sst_dbg_print_write_reg(reg, val);
  348. writel(val, vbase + reg);
  349. }
  350. static inline void __sst_set_bits(u_long vbase, u32 reg, u32 val)
  351. {
  352. r_dprintk("sst_set_bits(%#x, %#x)n", reg, val);
  353. __sst_write(vbase, reg, __sst_read(vbase, reg) | val);
  354. }
  355. static inline void __sst_unset_bits(u_long vbase, u32 reg, u32 val)
  356. {
  357. r_dprintk("sst_unset_bits(%#x, %#x)n", reg, val);
  358. __sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
  359. }
  360. /* dac access */
  361. /* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
  362. static u8 __sst_dac_read(u_long vbase, u8 reg)
  363. {
  364. u8 ret;
  365. #ifdef SST_DEBUG
  366. if ((reg & 0x07) != reg) {
  367. dprintk("bug line %d: register adress '%d' is too highn",
  368.          __LINE__,reg);
  369. }
  370. #endif
  371. reg &= 0x07;
  372. __sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
  373. __sst_wait_idle(vbase);
  374. /*udelay(10);*/
  375. ret=(__sst_read(vbase, DAC_READ) & 0xff);
  376. r_dprintk("sst_dac_read(%#x): %#xn", reg, ret);
  377. return (u8)ret;
  378. }
  379. static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
  380. {
  381. r_dprintk("sst_dac_write(%#x, %#x)n", reg, val);
  382. #ifdef SST_DEBUG
  383. if ((reg & 0x07) != reg)
  384. dprintk("bug line %d: register adress '%d' is too highn",
  385.          __LINE__,reg);
  386. #endif
  387. reg &= 0x07;
  388. __sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
  389. }
  390. /* indexed access to ti/att dacs */
  391. static u32 __dac_i_read(u_long vbase, u8 reg)
  392. {
  393. u32 ret;
  394. __sst_dac_write(vbase, DACREG_ADDR_I, reg);
  395. ret = __sst_dac_read(vbase, DACREG_DATA_I);
  396. r_dprintk("sst_dac_read_i(%#x): %#xn", reg, ret);
  397. return ret;
  398. }
  399. static void __dac_i_write(u_long vbase, u8 reg,u8 val)
  400. {
  401. r_dprintk("sst_dac_write_i(%#x, %#x)n", reg, val);
  402. __sst_dac_write(vbase, DACREG_ADDR_I, reg);
  403. __sst_dac_write(vbase, DACREG_DATA_I, val);
  404. }
  405. /*
  406.  *
  407.  *  Internal routines
  408.  *
  409.  */
  410. static void sstfb_install_cmap(int con, struct fb_info *info)
  411. {
  412. #define sst_info ((struct sstfb_info *) info)
  413. f_dprintk("sstfb_install_cmap(con: %d)n",con);
  414. f_ddprintk("currcon: %dn", sst_info->currcon);
  415. if (con != sst_info->currcon)
  416. return;
  417. if (fb_display[con].cmap.len)
  418. fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);
  419. else
  420. fb_set_cmap(
  421. fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
  422. 1, sstfb_setcolreg, info);
  423. #undef sst_info
  424. }
  425. static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
  426.                            u_int *transp, struct fb_info *info)
  427. {
  428. #define sst_info ((struct sstfb_info *) info)
  429. f_dddprintk("sstfb_getcolregn");
  430. if (regno >= 16) return 1;
  431. *red    = sst_info->palette[regno].red;
  432. *green  = sst_info->palette[regno].green;
  433. *blue   = sst_info->palette[regno].blue;
  434. *transp = sst_info->palette[regno].transp;
  435. f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#xn",
  436.             regno,*red, *green, *blue, *transp);
  437. return 0;
  438. #undef sst_info
  439. }
  440. static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  441.                            u_int transp, struct fb_info *info)
  442. {
  443. #define sst_info ((struct sstfb_info *) info)
  444. u32 col;
  445. struct display * disp;
  446. f_dddprintk("sstfb_setcolregn");
  447. f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#xn",
  448.             regno, red, green, blue, transp);
  449. if (regno >= 16) return 1;
  450. sst_info->palette[regno].red   = red;
  451. sst_info->palette[regno].green = green;
  452. sst_info->palette[regno].blue  = blue;
  453. sst_info->palette[regno].transp= transp;
  454. disp=&sst_info->disp;
  455. red    >>= (16 - disp->var.red.length);
  456. green  >>= (16 - disp->var.green.length);
  457. blue   >>= (16 - disp->var.blue.length);
  458. transp >>= (16 - disp->var.transp.length);
  459. col = (red << disp->var.red.offset)
  460.     | (green << disp->var.green.offset)
  461.     | (blue  << disp->var.blue.offset)
  462.     | (transp << disp->var.transp.offset);
  463. switch(disp->var.bits_per_pixel) {
  464. #ifdef FBCON_HAS_CFB16
  465. case 16:
  466. sst_info->fbcon_cmap.cfb16[regno]=(u16)col;
  467. break;
  468. #endif
  469. #ifdef EN_24_32_BPP
  470. #ifdef FBCON_HAS_CFB24
  471. case 24:
  472. sst_info->fbcon_cmap.cfb32[regno]=col;
  473. break;
  474. #endif
  475. #ifdef FBCON_HAS_CFB32
  476. case 32:
  477. sst_info->fbcon_cmap.cfb32[regno]=col;
  478. break;
  479. #endif
  480. #endif
  481. default:
  482. eprintk("bug line %d: bad depth '%u'n",__LINE__,
  483. disp->var.bits_per_pixel);
  484. break;
  485. }
  486. f_dddprintk("bpp: %d . encoded color: %#xn",
  487.             disp->var.bits_per_pixel, col);
  488. return 0;
  489. #undef sst_info
  490. }
  491. /* set par according to var ( checks var ) */
  492. static int sstfb_decode_var (const struct fb_var_screeninfo *var,
  493.                              struct sstfb_par *par,
  494.                              const struct sstfb_info *sst_info)
  495. {
  496. int real_length;
  497. f_dprintk("sstfb_decode_varn");
  498. /* Check var validity */
  499. par->valid=0;
  500. memset(par, 0, sizeof(par));
  501. par->xDim       = var->xres;
  502. par->hSyncOn    = var->hsync_len;
  503. par->hSyncOff   = var->xres + var->right_margin + var->left_margin;
  504. par->hBackPorch = var->left_margin;
  505. par->yDim       = var->yres;
  506. par->vSyncOn    = var->vsync_len;
  507. par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
  508. par->vBackPorch = var->upper_margin;
  509. if(sst_calc_pll (PS2KHZ(var->pixclock), &par->freq, &par->pll)) {
  510. eprintk("Pixclock %d out of rangen", var->pixclock);
  511. return -EINVAL; //XXX
  512. }
  513. par->sync=var->sync & (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
  514. par->vmode=var->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE);
  515. /* in laced mode, vBackPorch should be even. odd -> funky display */
  516. if (par->vmode & FB_VMODE_INTERLACED)
  517. par->vBackPorch += (par->vBackPorch % 2);
  518. if (par->vmode & FB_VMODE_DOUBLE) {
  519. par->vBackPorch <<= 1;
  520. par->yDim <<=1;
  521. par->vSyncOn <<=1;
  522. par->vSyncOff <<=1;
  523. }
  524. switch (var->bits_per_pixel) {
  525. case 0 ... 16 :
  526. par->bpp = 16;
  527. break;
  528. #ifdef EN_24_32_BPP
  529. case 17 ... 24 :
  530. par->bpp = 24;
  531. break;
  532. case 25 ... 32 :
  533. par->bpp = 32;
  534. break;
  535. #endif
  536. default :
  537. eprintk ("Unsupported bpp %dn", par->bpp);
  538. return -EINVAL;
  539. break;
  540. }
  541. if (IS_VOODOO2(sst_info)) {
  542. /* voodoo2 has 32 pixel wide tiles , BUT stange things
  543.  happen with odd number of tiles */
  544. par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;
  545. } else {
  546. /* voodoo1 has 64 pixels wide tiles. */
  547. par->tiles_in_X= (par->xDim + 63 ) / 64;
  548. }
  549. /* validity tests */
  550. if((par->xDim <= 1) || (par->yDim <= 0 )
  551.    || (par->hSyncOn <= 1)
  552.    || (par->hSyncOff <= 1)
  553.    || (par->hBackPorch <= 2)
  554.    || (par->vSyncOn <= 0)
  555.    || (par->vSyncOff <= 0)
  556.    || (par->vBackPorch <= 0)
  557.    || (par->tiles_in_X <= 0)) {
  558. return -EINVAL;
  559. }
  560. if (IS_VOODOO2(sst_info)) {
  561. /* Voodoo 2 limits */
  562. if(((par->xDim-1) >= POW2(11)) || (par->yDim >= POW2(11))) {
  563. eprintk ("Unsupported resolution %dx%dn",
  564.          var->xres, var->yres);
  565. return -EINVAL;
  566. }
  567. if (((par->hSyncOn-1) >= POW2(9))
  568.    || ((par->hSyncOff-1) >= POW2(11))
  569.    || ((par->hBackPorch-2) >= POW2(9))
  570.    || (par->vSyncOn >= POW2(13))
  571.    || (par->vSyncOff >= POW2(13))
  572.    || (par->vBackPorch >= POW2(9))
  573.    || (par->tiles_in_X >= POW2(6))) {
  574. eprintk ("Unsupported Timingn");
  575. return -EINVAL;
  576. }
  577. } else {
  578. /* Voodoo limits */
  579. if (par->vmode) {
  580. eprintk("Interlace/Doublescan not supported %#xn",
  581. par->vmode);
  582. return -EINVAL;
  583. }
  584. if(((par->xDim-1) >= POW2(10)) || (par->yDim >= POW2(10))) {
  585. eprintk ("Unsupported resolution %dx%dn",
  586.          var->xres, var->yres);
  587. return -EINVAL;
  588. }
  589. if (((par->hSyncOn-1) >= POW2(8))
  590.    || ((par->hSyncOff-1) >= POW2(10))
  591.    || ((par->hBackPorch-2) >= POW2(8))
  592.    || (par->vSyncOn >= POW2(12))
  593.    || (par->vSyncOff >= POW2(12))
  594.    || (par->vBackPorch >= POW2(8))
  595.    || (par->tiles_in_X >= POW2(4))) {
  596. eprintk ("Unsupported Timingsn");
  597. return -EINVAL;
  598. }
  599. }
  600. /* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/
  601. /* FIXME: i don't like this... looks wrong*/
  602. real_length = par->tiles_in_X  * (IS_VOODOO2(sst_info) ? 32 : 64 )
  603.               * ((par->bpp == 16) ? 2 : 4);
  604. if ((real_length * var->yres) > sst_info->video.len) {
  605. eprintk ("Not enough video memoryn");
  606. return -ENOMEM;
  607. }
  608. par->valid=1;
  609. return 0;
  610. }
  611. /* sets var according to par (basicaly, sets sane values) */
  612. static int sstfb_encode_var (struct fb_var_screeninfo *var,
  613.                              const struct sstfb_par *par,
  614.                              const struct sstfb_info *sst_info)
  615. {
  616. memset(var,0,sizeof(struct fb_var_screeninfo));
  617. var->xres           = par->xDim;
  618. var->yres           = par->yDim;
  619. var->xres_virtual   = par->xDim;
  620. var->yres_virtual   = par->yDim;
  621. var->bits_per_pixel = par->bpp;
  622. /* {x|y}offset = 0 ; sync=0 */
  623. var->height         = -1;
  624. var->width          = -1;
  625. var->pixclock       = KHZ2PS(par->freq);
  626. var->left_margin    = par->hBackPorch;
  627. var->right_margin   = par->hSyncOff - par->xDim - par->hBackPorch;
  628. var->upper_margin   = par->vBackPorch;
  629. var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;
  630. var->hsync_len      = par->hSyncOn;
  631. var->vsync_len      = par->vSyncOn;
  632. var->sync           = par->sync;
  633. var->vmode          = par->vmode;
  634. if (var->vmode & FB_VMODE_DOUBLE) {
  635. var->yres           >>=1;
  636. var->yres_virtual   >>=1;
  637. var->vsync_len      >>=1;
  638. var->upper_margin   >>=1;
  639. var->lower_margin   >>=1;
  640. }
  641. /*
  642.  * correct the color bit fields
  643.  */
  644. /* var->{red|green|blue}.msb_right    = 0; */
  645. switch (par->bpp) {
  646. case 16: /* RGB 565  LfbMode 0 */
  647. var->red.length    = 5;
  648. var->green.length  = 6;
  649. var->blue.length   = 5;
  650. var->transp.length = 0;
  651. var->red.offset    = 11;
  652. var->green.offset  = 5;
  653. var->blue.offset   = 0;
  654. var->transp.offset = 0;
  655. break;
  656. #ifdef EN_24_32_BPP
  657. case 24: /* RGB 888 LfbMode 4 */
  658. case 32: /* ARGB 8888 LfbMode 5 */
  659. var->red.length    = 8;
  660. var->green.length  = 8;
  661. var->blue.length   = 8;
  662. var->transp.length = 0;
  663. var->red.offset    = 16;
  664. var->green.offset  = 8;
  665. var->blue.offset   = 0;
  666. var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
  667. break;
  668. #endif
  669. default:
  670. eprintk ("bug line %d: bad depth '%u'n", __LINE__, par->bpp);
  671. break;
  672. }
  673. return 0;
  674. }
  675. /*
  676.  * Frame buffer API
  677.  */
  678. static int sstfb_open(struct fb_info *info, int user)
  679. {
  680. f_dprintk("sstfb_open(user: %d)n",user);
  681. return 0;
  682. }
  683. static int sstfb_release(struct fb_info *info, int user)
  684. {
  685. f_dprintk("sstfb_release(user: %d)n",user);
  686. return 0;
  687. }
  688. static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
  689.                          int con, struct fb_info *info)
  690. {
  691. #define sst_info ((struct sstfb_info *) info)
  692.    struct fb_var_screeninfo *var;
  693.   struct fb_var_screeninfo var2;
  694. f_dprintk("sstfb_get_fix(con: %d)n",con);
  695. memset(fix, 0, sizeof(struct fb_fix_screeninfo));
  696. if (con == -1)
  697. {
  698. sstfb_encode_var(&var2, &sst_info->current_par, sst_info);
  699. var = &var2;
  700. }
  701. else
  702. var = &fb_display[con].var;
  703. strcpy(fix->id, sst_info->info.modename);
  704. /* lfb phys address = membase + 4Mb */
  705. fix->smem_start  = sst_info->video.base;
  706. fix->smem_len    = sst_info->video.len;
  707. fix->type        = FB_TYPE_PACKED_PIXELS;
  708. fix->visual      = FB_VISUAL_TRUECOLOR;
  709. fix->accel       = FB_ACCEL_NONE;
  710. /*
  711.  *   According to the specs, the linelength must be of 1024 *pixels*.
  712.  * and the 24bpp mode is in fact a 32 bpp mode.
  713.  */
  714. fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;
  715. return 0;
  716. #undef sst_info
  717. }
  718. static int sstfb_get_var(struct fb_var_screeninfo *var,
  719.                          int con, struct fb_info *info)
  720. {
  721. #define sst_info ((struct sstfb_info *) info)
  722. f_dprintk("sstfb_get_var(con: %d)n",con);
  723. if (con == -1)
  724. sstfb_encode_var(var, &sst_info->current_par, sst_info);
  725. else
  726. *var = fb_display[con].var;
  727. print_var(var, "var");
  728. return 0;
  729. #undef sst_info
  730.  }
  731. static int sstfb_set_var(struct fb_var_screeninfo *var,
  732.                          int con, struct fb_info *info)
  733. {
  734. #define sst_info ((struct sstfb_info *) info)
  735. struct sstfb_par par;
  736. struct display *display;
  737. int err;
  738. int old_bpp,old_xres,old_yres;
  739. f_dprintk("sstfb_set_var(con: %d)n",con);
  740. f_ddprintk("xres yres vxres vyres bpp activaten");
  741. f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8xn",
  742.  var->xres,var->yres,var->xres_virtual,var->yres_virtual,
  743.  var->bits_per_pixel,var->activate);
  744. if (con < 0)
  745. display = &sst_info->disp;
  746. else
  747. display = &fb_display[con];
  748. if ((err = sstfb_decode_var(var, &par, sst_info)))
  749. return err;
  750. sstfb_encode_var (var, &par, sst_info);
  751. switch (var->activate & FB_ACTIVATE_MASK) {
  752. case FB_ACTIVATE_TEST:
  753. return 0;
  754. case FB_ACTIVATE_NXTOPEN:
  755. case FB_ACTIVATE_NOW:
  756. break;
  757. default:
  758. return -EINVAL;
  759. }
  760. old_xres = display->var.xres;
  761. old_yres = display->var.yres;
  762. old_bpp  = display->var.bits_per_pixel;
  763. display->var = *var;
  764. if ((old_xres != var->xres) || (old_yres != var->yres)
  765.     || (old_bpp != var->bits_per_pixel)) {
  766. /* 2-3  lignes redondantes avec get_fix */
  767. display->screen_base = (char *) sst_info->video.vbase;
  768. display->visual = FB_VISUAL_TRUECOLOR;
  769. display->type = FB_TYPE_PACKED_PIXELS;
  770. display->type_aux = 0;
  771. display->ypanstep = 0;
  772. display->ywrapstep = 0;
  773. display->line_length = (var->bits_per_pixel==16) ? 2048 : 4096;
  774. display->inverse = 0;
  775. switch (var->bits_per_pixel) {
  776. #ifdef FBCON_HAS_CFB16
  777. case 16:
  778. display->dispsw = &fbcon_cfb16;
  779. display->dispsw_data = sst_info->fbcon_cmap.cfb16;
  780. break;
  781. #endif
  782. #ifdef EN_24_32_BPP
  783. #if defined (FBCON_HAS_CFB24) || defined (FBCON_HAS_CFB32 )
  784. case 24: /*24bpp non packed <=> 32 bpp */
  785. case 32:
  786. display->dispsw = &fbcon_cfb32;
  787. display->dispsw_data = sst_info->fbcon_cmap.cfb32;
  788. break;
  789. #endif
  790. #endif
  791. default:
  792. display->dispsw = &fbcon_dummy;
  793. break;
  794. }
  795. display->scrollmode = SCROLL_YREDRAW;
  796. if (sst_info->info.changevar) {
  797. v_dprintk("fb_info.changevar(con: %d)n", con);
  798. (*sst_info->info.changevar)(con);
  799. v_dprintk("fb_info.changevar: done n");
  800. } else {
  801. v_dprintk("fb_info.changevar() == NULL . n");
  802. }
  803. }
  804. if ((con == -1) || (con==sst_info->currcon)) {
  805. sstfb_set_par (&par, sst_info);
  806. }
  807. print_var(var, "var");
  808. print_var(&display->var, "&display->var");
  809. if (old_bpp != var->bits_per_pixel) {
  810.     if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
  811. return err;
  812.     sstfb_install_cmap(con, info);
  813. }
  814. return 0;
  815. #undef sst_info
  816. }
  817. static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
  818.                           int con, struct fb_info *info)
  819. {
  820. #define sst_info ((struct sstfb_info *) info)
  821. struct display *d = (con<0) ? info->disp : fb_display + con;
  822. f_dprintk("sstfb_set_cmapn");
  823. f_ddprintk("con: %d, currcon: %d, d->cmap.len %dn",
  824.  con, sst_info->currcon, d->cmap.len);
  825. if (d->cmap.len != 16 ) { /* or test if cmap.len == 0 ? */
  826. int err;
  827. err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */
  828. if (err) return err;
  829. }
  830. if (con == sst_info->currcon) {
  831. return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);
  832. } else {
  833. fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
  834. }
  835. return 0;
  836. #undef sst_info
  837. }
  838. static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
  839.                           int con, struct fb_info *info)
  840. {
  841. #define sst_info ((struct sstfb_info *) info)
  842. f_dprintk("sstfb_get_cmapn");
  843. f_ddprintk("con %d, curcon %d, cmap.len %dn",
  844.  con, sst_info->currcon, fb_display[con].cmap.len);
  845. /* FIXME: check if con = -1 ? cf sstfb_set_cmap...  */
  846. if (con == sst_info->currcon)
  847. return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);
  848. else if (fb_display[con].cmap.len)
  849. fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
  850. else
  851. fb_copy_cmap(
  852. fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
  853. cmap, kspc ? 0 : 2);
  854. return 0;
  855. #undef sst_info
  856. }
  857. /* TODO */
  858. static int sstfb_pan_display(struct fb_var_screeninfo *var,
  859.                              int con, struct fb_info *info)
  860. {
  861. f_dprintk("sstfb_pan_displayn");
  862. return -EINVAL;
  863. }
  864. static int sstfb_ioctl(struct inode *inode, struct file *file,
  865.                        u_int cmd, u_long arg, int con,
  866.                        struct fb_info *info)
  867. {
  868. #define sst_info ((struct sstfb_info *) info)
  869. #if (SST_DEBUG_IOCTL >0)
  870. int i;
  871. u_long p;
  872. u32 tmp, val;
  873. u32 fbiinit0;
  874. struct pci_dev * sst_dev = sst_info->dev;
  875. #endif
  876. f_dprintk("sstfb_ioctl(%x)n", cmd);
  877. #if (SST_DEBUG_IOCTL >0)
  878. switch (cmd) {
  879. #  if (SST_DEBUG_VAR >0)
  880. /* tmp ioctl : dumps fb_display[0-5] */
  881. case _IO('F', 0xdb): /* 0x46db */
  882. f_dprintk("dumping fb_display[0-5].varn");
  883. for (i = 0 ; i< 6 ; i++) {
  884. print_var(&fb_display[i].var, "var(%d)", i);
  885. }
  886. return 0;
  887. #  endif /* (SST_DEBUG_VAR >0) */
  888. /* fills the lfb up to *(u32*)arg */
  889. case _IOW('F', 0xdc, u32): /* 0x46dc */
  890. if (copy_from_user(&val, (void *) arg, sizeof(val)))
  891. return -EFAULT;
  892. if (val > 0x400000 )
  893. val = 0x400000;
  894. f_dprintk("filling %#x n", val);
  895. for (p = 0 ; p < val; p+=2)
  896. writew( p >> 6 , sst_info->video.vbase + p);
  897. return 0;
  898. /* change VGA pass_through */
  899. case _IOW('F', 0xdd, u32): /* 0x46dd */
  900. if (copy_from_user(&val, (void *) arg, sizeof(val)))
  901. return -EFAULT;
  902. f_dprintk("switch VGA pass-throughn");
  903. pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
  904. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  905.        tmp | PCI_EN_INIT_WR );
  906. fbiinit0 = sst_read (FBIINIT0);
  907. if (val) {
  908. sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
  909. iprintk ( "Disabling VGA pass-throughn");
  910. } else {
  911. sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
  912. iprintk ( "Enabling VGA pass-throughn");
  913. }
  914. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
  915. return 0;
  916. case _IO('F', 0xde): /* 0x46de */
  917. f_dprintk("test color displayn");
  918. f_ddprintk("currcon: %d, bpp %dn", sst_info->currcon,
  919.   sst_info->current_par.bpp);
  920. memset_io(sst_info->video.vbase, 0, sst_info->video.len);
  921. switch (sst_info->current_par.bpp) {
  922.         case 16:
  923. sstfb_test16(sst_info);
  924. break;
  925. #  ifdef EN_24_32_BPP
  926. case 24:
  927. case 32:
  928. sstfb_test32(sst_info);
  929. break;
  930. #  endif
  931. default:
  932. dprintk("bug line %d: bad depth '%u'n", __LINE__,
  933.         sst_info->current_par.bpp);
  934. }
  935. return 0;
  936. }
  937. #endif /* (SST_DEBUG_IOCTL >0) */
  938. return -EINVAL;
  939. #undef sst_info
  940. }
  941. /*
  942.  * Low level routines
  943.  */
  944. /* get lfb size */
  945. static int __devinit sst_get_memsize(struct sstfb_info *sst_info, u_long *memsize)
  946. {
  947. u_long fbbase_virt = sst_info->video.vbase;
  948. f_dprintk("sst_get_memsizen");
  949. /* force memsize */
  950. if ((mem >= 1 ) &&  (mem <= 4)) {
  951. *memsize = (mem * 0x100000);
  952. iprintk("supplied memsize: %#lxn", *memsize);
  953. return 1;
  954. }
  955. writel (0xdeadbeef, fbbase_virt);
  956. writel (0xdeadbeef, fbbase_virt+0x100000);
  957. writel (0xdeadbeef, fbbase_virt+0x200000);
  958. f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#xn",
  959.            readl(fbbase_virt), readl(fbbase_virt + 0x100000),
  960.            readl(fbbase_virt + 0x200000));
  961. writel (0xabcdef01, fbbase_virt);
  962. f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#xn",
  963.            readl(fbbase_virt), readl(fbbase_virt + 0x100000),
  964.            readl(fbbase_virt + 0x200000));
  965. /* checks for 4mb lfb , then 2, then defaults to 1*/
  966. if (readl(fbbase_virt + 0x200000) == 0xdeadbeef) {
  967. *memsize = 0x400000;
  968. } else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef) {
  969. *memsize = 0x200000;
  970. } else {
  971. *memsize = 0x100000;
  972. }
  973. f_ddprintk("detected memsize: %#lxn", *memsize);
  974. return 1;
  975. }
  976. /*
  977.  * wait for the fbi chip. ASK: what happens if the fbi is stuck ?
  978.  *
  979.  * the FBI is supposed to be ready if we receive 5 time
  980.  * in a row a "idle" answer to our requests
  981.  */
  982. static int __sst_wait_idle(u_long vbase)
  983. {
  984. int count = 0;
  985. f_ddprintk("sst_wait_idlen");
  986. while(1) {
  987. if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
  988. f_dddprintk("status: busyn");
  989. /* FIXME basicaly, this is a busy wait. maybe not that good. oh well; this is a small loop after all ...*/
  990. count = 0;
  991. } else {
  992. count++;
  993. f_dddprintk("status: idle(%d)n", count);
  994. }
  995. if (count >= 5) return 1;
  996. //XXX  do something to avoid hanging the machine if the voodoo is out
  997. }
  998. }
  999. /*
  1000.  * detect dac type
  1001.  * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
  1002.  * dram refresh disabled, FbiInit remaped.
  1003.  * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
  1004.  */
  1005. static int __devinit sst_detect_dactype(struct sstfb_info * sst_info)
  1006. {
  1007. int ret=0,i;
  1008. f_dprintk("sst_detect_dactypen");
  1009. for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) {
  1010. ret = dacs[i].detect(sst_info);
  1011. if (ret) break;
  1012. }
  1013. if (!ret)
  1014. return 0;
  1015. f_dprintk("found %sn", dacs[i].name);
  1016. sst_info->dac_sw=dacs[i];
  1017. return 1;
  1018. }
  1019. /* fbi should be idle, and fifo emty and mem disabled */
  1020. /* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
  1021. static int __devinit sst_detect_att(struct sstfb_info * sst_info)
  1022. {
  1023. int i, mir, dir;
  1024. f_dprintk("sst_detect_attn");
  1025. for (i = 0; i<3; i++) {
  1026. sst_dac_write(DACREG_WMA, 0);  /* backdoor */
  1027. sst_dac_read(DACREG_RMR); /* read 4 times RMR */
  1028. sst_dac_read(DACREG_RMR);
  1029. sst_dac_read(DACREG_RMR);
  1030. sst_dac_read(DACREG_RMR);
  1031. /* the fifth time,  CR0 is read */
  1032. sst_dac_read(DACREG_RMR);
  1033. /* the 6th, manufacturer id register */
  1034. mir = sst_dac_read(DACREG_RMR);
  1035. /*the 7th, device ID register */
  1036. dir = sst_dac_read(DACREG_RMR);
  1037. f_ddprintk("mir: %#x, dir: %#xn", mir, dir);
  1038. if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
  1039. return 1;
  1040. }
  1041. }
  1042. return 0;
  1043. }
  1044. static int __devinit sst_detect_ti(struct sstfb_info * sst_info)
  1045. {
  1046. int i, mir, dir;
  1047. f_dprintk("sst_detect_tin");
  1048. for (i = 0; i<3; i++) {
  1049. sst_dac_write(DACREG_WMA, 0);  /* backdoor */
  1050. sst_dac_read(DACREG_RMR); /* read 4 times RMR */
  1051. sst_dac_read(DACREG_RMR);
  1052. sst_dac_read(DACREG_RMR);
  1053. sst_dac_read(DACREG_RMR);
  1054. /* the fifth time,  CR0 is read */
  1055. sst_dac_read(DACREG_RMR);
  1056. /* the 6th, manufacturer id register */
  1057. mir = sst_dac_read(DACREG_RMR);
  1058. /*the 7th, device ID register */
  1059. dir = sst_dac_read(DACREG_RMR);
  1060. f_ddprintk("mir: %#x, dir: %#xn", mir, dir);
  1061. if ((mir == DACREG_MIR_TI ) && (dir == DACREG_DIR_TI)) {
  1062. return 1;
  1063. }
  1064. }
  1065. return 0;
  1066. }
  1067. /*
  1068.  * try to detect ICS5342  ramdac
  1069.  * we get the 1st byte (M value) of preset f1,f7 and fB
  1070.  * why those 3 ? mmmh... for now, i'll do it the glide way...
  1071.  * and ask questions later. anyway, it seems that all the freq registers are
  1072.  * realy at their default state (cf specs) so i ask again, why those 3 regs ?
  1073.  * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for
  1074.  * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be
  1075.  * touched...
  1076.  * is it realy safe ? how can i reset this ramdac ? geee...
  1077.  */
  1078. static int __devinit sst_detect_ics(struct sstfb_info * sst_info)
  1079. {
  1080. int i;
  1081. int m_clk0_1, m_clk0_7, m_clk1_b;
  1082. int n_clk0_1, n_clk0_7, n_clk1_b;
  1083. f_dprintk("sst_detect_icsn");
  1084. for (i = 0; i<5; i++ ) {
  1085. sst_dac_write(DACREG_ICS_PLLRMA, 0x1); /* f1 */
  1086. m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
  1087. n_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
  1088. sst_dac_write(DACREG_ICS_PLLRMA, 0x7); /* f7 */
  1089. m_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
  1090. n_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
  1091. sst_dac_write(DACREG_ICS_PLLRMA, 0xb); /* fB */
  1092. m_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
  1093. n_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
  1094. f_ddprintk("m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#xn",
  1095. m_clk0_1, m_clk0_7, m_clk1_b);
  1096. f_ddprintk("n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#xn",
  1097. n_clk0_1, n_clk0_7, n_clk1_b);
  1098. if ((   m_clk0_1 == DACREG_ICS_PLL_CLK0_1_INI)
  1099.     && (m_clk0_7 == DACREG_ICS_PLL_CLK0_7_INI)
  1100.     && (m_clk1_b == DACREG_ICS_PLL_CLK1_B_INI)) {
  1101. return 1;
  1102. }
  1103. }
  1104. return 0;
  1105. }
  1106. /* compute the m,n,p  , returns the real freq
  1107.  * (ics datasheet :  N <-> N1 , P <-> N2)
  1108.  *
  1109.  * Fout= Fref * (M+2)/( 2^P * (N+2))
  1110.  *  we try to get close to the asked freq
  1111.  *  with P as high, and M as low as possible
  1112.  * range:
  1113.  * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N <= 63
  1114.  * ics    : 1 <= M <= 127; 0 <= P <= 3; 1<= N <= 31
  1115.  * we'll use the lowest limitation, should be precise enouth
  1116.  */
  1117. static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
  1118. {
  1119. int m, m2, n, p, best_err, fout;
  1120. int best_n=-1;
  1121. int best_m=-1;
  1122. f_dprintk("sst_calc_pll(%dKhz)n", freq);
  1123. best_err = freq;
  1124. p=3;
  1125. /* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/
  1126. while (((1 << p) * freq > VCO_MAX) && (p >= 0))
  1127. p--;
  1128. if (p == -1)
  1129. return -EINVAL;
  1130. for (n = 1; n < 32; n++) {
  1131. /* calc 2 * m so we can round it later*/
  1132. m2 = (2 * freq * (1 << p) * (n + 2) ) / DAC_FREF - 4 ;
  1133. m = (m2 % 2 ) ? m2/2+1 : m2/2 ;
  1134. if (m >= 128)
  1135. break;
  1136. fout = (DAC_FREF * (m + 2)) / ((1 << p) * (n + 2));
  1137. if ((ABS(fout - freq) < best_err) && (m > 0)) {
  1138. best_n = n;
  1139. best_m = m;
  1140. best_err = ABS(fout - freq);
  1141. /* we get the lowest m , allowing 0.5% error in freq*/
  1142. if (200*best_err < freq) break;
  1143. }
  1144. }
  1145. if (best_n == -1)  /* unlikely, but who knows ? */
  1146. return -EINVAL;
  1147. t->p=p;
  1148. t->n=best_n;
  1149. t->m=best_m;
  1150. *freq_out=(DAC_FREF * (t->m + 2)) / ((1 << t->p) * (t->n + 2));
  1151. f_ddprintk ("m: %d, n: %d, p: %d, F: %dKhzn",
  1152.   t->m, t->n, t->p, *freq_out);
  1153. return 0;
  1154. }
  1155. /*
  1156.  * gfx, video, pci fifo should be reset, dram refresh disabled
  1157.  * see detect_dac
  1158.  */
  1159. static int sst_set_pll_att_ti(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
  1160. {
  1161. u8 cr0, cc;
  1162. f_dprintk("sst_set_pll_att_tin");
  1163. /* enable indexed mode */
  1164. sst_dac_write(DACREG_WMA, 0);  /* backdoor */
  1165. sst_dac_read(DACREG_RMR); /* 1 time:  RMR */
  1166. sst_dac_read(DACREG_RMR); /* 2 RMR */
  1167. sst_dac_read(DACREG_RMR); /* 3 //  */
  1168. sst_dac_read(DACREG_RMR); /* 4 //  */
  1169. cr0 = sst_dac_read(DACREG_RMR); /* 5 CR0 */
  1170. sst_dac_write(DACREG_WMA, 0);
  1171. sst_dac_read(DACREG_RMR);
  1172. sst_dac_read(DACREG_RMR);
  1173. sst_dac_read(DACREG_RMR);
  1174. sst_dac_read(DACREG_RMR);
  1175. sst_dac_write(DACREG_RMR, (cr0 & 0xf0)
  1176.               | DACREG_CR0_EN_INDEXED
  1177.               | DACREG_CR0_8BIT
  1178.               | DACREG_CR0_PWDOWN );
  1179. /* so, now we are in indexed mode . dunno if its common, but
  1180.    i find this way of doing things a little bit weird :p */
  1181. udelay(300);
  1182. cc = dac_i_read(DACREG_CC_I);
  1183. switch (clock) {
  1184. case VID_CLOCK:
  1185. dac_i_write(DACREG_AC0_I, t->m);
  1186. dac_i_write(DACREG_AC1_I, t->p << 6 | t->n);
  1187. dac_i_write(DACREG_CC_I,
  1188.             (cc & 0x0f) | DACREG_CC_CLKA | DACREG_CC_CLKA_C);
  1189. break;
  1190. case GFX_CLOCK:
  1191. dac_i_write(DACREG_BD0_I, t->m);
  1192. dac_i_write(DACREG_BD1_I, t->p << 6 | t->n);
  1193. dac_i_write(DACREG_CC_I,
  1194.             (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D);
  1195. break;
  1196. default:
  1197. dprintk("bug line %d: wrong clock code '%d'n",
  1198.         __LINE__,clock);
  1199. return 0;
  1200. }
  1201. udelay(300);
  1202. /* power up the dac & return to "normal" non-indexed mode */
  1203. dac_i_write(DACREG_CR0_I,
  1204.             cr0 & ~DACREG_CR0_PWDOWN & ~DACREG_CR0_EN_INDEXED);
  1205. return 1;
  1206. }
  1207. static int sst_set_pll_ics(struct sstfb_info * sst_info, const struct pll_timing *t, const int clock)
  1208. {
  1209. u8 pll_ctrl;
  1210. f_dprintk("sst_set_pll_icsn");
  1211. sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
  1212. pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA);
  1213. switch(clock) {
  1214. case VID_CLOCK:
  1215. sst_dac_write(DACREG_ICS_PLLWMA, 0x0); /* CLK0, f0 */
  1216. sst_dac_write(DACREG_ICS_PLLDATA, t->m);
  1217. sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
  1218. /* selects freq f0 for clock 0 */
  1219. sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
  1220. sst_dac_write(DACREG_ICS_PLLDATA,
  1221.               (pll_ctrl & 0xd8)
  1222.               | DACREG_ICS_CLK0
  1223.               | DACREG_ICS_CLK0_0);
  1224. break;
  1225. case GFX_CLOCK :
  1226. sst_dac_write(DACREG_ICS_PLLWMA, 0xa); /* CLK1, fA */
  1227. sst_dac_write(DACREG_ICS_PLLDATA, t->m);
  1228. sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
  1229. /* selects freq fA for clock 1 */
  1230. sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
  1231. sst_dac_write(DACREG_ICS_PLLDATA,
  1232.               (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A);
  1233. break;
  1234. default:
  1235. dprintk("bug line %d: wrong clock code '%d'n",
  1236.         __LINE__, clock);
  1237. return 0;
  1238. }
  1239. udelay(300);
  1240. return 1;
  1241. }
  1242. static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info)
  1243. {
  1244. u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
  1245. int ntiles;
  1246. struct pci_dev * sst_dev = sst_info->dev;
  1247. f_dprintk("sst_set_par(%dx%d)n", par->xDim, par->yDim);
  1248. f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOffn");
  1249. f_ddprintk("%-7d %-8d %-7d %-8dn",
  1250.            par->hSyncOn, par->hSyncOff,
  1251.            par->vSyncOn, par->vSyncOff);
  1252. f_ddprintk("hBackPorch vBackPorch xDim yDim Freqn");
  1253. f_ddprintk("%-10d %-10d %-4d %-4d %-8dn",
  1254.            par->hBackPorch, par->vBackPorch,
  1255.            par->xDim, par->yDim, par->freq);
  1256. if (!par->valid) {
  1257. BUG();
  1258. return -1;
  1259. }
  1260. sst_write(NOPCMD, 0);
  1261. sst_wait_idle();
  1262. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
  1263. sst_set_bits(FBIINIT1, VIDEO_RESET);
  1264. sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
  1265. sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
  1266. sst_wait_idle();
  1267. /*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
  1268. sst_write(BACKPORCH, par->vBackPorch << 16 | (par->hBackPorch - 2));
  1269. sst_write(VIDEODIMENSIONS, par->yDim << 16 | (par->xDim - 1));
  1270. sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (par->hSyncOn - 1));
  1271. sst_write(VSYNC,       par->vSyncOff << 16 | par->vSyncOn);
  1272. fbiinit2=sst_read(FBIINIT2);
  1273. fbiinit3=sst_read(FBIINIT3);
  1274. /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */
  1275. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1276.                        PCI_EN_INIT_WR | PCI_REMAP_DAC );
  1277. sst_info->dac_sw.set_vidmod(sst_info, par->bpp);
  1278. /* set video clock */
  1279. sst_info->dac_sw.set_pll(sst_info, &par->pll, VID_CLOCK);
  1280. /* disable fbiinit2/3 remap */
  1281. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1282.                        PCI_EN_INIT_WR);
  1283. /* restore fbiinit2/3 */
  1284. sst_write(FBIINIT2,fbiinit2);
  1285. sst_write(FBIINIT3,fbiinit3);
  1286. fbiinit1 = (sst_read(FBIINIT1) & VIDEO_MASK)
  1287.             | EN_DATA_OE
  1288.             | EN_BLANK_OE
  1289.             | EN_HVSYNC_OE
  1290.             | EN_DCLK_OE
  1291. /*             | (15 << TILES_IN_X_SHIFT)*/
  1292.             | SEL_INPUT_VCLK_2X
  1293. /*             | (2 << VCLK_2X_SEL_DEL_SHIFT)
  1294.             | (2 << VCLK_DEL_SHIFT)*/;
  1295. /* try with vclk_in_delay =0 (bits 29:30) , vclk_out_delay =0 (bits(27:28)
  1296.  in (near) future set them accordingly to revision + resolution (cf glide)
  1297.  first understand what it stands for :)
  1298.  FIXME: there are some artefacts... check for the vclk_in_delay
  1299.  lets try with 6ns delay in both vclk_out & in...
  1300.  doh... they're still there :
  1301. */
  1302. ntiles = par->tiles_in_X;
  1303. if (IS_VOODOO2(sst_info)) {
  1304. fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
  1305.             | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
  1306. /* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
  1307.    and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just
  1308.    write our value. BTW due to the dac unable to read odd number of tiles, this
  1309.    field is always null ... */
  1310. fbiinit6 = (ntiles & 0x1) << TILES_IN_X_LSB_SHIFT;
  1311. }
  1312. else
  1313. fbiinit1 |= ntiles << TILES_IN_X_SHIFT;
  1314. switch(par->bpp) {
  1315. case 16:
  1316. fbiinit1 |=  SEL_SOURCE_VCLK_2X_SEL;
  1317. break;
  1318. #ifdef EN_24_32_BPP
  1319. case 24:
  1320. case 32:
  1321. /* orig sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP); */
  1322. fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
  1323. break;
  1324. #endif
  1325. default:
  1326. dprintk("bug line %d: bad depth '%u'n", __LINE__,
  1327. par->bpp );
  1328. return 0;
  1329. break;
  1330. }
  1331. sst_write(FBIINIT1, fbiinit1);
  1332. if (IS_VOODOO2(sst_info)) {
  1333. sst_write(FBIINIT6, fbiinit6);
  1334. fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ;
  1335. if (par->vmode & FB_VMODE_INTERLACED)
  1336. fbiinit5 |= INTERLACE;
  1337. if (par->vmode & FB_VMODE_DOUBLE )
  1338. fbiinit5 |= VDOUBLESCAN;
  1339. if (par->sync & FB_SYNC_HOR_HIGH_ACT)
  1340. fbiinit5 |= HSYNC_HIGH;
  1341. if (par->sync & FB_SYNC_VERT_HIGH_ACT)
  1342. fbiinit5 |= VSYNC_HIGH;
  1343. sst_write(FBIINIT5, fbiinit5);
  1344. }
  1345. sst_wait_idle();
  1346. sst_unset_bits(FBIINIT1, VIDEO_RESET);
  1347. sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
  1348. sst_set_bits(FBIINIT2, EN_DRAM_REFRESH);
  1349. /* disables fbiinit writes */
  1350. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
  1351. /* set lfbmode : set mode + front buffer for reads/writes
  1352.    + disable pipeline */
  1353. switch(par->bpp) {
  1354. case 16:
  1355. lfbmode = LFB_565;
  1356. break;
  1357. #ifdef EN_24_32_BPP
  1358. case 24:
  1359. lfbmode = LFB_888;
  1360. break;
  1361. case 32:
  1362. lfbmode = LFB_8888;
  1363. break;
  1364. #endif
  1365. default:
  1366. dprintk("bug line %d: bad depth '%u'n", __LINE__,
  1367. par->bpp );
  1368. return 0;
  1369. break;
  1370. }
  1371. #if defined(__BIG_ENDIAN)
  1372. /* enable byte-swizzle functionality in hardware */
  1373. lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB_BYTE_SWIZZLE_WR |
  1374.      LFB_WORD_SWIZZLE_RD | LFB_BYTE_SWIZZLE_RD );
  1375. #endif
  1376. if (clipping) {
  1377. sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE);
  1378. /*
  1379.  * Set "clipping" dimensions. If clipping is disabled and
  1380.  * writes to offscreen areas of the framebuffer are performed,
  1381.  * the "behaviour is undefined" (_very_ undefined) - Urs
  1382.  */
  1383. /* btw, it requires enabling pixel pipeline in LFBMODE .
  1384.    off screen read/writes will just wrap and read/print pixels
  1385.    on screen. Ugly but not that dangerous */
  1386. f_ddprintk("setting clipping dimensions 0..%d, 0..%dn",
  1387.             par->xDim-1, par->yDim-1);
  1388. sst_write(CLIP_LEFT_RIGHT, par->xDim );
  1389. sst_write(CLIP_LOWY_HIGHY, par->yDim );
  1390. sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
  1391. } else {
  1392. /* no clipping : direct access, no pipeline */
  1393. sst_write(LFBMODE, lfbmode );
  1394. }
  1395. sst_info->current_par = *par ;
  1396. return 1;
  1397. }
  1398. static void sst_set_vidmod_att_ti(struct sstfb_info * sst_info, const int bpp)
  1399. {
  1400. u8 cr0;
  1401. f_dprintk("sst_set_vidmod_att_ti(bpp: %d)n", bpp);
  1402. sst_dac_write(DACREG_WMA, 0);  /* backdoor */
  1403. sst_dac_read(DACREG_RMR); /* read 4 times RMR */
  1404. sst_dac_read(DACREG_RMR);
  1405. sst_dac_read(DACREG_RMR);
  1406. sst_dac_read(DACREG_RMR);
  1407. /* the fifth time,  CR0 is read */
  1408. cr0 = sst_dac_read(DACREG_RMR);
  1409. sst_dac_write(DACREG_WMA, 0);  /* backdoor */
  1410. sst_dac_read(DACREG_RMR); /* read 4 times RMR */
  1411. sst_dac_read(DACREG_RMR);
  1412. sst_dac_read(DACREG_RMR);
  1413. sst_dac_read(DACREG_RMR);
  1414. /* cr0 */
  1415. switch(bpp) {
  1416. case 16:
  1417. sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
  1418. break;
  1419. #ifdef EN_24_32_BPP
  1420. case 24:
  1421. case 32:
  1422. sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
  1423. break;
  1424. #endif
  1425. default:
  1426. dprintk("bug line %d: bad depth '%u'n", __LINE__, bpp);
  1427. break;
  1428. }
  1429. }
  1430. static void sst_set_vidmod_ics(struct sstfb_info * sst_info, const int bpp)
  1431. {
  1432. f_dprintk("sst_set_vidmod_ics(bpp: %d)n", bpp);
  1433. switch(bpp) {
  1434. case 16:
  1435. sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
  1436. break;
  1437. #ifdef EN_24_32_BPP
  1438. case 24:
  1439. case 32:
  1440. sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
  1441. break;
  1442. #endif
  1443. default:
  1444. dprintk("bug line %d: bad depth '%u'n", __LINE__, bpp);
  1445. break;
  1446. }
  1447. }
  1448. static int __devinit sst_init(struct sstfb_info *sst_info)
  1449. {
  1450. struct pll_timing gfx_timings;
  1451. struct sst_spec * spec;
  1452. struct pci_dev * sst_dev = sst_info->dev;
  1453. int Fout;
  1454. u32 fbiinit0, fbiinit1, fbiinit4;
  1455. spec = &voodoo_spec[sst_info->type];
  1456. f_dprintk("sst_initn");
  1457. f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
  1458.            " fbiinit6n");
  1459. f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10xn",
  1460.             sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),
  1461.             sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));
  1462. /* disable video clock */
  1463. pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
  1464. /* enable writing to init registers ,disable pci fifo*/
  1465. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
  1466. /* reset video */
  1467. sst_set_bits(FBIINIT1, VIDEO_RESET);
  1468. sst_wait_idle();
  1469. /* reset gfx + pci fifo */
  1470. sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
  1471. sst_wait_idle();
  1472. /* unreset fifo */
  1473. /*sst_unset_bits(FBIINIT0, FIFO_RESET);
  1474. sst_wait_idle();*/
  1475. /* unreset FBI */
  1476. /*sst_unset_bits(FBIINIT0, FBI_RESET);
  1477. sst_wait_idle();*/
  1478. /* disable dram refresh */
  1479. sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
  1480. sst_wait_idle();
  1481. /* remap fbinit2/3 to dac */
  1482. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1483.                                PCI_EN_INIT_WR | PCI_REMAP_DAC );
  1484. /* detect dac type */
  1485. if (!sst_detect_dactype(sst_info)) {
  1486. eprintk("Unknown dac typen");
  1487. //FIXME watch it : we are not in a safe state , bad bad bad .
  1488. return 0;
  1489. }
  1490. /* set graphic clock */
  1491. sst_info->gfx_clock = spec->default_gfx_clock;
  1492. if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
  1493. iprintk ("Using supplied graphic freq : %dMHzn", gfxclk);
  1494.  sst_info->gfx_clock = gfxclk *1000;
  1495. } else if (gfxclk) {
  1496. wprintk ("You fool, %dMhz is way out of spec! Using defaultn", gfxclk);
  1497. }
  1498. sst_calc_pll(sst_info->gfx_clock, &Fout, &gfx_timings);
  1499. sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
  1500. /* disable fbiinit remap */
  1501. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1502.                        PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
  1503. /* defaults init registers */
  1504. /* FbiInit0: unreset gfx, unreset fifo */
  1505. fbiinit0 = FBIINIT0_DEFAULT;
  1506. fbiinit1 = FBIINIT1_DEFAULT;
  1507. fbiinit4 = FBIINIT4_DEFAULT;
  1508. if (vgapass)
  1509. fbiinit0 &= ~EN_VGA_PASSTHROUGH;
  1510. else
  1511. fbiinit0 |= EN_VGA_PASSTHROUGH;
  1512. if (slowpci) {
  1513. fbiinit1 |= SLOW_PCI_WRITES;
  1514. fbiinit4 |= SLOW_PCI_READS;
  1515. } else {
  1516. fbiinit1 &= ~SLOW_PCI_WRITES;
  1517. fbiinit4 &= ~SLOW_PCI_READS;
  1518. }
  1519. sst_write(FBIINIT0, fbiinit0);
  1520. sst_wait_idle();
  1521. sst_write(FBIINIT1, fbiinit1);
  1522. sst_wait_idle();
  1523. sst_write(FBIINIT2, FBIINIT2_DEFAULT);
  1524. sst_wait_idle();
  1525. sst_write(FBIINIT3, FBIINIT3_DEFAULT);
  1526. sst_wait_idle();
  1527. sst_write(FBIINIT4, fbiinit4);
  1528. sst_wait_idle();
  1529. if (IS_VOODOO2(sst_info)) {
  1530. sst_write(FBIINIT6, FBIINIT6_DEFAULT);
  1531. sst_wait_idle();
  1532. }
  1533. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
  1534. pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);
  1535. return 1;
  1536. }
  1537. static void  __devexit sst_shutdown(struct sstfb_info *sst_info)
  1538. {
  1539. struct pci_dev * sst_dev = sst_info->dev;
  1540. struct pll_timing gfx_timings;
  1541. int Fout;
  1542. f_dprintk("sst_shutdownn");
  1543. /* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
  1544. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
  1545. sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);
  1546. sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
  1547. sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
  1548. sst_wait_idle();
  1549. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1550.                        PCI_EN_INIT_WR | PCI_REMAP_DAC );
  1551. /*set 20Mhz gfx clock */
  1552. sst_calc_pll(20000, &Fout, &gfx_timings);
  1553. sst_info->dac_sw.set_pll(sst_info, &gfx_timings, GFX_CLOCK);
  1554. /* TODO maybe shutdown the dac, vrefresh and so on... */
  1555. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
  1556.                        PCI_EN_INIT_WR);
  1557. sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
  1558. pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
  1559. /* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */
  1560. pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);
  1561. }
  1562. /*
  1563.  * Interface to the world
  1564.  */
  1565. int  __init sstfb_setup(char *options)
  1566. {
  1567. char *this_opt;
  1568. f_dprintk("sstfb_setupn");
  1569. if (!options || !*options)
  1570. return 0;
  1571. for(this_opt = strtok(options, ","); this_opt;
  1572. this_opt = strtok(NULL, ",")) { //XXX
  1573. //XXX while ((this_opt = strsep(&options, ",")) != NULL) {
  1574. if (!*this_opt) continue;
  1575. f_ddprintk("option %sn", this_opt);
  1576. if (!strcmp(this_opt, "inverse")) {
  1577. inverse = 1;
  1578. fb_invert_cmaps();
  1579. }
  1580. else if (!strcmp(this_opt, "vganopass"))
  1581. vgapass = 0;
  1582. else if (!strcmp(this_opt, "vgapass"))
  1583. vgapass = 1;
  1584. else if (!strcmp(this_opt, "clipping"))
  1585.         clipping = 1;
  1586. else if (!strcmp(this_opt, "noclipping"))
  1587.         clipping = 0;
  1588. else if (!strcmp(this_opt, "fastpci"))
  1589.         slowpci = 0;
  1590. else if (!strcmp(this_opt, "slowpci"))
  1591.         slowpci = 1;
  1592. else if (!strncmp(this_opt, "mem:",4))
  1593. mem=simple_strtoul (this_opt+4, NULL, 0);
  1594. else if (!strncmp(this_opt, "gfxclk:",7))
  1595. gfxclk=simple_strtoul (this_opt+7, NULL, 0);
  1596. else if (!strncmp(this_opt, "dev:",4))
  1597. dev=simple_strtoul (this_opt+4, NULL, 0);
  1598. else
  1599. mode_option=this_opt;
  1600. }
  1601. return 0;
  1602. }
  1603. int __devinit sstfb_init(void)
  1604. {
  1605. f_dprintk("sstfb_initn");
  1606. dprintk("Compile date: "__DATE__" "__TIME__"n");
  1607. return pci_module_init(&sstfb_driver);
  1608. }
  1609. void __devexit sstfb_exit(void)
  1610. {
  1611. f_dprintk("sstfb_exitn");
  1612. pci_unregister_driver(&sstfb_driver);
  1613. }
  1614. #ifdef MODULE
  1615. module_init(sstfb_init);
  1616. module_exit(sstfb_exit);
  1617. #endif
  1618. static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  1619. {
  1620. struct fb_var_screeninfo var;
  1621. struct sstfb_info * sst_info;
  1622. struct sst_spec * spec;
  1623. int tmp,err;
  1624. f_dprintk("sstfb_proben");
  1625. /* dev >  0  the device is not the one asked for.   skip */
  1626. /* dev == 0  this is the device the user asked.     init */
  1627. /* dev == -1 we already inited the asked device.    skip */
  1628. /* dev < -1  init all devices. including this one.  init */
  1629. if ((dev == -1 ) || (dev-- > 0))
  1630. return -1;
  1631. if ((err=pci_enable_device(pdev))) {
  1632. eprintk("cannot enable devicen");
  1633. return err;
  1634. }
  1635. sst_info = (struct sstfb_info*)kmalloc(sizeof(*sst_info), GFP_KERNEL);
  1636. if (!sst_info)
  1637. goto fail_kmalloc;
  1638. pci_set_drvdata(pdev, sst_info);
  1639. sst_info->type = id->driver_data;
  1640. spec = &voodoo_spec[sst_info->type];
  1641. f_ddprintk("found device : %sn", spec->name);
  1642. sst_info->dev = pdev;
  1643. pci_read_config_byte(pdev, PCI_REVISION_ID, &sst_info->revision);
  1644. sst_info->mmio.base = pci_resource_start(pdev,0);
  1645. sst_info->video.base = sst_info->mmio.base+0x400000;
  1646. if (!request_mem_region(sst_info->mmio.base,0x400000,"sstfb MMIO")) {
  1647. eprintk ("cannot reserve mmio memoryn");
  1648. goto fail_mmio_mem;
  1649. }
  1650. if (!request_mem_region(sst_info->video.base,0x400000,"sstfb FB")) {
  1651. eprintk ("cannot reserve fb memoryn");
  1652. goto fail_fb_mem;
  1653. }
  1654. sst_info->mmio.vbase = (u_long) ioremap_nocache(sst_info->mmio.base, 0x400000);
  1655. if (!sst_info->mmio.vbase) {
  1656. eprintk("cannot remap register area %#lxn",
  1657.         sst_info->mmio.base);
  1658. goto fail_mmio_remap;
  1659. }
  1660. sst_info->video.vbase = (u_long) ioremap_nocache(sst_info->video.base, 0x400000);
  1661. if (!sst_info->video.vbase) {
  1662. eprintk("cannot remap framebuffer %#lxn",
  1663.         sst_info->video.base);
  1664. goto fail_fb_remap;
  1665. }
  1666. if(!sst_init(sst_info)) {
  1667. eprintk("Init failedn");
  1668. goto fail;
  1669. }
  1670. sst_get_memsize(sst_info, &sst_info->video.len);
  1671. strncpy(sst_info->info.modename, spec->name, 16);
  1672. iprintk("%s with %s dacn", sst_info->info.modename, sst_info->dac_sw.name);
  1673. iprintk("framebuffer at %#lx, mapped to %#lx,"
  1674.         " size %ldMbn",
  1675.         sst_info->video.base, sst_info->video.vbase,
  1676.         sst_info->video.len >> 20);
  1677. f_ddprintk("revision: %dn", sst_info->revision);
  1678. f_ddprintk("regbase_virt: %#lxn", sst_info->mmio.vbase);
  1679. f_ddprintk("membase_phys: %#lxn", sst_info->video.base);
  1680. f_ddprintk("fbbase_virt: %#lxn", sst_info->video.vbase);
  1681. sst_info->info.node       = -1 ;
  1682. sst_info->info.flags      = FBINFO_FLAG_DEFAULT;
  1683. sst_info->info.fbops      = &sstfb_ops;
  1684. sst_info->info.disp       = &sst_info->disp;
  1685. sst_info->info.changevar  = NULL;
  1686. sst_info->info.switch_con = &sstfbcon_switch;
  1687. sst_info->info.updatevar  = &sstfbcon_updatevar;
  1688. sst_info->info.blank      = &sstfbcon_blank;
  1689. tmp=0;
  1690. var = sstfb_default;
  1691. if ( mode_option  &&
  1692.      fb_find_mode(&var, &sst_info->info, mode_option,
  1693.                    NULL, 0, NULL, 16)) {
  1694. if (sstfb_set_var(&var, -1, &sst_info->info)) {
  1695. eprintk("can't set supplied video mode. Using defaultn");
  1696. var = sstfb_default;
  1697. } else {
  1698. /* set the new default */
  1699. sstfb_default = var;
  1700. tmp=1;  /* no need to set the mode. */
  1701. }
  1702. }
  1703. if (!tmp && sstfb_set_var(&var, -1, &sst_info->info)) {
  1704. eprintk("can't set default video mode.n");
  1705. goto fail;
  1706. }
  1707. /*clear fb */
  1708. memset_io(sst_info->video.vbase, 0, sst_info->video.len);
  1709. /* print some squares ... */
  1710. sstfb_test16(sst_info); /* FIXME this is only for 16bpp */
  1711. /* register fb */
  1712. if (register_framebuffer(&sst_info->info) < 0) {
  1713. eprintk("can't register framebuffer.n");
  1714. goto fail;
  1715. }
  1716. printk(KERN_INFO "fb%d: %s frame buffer devicen",
  1717.        GET_FB_IDX(sst_info->info.node),sst_info->info.modename);
  1718. return 0;
  1719. fail:
  1720. iounmap((void *)sst_info->video.base);
  1721. fail_fb_remap:
  1722. iounmap((void *)sst_info->mmio.base);
  1723. fail_mmio_remap:
  1724. release_mem_region(sst_info->video.base,0x400000);
  1725. fail_fb_mem:
  1726. release_mem_region(sst_info->mmio.base,0x400000);
  1727. fail_mmio_mem:
  1728. kfree(sst_info);
  1729. fail_kmalloc:
  1730. return -ENXIO;  /* no voodoo detected */
  1731. }
  1732. static void __devexit sstfb_remove(struct pci_dev *pdev)
  1733. {
  1734. struct sstfb_info * sst_info;
  1735. f_dprintk("sstfb_removen");
  1736. sst_info=pci_get_drvdata(pdev);
  1737. sst_shutdown(sst_info);
  1738. unregister_framebuffer(&sst_info->info);
  1739. iounmap((void*)sst_info->video.vbase);
  1740. iounmap((void*)sst_info->mmio.vbase);
  1741. release_mem_region(sst_info->video.base,0x400000);
  1742. release_mem_region(sst_info->mmio.base,0x400000);
  1743. kfree(sst_info);
  1744. }
  1745. /*
  1746.  * console driver
  1747.  */
  1748. static int sstfbcon_switch(int con, struct fb_info *info)
  1749. {
  1750. #define sst_info  ((struct sstfb_info *) info)
  1751. struct sstfb_par par;
  1752. f_dprintk("sstfbcon_switch(con: %d)n",con);
  1753. f_ddprintk("currcon: %dn", sst_info->currcon);
  1754. v_dprintk("currcon: %dn", sst_info->currcon);
  1755. if (sst_info->currcon >=  0) {
  1756. if (fb_display[sst_info->currcon].cmap.len)
  1757. fb_get_cmap(&fb_display[sst_info->currcon].cmap, 1,
  1758.             sstfb_getcolreg, info);
  1759. }
  1760. sst_info->currcon = con;
  1761. fb_display[con].var.activate = FB_ACTIVATE_NOW;
  1762. print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);
  1763. sstfb_decode_var(&fb_display[con].var, &par, sst_info);
  1764. if (memcmp(&par,&(sst_info->current_par),sizeof(par))) {
  1765. sstfb_set_par(&par, sst_info);
  1766. }
  1767. sstfb_install_cmap(con, info);
  1768. return 0;
  1769. #undef sst_info
  1770. }
  1771. static int sstfbcon_updatevar(int con, struct fb_info *info)
  1772. {
  1773. f_dprintk("sstfbcon_updatevarn");
  1774. return -EINVAL;
  1775. }
  1776. static void sstfbcon_blank(int blank, struct fb_info *info)
  1777. {
  1778. f_dprintk("sstfbcon_blank(level %d)n", blank);
  1779. }
  1780. /* print some squares on the fb (presuming 16bpp)  */
  1781. static void sstfb_test16(struct sstfb_info *sst_info)
  1782. {
  1783. int i,j;
  1784. u_long p;
  1785. u_long fbbase_virt = sst_info->video.vbase;
  1786. f_dprintk("sstfb_test16n");
  1787. /* rect blanc 20x100+200+0 */
  1788. for (i=0 ; i< 100; i++) {
  1789.   p = fbbase_virt + 2048 *i+400;
  1790.   for (j=0 ; j < 10 ; j++) {
  1791.     writel( 0xffffffff, p);
  1792.     p+=4;
  1793.   }
  1794. }
  1795. /* rect bleu 180x200+0+0 */
  1796. for (i=0 ; i< 200; i++) {
  1797.   p = fbbase_virt + 2048 *i;
  1798.   for (j=0 ; j < 90 ; j++) {
  1799.     writel(0x001f001f,p);
  1800.     p+=4;
  1801.   }
  1802. }
  1803. /* carre vert 40x40+100+0 */
  1804. for (i=0 ; i< 40 ; i++) {
  1805.   p = fbbase_virt + 2048 *i + 200;
  1806.   for (j=0; j <20;j++) {
  1807.     writel(0x07e007e0, p);
  1808.     p+=4;
  1809.   }
  1810. }
  1811. /*carre rouge 40x40+100+40 */
  1812. for (i=0; i<40; i++) {
  1813.   p = fbbase_virt + 2048 * (i+40) + 200;
  1814.   for (j=0; j <20;j++) {
  1815.     writel( 0xf800f800, p);
  1816.     p+=4;
  1817.   }
  1818. }
  1819. }
  1820. /* print some squares on the fb (24/32bpp)  */
  1821. #ifdef EN_24_32_BPP
  1822. static void sstfb_test32(struct sstfb_info *sst_info)
  1823. {
  1824. int i,j;
  1825. u_long p;
  1826. u_long fbbase_virt = sst_info->video.vbase;
  1827. f_dprintk("sstfb_test32n");
  1828. /* rect blanc 20x100+200+0 */
  1829. for (i=0 ; i< 100; i++) {
  1830.   p = fbbase_virt + 4096*i + 800;
  1831.   for (j=0 ; j < 20 ; j++) {
  1832.     writel( 0x00ffffff, p);
  1833.     p+=4;
  1834.   }
  1835. }
  1836. /* rect bleu 180x200+0+0 */
  1837. for (i=0 ; i< 200; i++) {
  1838.   p = fbbase_virt + 4096 * i;
  1839.   for (j=0 ; j < 180 ; j++) {
  1840.     writel(0x000000ff,p);
  1841.     p+=4;
  1842.   }
  1843. }
  1844. /* carre vert 40x40+100+0 */
  1845. for (i=0 ; i< 40 ; i++) {
  1846.   p = fbbase_virt + 4096 *i + 400;
  1847.   for (j=0; j <40;j++) {
  1848.     writel(0x0000ff00, p);
  1849.     p+=4;
  1850.   }
  1851. }
  1852. /*carre rouge 40x40+100+10 */
  1853. for (i=0; i<40; i++) {
  1854.   p = fbbase_virt + 4096 * (i+40) + 400;
  1855.   for (j=0; j <40;j++) {
  1856.     writel( 0x00ff0000, p);
  1857.     p+=4;
  1858.   }
  1859. }
  1860. }
  1861. #endif /* EN_24_32_BPP */
  1862. MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
  1863. MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
  1864. MODULE_LICENSE("GPL");
  1865. MODULE_PARM(mem, "i");
  1866. MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)");
  1867. MODULE_PARM(vgapass, "i");
  1868. MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)");
  1869. MODULE_PARM(inverse, "i");
  1870. MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)");
  1871. MODULE_PARM(clipping , "i");
  1872. MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
  1873. MODULE_PARM(gfxclk , "i");
  1874. MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)");
  1875. MODULE_PARM(slowpci, "i");
  1876. MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
  1877. MODULE_PARM(dev,"i");
  1878. MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
  1879. /*
  1880.  * Overrides for Emacs so that we follow Linus's tabbing style.
  1881.  * ---------------------------------------------------------------------------
  1882.  * Local variables:
  1883.  * c-basic-offset: 8
  1884.  * End:
  1885.  */
  1886. #if 0
  1887. void __Dump_regs (struct sstfb_info * sst_info)
  1888. {
  1889. struct { u32 reg ; char * reg_name;}  pci_regs [] =  {
  1890. { PCI_INIT_ENABLE, "initenable"},
  1891. { PCI_VCLK_ENABLE, "enable vclk"},
  1892. { PCI_VCLK_DISABLE, "disable vclk"},
  1893. };
  1894. struct { u32 reg ; char * reg_name;}  sst_regs [] =  {
  1895. {FBIINIT0,"fbiinit0"},
  1896. {FBIINIT1,"fbiinit1"},
  1897. {FBIINIT2,"fbiinit2"},
  1898. {FBIINIT3,"fbiinit3"},
  1899. {FBIINIT4,"fbiinit4"},
  1900. {FBIINIT5,"fbiinit5"},
  1901. {FBIINIT6,"fbiinit6"},
  1902. {FBIINIT7,"fbiinit7"},
  1903. {LFBMODE,"lfbmode"},
  1904. {FBZMODE,"fbzmode"},
  1905. };
  1906. int pci_s = sizeof(pci_regs)/sizeof(*pci_regs);
  1907. int sst_s = sizeof(sst_regs)/sizeof(*sst_regs);
  1908. u32 pci_res[pci_s];
  1909. u32 sst_res[sst_s];
  1910. struct pci_dev * dev = sst_info->dev;
  1911. int i;
  1912. for (i=0; i < pci_s ; i++ ) {
  1913. pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
  1914. }
  1915. for (i=0; i < sst_s ; i++ ) {
  1916. sst_res[i]=sst_read(sst_regs[i].reg);
  1917. }
  1918. dprintk ("Dump regsn");
  1919. for (i=0; i < pci_s ; i++ ) {
  1920. dprintk("%s = %0#10xn", pci_regs[i].reg_name , pci_res[i]) ;
  1921. }
  1922. for (i=0; i < sst_s ; i++ ) {
  1923. dprintk("%s = %0#10xn", sst_regs[i].reg_name , sst_res[i]) ;
  1924. }
  1925. }
  1926. #endif