/*
 *  linux/drivers/video/console/sticon.c - console driver using HP's STI firmware
 *
 *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
 *	Copyright (C) 2002-2020 Helge Deller <deller@gmx.de>
 *
 *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
 *  which were
 *
 *	Created 28 Sep 1997 by Geert Uytterhoeven
 *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
 *	Copyright (C) 1991, 1992  Linus Torvalds
 *			    1995  Jay Estabrook
 *	Copyright (C) 1995 Geert Uytterhoeven
 *	Copyright (C) 1993 Bjoern Brauel
 *			   Roman Hodek
 *	Copyright (C) 1993 Hamish Macdonald
 *			   Greg Harp
 *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
 *
 *	      with work by William Rucklidge (wjr@cs.cornell.edu)
 *			   Geert Uytterhoeven
 *			   Jes Sorensen (jds@kom.auc.dk)
 *			   Martin Apel
 *	      with work by Guenther Kelleter
 *			   Martin Schaller
 *			   Andreas Schwab
 *			   Emmanuel Marty (core@ggi-project.org)
 *			   Jakub Jelinek (jj@ultra.linux.cz)
 *			   Martin Mares <mj@ucw.cz>
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of this archive for
 *  more details.
 *
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/vt_kern.h>
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/font.h>
#include <linux/crc32.h>

#include <asm/io.h>

#include "../fbdev/sticore.h"

/* switching to graphics mode */
#define BLANK 0
static int vga_is_gfx;

#define STI_DEF_FONT	sticon_sti->font

/* borrowed from fbcon.c */
#define FNTREFCOUNT(fd)	(fd->refcount)
#define FNTCRC(fd)	(fd->crc)
static struct sti_cooked_font *font_data[MAX_NR_CONSOLES];

/* this is the sti_struct used for this console */
static struct sti_struct *sticon_sti;

static const char *sticon_startup(void)
{
    return "STI console";
}

static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
{
    if (vga_is_gfx || console_blanked)
	    return;

    if (conp->vc_mode != KD_TEXT)
    	    return;

    sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]);
}

static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
			 int count, int ypos, int xpos)
{
    if (vga_is_gfx || console_blanked)
	    return;

    if (conp->vc_mode != KD_TEXT)
    	    return;

    while (count--) {
	sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++,
		 font_data[conp->vc_num]);
    }
}

static void sticon_cursor(struct vc_data *conp, int mode)
{
    unsigned short car1;

    /* no cursor update if screen is blanked */
    if (vga_is_gfx || console_blanked)
	return;

    car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
    switch (mode) {
    case CM_ERASE:
	sti_putc(sticon_sti, car1, conp->state.y, conp->state.x,
		 font_data[conp->vc_num]);
	break;
    case CM_MOVE:
    case CM_DRAW:
	switch (CUR_SIZE(conp->vc_cursor_type)) {
	case CUR_UNDERLINE:
	case CUR_LOWER_THIRD:
	case CUR_LOWER_HALF:
	case CUR_TWO_THIRDS:
	case CUR_BLOCK:
	    sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
		     conp->state.y, conp->state.x, font_data[conp->vc_num]);
	    break;
	}
	break;
    }
}

static bool sticon_scroll(struct vc_data *conp, unsigned int t,
		unsigned int b, enum con_scroll dir, unsigned int count)
{
    struct sti_struct *sti = sticon_sti;

    if (vga_is_gfx)
        return false;

    sticon_cursor(conp, CM_ERASE);

    switch (dir) {
    case SM_UP:
	sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols,
		  font_data[conp->vc_num]);
	sti_clear(sti, b - count, 0, count, conp->vc_cols,
		  conp->vc_video_erase_char, font_data[conp->vc_num]);
	break;

    case SM_DOWN:
	sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols,
		  font_data[conp->vc_num]);
	sti_clear(sti, t, 0, count, conp->vc_cols,
		  conp->vc_video_erase_char, font_data[conp->vc_num]);
	break;
    }

    return false;
}

static int sticon_set_def_font(int unit, struct console_font *op)
{
	if (font_data[unit] != STI_DEF_FONT) {
		if (--FNTREFCOUNT(font_data[unit]) == 0) {
			kfree(font_data[unit]->raw_ptr);
			kfree(font_data[unit]);
		}
		font_data[unit] = STI_DEF_FONT;
	}

	return 0;
}

