/*
* linux/drivers/video/console/sticore.c -
* core code for console driver using HP's STI firmware
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*
* TODO:
* - call STI in virtual mode rather than in real mode
* - screen blanking with state_mgmt() in text mode STI ?
* - try to make it work on m68k hp workstations ;)
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/font.h>
#include <asm/hardware.h>
#include <asm/page.h>
#include <asm/parisc-device.h>
#include <asm/pdc.h>
#include <asm/cacheflush.h>
#include <asm/grfioctl.h>
#include "../fbdev/sticore.h"
#define STI_DRIVERVERSION "Version 0.9b"
static struct sti_struct *default_sti __read_mostly;
/* number of STI ROMS found and their ptrs to each struct */
static int num_sti_roms __read_mostly;
static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly;
/* The colour indices used by STI are
* 0 - Black
* 1 - White
* 2 - Red
* 3 - Yellow/Brown
* 4 - Green
* 5 - Cyan
* 6 - Blue
* 7 - Magenta
*
* So we have the same colours as VGA (basically one bit each for R, G, B),
* but have to translate them, anyway. */
static const u8 col_trans[8] = {
0, 6, 4, 5,
2, 7, 3, 1
};
#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
#define c_bg(sti, c) col_trans[((c>>11) & 7)]
#define c_index(sti, c) ((c) & 0xff)
static const struct sti_init_flags default_init_flags = {
.wait = STI_WAIT,
.reset = 1,
.text = 1,
.nontext = 1,
.no_chg_bet = 1,
.no_chg_bei = 1,
.init_cmap_tx = 1,
};
static int sti_init_graph(struct sti_struct *sti)
{
struct sti_init_inptr *inptr = &sti->sti_data->init_inptr;
struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext;
struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;
unsigned long flags;
int ret, err;
spin_lock_irqsave(&sti->lock, flags);
memset(inptr, 0, sizeof(*inptr));
inptr->text_planes = 3; /* # of text planes (max 3 for STI) */
memset(inptr_ext, 0, sizeof(*inptr_ext));
inptr->ext_ptr = STI_PTR(inptr_ext);
outptr->errno = 0;
ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr,
outptr, sti->glob_cfg);
if (ret >= 0)
sti->text_planes = outptr->text_planes;
err = outptr->errno;
spin_unlock_irqrestore(&sti->lock, flags);
if (ret < 0) {
pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
return -1;
}
return 0;
}
static const struct sti_conf_flags default_conf_flags = {
.wait = STI_WAIT,
};
static void sti_inq_conf(struct sti_struct *sti)
{
struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr;
struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;
unsigned long flags;
s32 ret;
outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
do {
spin_lock_irqsave(&sti->lock, flags);
memset(inptr, 0, sizeof(*inptr));
ret = sti_call(sti, sti->inq_conf, &default_conf_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1);
}
static const struct sti_font_flags default_font_flags = {
.wait = STI_WAIT,
.non_text =