newport_con.c

来自「Linux内核源代码 为压缩文件 是<<Linux内核>&gt」· C语言 代码 · 共 615 行 · 第 1/2 页

C
615
字号
/* * newport_con.c: Abscon for newport hardware *  * (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de) * (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com) *  * This driver is based on sgicons.c and cons_newport. *  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) */#include <linux/init.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/tty.h>#include <linux/kd.h>#include <linux/selection.h>#include <linux/console.h>#include <linux/console_struct.h>#include <linux/vt_kern.h>#include <linux/mm.h>#include <linux/module.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/page.h>#include <asm/pgtable.h>#include <video/newport.h>#define INCLUDE_LINUX_LOGO_DATA#include <asm/linux_logo.h>#include <video/font.h>#define LOGO_W		80#define LOGO_H		80extern struct fbcon_font_desc font_vga_8x16;#define FONT_DATA ((unsigned char *)font_vga_8x16.data)extern struct newport_regs *npregs;static int logo_active;static int topscan;static int xcurs_correction = 29;static int newport_xsize;static int newport_ysize;#define BMASK(c) (c << 24)#define RENDER(regs, cp) do { \(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \} while(0)#define TESTVAL 0xdeadbeef#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)static inline void newport_render_background(int xstart, int ystart,					     int xend, int yend, int ci){    newport_wait();    npregs->set.wrmask = 0xffffffff;    npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX |			     NPORT_DMODE0_STOPY);    npregs->set.colori = ci;    npregs->set.xystarti = (xstart << 16) | ((ystart + topscan) & 0x3ff);    npregs->go.xyendi = ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);}static inline void newport_init_cmap(void){    unsigned short i;        for(i = 0; i < 16; i++) {	newport_bfwait();	newport_cmap_setaddr(npregs, color_table[i]);	newport_cmap_setrgb(npregs,			    default_red[i],			    default_grn[i],			    default_blu[i]);    }}static inline void newport_show_logo(void){    unsigned long i;    for(i = 0; i < LINUX_LOGO_COLORS; i++) {	newport_bfwait();	newport_cmap_setaddr(npregs, i + 0x20);	newport_cmap_setrgb(npregs,			    linux_logo_red[i],			    linux_logo_green[i],			    linux_logo_blue[i]);    }    newport_wait();    npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_CHOST);        npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);    npregs->set.xyendi = ((newport_xsize - 1) << 16);    newport_wait();    for (i = 0; i < LOGO_W * LOGO_H; i++)	npregs->go.hostrw0 = linux_logo[i] << 24;}static inline void newport_clear_screen(int xstart, int ystart, int xend,					int yend, int ci) {    if (logo_active)	return;    newport_wait();    npregs->set.wrmask = 0xffffffff;    npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |			     NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX |			     NPORT_DMODE0_STOPY);    npregs->set.colori = ci;    npregs->set.xystarti = (xstart << 16) | ystart;    npregs->go.xyendi = (xend << 16) | yend;}static inline void newport_clear_lines(int ystart, int yend, int ci){    ystart = ((ystart << 4) + topscan) & 0x3ff;    yend = ((yend << 4) + topscan + 15) & 0x3ff;        newport_clear_screen (0, ystart, 1280+63, yend, ci);}void newport_reset (void){    unsigned short treg;        int i;        newport_wait();    treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);    newport_vc2_set(npregs, VC2_IREG_CONTROL, (treg | VC2_CTRL_EVIDEO));    treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);    newport_vc2_set(npregs, VC2_IREG_RADDR, treg);    npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |			   NPORT_DMODE_W2 | VC2_PROTOCOL);    for(i = 0; i < 128; i++) {	newport_bfwait();	if (i == 92 || i == 94)	    npregs->set.dcbdata0.byshort.s1 = 0xff00;	else	    npregs->set.dcbdata0.byshort.s1 = 0x0000;    }    newport_init_cmap();    /* turn off popup plane */    npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |                           XM9_CRS_CONFIG | NPORT_DMODE_W1);    npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;    npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |                           XM9_CRS_CONFIG | NPORT_DMODE_W1);    npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;        topscan = 0;    npregs->cset.topscan = 0x3ff;    npregs->cset.xywin = (4096 << 16) | 4096;    /* Clear the screen. */    newport_clear_screen(0,0,1280+63,1024,0);}/* * calculate the actual screen size by reading * the video timing out of the VC2 */void newport_get_screensize(void){    int i,cols;    unsigned short ventry,treg;    unsigned short linetable[128]; /* should be enough */    ventry = newport_vc2_get (npregs, VC2_IREG_VENTRY);    newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);    npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |			   NPORT_DMODE_W2 | VC2_PROTOCOL);    for(i = 0; i < 128; i++) {	newport_bfwait();	linetable[i] = npregs->set.dcbdata0.byshort.s1;    }    newport_xsize = newport_ysize = 0;    for (i = 0; linetable[i+1] && (i < sizeof(linetable)); i+=2) {	cols = 0;        newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);        npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |			       NPORT_DMODE_W2 | VC2_PROTOCOL);	do {	    newport_bfwait();	    treg = npregs->set.dcbdata0.byshort.s1;	    if ((treg & 1) == 0)		cols += (treg >> 7) & 0xfe;	    if ((treg & 0x80) == 0) {		newport_bfwait();		treg = npregs->set.dcbdata0.byshort.s1;	    } 	} while ((treg & 0x8000) == 0);	if (cols) {	    if (cols > newport_xsize)		newport_xsize = cols;	    newport_ysize += linetable[i+1];	}    }    printk ("NG1: Screensize %dx%d\n",newport_xsize,newport_ysize);}static void newport_get_revisions(void){    unsigned int tmp;    unsigned int board_rev;    unsigned int rex3_rev;    unsigned int vc2_rev;    unsigned int cmap_rev;    unsigned int xmap9_rev;    unsigned int bt445_rev;    unsigned int bitplanes;    rex3_rev = npregs->cset.status & NPORT_STAT_VERS;    npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |                           NCMAP_REGADDR_RREG | NPORT_DMODE_W1);    tmp = npregs->set.dcbdata0.bybytes.b3;    cmap_rev = tmp & 7;    board_rev = (tmp >> 4) & 7;    bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;     npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |                           NCMAP_REGADDR_RREG | NPORT_DMODE_W1);    tmp = npregs->set.dcbdata0.bybytes.b3;    if ((tmp & 7) < cmap_rev)	cmap_rev = (tmp & 7);    vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;    npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |                           XM9_CRS_REVISION | NPORT_DMODE_W1);    xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;    npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |                           BT445_CSR_ADDR_REG | NPORT_DMODE_W1);    npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;    npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |                           BT445_CSR_REVISION | NPORT_DMODE_W1);    bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;#define L(a)     (char)('A'+(a))    printk ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",	    board_rev,bitplanes,L(rex3_rev),L(vc2_rev), L(xmap9_rev),	    L(cmap_rev ? (cmap_rev+1):0),L(bt445_rev));#undef L    if (board_rev == 3) /* I don't know all affected revisions */	xcurs_correction = 21;}#ifdef MODULEstatic const char *newport_startup(void)#elsestatic const char * __init newport_startup(void)#endif{    struct newport_regs *p;    npregs = (struct newport_regs *) (KSEG1 + 0x1f0f0000);	    p = npregs;    p->cset.config = NPORT_CFG_GD0;    if(newport_wait()) {	return NULL;    }    p->set.xstarti = TESTVAL; if(p->set._xstart.word != XSTI_TO_FXSTART(TESTVAL)) {	return NULL;    }    newport_reset ();    newport_get_revisions();    newport_get_screensize();    // gfx_init (display_desc);        return "SGI Newport";}static void newport_init(struct vc_data *vc, int init){    vc->vc_cols = newport_xsize / 8;    vc->vc_rows = newport_ysize / 16;    vc->vc_can_do_color = 1;}static void newport_clear(struct vc_data *vc, int sy, int sx, int height, int width)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?