static int sticon_set_font(struct vc_data *vc, struct console_font *op)
{
	struct sti_struct *sti = sticon_sti;
	int vc_cols, vc_rows, vc_old_cols, vc_old_rows;
	int unit = vc->vc_num;
	int w = op->width;
	int h = op->height;
	int size, i, bpc, pitch;
	struct sti_rom_font *new_font;
	struct sti_cooked_font *cooked_font;
	unsigned char *data = op->data, *p;

	if ((w < 6) || (h < 6) || (w > 32) || (h > 32)
	    || (op->charcount != 256 && op->charcount != 512))
		return -EINVAL;
	pitch = ALIGN(w, 8) / 8;
	bpc = pitch * h;
	size = bpc * op->charcount;

	new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM);
	if (!new_font)
		return -ENOMEM;

	new_font->first_char = 0;
	new_font->last_char = op->charcount - 1;
	new_font->width = w;
	new_font->height = h;
	new_font->font_type = STI_FONT_HPROMAN8;
	new_font->bytes_per_char = bpc;
	new_font->underline_height = 0;
	new_font->underline_pos = 0;

	cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
	if (!cooked_font) {
		kfree(new_font);
		return -ENOMEM;
	}
	cooked_font->raw = new_font;
	cooked_font->raw_ptr = new_font;
	cooked_font->width = w;
	cooked_font->height = h;
	FNTREFCOUNT(cooked_font) = 0;	/* usage counter */

	p = (unsigned char *) new_font;
	p += sizeof(*new_font);
	for (i = 0; i < op->charcount; i++) {
		memcpy(p, data, bpc);
		data += pitch*32;
		p += bpc;
	}
	FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font));
	sti_font_convert_bytemode(sti, cooked_font);
	new_font = cooked_font->raw_ptr;

	/* check if font is already used by other console */
	for (i = 0; i < MAX_NR_CONSOLES; i++) {
		if (font_data[i] != STI_DEF_FONT
		    && (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) {
			kfree(new_font);
			kfree(cooked_font);
			/* current font is the same as the new one */
			if (i == unit)
				return 0;
			cooked_font = font_data[i];
			new_font = cooked_font->raw_ptr;
			break;
		}
	}

	/* clear screen with old font: we now may have less rows */
	vc_old_rows = vc->vc_rows;
	vc_old_cols = vc->vc_cols;
	sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols,
		  vc->vc_video_erase_char, font_data[vc->vc_num]);

	/* delete old font in case it is a user font */
	sticon_set_def_font(unit, NULL);

	FNTREFCOUNT(cooked_font)++;
	font_data[unit] = cooked_font;

	vc_cols = sti_onscreen_x(sti) / cooked_font->width;
	vc_rows = sti_onscreen_y(sti) / cooked_font->height;
	vc_resize(vc, vc_cols, vc_rows);

	/* need to repaint screen if cols & rows are same as old font */
	if (vc_cols == vc_old_cols && vc_rows == vc_old_rows)
		update_screen(vc);

	return 0;
}

static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name)
{
	return sticon_set_def_font(vc->vc_num, op);
}

static int sticon_font_set(struct vc_data *vc, struct console_font *font,
			   unsigned int flags)
{
	return sticon_set_font(vc, font);
}

static void sticon_init(struct vc_data *c, int init)
{
    struct sti_struct *sti = sticon_sti;
    int vc_cols, vc_rows;

    sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
    vc_cols = sti_onscreen_x(sti) / sti->font->width;
    vc_rows = sti_onscreen_y(sti) / sti->font->height;
    c->vc_can_do_color = 1;
    
    if (init) {
	c->vc_cols = vc_cols;
	c->vc_rows = vc_rows;
    } else {
	vc_resize(c, vc_cols, vc_rows);
    }
}

static void sticon_deinit(struct vc_data *c)
{
    int i;

    /* free memory used by user font */
    for (i = 0; i < MAX_NR_CONSOLES; i++)
	sticon_set_def_font(i, NULL);
}

static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
			 int width)
{
    if (!height || !width)
	return;

    sti_clear(sticon_sti, sy, sx, height, width,
	      conp->vc_video_erase_char, font_data[conp->vc_num]);
}

static int sticon_switch(struct vc_data *conp)
{
    return 1;	/* needs refreshing */
}

static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
{
    if (blank == 0) {
	if (mode_switch)
	    vga_is_gfx = 0;
	return 1;
    }
    sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK,
	      font_data[c->vc_num]);
    if (mode_switch)
	vga_is_gfx = 1;
    return 1;
}

static u8 sticon_build_attr(struct vc_data *conp, u8 color,
			    enum vc_intensity intens,
			    bool blink, bool underline, bool reverse,
			    bool italic)
{
    u8 attr = ((color & 0x70) >> 1) | ((color & 7));

    if (reverse) {
	color = ((color >> 3) & 0x7) | ((color & 0x7) << 3);
    }

    return attr;
}

static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
{
    int col = 1; /* vga_can_do_color; */

    while (count--) {
	u16 a = scr_readw(p);

	if (col)
		a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
	else
		a = ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;

	scr_writew(a, p++);
    }
}

static const struct consw sti_con = {
	.owner			= THIS_MODULE,
	.con_startup		= sticon_startup,
	.con_init		= sticon_init,
	.con_deinit		= sticon_deinit,
	.con_clear		= sticon_clear,
	.con_putc		= sticon_putc,
	.con_putcs		= sticon_putcs,
	.con_cursor		= sticon_cursor,
	.con_scroll		= sticon_scroll,
	.con_switch		= sticon_switch,
	.con_blank		= sticon_blank,
	.con_font_set		= sticon_font_set,
	.con_font_default	= sticon_font_default,
	.con_build_attr		= sticon_build_attr,
	.con_invert_region	= sticon_invert_region, 
};



static int __init sticonsole_init(void)
{
    int err, i;

    /* already initialized ? */
    if (sticon_sti)
	 return 0;

    sticon_sti = sti_get_rom(0);
    if (!sticon_sti)
	return -ENODEV;

    for (i = 0; i < MAX_NR_CONSOLES; i++)
	font_data[i] = STI_DEF_FONT;

    pr_info("sticon: Initializing STI text console.\n");
    console_lock();
    err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1,
		PAGE0->mem_cons.cl_class != CL_DUPLEX);
    console_unlock();

    return err;
}

module_init(sticonsole_init);
MODULE_LICENSE("GPL");
