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

嵌入式Linux

开发平台:

Unix_Linux

  1. #include <linux/kernel.h>
  2. #include <linux/errno.h>
  3. #include <linux/string.h>
  4. #include <linux/mm.h>
  5. #include <linux/tty.h>
  6. #include <linux/slab.h>
  7. #include <linux/delay.h>
  8. #include <linux/interrupt.h>
  9. #include <asm/setup.h>
  10. #include <asm/segment.h>
  11. #include <asm/system.h>
  12. #include <asm/irq.h>
  13. #include <asm/amigahw.h>
  14. #include <asm/amigaints.h>
  15. #include <asm/apollohw.h>
  16. #include <linux/fb.h>
  17. #include <linux/module.h>
  18. #include "dn_accel.h"
  19. #include "fbcon.h"
  20. #include "fbcon-mfb.h"
  21. /* apollo video HW definitions */
  22. /*
  23.  * Control Registers.   IOBASE + $x
  24.  *
  25.  * Note: these are the Memory/IO BASE definitions for a mono card set to the
  26.  * alternate address
  27.  *
  28.  * Control 3A and 3B serve identical functions except that 3A
  29.  * deals with control 1 and 3b deals with Color LUT reg.
  30.  */
  31. #define AP_IOBASE       0x3d0          /* Base address of 1 plane board. */
  32. #define AP_STATUS       isaIO2mem(AP_IOBASE+0) /* Status register.  Read */
  33. #define AP_WRITE_ENABLE isaIO2mem(AP_IOBASE+0) /* Write Enable Register Write */
  34. #define AP_DEVICE_ID    isaIO2mem(AP_IOBASE+1) /* Device ID Register. Read */
  35. #define AP_ROP_0        isaIO2mem(AP_IOBASE+2) /* Raster Operation reg. Write Word */
  36. #define AP_ROP_1        isaIO2mem(AP_IOBASE+4) /* Raster Operation reg. Write Word */
  37. #define AP_DIAG_MEM_REQ isaIO2mem(AP_IOBASE+6) /* Diagnostic Memory Request. Write Word */
  38. #define AP_CONTROL_0    isaIO2mem(AP_IOBASE+8) /* Control Register 0.  Read/Write */
  39. #define AP_LUT_DATA     isaIO2mem(AP_IOBASE+9) /* Control Register 0.  Read/Write */
  40. #define AP_CONTROL_1    isaIO2mem(AP_IOBASE+0xa) /* Control Register 1.  Read/Write */
  41. #define AP_LUT_CONTROL  isaIO2mem(AP_IOBASE+0xb) /* Control Register 1.  Read/Write */
  42. #define AP_CONTROL_2A   isaIO2mem(AP_IOBASE+0xc) /* Control Register 2. Read/Write */
  43. #define AP_CONTROL_2B   isaIO2mem(AP_IOBASE+0xd) /* Control Register 2. Read/Write */
  44. #define AP_CONTROL_3A   isaIO2mem(AP_IOBASE+0xe) /* Control Register 3a. Read/Write */
  45. #define AP_CONTROL_3B   isaIO2mem(AP_IOBASE+0xf) /* Control Register 3a. Read/Write */
  46. #define FRAME_BUFFER_START 0x0A0000
  47. #define FRAME_BUFFER_LEN 0x20000
  48. /* CREG 0 */
  49. #define VECTOR_MODE 0x40 /* 010x.xxxx */
  50. #define DBLT_MODE   0x80 /* 100x.xxxx */
  51. #define NORMAL_MODE 0xE0 /* 111x.xxxx */
  52. #define SHIFT_BITS  0x1F /* xxx1.1111 */
  53.         /* other bits are Shift value */
  54. /* CREG 1 */
  55. #define AD_BLT      0x80 /* 1xxx.xxxx */
  56. #define ROP_EN          0x10 /* xxx1.xxxx */
  57. #define DST_EQ_SRC      0x00 /* xxx0.xxxx */
  58. #define nRESET_SYNC     0x08 /* xxxx.1xxx */
  59. #define SYNC_ENAB       0x02 /* xxxx.xx1x */
  60. #define BLANK_DISP      0x00 /* xxxx.xxx0 */
  61. #define ENAB_DISP       0x01 /* xxxx.xxx1 */
  62. #define NORM_CREG1      (nRESET_SYNC | SYNC_ENAB | ENAB_DISP) /* no reset sync */
  63. /* CREG 2B */
  64. /*
  65.  * Following 3 defines are common to 1, 4 and 8 plane.
  66.  */
  67. #define S_DATA_1s   0x00 /* 00xx.xxxx */ /* set source to all 1's -- vector drawing */
  68. #define S_DATA_PIX  0x40 /* 01xx.xxxx */ /* takes source from ls-bits and replicates over 16 bits */
  69. #define S_DATA_PLN  0xC0 /* 11xx.xxxx */ /* normal, each data access =16-bits in
  70.  one plane of image mem */
  71. /* CREG 3A/CREG 3B */
  72. #       define RESET_CREG 0x80 /* 1000.0000 */
  73. /* ROP REG  -  all one nibble */
  74. /*      ********* NOTE : this is used r0,r1,r2,r3 *********** */
  75. #define ROP(r2,r3,r0,r1) ( (U_SHORT)((r0)|((r1)<<4)|((r2)<<8)|((r3)<<12)) )
  76. #define DEST_ZERO               0x0
  77. #define SRC_AND_DEST    0x1
  78. #define SRC_AND_nDEST   0x2
  79. #define SRC                             0x3
  80. #define nSRC_AND_DEST   0x4
  81. #define DEST                    0x5
  82. #define SRC_XOR_DEST    0x6
  83. #define SRC_OR_DEST             0x7
  84. #define SRC_NOR_DEST    0x8
  85. #define SRC_XNOR_DEST   0x9
  86. #define nDEST                   0xA
  87. #define SRC_OR_nDEST    0xB
  88. #define nSRC                    0xC
  89. #define nSRC_OR_DEST    0xD
  90. #define SRC_NAND_DEST   0xE
  91. #define DEST_ONE                0xF
  92. #define SWAP(A) ((A>>8) | ((A&0xff) <<8))
  93. /* frame buffer operations */
  94. static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con, 
  95.  struct fb_info *info);
  96. static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
  97.  struct fb_info *info);
  98. static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive,
  99.  struct fb_info *info);
  100. static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
  101.   struct fb_info *info);
  102. static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
  103.   struct fb_info *info);
  104. static int dnfbcon_switch(int con,struct fb_info *info);
  105. static int dnfbcon_updatevar(int con,struct fb_info *info);
  106. static void dnfbcon_blank(int blank,struct fb_info *info);
  107. static void dn_fb_set_disp(int con,struct fb_info *info);
  108. static struct display disp[MAX_NR_CONSOLES];
  109. static struct fb_info fb_info;
  110. static struct fb_ops dn_fb_ops = {
  111. owner: THIS_MODULE,
  112. fb_get_fix: dn_fb_get_fix,
  113. fb_get_var: dn_fb_get_var,
  114. fb_set_var: dn_fb_set_var,
  115. fb_get_cmap: dn_fb_get_cmap,
  116. fb_set_cmap: dn_fb_set_cmap,
  117. };
  118. static int currcon=0;
  119. #define NUM_TOTAL_MODES 1
  120. struct fb_var_screeninfo dn_fb_predefined[] = {
  121. { 0, },
  122. };
  123. static char dn_fb_name[]="Apollo ";
  124. /* accel stuff */
  125. #define USE_DN_ACCEL
  126. static struct display_switch dispsw_apollofb;
  127. static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
  128.  struct fb_info *info) {
  129. strcpy(fix->id,"Apollo Color8");
  130. fix->smem_start=(char*)(FRAME_BUFFER_START+IO_BASE);
  131. fix->smem_len=FRAME_BUFFER_LEN;
  132. fix->type=FB_TYPE_PACKED_PIXELS;
  133. fix->type_aux=0;
  134. fix->visual=FB_VISUAL_MONO10;
  135. fix->xpanstep=0;
  136. fix->ypanstep=0;
  137. fix->ywrapstep=0;
  138.         fix->line_length=128;
  139. return 0;
  140. }
  141.         
  142. static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
  143.  struct fb_info *info) {
  144. var->xres=1024;
  145. var->yres=800;
  146. var->xres_virtual=1024;
  147. var->yres_virtual=1024;
  148. var->xoffset=0;
  149. var->yoffset=0;
  150. var->bits_per_pixel=1;
  151. var->grayscale=0;
  152. var->nonstd=0;
  153. var->activate=0;
  154. var->height=-1;
  155. var->width=-1;
  156. var->pixclock=0;
  157. var->left_margin=0;
  158. var->right_margin=0;
  159. var->hsync_len=0;
  160. var->vsync_len=0;
  161. var->sync=0;
  162. var->vmode=FB_VMODE_NONINTERLACED;
  163. return 0;
  164. }
  165. static int dn_fb_set_var(struct fb_var_screeninfo *var, int con,
  166.  struct fb_info *info) {
  167.         printk("fb_set_varn");
  168. if(var->xres!=1024) 
  169. return -EINVAL;
  170. if(var->yres!=800)
  171. return -EINVAL;
  172. if(var->xres_virtual!=1024)
  173. return -EINVAL;
  174. if(var->yres_virtual!=1024)
  175. return -EINVAL;
  176. if(var->xoffset!=0)
  177. return -EINVAL;
  178. if(var->yoffset!=0)
  179. return -EINVAL;
  180. if(var->bits_per_pixel!=1)
  181. return -EINVAL;
  182. if(var->grayscale!=0)
  183. return -EINVAL;
  184. if(var->nonstd!=0)
  185. return -EINVAL;
  186. if(var->activate!=0)
  187. return -EINVAL;
  188. if(var->pixclock!=0)
  189. return -EINVAL;
  190. if(var->left_margin!=0)
  191. return -EINVAL;
  192. if(var->right_margin!=0)
  193. return -EINVAL;
  194. if(var->hsync_len!=0)
  195. return -EINVAL;
  196. if(var->vsync_len!=0)
  197. return -EINVAL;
  198. if(var->sync!=0)
  199. return -EINVAL;
  200. if(var->vmode!=FB_VMODE_NONINTERLACED)
  201. return -EINVAL;
  202. return 0;
  203. }
  204. static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
  205.   struct fb_info *info) {
  206. printk("get cmap not supportedn");
  207. return -EINVAL;
  208. }
  209. static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
  210.   struct fb_info *info) {
  211. printk("set cmap not supportedn");
  212. return -EINVAL;
  213. }
  214. static void dn_fb_set_disp(int con, struct fb_info *info) {
  215.   struct fb_fix_screeninfo fix;
  216.   dn_fb_get_fix(&fix,con, info);
  217.   if(con==-1) 
  218.     con=0;
  219.    disp[con].screen_base = (u_char *)fix.smem_start;
  220. printk("screenbase: %pn",fix.smem_start);
  221.    disp[con].visual = fix.visual;
  222.    disp[con].type = fix.type;
  223.    disp[con].type_aux = fix.type_aux;
  224.    disp[con].ypanstep = fix.ypanstep;
  225.    disp[con].ywrapstep = fix.ywrapstep;
  226.    disp[con].can_soft_blank = 1;
  227.    disp[con].inverse = 0;
  228.    disp[con].line_length = fix.line_length;
  229.    disp[con].dispsw = &dispsw_apollofb;
  230. }
  231.   
  232. unsigned long dn_fb_init(unsigned long mem_start) {
  233. int err;
  234.        
  235. printk("dn_fb_initn");
  236. fb_info.changevar=NULL;
  237. strcpy(&fb_info.modename[0],dn_fb_name);
  238. fb_info.fontname[0]=0;
  239. fb_info.disp=disp;
  240. fb_info.switch_con=&dnfbcon_switch;
  241. fb_info.updatevar=&dnfbcon_updatevar;
  242. fb_info.blank=&dnfbcon_blank;
  243. fb_info.node = -1;
  244. fb_info.fbops = &dn_fb_ops;
  245. printk("dn_fb_init: registern");
  246. err=register_framebuffer(&fb_info);
  247. if(err < 0) {
  248. panic("unable to register apollo frame buffern");
  249. }
  250.  
  251. /* now we have registered we can safely setup the hardware */
  252.         outb(RESET_CREG,  AP_CONTROL_3A);
  253.         outb(RESET_CREG,  AP_CONTROL_3B);
  254.         outw(0x0,  AP_WRITE_ENABLE);
  255.         outb(NORMAL_MODE, AP_CONTROL_0); 
  256.         outb((AD_BLT | DST_EQ_SRC | NORM_CREG1),  AP_CONTROL_1);
  257.         outb(0,  AP_CONTROL_2A);
  258.         outb(S_DATA_PLN,  AP_CONTROL_2B);
  259.         outw(SWAP(0x3), AP_ROP_1);
  260.         printk("apollo frame buffer alive and kicking !n");
  261.         dn_fb_get_var(&disp[0].var,0, &fb_info);
  262. dn_fb_set_disp(-1, &fb_info);
  263. return mem_start;
  264. }
  265. static int dnfbcon_switch(int con,  struct fb_info *info) { 
  266. currcon=con;
  267. return 0;
  268. }
  269. static int dnfbcon_updatevar(int con,  struct fb_info *info) {
  270. return 0;
  271. }
  272. static void dnfbcon_blank(int blank,  struct fb_info *info) {
  273. if(blank)  {
  274.          outb(0x0,  AP_CONTROL_3A);
  275. }
  276. else {
  277.         outb(0x1,  AP_CONTROL_3A);
  278. }
  279. return ;
  280. }
  281. void dn_bitblt(struct display *p,int x_src,int y_src, int x_dest, int y_dest,
  282.                int x_count, int y_count) {
  283. int incr,y_delta,pre_read=0,x_end,x_word_count;
  284. ushort *src,dummy;
  285. uint start_mask,end_mask,dest;
  286. short i,j;
  287. incr=(y_dest<=y_src) ? 1 : -1 ;
  288. src=(ushort *)(p->screen_base+ y_src*p->next_line+(x_src >> 4));
  289. dest=y_dest*(p->next_line >> 1)+(x_dest >> 4);
  290. if(incr>0) {
  291. y_delta=(p->next_line*8)-x_src-x_count;
  292. x_end=x_dest+x_count-1;
  293. x_word_count=(x_end>>4) - (x_dest >> 4) + 1;
  294. start_mask=0xffff0000 >> (x_dest & 0xf);
  295. end_mask=0x7ffff >> (x_end & 0xf);
  296. outb((((x_dest & 0xf) - (x_src &0xf))  % 16)|(0x4 << 5),AP_CONTROL_0);
  297. if((x_dest & 0xf) < (x_src & 0xf))
  298. pre_read=1;
  299. }
  300. else {
  301. y_delta=-((p->next_line*8)-x_src-x_count);
  302. x_end=x_dest-x_count+1;
  303. x_word_count=(x_dest>>4) - (x_end >> 4) + 1;
  304. start_mask=0x7ffff >> (x_dest & 0xf);
  305. end_mask=0xffff0000 >> (x_end & 0xf);
  306. outb(((-((x_src & 0xf) - (x_dest &0xf))) % 16)|(0x4 << 5),AP_CONTROL_0);
  307. if((x_dest & 0xf) > (x_src & 0xf))
  308. pre_read=1;
  309. }
  310. for(i=0;i<y_count;i++) {
  311. if(pre_read) {
  312. dummy=*src;
  313. src+=incr;
  314. }
  315. if(x_word_count) {
  316. outb(start_mask,AP_WRITE_ENABLE);
  317. *src=dest;
  318. src+=incr;
  319. dest+=incr;
  320. outb(0,AP_WRITE_ENABLE);
  321. for(j=1;j<(x_word_count-1);j++) {
  322. *src=dest;
  323. src+=incr;
  324. dest+=incr;
  325. }
  326. outb(start_mask,AP_WRITE_ENABLE);
  327. *src=dest;
  328. dest+=incr;
  329. src+=incr;
  330. }
  331. else {
  332. outb(start_mask | end_mask, AP_WRITE_ENABLE);
  333. *src=dest;
  334. dest+=incr;
  335. src+=incr;
  336. }
  337. src+=(y_delta/16);
  338. dest+=(y_delta/16);
  339. }
  340. outb(NORMAL_MODE,AP_CONTROL_0);
  341. }
  342. static void bmove_apollofb(struct display *p, int sy, int sx, int dy, int dx,
  343.       int height, int width)
  344. {
  345. #ifdef USE_DN_ACCEL
  346.     dn_bitblt(p,sx,sy*p->fontheight,dx,dy*p->fontheight,width*p->fontwidth,
  347.       height*p->fontheight);
  348. #else
  349.     u_char *src, *dest;
  350.     u_int rows;
  351.     if (sx == 0 && dx == 0 && width == p->next_line) {
  352. src = p->screen_base+sy*p->fontheight*width;
  353. dest = p->screen_base+dy*p->fontheight*width;
  354. mymemmove(dest, src, height*p->fontheight*width);
  355.     } else if (dy <= sy) {
  356. src = p->screen_base+sy*p->fontheight*p->next_line+sx;
  357. dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
  358. for (rows = height*p->fontheight; rows--;) {
  359.     mymemmove(dest, src, width);
  360.     src += p->next_line;
  361.     dest += p->next_line;
  362. }
  363.     } else {
  364. src = p->screen_base+((sy+height)*p->fontheight-1)*p->next_line+sx;
  365. dest = p->screen_base+((dy+height)*p->fontheight-1)*p->next_line+dx;
  366. for (rows = height*p->fontheight; rows--;) {
  367.     mymemmove(dest, src, width);
  368.     src -= p->next_line;
  369.     dest -= p->next_line;
  370. }
  371.     }
  372. #endif
  373. }
  374. static void clear_apollofb(struct vc_data *conp, struct display *p, int sy, int sx,
  375.       int height, int width)
  376. {
  377.     u_char *dest;
  378.     u_int rows;
  379.     dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
  380.     if (sx == 0 && width == p->next_line)
  381. if (attr_reverse(p,conp))
  382.     mymemset(dest, height*p->fontheight*width);
  383. else
  384.     mymemclear(dest, height*p->fontheight*width);
  385.     else
  386. for (rows = height*p->fontheight; rows--; dest += p->next_line)
  387.     if (attr_reverse(p,conp))
  388. mymemset(dest, width);
  389.     else
  390. mymemclear_small(dest, width);
  391. }
  392. static void putc_apollofb(struct vc_data *conp, struct display *p, int c, int yy,
  393.      int xx)
  394. {
  395.     u_char *dest, *cdat;
  396.     u_int rows, bold, revs, underl;
  397.     u_char d;
  398.     c &= 0xff;
  399.     dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
  400.     cdat = p->fontdata+c*p->fontheight;
  401.     bold = attr_bold(p,conp);
  402.     revs = attr_reverse(p,conp);
  403.     underl = attr_underline(p,conp);
  404.     for (rows = p->fontheight; rows--; dest += p->next_line) {
  405. d = *cdat++;
  406. if (underl && !rows)
  407.     d = 0xff;
  408. else if (bold)
  409.     d |= d>>1;
  410. if (revs)
  411.     d = ~d;
  412. *dest = d;
  413.     }
  414. }
  415. static void putcs_apollofb(struct vc_data *conp, struct display *p, const char *s,
  416.       int count, int yy, int xx)
  417. {
  418.     u_char *dest, *dest0, *cdat;
  419.     u_int rows, bold, revs, underl;
  420.     u_char c, d;
  421.     dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
  422.     bold = attr_bold(p,conp);
  423.     revs = attr_reverse(p,conp);
  424.     underl = attr_underline(p,conp);
  425.     while (count--) {
  426. c = scr_readw(s++);
  427. dest = dest0++;
  428. cdat = p->fontdata+c*p->fontheight;
  429. for (rows = p->fontheight; rows--; dest += p->next_line) {
  430.     d = *cdat++;
  431.     if (underl && !rows)
  432. d = 0xff;
  433.     else if (bold)
  434. d |= d>>1;
  435.     if (revs)
  436. d = ~d;
  437.     *dest = d;
  438. }
  439.     }
  440. }
  441. static void rev_char_apollofb(struct display *p, int xx, int yy)
  442. {
  443.     u_char *dest;
  444.     u_int rows;
  445.     dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
  446.     for (rows = p->fontheight; rows--; dest += p->next_line)
  447. *dest = ~*dest;
  448. }
  449. static struct display_switch dispsw_apollofb = {
  450.     setup: fbcon_mfb_setup,
  451.     bmove: bmove_apollofb,
  452.     clear: clear_apollofb,
  453.     putc: putc_apollofb,
  454.     putcs: putcs_apollofb,
  455.     revc: rev_char_apollofb,
  456.     fontwidthmask: FONTWIDTH(8)
  457. };
  458. MODULE_LICENSE("GPL");