/* -*- linux-c -*- ------------------------------------------------------- *
 *
 *   Copyright (C) 1991, 1992 Linus Torvalds
 *   Copyright 2007 rPath, Inc. - All Rights Reserved
 *
 *   This file is part of the Linux kernel, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

/*
 * arch/i386/boot/video-vesa.c
 *
 * VESA text modes
 */

#include "boot.h"
#include "video.h"
#include "vesa.h"

/* VESA information */
static struct vesa_general_info vginfo;
static struct vesa_mode_info vminfo;

__videocard video_vesa;

static void vesa_store_mode_params_graphics(void);

static int vesa_probe(void)
{
#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
	u16 ax;
	u16 mode;
	addr_t mode_ptr;
	struct mode_info *mi;
	int nmodes = 0;

	video_vesa.modes = GET_HEAP(struct mode_info, 0);

	vginfo.signature = VBE2_MAGIC;

	/* Optimistically assume a VESA BIOS is register-clean... */
	ax = 0x4f00;
	asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));

	if (ax != 0x004f ||
	    vginfo.signature != VESA_MAGIC ||
	    vginfo.version < 0x0102)
		return 0;	/* Not present */
#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
#ifdef CONFIG_VIDEO_VESA
	set_fs(vginfo.video_mode_ptr.seg);
	mode_ptr = vginfo.video_mode_ptr.off;

	while ((mode = rdfs16(mode_ptr)) != 0xffff) {
		mode_ptr += 2;

		if (heap_free() < sizeof(struct mode_info))
			break;	/* Heap full, can't save mode info */

		if (mode & ~0x1ff)
			continue;

		memset(&vminfo, 0, sizeof vminfo); /* Just in case... */

		ax = 0x4f01;
		asm("int $0x10"
		    : "+a" (ax), "=m" (vminfo)
		    : "c" (mode), "D" (&vminfo));

		if (ax != 0x004f)
			continue;

		if ((vminfo.mode_attr & 0x15) == 0x05) {
			/* Text Mode, TTY BIOS supported,
			   supported by hardware */
			mi = GET_HEAP(struct mode_info, 1);
			mi->mode = mode + VIDEO_FIRST_VESA;
			mi->x    = vminfo.h_res;
			mi->y    = vminfo.v_res;
			nmodes++;
		} else if ((vminfo.mode_attr & 0x99) == 0x99) {
#ifdef CONFIG_FB
			/* Graphics mode, color, linear frame buffer
			   supported -- register the mode but hide from
			   the menu.  Only do this if framebuffer is
			   configured, however, otherwise the user will
			   be left without a screen. */
			mi = GET_HEAP(struct mode_info, 1);
			mi->mode = mode + VIDEO_FIRST_VESA;
			mi->x = mi->y = 0;
			nmodes++;
#endif
		}
	}

	return nmodes;
#else
	return 0;
#endif /* CONFIG_VIDEO_VESA */
}

static int vesa_set_mode(struct mode_info *mode)
{
	u16 ax;
	int is_graphic;
	u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;

	memset(&vminfo, 0, sizeof vminfo); /* Just in case... */

	ax = 0x4f01;
	asm("int $0x10"
	    : "+a" (ax), "=m" (vminfo)
	    : "c" (vesa_mode), "D" (&vminfo));

	if (ax != 0x004f)
		return -1;

	if ((vminfo.mode_attr & 0x15) == 0x05) {
		/* It's a supported text mode */
		is_graphic = 0;
	} else if ((vminfo.mode_attr & 0x99) == 0x99) {
		/* It's a graphics mode with linear frame buffer */
		is_graphic = 1;
		vesa_mode |= 0x4000; /* Request linear frame buffer */
	} else {
		return -1;	/* Invalid mode */
	}


	ax = 0x4f02;
	asm volatile("int $0x10"
		     : "+a" (ax)
		     : "b" (vesa_mode), "D" (0));

	if (ax != 0x004f)
		return -1;

	graphic_mode = is_graphic;
	if (!is_graphic) {
		/* Text mode */
		force_x = mode->x;
		force_y = mode->y;
		do_restore = 1;
	} else {
		/* Graphics mode */
		vesa_store_mode_params_graphics();
	}

	return 0;
}


