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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
  4.  *
  5.  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  6.  *
  7.  * Version: 1.51 2001/06/18
  8.  *
  9.  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  10.  *
  11.  * Contributors: "menion?" <menion@mindless.com>
  12.  *                     Betatesting, fixes, ideas
  13.  *
  14.  *               "Kurt Garloff" <garloff@suse.de>
  15.  *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
  16.  *
  17.  *               "Tom Rini" <trini@kernel.crashing.org>
  18.  *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
  19.  *
  20.  *               "Bibek Sahu" <scorpio@dodds.net>
  21.  *                     Access device through readb|w|l and write b|w|l
  22.  *                     Extensive debugging stuff
  23.  *
  24.  *               "Daniel Haun" <haund@usa.net>
  25.  *                     Testing, hardware cursor fixes
  26.  *
  27.  *               "Scott Wood" <sawst46+@pitt.edu>
  28.  *                     Fixes
  29.  *
  30.  *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
  31.  *                     Betatesting
  32.  *
  33.  *               "Kelly French" <targon@hazmat.com>
  34.  *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
  35.  *                     Betatesting, bug reporting
  36.  *
  37.  *               "Pablo Bianucci" <pbian@pccp.com.ar>
  38.  *                     Fixes, ideas, betatesting
  39.  *
  40.  *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
  41.  *                     Fixes, enhandcements, ideas, betatesting
  42.  *
  43.  *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
  44.  *                     PPC betatesting, PPC support, backward compatibility
  45.  *
  46.  *               "Paul Womar" <Paul@pwomar.demon.co.uk>
  47.  *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
  48.  *                     PPC betatesting
  49.  *
  50.  *               "Thomas Pornin" <pornin@bolet.ens.fr>
  51.  *                     Alpha betatesting
  52.  *
  53.  *               "Pieter van Leuven" <pvl@iae.nl>
  54.  *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
  55.  *                     G100 testing
  56.  *
  57.  *               "H. Peter Arvin" <hpa@transmeta.com>
  58.  *                     Ideas
  59.  *
  60.  *               "Cort Dougan" <cort@cs.nmt.edu>
  61.  *                     CHRP fixes and PReP cleanup
  62.  *
  63.  *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
  64.  *                     G400 support
  65.  *
  66.  * (following author is not in any relation with this code, but his code
  67.  *  is included in this driver)
  68.  *
  69.  * Based on framebuffer driver for VBE 2.0 compliant graphic boards
  70.  *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
  71.  *
  72.  * (following author is not in any relation with this code, but his ideas
  73.  *  were used when writting this driver)
  74.  *
  75.  *  FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
  76.  *
  77.  */
  78. #include "matroxfb_accel.h"
  79. #include "matroxfb_DAC1064.h"
  80. #include "matroxfb_Ti3026.h"
  81. #include "matroxfb_misc.h"
  82. #define curr_ydstorg(x) ACCESS_FBINFO2(x, curr.ydstorg.pixels)
  83. #define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
  84. void matrox_cfbX_init(WPMINFO struct display* p) {
  85. u_int32_t maccess;
  86. u_int32_t mpitch;
  87. u_int32_t mopmode;
  88. DBG("matrox_cfbX_init")
  89. mpitch = p->var.xres_virtual;
  90. if (p->type == FB_TYPE_TEXT) {
  91. maccess = 0x00000000;
  92. mpitch = (mpitch >> 4) | 0x8000; /* set something */
  93. mopmode = M_OPMODE_8BPP;
  94. } else {
  95. switch (p->var.bits_per_pixel) {
  96. case 4: maccess = 0x00000000; /* accelerate as 8bpp video */
  97. mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */
  98. mopmode = M_OPMODE_4BPP;
  99. break;
  100. case 8: maccess = 0x00000000;
  101. mopmode = M_OPMODE_8BPP;
  102. break;
  103. case 16: if (p->var.green.length == 5)
  104. maccess = 0xC0000001;
  105. else
  106. maccess = 0x40000001;
  107. mopmode = M_OPMODE_16BPP;
  108. break;
  109. case 24: maccess = 0x00000003;
  110. mopmode = M_OPMODE_24BPP;
  111. break;
  112. case 32: maccess = 0x00000002;
  113. mopmode = M_OPMODE_32BPP;
  114. break;
  115. default: maccess = 0x00000000;
  116. mopmode = 0x00000000;
  117. break; /* turn off acceleration!!! */
  118. }
  119. }
  120. mga_fifo(8);
  121. mga_outl(M_PITCH, mpitch);
  122. mga_outl(M_YDSTORG, curr_ydstorg(MINFO));
  123. if (ACCESS_FBINFO(capable.plnwt))
  124. mga_outl(M_PLNWT, -1);
  125. if (ACCESS_FBINFO(capable.srcorg)) {
  126. mga_outl(M_SRCORG, 0);
  127. mga_outl(M_DSTORG, 0);
  128. }
  129. mga_outl(M_OPMODE, mopmode);
  130. mga_outl(M_CXBNDRY, 0xFFFF0000);
  131. mga_outl(M_YTOP, 0);
  132. mga_outl(M_YBOT, 0x01FFFFFF);
  133. mga_outl(M_MACCESS, maccess);
  134. ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
  135. if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC;
  136. ACCESS_FBINFO(accel.m_opmode) = mopmode;
  137. }
  138. static void matrox_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
  139. int pixx = p->var.xres_virtual, start, end;
  140. CRITFLAGS
  141. MINFO_FROM_DISP(p);
  142. DBG("matrox_cfbX_bmove")
  143. CRITBEGIN
  144. sx *= fontwidth(p);
  145. dx *= fontwidth(p);
  146. width *= fontwidth(p);
  147. height *= fontheight(p);
  148. sy *= fontheight(p);
  149. dy *= fontheight(p);
  150. if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
  151. mga_fifo(2);
  152. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
  153.  M_DWG_BFCOL | M_DWG_REPLACE);
  154. mga_outl(M_AR5, pixx);
  155. width--;
  156. start = sy*pixx+sx+curr_ydstorg(MINFO);
  157. end = start+width;
  158. } else {
  159. mga_fifo(3);
  160. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
  161. mga_outl(M_SGN, 5);
  162. mga_outl(M_AR5, -pixx);
  163. width--;
  164. end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
  165. start = end+width;
  166. dy += height-1;
  167. }
  168. mga_fifo(4);
  169. mga_outl(M_AR0, end);
  170. mga_outl(M_AR3, start);
  171. mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
  172. mga_ydstlen(dy, height);
  173. WaitTillIdle();
  174. CRITEND
  175. }
  176. #ifdef FBCON_HAS_CFB4
  177. static void matrox_cfb4_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width) {
  178. int pixx, start, end;
  179. CRITFLAGS
  180. MINFO_FROM_DISP(p);
  181. /* both (sx or dx or width) and fontwidth() are odd, so their multiply is
  182.    also odd, that means that we cannot use acceleration */
  183. DBG("matrox_cfb4_bmove")
  184. CRITBEGIN
  185. if ((sx | dx | width) & fontwidth(p) & 1) {
  186. fbcon_cfb4_bmove(p, sy, sx, dy, dx, height, width);
  187. return;
  188. }
  189. sx *= fontwidth(p);
  190. dx *= fontwidth(p);
  191. width *= fontwidth(p);
  192. height *= fontheight(p);
  193. sy *= fontheight(p);
  194. dy *= fontheight(p);
  195. pixx = p->var.xres_virtual >> 1;
  196. sx >>= 1;
  197. dx >>= 1;
  198. width >>= 1;
  199. if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
  200. mga_fifo(2);
  201. mga_outl(M_AR5, pixx);
  202. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
  203. M_DWG_BFCOL | M_DWG_REPLACE);
  204. width--;
  205. start = sy*pixx+sx+curr_ydstorg(MINFO);
  206. end = start+width;
  207. } else {
  208. mga_fifo(3);
  209. mga_outl(M_SGN, 5);
  210. mga_outl(M_AR5, -pixx);
  211. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
  212. width--;
  213. end = (sy+height-1)*pixx+sx+curr_ydstorg(MINFO);
  214. start = end+width;
  215. dy += height-1;
  216. }
  217. mga_fifo(5);
  218. mga_outl(M_AR0, end);
  219. mga_outl(M_AR3, start);
  220. mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
  221. mga_outl(M_YDST, dy*pixx >> 5);
  222. mga_outl(M_LEN | M_EXEC, height);
  223. WaitTillIdle();
  224. CRITEND
  225. }
  226. #endif
  227. static void matroxfb_accel_clear(WPMINFO u_int32_t color, int sy, int sx, int height,
  228. int width) {
  229. CRITFLAGS
  230. DBG("matroxfb_accel_clear")
  231. CRITBEGIN
  232. mga_fifo(5);
  233. mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE);
  234. mga_outl(M_FCOL, color);
  235. mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
  236. mga_ydstlen(sy, height);
  237. WaitTillIdle();
  238. CRITEND
  239. }
  240. static void matrox_cfbX_clear(u_int32_t color, struct display* p, int sy, int sx, int height, int width) {
  241. DBG("matrox_cfbX_clear")
  242. matroxfb_accel_clear(PMXINFO(p) color, sy * fontheight(p), sx * fontwidth(p),
  243.      height * fontheight(p), width * fontwidth(p));
  244. }
  245. #ifdef FBCON_HAS_CFB4
  246. static void matrox_cfb4_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
  247. u_int32_t bgx;
  248. int whattodo;
  249. CRITFLAGS
  250. MINFO_FROM_DISP(p);
  251. DBG("matrox_cfb4_clear")
  252. CRITBEGIN
  253. whattodo = 0;
  254. bgx = attr_bgcol_ec(p, conp);
  255. bgx |= bgx << 4;
  256. bgx |= bgx << 8;
  257. bgx |= bgx << 16;
  258. sy *= fontheight(p);
  259. sx *= fontwidth(p);
  260. height *= fontheight(p);
  261. width *= fontwidth(p);
  262. if (sx & 1) {
  263. sx ++;
  264. if (!width) return;
  265. width --;
  266. whattodo = 1;
  267. }
  268. if (width & 1) {
  269. whattodo |= 2;
  270. }
  271. width >>= 1;
  272. sx >>= 1;
  273. if (width) {
  274. mga_fifo(5);
  275. mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE2);
  276. mga_outl(M_FCOL, bgx);
  277. mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
  278. mga_outl(M_YDST, sy * p->var.xres_virtual >> 6);
  279. mga_outl(M_LEN | M_EXEC, height);
  280. WaitTillIdle();
  281. }
  282. if (whattodo) {
  283. u_int32_t step = p->var.xres_virtual >> 1;
  284. vaddr_t vbase = ACCESS_FBINFO(video.vbase);
  285. if (whattodo & 1) {
  286. unsigned int uaddr = sy * step + sx - 1;
  287. u_int32_t loop;
  288. u_int8_t bgx2 = bgx & 0xF0;
  289. for (loop = height; loop > 0; loop --) {
  290. mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0x0F) | bgx2);
  291. uaddr += step;
  292. }
  293. }
  294. if (whattodo & 2) {
  295. unsigned int uaddr = sy * step + sx + width;
  296. u_int32_t loop;
  297. u_int8_t bgx2 = bgx & 0x0F;
  298. for (loop = height; loop > 0; loop --) {
  299. mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0xF0) | bgx2);
  300. uaddr += step;
  301. }
  302. }
  303. }
  304. CRITEND
  305. }
  306. #endif
  307. #ifdef FBCON_HAS_CFB8
  308. static void matrox_cfb8_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
  309. u_int32_t bgx;
  310. DBG("matrox_cfb8_clear")
  311. bgx = attr_bgcol_ec(p, conp);
  312. bgx |= bgx << 8;
  313. bgx |= bgx << 16;
  314. matrox_cfbX_clear(bgx, p, sy, sx, height, width);
  315. }
  316. #endif
  317. #ifdef FBCON_HAS_CFB16
  318. static void matrox_cfb16_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
  319. u_int32_t bgx;
  320. DBG("matrox_cfb16_clear")
  321. bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
  322. matrox_cfbX_clear((bgx << 16) | bgx, p, sy, sx, height, width);
  323. }
  324. #endif
  325. #if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
  326. static void matrox_cfb32_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width) {
  327. u_int32_t bgx;
  328. DBG("matrox_cfb32_clear")
  329. bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
  330. matrox_cfbX_clear(bgx, p, sy, sx, height, width);
  331. }
  332. #endif
  333. static void matrox_cfbX_fastputc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
  334. unsigned int charcell;
  335. unsigned int ar3;
  336. CRITFLAGS
  337. MINFO_FROM_DISP(p);
  338. charcell = fontwidth(p) * fontheight(p);
  339. yy *= fontheight(p);
  340. xx *= fontwidth(p);
  341. CRITBEGIN
  342. mga_fifo(8);
  343. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
  344. mga_outl(M_FCOL, fgx);
  345. mga_outl(M_BCOL, bgx);
  346. mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
  347. ar3 = ACCESS_FBINFO(fastfont.mgabase) + (c & p->charmask) * charcell;
  348. mga_outl(M_AR3, ar3);
  349. mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
  350. mga_ydstlen(yy, fontheight(p));
  351. WaitTillIdle();
  352. CRITEND
  353. }
  354. static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
  355. u_int32_t ar0;
  356. u_int32_t step;
  357. CRITFLAGS
  358. MINFO_FROM_DISP(p);
  359. DBG_HEAVY("matrox_cfbX_putc");
  360. yy *= fontheight(p);
  361. xx *= fontwidth(p);
  362. CRITBEGIN
  363. #ifdef __BIG_ENDIAN
  364. WaitTillIdle();
  365. mga_outl(M_OPMODE, M_OPMODE_8BPP);
  366. #else
  367. mga_fifo(7);
  368. #endif
  369. ar0 = fontwidth(p) - 1;
  370. mga_outl(M_FXBNDRY, ((xx+ar0)<<16) | xx);
  371. if (fontwidth(p) <= 8)
  372. step = 1;
  373. else if (fontwidth(p) <= 16)
  374. step = 2;
  375. else
  376. step = 4;
  377. if (fontwidth(p) == step << 3) {
  378. size_t charcell = fontheight(p)*step;
  379. /* TODO: Align charcell to 4B for BE */
  380. mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
  381. mga_outl(M_FCOL, fgx);
  382. mga_outl(M_BCOL, bgx);
  383. mga_outl(M_AR3, 0);
  384. mga_outl(M_AR0, fontheight(p)*fontwidth(p)-1);
  385. mga_ydstlen(yy, fontheight(p));
  386. mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, p->fontdata+(c&p->charmask)*charcell, charcell);
  387. } else {
  388. u8* chardata = p->fontdata+(c&p->charmask)*fontheight(p)*step;
  389. int i;
  390. mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
  391. mga_outl(M_FCOL, fgx);
  392. mga_outl(M_BCOL, bgx);
  393. mga_outl(M_AR5, 0);
  394. mga_outl(M_AR3, 0);
  395. mga_outl(M_AR0, ar0);
  396. mga_ydstlen(yy, fontheight(p));
  397. switch (step) {
  398. case 1:
  399. for (i = fontheight(p); i > 0; i--) {
  400. #ifdef __LITTLE_ENDIAN
  401. mga_outl(0, *chardata++);
  402. #else
  403. mga_outl(0, (*chardata++) << 24);
  404. #endif
  405. }
  406. break;
  407. case 2:
  408. for (i = fontheight(p); i > 0; i--) {
  409. #ifdef __LITTLE_ENDIAN
  410. mga_outl(0, *(u_int16_t*)chardata);
  411. #else
  412. mga_outl(0, (*(u_int16_t*)chardata) << 16);
  413. #endif
  414. chardata += 2;
  415. }
  416. break;
  417. case 4:
  418. mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, chardata, fontheight(p) * 4);
  419. break;
  420. }
  421. }
  422. WaitTillIdle();
  423. #ifdef __BIG_ENDIAN
  424. mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
  425. #endif
  426. CRITEND
  427. }
  428. #ifdef FBCON_HAS_CFB8
  429. static void matrox_cfb8_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
  430. u_int32_t fgx, bgx;
  431. MINFO_FROM_DISP(p);
  432. DBG_HEAVY("matroxfb_cfb8_putc");
  433. fgx = attr_fgcol(p, c);
  434. bgx = attr_bgcol(p, c);
  435. fgx |= (fgx << 8);
  436. fgx |= (fgx << 16);
  437. bgx |= (bgx << 8);
  438. bgx |= (bgx << 16);
  439. ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
  440. }
  441. #endif
  442. #ifdef FBCON_HAS_CFB16
  443. static void matrox_cfb16_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
  444. u_int32_t fgx, bgx;
  445. MINFO_FROM_DISP(p);
  446. DBG_HEAVY("matroxfb_cfb16_putc");
  447. fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
  448. bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
  449. fgx |= (fgx << 16);
  450. bgx |= (bgx << 16);
  451. ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
  452. }
  453. #endif
  454. #if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
  455. static void matrox_cfb32_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
  456. u_int32_t fgx, bgx;
  457. MINFO_FROM_DISP(p);
  458. DBG_HEAVY("matroxfb_cfb32_putc");
  459. fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
  460. bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
  461. ACCESS_FBINFO(curr.putc)(fgx, bgx, p, c, yy, xx);
  462. }
  463. #endif
  464. static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
  465. unsigned int charcell;
  466. CRITFLAGS
  467. MINFO_FROM_DISP(p);
  468. yy *= fontheight(p);
  469. xx *= fontwidth(p);
  470. charcell = fontwidth(p) * fontheight(p);
  471. CRITBEGIN
  472. mga_fifo(3);
  473. mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
  474. mga_outl(M_FCOL, fgx);
  475. mga_outl(M_BCOL, bgx);
  476. while (count--) {
  477. u_int32_t ar3 = ACCESS_FBINFO(fastfont.mgabase) + (scr_readw(s++) & p->charmask)*charcell;
  478. mga_fifo(4);
  479. mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
  480. mga_outl(M_AR3, ar3);
  481. mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
  482. mga_ydstlen(yy, fontheight(p));
  483. xx += fontwidth(p);
  484. }
  485. WaitTillIdle();
  486. CRITEND
  487. }
  488. static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
  489. u_int32_t step;
  490. u_int32_t ydstlen;
  491. u_int32_t xlen;
  492. u_int32_t ar0;
  493. u_int32_t charcell;
  494. u_int32_t fxbndry;
  495. vaddr_t mmio;
  496. int easy;
  497. CRITFLAGS
  498. MINFO_FROM_DISP(p);
  499. DBG_HEAVY("matroxfb_cfbX_putcs");
  500. yy *= fontheight(p);
  501. xx *= fontwidth(p);
  502. if (fontwidth(p) <= 8)
  503. step = 1;
  504. else if (fontwidth(p) <= 16)
  505. step = 2;
  506. else
  507. step = 4;
  508. charcell = fontheight(p)*step;
  509. xlen = (charcell + 3) & ~3;
  510. ydstlen = (yy << 16) | fontheight(p);
  511. if (fontwidth(p) == step << 3) {
  512. ar0 = fontheight(p)*fontwidth(p) - 1;
  513. easy = 1;
  514. } else {
  515. ar0 = fontwidth(p) - 1;
  516. easy = 0;
  517. }
  518. CRITBEGIN
  519. #ifdef __BIG_ENDIAN
  520. WaitTillIdle();
  521. mga_outl(M_OPMODE, M_OPMODE_8BPP);
  522. #else
  523. mga_fifo(3);
  524. #endif
  525. if (easy)
  526. mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
  527. else
  528. mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
  529. mga_outl(M_FCOL, fgx);
  530. mga_outl(M_BCOL, bgx);
  531. fxbndry = ((xx + fontwidth(p) - 1) << 16) | xx;
  532. mmio = ACCESS_FBINFO(mmio.vbase);
  533. while (count--) {
  534. u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
  535. mga_fifo(6);
  536. mga_writel(mmio, M_FXBNDRY, fxbndry);
  537. mga_writel(mmio, M_AR0, ar0);
  538. mga_writel(mmio, M_AR3, 0);
  539. if (easy) {
  540. mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
  541. mga_memcpy_toio(mmio, 0, chardata, xlen);
  542. } else {
  543. mga_writel(mmio, M_AR5, 0);
  544. mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
  545. switch (step) {
  546. case 1: {
  547. u_int8_t* charend = chardata + charcell;
  548. for (; chardata != charend; chardata++) {
  549. #ifdef __LITTLE_ENDIAN
  550. mga_writel(mmio, 0, *chardata);
  551. #else
  552. mga_writel(mmio, 0, (*chardata) << 24);
  553. #endif
  554. }
  555. }
  556. break;
  557. case 2: {
  558. u_int8_t* charend = chardata + charcell;
  559. for (; chardata != charend; chardata += 2) {
  560. #ifdef __LITTLE_ENDIAN
  561. mga_writel(mmio, 0, *(u_int16_t*)chardata);
  562. #else
  563. mga_writel(mmio, 0, (*(u_int16_t*)chardata) << 16);
  564. #endif
  565. }
  566. }
  567. break;
  568. default:
  569. mga_memcpy_toio(mmio, 0, chardata, charcell);
  570. break;
  571. }
  572. }
  573. fxbndry += fontwidth(p) + (fontwidth(p) << 16);
  574. }
  575. WaitTillIdle();
  576. #ifdef __BIG_ENDIAN
  577. mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
  578. #endif
  579. CRITEND
  580. }
  581. #ifdef FBCON_HAS_CFB8
  582. static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
  583. u_int16_t c;
  584. u_int32_t fgx, bgx;
  585. MINFO_FROM_DISP(p);
  586. DBG_HEAVY("matroxfb_cfb8_putcs");
  587. c = scr_readw(s);
  588. fgx = attr_fgcol(p, c);
  589. bgx = attr_bgcol(p, c);
  590. fgx |= (fgx << 8);
  591. fgx |= (fgx << 16);
  592. bgx |= (bgx << 8);
  593. bgx |= (bgx << 16);
  594. ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
  595. }
  596. #endif
  597. #ifdef FBCON_HAS_CFB16
  598. static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
  599. u_int16_t c;
  600. u_int32_t fgx, bgx;
  601. MINFO_FROM_DISP(p);
  602. DBG_HEAVY("matroxfb_cfb16_putcs");
  603. c = scr_readw(s);
  604. fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
  605. bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
  606. fgx |= (fgx << 16);
  607. bgx |= (bgx << 16);
  608. ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
  609. }
  610. #endif
  611. #if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
  612. static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
  613. u_int16_t c;
  614. u_int32_t fgx, bgx;
  615. MINFO_FROM_DISP(p);
  616. DBG_HEAVY("matroxfb_cfb32_putcs");
  617. c = scr_readw(s);
  618. fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
  619. bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
  620. ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
  621. }
  622. #endif
  623. #ifdef FBCON_HAS_CFB4
  624. static void matrox_cfb4_revc(struct display* p, int xx, int yy) {
  625. CRITFLAGS
  626. MINFO_FROM_DISP(p);
  627. DBG_LOOP("matroxfb_cfb4_revc");
  628. if (fontwidth(p) & 1) {
  629. fbcon_cfb4_revc(p, xx, yy);
  630. return;
  631. }
  632. yy *= fontheight(p);
  633. xx *= fontwidth(p);
  634. xx |= (xx + fontwidth(p)) << 16;
  635. xx >>= 1;
  636. CRITBEGIN
  637. mga_fifo(5);
  638. mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
  639. mga_outl(M_FCOL, 0xFFFFFFFF);
  640. mga_outl(M_FXBNDRY, xx);
  641. mga_outl(M_YDST, yy * p->var.xres_virtual >> 6);
  642. mga_outl(M_LEN | M_EXEC, fontheight(p));
  643. WaitTillIdle();
  644. CRITEND
  645. }
  646. #endif
  647. #ifdef FBCON_HAS_CFB8
  648. static void matrox_cfb8_revc(struct display* p, int xx, int yy) {
  649. CRITFLAGS
  650. MINFO_FROM_DISP(p);
  651. DBG_LOOP("matrox_cfb8_revc")
  652. yy *= fontheight(p);
  653. xx *= fontwidth(p);
  654. CRITBEGIN
  655. mga_fifo(4);
  656. mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
  657. mga_outl(M_FCOL, 0x0F0F0F0F);
  658. mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
  659. mga_ydstlen(yy, fontheight(p));
  660. WaitTillIdle();
  661. CRITEND
  662. }
  663. #endif
  664. static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
  665. CRITFLAGS
  666. MINFO_FROM_DISP(p);
  667. DBG_LOOP("matrox_cfbX_revc")
  668. yy *= fontheight(p);
  669. xx *= fontwidth(p);
  670. CRITBEGIN
  671. mga_fifo(4);
  672. mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
  673. mga_outl(M_FCOL, 0xFFFFFFFF);
  674. mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
  675. mga_ydstlen(yy, fontheight(p));
  676. WaitTillIdle();
  677. CRITEND
  678. }
  679. static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
  680. unsigned int bottom_height, right_width;
  681. unsigned int bottom_start, right_start;
  682. unsigned int cell_h, cell_w;
  683. DBG("matrox_cfbX_clear_margins")
  684. cell_w = fontwidth(p);
  685. if (!cell_w) return; /* PARANOID */
  686. right_width = p->var.xres % cell_w;
  687. right_start = p->var.xres - right_width;
  688. if (!bottom_only && right_width) {
  689. /* clear whole right margin, not only visible portion */
  690. matroxfb_accel_clear(     PMXINFO(p)
  691.      /* color */  0x00000000,
  692.      /* y */      0,
  693.      /* x */      p->var.xoffset + right_start,
  694.      /* height */ p->var.yres_virtual,
  695.      /* width */  right_width);
  696. }
  697. cell_h = fontheight(p);
  698. if (!cell_h) return; /* PARANOID */
  699. bottom_height = p->var.yres % cell_h;
  700. if (bottom_height) {
  701. bottom_start = p->var.yres - bottom_height;
  702. matroxfb_accel_clear(   PMXINFO(p)
  703.      /* color */  0x00000000,
  704.      /* y */   p->var.yoffset + bottom_start,
  705.      /* x */   p->var.xoffset,
  706.      /* height */ bottom_height,
  707.      /* width */  right_start);
  708. }
  709. }
  710. static void matrox_text_setup(struct display* p) {
  711. MINFO_FROM_DISP(p);
  712. p->next_line = p->line_length ? p->line_length : ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
  713. p->next_plane = 0;
  714. }
  715. static void matrox_text_bmove(struct display* p, int sy, int sx, int dy, int dx,
  716. int height, int width) {
  717. unsigned int srcoff;
  718. unsigned int dstoff;
  719. unsigned int step;
  720. CRITFLAGS
  721. MINFO_FROM_DISP(p);
  722. CRITBEGIN
  723. step = ACCESS_FBINFO(devflags.textstep);
  724. srcoff = (sy * p->next_line) + (sx * step);
  725. dstoff = (dy * p->next_line) + (dx * step);
  726. if (dstoff < srcoff) {
  727. while (height > 0) {
  728. int i;
  729. for (i = width; i > 0; dstoff += step, srcoff += step, i--)
  730. mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
  731. height--;
  732. dstoff += p->next_line - width * step;
  733. srcoff += p->next_line - width * step;
  734. }
  735. } else {
  736. unsigned int off;
  737. off = (height - 1) * p->next_line + (width - 1) * step;
  738. srcoff += off;
  739. dstoff += off;
  740. while (height > 0) {
  741. int i;
  742. for (i = width; i > 0; dstoff -= step, srcoff -= step, i--)
  743. mga_writew(ACCESS_FBINFO(video.vbase), dstoff, mga_readw(ACCESS_FBINFO(video.vbase), srcoff));
  744. dstoff -= p->next_line - width * step;
  745. srcoff -= p->next_line - width * step;
  746. height--;
  747. }
  748. }
  749. CRITEND
  750. }
  751. static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx,
  752. int height, int width) {
  753. unsigned int offs;
  754. unsigned int val;
  755. unsigned int step;
  756. CRITFLAGS
  757. MINFO_FROM_DISP(p);
  758. step = ACCESS_FBINFO(devflags.textstep);
  759. offs = sy * p->next_line + sx * step;
  760. val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8));
  761. CRITBEGIN
  762. while (height > 0) {
  763. int i;
  764. for (i = width; i > 0; offs += step, i--)
  765. mga_writew(ACCESS_FBINFO(video.vbase), offs, val);
  766. offs += p->next_line - width * step;
  767. height--;
  768. }
  769. CRITEND
  770. }
  771. static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
  772. unsigned int offs;
  773. unsigned int chr;
  774. unsigned int step;
  775. CRITFLAGS
  776. MINFO_FROM_DISP(p);
  777. step = ACCESS_FBINFO(devflags.textstep);
  778. offs = yy * p->next_line + xx * step;
  779. chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8);
  780. if (chr & 0x10000) chr |= 0x08;
  781. CRITBEGIN
  782. mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr));
  783. CRITEND
  784. }
  785. static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s,
  786. int count, int yy, int xx) {
  787. unsigned int offs;
  788. unsigned int attr;
  789. unsigned int step;
  790. u_int16_t c;
  791. CRITFLAGS
  792. MINFO_FROM_DISP(p);
  793. step = ACCESS_FBINFO(devflags.textstep);
  794. offs = yy * p->next_line + xx * step;
  795. c = scr_readw(s);
  796. attr = attr_fgcol(p, c) | (attr_bgcol(p, c) << 4);
  797. CRITBEGIN
  798. while (count-- > 0) {
  799. unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
  800. if (chr & 0x10000) chr ^= 0x10008;
  801. mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
  802. offs += step;
  803. }
  804. CRITEND
  805. }
  806. static void matrox_text_revc(struct display* p, int xx, int yy) {
  807. unsigned int offs;
  808. unsigned int step;
  809. CRITFLAGS
  810. MINFO_FROM_DISP(p);
  811. step = ACCESS_FBINFO(devflags.textstep);
  812. offs = yy * p->next_line + xx * step + 1;
  813. CRITBEGIN
  814. mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77);
  815. CRITEND
  816. }
  817. void matrox_text_createcursor(WPMINFO struct display* p) {
  818. CRITFLAGS
  819. if (ACCESS_FBINFO(currcon_display) != p)
  820. return;
  821. matroxfb_createcursorshape(PMINFO p, 0);
  822. CRITBEGIN
  823. mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
  824. mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1);
  825. CRITEND
  826. }
  827. static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
  828. unsigned int pos;
  829. CRITFLAGS
  830. MINFO_FROM_DISP(p);
  831. if (ACCESS_FBINFO(currcon_display) != p)
  832. return;
  833. if (mode == CM_ERASE) {
  834. if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
  835. CRITBEGIN
  836. mga_setr(M_CRTC_INDEX, 0x0A, 0x20);
  837. CRITEND
  838. ACCESS_FBINFO(cursor.state) = CM_ERASE;
  839. }
  840. return;
  841. }
  842. if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
  843. matrox_text_createcursor(PMINFO p);
  844. /* DO NOT CHECK cursor.x != x because of matroxfb_vgaHWinit moves cursor to 0,0 */
  845. ACCESS_FBINFO(cursor.x) = x;
  846. ACCESS_FBINFO(cursor.y) = y;
  847. pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x;
  848. CRITBEGIN
  849. mga_setr(M_CRTC_INDEX, 0x0F, pos);
  850. mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8);
  851. mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
  852. CRITEND
  853. ACCESS_FBINFO(cursor.state) = CM_DRAW;
  854. }
  855. void matrox_text_round(CPMINFO struct fb_var_screeninfo* var, struct display* p) {
  856. unsigned hf;
  857. unsigned vf;
  858. unsigned vxres;
  859. unsigned ych;
  860. hf = fontwidth(p);
  861. if (!hf) hf = 8;
  862. /* do not touch xres */
  863. vxres = (var->xres_virtual + hf - 1) / hf;
  864. if (vxres >= 256)
  865. vxres = 255;
  866. if (vxres < 16)
  867. vxres = 16;
  868. vxres = (vxres + 1) & ~1; /* must be even */
  869. vf = fontheight(p);
  870. if (!vf) vf = 16;
  871. if (var->yres < var->yres_virtual) {
  872. ych = ACCESS_FBINFO(devflags.textvram) / vxres;
  873. var->yres_virtual = ych * vf;
  874. } else
  875. ych = var->yres_virtual / vf;
  876. if (vxres * ych > ACCESS_FBINFO(devflags.textvram)) {
  877. ych = ACCESS_FBINFO(devflags.textvram) / vxres;
  878. var->yres_virtual = ych * vf;
  879. }
  880. var->xres_virtual = vxres * hf;
  881. }
  882. static int matrox_text_setfont(struct display* p, int width, int height) {
  883. DBG("matrox_text_setfont");
  884. if (p) {
  885. MINFO_FROM_DISP(p);
  886. matrox_text_round(PMINFO &p->var, p);
  887. p->next_line = p->line_length = ((p->var.xres_virtual / (fontwidth(p)?fontwidth(p):8)) * ACCESS_FBINFO(devflags.textstep));
  888. if (p->conp)
  889. matrox_text_createcursor(PMINFO p);
  890. }
  891. return 0;
  892. }
  893. #define matrox_cfb16_revc matrox_cfbX_revc
  894. #define matrox_cfb24_revc matrox_cfbX_revc
  895. #define matrox_cfb32_revc matrox_cfbX_revc
  896. #define matrox_cfb24_clear matrox_cfb32_clear
  897. #define matrox_cfb24_putc matrox_cfb32_putc
  898. #define matrox_cfb24_putcs matrox_cfb32_putcs
  899. #ifdef FBCON_HAS_VGATEXT
  900. static struct display_switch matroxfb_text = {
  901. setup: matrox_text_setup,
  902. bmove: matrox_text_bmove,
  903. clear: matrox_text_clear,
  904. putc: matrox_text_putc,
  905. putcs: matrox_text_putcs,
  906. revc: matrox_text_revc,
  907. cursor: matrox_text_cursor,
  908. set_font: matrox_text_setfont,
  909. fontwidthmask: FONTWIDTH(8)|FONTWIDTH(9)
  910. };
  911. #endif
  912. #ifdef FBCON_HAS_CFB4
  913. static struct display_switch matroxfb_cfb4 = {
  914. setup: fbcon_cfb4_setup,
  915. bmove: matrox_cfb4_bmove,
  916. clear: matrox_cfb4_clear,
  917. putc: fbcon_cfb4_putc,
  918. putcs: fbcon_cfb4_putcs,
  919. revc: matrox_cfb4_revc,
  920. fontwidthmask: FONTWIDTH(8) /* fix, fix, fix it */
  921. };
  922. #endif
  923. #ifdef FBCON_HAS_CFB8
  924. static struct display_switch matroxfb_cfb8 = {
  925. setup: fbcon_cfb8_setup,
  926. bmove: matrox_cfbX_bmove,
  927. clear: matrox_cfb8_clear,
  928. putc: matrox_cfb8_putc,
  929. putcs: matrox_cfb8_putcs,
  930. revc: matrox_cfb8_revc,
  931. clear_margins: matrox_cfbX_clear_margins,
  932. fontwidthmask: ~1 /* FONTWIDTHS */
  933. };
  934. #endif
  935. #ifdef FBCON_HAS_CFB16
  936. static struct display_switch matroxfb_cfb16 = {
  937. setup: fbcon_cfb16_setup,
  938. bmove: matrox_cfbX_bmove,
  939. clear: matrox_cfb16_clear,
  940. putc: matrox_cfb16_putc,
  941. putcs: matrox_cfb16_putcs,
  942. revc: matrox_cfb16_revc,
  943. clear_margins: matrox_cfbX_clear_margins,
  944. fontwidthmask: ~1 /* FONTWIDTHS */
  945. };
  946. #endif
  947. #ifdef FBCON_HAS_CFB24
  948. static struct display_switch matroxfb_cfb24 = {
  949. setup: fbcon_cfb24_setup,
  950. bmove: matrox_cfbX_bmove,
  951. clear: matrox_cfb24_clear,
  952. putc: matrox_cfb24_putc,
  953. putcs: matrox_cfb24_putcs,
  954. revc: matrox_cfb24_revc,
  955. clear_margins: matrox_cfbX_clear_margins,
  956. fontwidthmask: ~1 /* FONTWIDTHS */ /* TODO: and what about non-aligned access on BE? I think that there are no in my code */
  957. };
  958. #endif
  959. #ifdef FBCON_HAS_CFB32
  960. static struct display_switch matroxfb_cfb32 = {
  961. setup: fbcon_cfb32_setup,
  962. bmove: matrox_cfbX_bmove,
  963. clear: matrox_cfb32_clear,
  964. putc: matrox_cfb32_putc,
  965. putcs: matrox_cfb32_putcs,
  966. revc: matrox_cfb32_revc,
  967. clear_margins: matrox_cfbX_clear_margins,
  968. fontwidthmask: ~1 /* FONTWIDTHS */
  969. };
  970. #endif
  971. void initMatrox(WPMINFO struct display* p) {
  972. struct display_switch *swtmp;
  973. DBG("initMatrox")
  974. if (ACCESS_FBINFO(currcon_display) != p)
  975. return;
  976. if (p->dispsw && p->conp)
  977. fb_con.con_cursor(p->conp, CM_ERASE);
  978. p->dispsw_data = NULL;
  979. if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) {
  980. if (p->type == FB_TYPE_TEXT) {
  981. swtmp = &matroxfb_text;
  982. } else {
  983. switch (p->var.bits_per_pixel) {
  984. #ifdef FBCON_HAS_CFB4
  985. case 4:
  986. swtmp = &fbcon_cfb4;
  987. break;
  988. #endif
  989. #ifdef FBCON_HAS_CFB8
  990. case 8:
  991. swtmp = &fbcon_cfb8;
  992. break;
  993. #endif
  994. #ifdef FBCON_HAS_CFB16
  995. case 16:
  996. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
  997. swtmp = &fbcon_cfb16;
  998. break;
  999. #endif
  1000. #ifdef FBCON_HAS_CFB24
  1001. case 24:
  1002. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
  1003. swtmp = &fbcon_cfb24;
  1004. break;
  1005. #endif
  1006. #ifdef FBCON_HAS_CFB32
  1007. case 32:
  1008. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
  1009. swtmp = &fbcon_cfb32;
  1010. break;
  1011. #endif
  1012. default:
  1013. p->dispsw = &fbcon_dummy;
  1014. return;
  1015. }
  1016. }
  1017. dprintk(KERN_INFO "matroxfb: acceleration disabledn");
  1018. } else if (p->type == FB_TYPE_TEXT) {
  1019. swtmp = &matroxfb_text;
  1020. } else {
  1021. switch (p->var.bits_per_pixel) {
  1022. #ifdef FBCON_HAS_CFB4
  1023. case 4:
  1024. swtmp = &matroxfb_cfb4;
  1025. break;
  1026. #endif
  1027. #ifdef FBCON_HAS_CFB8
  1028. case 8:
  1029. swtmp = &matroxfb_cfb8;
  1030. break;
  1031. #endif
  1032. #ifdef FBCON_HAS_CFB16
  1033. case 16:
  1034. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb16);
  1035. swtmp = &matroxfb_cfb16;
  1036. break;
  1037. #endif
  1038. #ifdef FBCON_HAS_CFB24
  1039. case 24:
  1040. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb24);
  1041. swtmp = &matroxfb_cfb24;
  1042. break;
  1043. #endif
  1044. #ifdef FBCON_HAS_CFB32
  1045. case 32:
  1046. p->dispsw_data = &ACCESS_FBINFO(cmap.cfb32);
  1047. swtmp = &matroxfb_cfb32;
  1048. break;
  1049. #endif
  1050. default:
  1051. p->dispsw = &fbcon_dummy;
  1052. return;
  1053. }
  1054. }
  1055. memcpy(&ACCESS_FBINFO(dispsw), swtmp, sizeof(ACCESS_FBINFO(dispsw)));
  1056. p->dispsw = &ACCESS_FBINFO(dispsw);
  1057. if ((p->type != FB_TYPE_TEXT) && ACCESS_FBINFO(devflags.hwcursor)) {
  1058. ACCESS_FBINFO(hw_switch)->selhwcursor(PMINFO p);
  1059. }
  1060. }
  1061. void matrox_init_putc(WPMINFO struct display* p, void (*dac_createcursor)(WPMINFO struct display* p)) {
  1062. int i;
  1063. if (p && p->conp) {
  1064. if (p->type == FB_TYPE_TEXT) {
  1065. matrox_text_createcursor(PMINFO p);
  1066. matrox_text_loadfont(PMINFO p);
  1067. i = 0;
  1068. } else {
  1069. dac_createcursor(PMINFO p);
  1070. i = matroxfb_fastfont_tryset(PMINFO p);
  1071. }
  1072. } else
  1073. i = 0;
  1074. if (i) {
  1075. ACCESS_FBINFO(curr.putc) = matrox_cfbX_fastputc;
  1076. ACCESS_FBINFO(curr.putcs) = matrox_cfbX_fastputcs;
  1077. } else {
  1078. ACCESS_FBINFO(curr.putc) = matrox_cfbX_putc;
  1079. ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
  1080. }
  1081. }
  1082. MODULE_LICENSE("GPL");