#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/module.h>
#include <linux/slab.h>
+#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/page.h>
#include <linux/font.h>
-extern struct font_desc font_vga_8x16;
+extern unsigned long sgi_gfxaddr;
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
static unsigned char *font_data[MAX_NR_CONSOLES];
-extern struct newport_regs *npregs;
+static struct newport_regs *npregs;
static int logo_active;
static int topscan;
static int xcurs_correction = 29;
static int newport_xsize;
static int newport_ysize;
+static int newport_has_init;
+
+static int newport_set_def_font(int unit, struct console_font *op);
#define BMASK(c) (c << 24)
static inline void newport_render_background(int xstart, int ystart,
int xend, int yend, int ci)
{
- newport_wait();
+ newport_wait(npregs);
npregs->set.wrmask = 0xffffffff;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
unsigned short i;
for (i = 0; i < 16; i++) {
- newport_bfwait();
+ newport_bfwait(npregs);
newport_cmap_setaddr(npregs, color_table[i]);
newport_cmap_setrgb(npregs,
default_red[i],
}
}
+static void newport_show_logo(void)
+{
#ifdef CONFIG_LOGO_SGI_CLUT224
-static void newport_show_logo(void);
-#else
-#define newport_show_logo() do { } while (0)
-#endif
+ const struct linux_logo *logo = fb_find_logo(8);
+ const unsigned char *clut = logo->clut;
+ const unsigned char *data = logo->data;
+ unsigned long i;
+
+ for (i = 0; i < logo->clutsize; i++) {
+ newport_bfwait(npregs);
+ newport_cmap_setaddr(npregs, i + 0x20);
+ newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
+ clut += 3;
+ }
+
+ newport_wait(npregs);
+ npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+ NPORT_DMODE0_CHOST);
+
+ npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
+ npregs->set.xyendi = ((newport_xsize - 1) << 16);
+ newport_wait(npregs);
+
+ for (i = 0; i < logo->width*logo->height; i++)
+ npregs->go.hostrw0 = *data++ << 24;
+#endif /* CONFIG_LOGO_SGI_CLUT224 */
+}
static inline void newport_clear_screen(int xstart, int ystart, int xend,
int yend, int ci)
if (logo_active)
return;
- newport_wait();
+ newport_wait(npregs);
npregs->set.wrmask = 0xffffffff;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
}
-void newport_reset(void)
+static void newport_reset(void)
{
unsigned short treg;
int i;
- newport_wait();
+ newport_wait(npregs);
treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
newport_vc2_set(npregs, VC2_IREG_CONTROL,
(treg | VC2_CTRL_EVIDEO));
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
for (i = 0; i < 128; i++) {
- newport_bfwait();
+ newport_bfwait(npregs);
if (i == 92 || i == 94)
npregs->set.dcbdata0.byshort.s1 = 0xff00;
else
* calculate the actual screen size by reading
* the video timing out of the VC2
*/
-void newport_get_screensize(void)
+static void newport_get_screensize(void)
{
int i, cols;
unsigned short ventry, treg;
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
for (i = 0; i < 128; i++) {
- newport_bfwait();
+ newport_bfwait(npregs);
linetable[i] = npregs->set.dcbdata0.byshort.s1;
}
npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
do {
- newport_bfwait();
+ newport_bfwait(npregs);
treg = npregs->set.dcbdata0.byshort.s1;
if ((treg & 1) == 0)
cols += (treg >> 7) & 0xfe;
if ((treg & 0x80) == 0) {
- newport_bfwait();
+ newport_bfwait(npregs);
treg = npregs->set.dcbdata0.byshort.s1;
}
} while ((treg & 0x8000) == 0);
xcurs_correction = 21;
}
-#ifdef MODULE
-static const char *newport_startup(void)
-#else
-static const char *__init newport_startup(void)
-#endif
+static void newport_exit(void)
{
int i;
- struct newport_regs *p;
- npregs = (struct newport_regs *) (KSEG1 + 0x1f0f0000);
+ /* free memory used by user font */
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ newport_set_def_font(i, NULL);
+}
- p = npregs;
- p->cset.config = NPORT_CFG_GD0;
+/* Can't be __init, take_over_console may call it later */
+static const char *newport_startup(void)
+{
+ int i;
- if (newport_wait()) {
+ if (!sgi_gfxaddr)
return NULL;
- }
- p->set.xstarti = TESTVAL;
- if (p->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
- return NULL;
+ if (!npregs)
+ npregs = (struct newport_regs *)/* ioremap cannot fail */
+ ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
+ npregs->cset.config = NPORT_CFG_GD0;
+
+ if (newport_wait(npregs))
+ goto out_unmap;
+
+ npregs->set.xstarti = TESTVAL;
+ if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
+ goto out_unmap;
for (i = 0; i < MAX_NR_CONSOLES; i++)
font_data[i] = FONT_DATA;
newport_reset();
newport_get_revisions();
newport_get_screensize();
-
- /* gfx_init (display_desc); */
+ newport_has_init = 1;
return "SGI Newport";
+
+out_unmap:
+ return NULL;
}
static void newport_init(struct vc_data *vc, int init)
vc->vc_can_do_color = 1;
}
+static void newport_deinit(struct vc_data *c)
+{
+ if (!con_is_bound(&newport_con) && newport_has_init) {
+ newport_exit();
+ newport_has_init = 0;
+ }
+}
+
static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
int width)
{
(charattr & 0xf0) >> 4);
/* Set the color and drawing mode. */
- newport_wait();
+ newport_wait(npregs);
npregs->set.colori = charattr & 0xf;
npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
/* Set coordinates for bitmap operation. */
npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
npregs->set.xyendi = ((xpos + 7) << 16);
- newport_wait();
+ newport_wait(npregs);
/* Go, baby, go... */
RENDER(npregs, p);
xpos + ((count - 1) << 3), ypos,
(charattr & 0xf0) >> 4);
- newport_wait();
+ newport_wait(npregs);
/* Set the color and drawing mode. */
npregs->set.colori = charattr & 0xf;
for (i = 0; i < count; i++, xpos += 8) {
p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
- newport_wait();
+ newport_wait(npregs);
/* Set coordinates for bitmap operation. */
npregs->set.xystarti =
return 1;
}
-static int newport_blank(struct vc_data *c, int blank)
+static int newport_blank(struct vc_data *c, int blank, int mode_switch)
{
unsigned short treg;
return 1;
}
-static int newport_set_font(int unit, struct console_font_op *op)
+static int newport_set_font(int unit, struct console_font *op)
{
int w = op->width;
int h = op->height;
return 0;
}
-static int newport_set_def_font(int unit, struct console_font_op *op)
+static int newport_set_def_font(int unit, struct console_font *op)
{
if (font_data[unit] != FONT_DATA) {
if (--REFCOUNT(font_data[unit]) == 0)
return 0;
}
-static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
+static int newport_font_default(struct vc_data *vc, struct console_font *op, char *name)
{
- int unit = vc->vc_num;
-
- switch (op->op) {
- case KD_FONT_OP_SET:
- return newport_set_font(unit, op);
- case KD_FONT_OP_SET_DEFAULT:
- return newport_set_def_font(unit, op);
- default:
- return -ENOSYS;
- }
+ return newport_set_def_font(vc->vc_num, op);
+}
+
+static int newport_font_set(struct vc_data *vc, struct console_font *font, unsigned flags)
+{
+ return newport_set_font(vc->vc_num, font);
}
static int newport_set_palette(struct vc_data *vc, unsigned char *table)
xe = xs;
xs = tmp;
}
- newport_wait();
+ newport_wait(npregs);
npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
| NPORT_DMODE0_STOPY);
#define DUMMY (void *) newport_dummy
const struct consw newport_con = {
- .con_startup = newport_startup,
- .con_init = newport_init,
- .con_deinit = DUMMY,
- .con_clear = newport_clear,
- .con_putc = newport_putc,
- .con_putcs = newport_putcs,
- .con_cursor = newport_cursor,
- .con_scroll = newport_scroll,
- .con_bmove = newport_bmove,
- .con_switch = newport_switch,
- .con_blank = newport_blank,
- .con_font_op = newport_font_op,
- .con_set_palette = newport_set_palette,
- .con_scrolldelta = newport_scrolldelta,
- .con_set_origin = DUMMY,
- .con_save_screen = DUMMY
+ .owner = THIS_MODULE,
+ .con_startup = newport_startup,
+ .con_init = newport_init,
+ .con_deinit = newport_deinit,
+ .con_clear = newport_clear,
+ .con_putc = newport_putc,
+ .con_putcs = newport_putcs,
+ .con_cursor = newport_cursor,
+ .con_scroll = newport_scroll,
+ .con_bmove = newport_bmove,
+ .con_switch = newport_switch,
+ .con_blank = newport_blank,
+ .con_font_set = newport_font_set,
+ .con_font_default = newport_font_default,
+ .con_set_palette = newport_set_palette,
+ .con_scrolldelta = newport_scrolldelta,
+ .con_set_origin = DUMMY,
+ .con_save_screen = DUMMY
};
#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
+static int __init newport_console_init(void)
{
- if (!newport_startup())
- printk("Error loading SGI Newport Console driver\n");
- else
- printk("Loading SGI Newport Console Driver\n");
- take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
- return 0;
-}
-
-int cleanup_module(void)
-{
- int i;
+ if (!sgi_gfxaddr)
+ return NULL;
- printk("Unloading SGI Newport Console Driver\n");
- /* free memory used by user font */
- for (i = 0; i < MAX_NR_CONSOLES; i++)
- newport_set_def_font(i, NULL);
+ if (!npregs)
+ npregs = (struct newport_regs *)/* ioremap cannot fail */
+ ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
- return 0;
+ return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
}
-#endif
+module_init(newport_console_init);
-
-#ifdef CONFIG_LOGO_SGI_CLUT224
-
-#undef __initdata
-#define __initdata
-#include "../logo/logo_sgi_clut224.c"
-
-static void newport_show_logo(void)
+static void __exit newport_console_exit(void)
{
- const struct linux_logo *logo = &logo_sgi_clut224;
- const unsigned char *clut = logo->clut;
- const unsigned char *data = logo->data;
- unsigned long i;
-
- for (i = 0; i < logo->clutsize; i++) {
- newport_bfwait();
- newport_cmap_setaddr(npregs, i + 0x20);
- newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
- clut += 3;
- }
-
- newport_wait();
- npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
- NPORT_DMODE0_CHOST);
-
- npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
- npregs->set.xyendi = ((newport_xsize - 1) << 16);
- newport_wait();
-
- for (i = 0; i < logo->width*logo->height; i++)
- npregs->go.hostrw0 = *data++ << 24;
+ give_up_console(&newport_con);
+ iounmap((void *)npregs);
}
-#endif /* CONFIG_LOGO_SGI_CLUT224 */
+module_exit(newport_console_exit);
+#endif
+MODULE_LICENSE("GPL");