/* Switch DAC to 8-bit mode */
static void vesa_dac_set_8bits(void)
{
	u8 dac_size = 6;

	/* If possible, switch the DAC to 8-bit mode */
	if (vginfo.capabilities & 1) {
		u16 ax, bx;

		ax = 0x4f08;
		bx = 0x0800;
		asm volatile(INT10
			     : "+a" (ax), "+b" (bx)
			     : : "ecx", "edx", "esi", "edi");

		if (ax == 0x004f)
			dac_size = bx >> 8;
	}

	/* Set the color sizes to the DAC size, and offsets to 0 */
	boot_params.screen_info.red_size = dac_size;
	boot_params.screen_info.green_size = dac_size;
	boot_params.screen_info.blue_size = dac_size;
	boot_params.screen_info.rsvd_size = dac_size;

	boot_params.screen_info.red_pos = 0;
	boot_params.screen_info.green_pos = 0;
	boot_params.screen_info.blue_pos = 0;
	boot_params.screen_info.rsvd_pos = 0;
}

/* Save the VESA protected mode info */
static void vesa_store_pm_info(void)
{
	u16 ax, bx, di, es;

	ax = 0x4f0a;
	bx = di = 0;
	asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
	    : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
	    : : "ecx", "esi");

	if (ax != 0x004f)
		return;

	boot_params.screen_info.vesapm_seg = es;
	boot_params.screen_info.vesapm_off = di;
}

/*
 * Save video mode parameters for graphics mode
 */
static void vesa_store_mode_params_graphics(void)
{
	/* Tell the kernel we're in VESA graphics mode */
	boot_params.screen_info.orig_video_isVGA = 0x23;

	/* Mode parameters */
	boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
	boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
	boot_params.screen_info.lfb_width = vminfo.h_res;
	boot_params.screen_info.lfb_height = vminfo.v_res;
	boot_params.screen_info.lfb_depth = vminfo.bpp;
	boot_params.screen_info.pages = vminfo.image_planes;
	boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
	memcpy(&boot_params.screen_info.red_size,
	       &vminfo.rmask, 8);

	/* General parameters */
	boot_params.screen_info.lfb_size = vginfo.total_memory;

	if (vminfo.bpp <= 8)
		vesa_dac_set_8bits();

	vesa_store_pm_info();
}

/*
 * Save EDID information for the kernel; this is invoked, separately,
 * after mode-setting.
 */
void vesa_store_edid(void)
{
#ifdef CONFIG_FIRMWARE_EDID
	u16 ax, bx, cx, dx, di;

	/* Apparently used as a nonsense token... */
	memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);

	if (vginfo.version < 0x0200)
		return;		/* EDID requires VBE 2.0+ */

	ax = 0x4f15;		/* VBE DDC */
	bx = 0x0000;		/* Report DDC capabilities */
	cx = 0;			/* Controller 0 */
	di = 0;			/* ES:DI must be 0 by spec */

	/* Note: The VBE DDC spec is different from the main VESA spec;
	   we genuinely have to assume all registers are destroyed here. */

	asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
	    : "+a" (ax), "+b" (bx)
	    :  "c" (cx), "D" (di)
	    : "esi");

	if (ax != 0x004f)
		return;		/* No EDID */

	/* BH = time in seconds to transfer EDD information */
	/* BL = DDC level supported */

	ax = 0x4f15;		/* VBE DDC */
	bx = 0x0001;		/* Read EDID */
	cx = 0;			/* Controller 0 */
	dx = 0;			/* EDID block number */
	di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
	asm(INT10
	    : "+a" (ax), "+b" (bx), "+d" (dx)
	    : "c" (cx), "D" (di)
	    : "esi");
#endif /* CONFIG_FIRMWARE_EDID */
}

__videocard video_vesa =
{
	.card_name	= "VESA",
	.probe		= vesa_probe,
	.set_mode	= vesa_set_mode,
	.xmode_first	= VIDEO_FIRST_VESA,
	.xmode_n	= 0x200,
};
