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

嵌入式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 <video/fbcon.h>
  20. #include <video/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       0x3b0          /* 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_3A   isaIO2mem(AP_IOBASE+0xe) /* Control Register 3a. Read/Write */
  40. #define AP_CONTROL_2    isaIO2mem(AP_IOBASE+0xc) /* Control Register 2. Read/Write */
  41. #define FRAME_BUFFER_START 0x0FA0000
  42. #define FRAME_BUFFER_LEN 0x40000
  43. /* CREG 0 */
  44. #define VECTOR_MODE 0x40 /* 010x.xxxx */
  45. #define DBLT_MODE   0x80 /* 100x.xxxx */
  46. #define NORMAL_MODE 0xE0 /* 111x.xxxx */
  47. #define SHIFT_BITS  0x1F /* xxx1.1111 */
  48.         /* other bits are Shift value */
  49. /* CREG 1 */
  50. #define AD_BLT      0x80 /* 1xxx.xxxx */
  51. #define NORMAL      0x80 /* 1xxx.xxxx */   /* What is happening here ?? */
  52. #define INVERSE     0x00 /* 0xxx.xxxx */   /* Clearing this reverses the screen */
  53. #define PIX_BLT     0x00 /* 0xxx.xxxx */
  54. #define AD_HIBIT        0x40 /* xIxx.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 2 */
  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. #if 0
  93. #define outb(a,d) *(char *)(a)=(d)
  94. #define outw(a,d) *(unsigned short *)a=d
  95. #endif
  96. /* frame buffer operations */
  97. static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con, 
  98.  struct fb_info *info);
  99. static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
  100.  struct fb_info *info);
  101. static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive,
  102.  struct fb_info *info);
  103. static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
  104.   struct fb_info *info);
  105. static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
  106.   struct fb_info *info);
  107. static int dnfbcon_switch(int con,struct fb_info *info);
  108. static int dnfbcon_updatevar(int con,struct fb_info *info);
  109. static void dnfbcon_blank(int blank,struct fb_info *info);
  110. static void dn_fb_set_disp(int con,struct fb_info *info);
  111. static struct display disp[MAX_NR_CONSOLES];
  112. static struct fb_info fb_info;
  113. static struct fb_ops dn_fb_ops = {
  114. owner: THIS_MODULE,
  115. fb_get_fix: dn_fb_get_fix,
  116. fb_get_var: dn_fb_get_var,
  117. fb_set_var: dn_fb_set_var,
  118. fb_get_cmap: dn_fb_get_cmap,
  119. fb_set_cmap: dn_fb_set_cmap,
  120. };
  121. static int currcon=0;
  122. #define NUM_TOTAL_MODES 1
  123. struct fb_var_screeninfo dn_fb_predefined[] = {
  124. { 0, },
  125. };
  126. static char dn_fb_name[]="Apollo ";
  127. /* accel stuff */
  128. #define USE_DN_ACCEL
  129. static struct display_switch dispsw_apollofb;
  130. static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
  131.  struct fb_info *info) {
  132. strcpy(fix->id,"Apollo Mono");
  133. fix->smem_start=(FRAME_BUFFER_START+IO_BASE);
  134. fix->smem_len=FRAME_BUFFER_LEN;
  135. fix->type=FB_TYPE_PACKED_PIXELS;
  136. fix->type_aux=0;
  137. fix->visual=FB_VISUAL_MONO10;
  138. fix->xpanstep=0;
  139. fix->ypanstep=0;
  140. fix->ywrapstep=0;
  141.         fix->line_length=256;
  142. return 0;
  143. }
  144.         
  145. static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
  146.  struct fb_info *info) {
  147. var->xres=1280;
  148. var->yres=1024;
  149. var->xres_virtual=2048;
  150. var->yres_virtual=1024;
  151. var->xoffset=0;
  152. var->yoffset=0;
  153. var->bits_per_pixel=1;
  154. var->grayscale=0;
  155. var->nonstd=0;
  156. var->activate=0;
  157. var->height=-1;
  158. var->width=-1;
  159. var->pixclock=0;
  160. var->left_margin=0;
  161. var->right_margin=0;
  162. var->hsync_len=0;
  163. var->vsync_len=0;
  164. var->sync=0;
  165. var->vmode=FB_VMODE_NONINTERLACED;
  166. return 0;
  167. }
  168. static int dn_fb_set_var(struct fb_var_screeninfo *var, int con,
  169.  struct fb_info *info) {
  170.         printk("fb_set_varn");
  171. if(var->xres!=1280) 
  172. return -EINVAL;
  173. if(var->yres!=1024)
  174. return -EINVAL;
  175. if(var->xres_virtual!=2048)
  176. return -EINVAL;
  177. if(var->yres_virtual!=1024)
  178. return -EINVAL;
  179. if(var->xoffset!=0)
  180. return -EINVAL;
  181. if(var->yoffset!=0)
  182. return -EINVAL;
  183. if(var->bits_per_pixel!=1)
  184. return -EINVAL;
  185. if(var->grayscale!=0)
  186. return -EINVAL;
  187. if(var->nonstd!=0)
  188. return -EINVAL;
  189. if(var->activate!=0)
  190. return -EINVAL;
  191. if(var->pixclock!=0)
  192. return -EINVAL;
  193. if(var->left_margin!=0)
  194. return -EINVAL;
  195. if(var->right_margin!=0)
  196. return -EINVAL;
  197. if(var->hsync_len!=0)
  198. return -EINVAL;
  199. if(var->vsync_len!=0)
  200. return -EINVAL;
  201. if(var->sync!=0)
  202. return -EINVAL;
  203. if(var->vmode!=FB_VMODE_NONINTERLACED)
  204. return -EINVAL;
  205. return 0;
  206. }
  207. static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
  208.   struct fb_info *info) {
  209. printk("get cmap not supportedn");
  210. return -EINVAL;
  211. }
  212. static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
  213.   struct fb_info *info) {
  214. printk("set cmap not supportedn");
  215. return -EINVAL;
  216. }
  217. static void dn_fb_set_disp(int con, struct fb_info *info) {
  218.   struct fb_fix_screeninfo fix;
  219.   struct display *display;
  220.   
  221.   dn_fb_get_fix(&fix,con, info);
  222.   if (con>=0)
  223. display=&fb_display[con];
  224.   else
  225. display=&disp[0];
  226.   if(con==-1) 
  227.     con=0;
  228.    display->screen_base = (u_char *)fix.smem_start;
  229.    display->visual = fix.visual;
  230.    display->type = fix.type;
  231.    display->type_aux = fix.type_aux;
  232.    display->ypanstep = fix.ypanstep;
  233.    display->ywrapstep = fix.ywrapstep;
  234.    display->can_soft_blank = 1;
  235.    display->inverse = 0;
  236.    display->line_length = fix.line_length;
  237. #ifdef FBCON_HAS_MFB
  238.    display->dispsw = &fbcon_mfb;
  239. #else
  240.    display->dispsw=&fbcon_dummy;
  241. #endif
  242. }
  243.   
  244. unsigned long __init dnfb_init(unsigned long mem_start) {
  245. int err;
  246.        
  247. fb_info.changevar=NULL;
  248. strcpy(&fb_info.modename[0],dn_fb_name);
  249. fb_info.fontname[0]=0;
  250. fb_info.disp=disp;
  251. fb_info.switch_con=&dnfbcon_switch;
  252. fb_info.updatevar=&dnfbcon_updatevar;
  253. fb_info.blank=&dnfbcon_blank;
  254. fb_info.node = -1;
  255. fb_info.fbops = &dn_fb_ops;
  256.         dn_fb_get_var(&disp[0].var,0, &fb_info);
  257. dn_fb_set_disp(-1, &fb_info);
  258. err=register_framebuffer(&fb_info);
  259. if(err < 0) {
  260. panic("unable to register apollo frame buffern");
  261. }
  262.  
  263. /* now we have registered we can safely setup the hardware */
  264.         outb(RESET_CREG,  AP_CONTROL_3A);
  265.         outw(0x0,  AP_WRITE_ENABLE);
  266.         outb(NORMAL_MODE, AP_CONTROL_0); 
  267.         outb((AD_BLT | DST_EQ_SRC | NORM_CREG1),  AP_CONTROL_1);
  268.         outb(S_DATA_PLN,  AP_CONTROL_2);
  269.         outw(SWAP(0x3), AP_ROP_1);
  270.         printk("apollo frame buffer alive and kicking !n");
  271. return mem_start;
  272. }
  273. static int dnfbcon_switch(int con,  struct fb_info *info) { 
  274. currcon=con;
  275. return 0;
  276. }
  277. static int dnfbcon_updatevar(int con,  struct fb_info *info) {
  278. return 0;
  279. }
  280. static void dnfbcon_blank(int blank,  struct fb_info *info) {
  281. if(blank)  {
  282.          outb(0x0,  AP_CONTROL_3A);
  283. }
  284. else {
  285.         outb(0x1,  AP_CONTROL_3A);
  286. }
  287. return ;
  288. }
  289. void dn_bitblt(struct display *p,int x_src,int y_src, int x_dest, int y_dest,
  290.                int x_count, int y_count) {
  291. int incr,y_delta,pre_read=0,x_end,x_word_count;
  292. ushort *src,dummy;
  293. uint start_mask,end_mask,dest;
  294. short i,j;
  295. incr=(y_dest<=y_src) ? 1 : -1 ;
  296. src=(ushort *)(p->screen_base+ y_src*p->next_line+(x_src >> 4));
  297. dest=y_dest*(p->next_line >> 1)+(x_dest >> 4);
  298. if(incr>0) {
  299. y_delta=(p->next_line*8)-x_src-x_count;
  300. x_end=x_dest+x_count-1;
  301. x_word_count=(x_end>>4) - (x_dest >> 4) + 1;
  302. start_mask=0xffff0000 >> (x_dest & 0xf);
  303. end_mask=0x7ffff >> (x_end & 0xf);
  304. outb((((x_dest & 0xf) - (x_src &0xf))  % 16)|(0x4 << 5),AP_CONTROL_0);
  305. if((x_dest & 0xf) < (x_src & 0xf))
  306. pre_read=1;
  307. }
  308. else {
  309. y_delta=-((p->next_line*8)-x_src-x_count);
  310. x_end=x_dest-x_count+1;
  311. x_word_count=(x_dest>>4) - (x_end >> 4) + 1;
  312. start_mask=0x7ffff >> (x_dest & 0xf);
  313. end_mask=0xffff0000 >> (x_end & 0xf);
  314. outb(((-((x_src & 0xf) - (x_dest &0xf))) % 16)|(0x4 << 5),AP_CONTROL_0);
  315. if((x_dest & 0xf) > (x_src & 0xf))
  316. pre_read=1;
  317. }
  318. for(i=0;i<y_count;i++) {
  319. outb(0xc | (dest >> 16), AP_CONTROL_3A);
  320. if(pre_read) {
  321. dummy=*src;
  322. src+=incr;
  323. }
  324. if(x_word_count) {
  325. outb(start_mask,AP_WRITE_ENABLE);
  326. *src=dest;
  327. src+=incr;
  328. dest+=incr;
  329. outb(0,AP_WRITE_ENABLE);
  330. for(j=1;j<(x_word_count-1);j++) {
  331. *src=dest;
  332. src+=incr;
  333. dest+=incr;
  334. }
  335. outb(start_mask,AP_WRITE_ENABLE);
  336. *src=dest;
  337. dest+=incr;
  338. src+=incr;
  339. }
  340. else {
  341. outb(start_mask | end_mask, AP_WRITE_ENABLE);
  342. *src=dest;
  343. dest+=incr;
  344. src+=incr;
  345. }
  346. src+=(y_delta/16);
  347. dest+=(y_delta/16);
  348. }
  349. outb(NORMAL_MODE,AP_CONTROL_0);
  350. }
  351. static void bmove_apollofb(struct display *p, int sy, int sx, int dy, int dx,
  352.       int height, int width)
  353. {
  354.     int fontheight,fontwidth;
  355.     fontheight=fontheight(p);
  356.     fontwidth=fontwidth(p);
  357. #ifdef USE_DN_ACCEL
  358.     dn_bitblt(p,sx,sy*fontheight,dx,dy*fontheight,width*fontwidth,
  359.       height*fontheight);
  360. #else
  361.     u_char *src, *dest;
  362.     u_int rows;
  363.     if (sx == 0 && dx == 0 && width == p->next_line) {
  364. src = p->screen_base+sy*fontheight*width;
  365. dest = p->screen_base+dy*fontheight*width;
  366. mymemmove(dest, src, height*fontheight*width);
  367.     } else if (dy <= sy) {
  368. src = p->screen_base+sy*fontheight*next_line+sx;
  369. dest = p->screen_base+dy*fontheight*next_line+dx;
  370. for (rows = height*fontheight; rows--;) {
  371.     mymemmove(dest, src, width);
  372.     src += p->next_line;
  373.     dest += p->next_line;
  374. }
  375.     } else {
  376. src = p->screen_base+((sy+height)*fontheight-1)*p->next_line+sx;
  377. dest = p->screen_base+((dy+height)*fontheight-1)*p->next_line+dx;
  378. for (rows = height*fontheight; rows--;) {
  379.     mymemmove(dest, src, width);
  380.     src -= p->next_line;
  381.     dest -= p->next_line;
  382. }
  383.     }
  384. #endif
  385. }
  386. static void clear_apollofb(struct vc_data *conp, struct display *p, int sy, int sx,
  387.       int height, int width)
  388. {
  389. fbcon_mfb_clear(conp,p,sy,sx,height,width);
  390. }
  391. static void putc_apollofb(struct vc_data *conp, struct display *p, int c, int yy,
  392.      int xx)
  393. {
  394. fbcon_mfb_putc(conp,p,c,yy,xx);
  395. }
  396. static void putcs_apollofb(struct vc_data *conp, struct display *p, const char *s,
  397.       int count, int yy, int xx)
  398. {
  399. fbcon_mfb_putcs(conp,p,s,count,yy,xx);
  400. }
  401. static void rev_char_apollofb(struct display *p, int xx, int yy)
  402. {
  403. fbcon_mfb_revc(p,xx,yy);
  404. }
  405. static struct display_switch dispsw_apollofb = {
  406.     setup: fbcon_mfb_setup,
  407.     bmove: bmove_apollofb,
  408.     clear: clear_apollofb,
  409.     putc: putc_apollofb,
  410.     putcs: putcs_apollofb,
  411.     revc: rev_char_apollofb,
  412.     fontwidthmask: FONTWIDTH(8)
  413. };
  414. MODULE_LICENSE("GPL");