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

Linux/Unix编程

开发平台:

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