/* -*- 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, cx, di;
	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;

	ax = 0x4f00;
	di = (size_t)&vginfo;
	asm(INT10
	    : "+a" (ax), "+D" (di), "=m" (vginfo)
	    : : "ebx", "ecx", "edx", "esi");

	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;
		cx = mode;
		di = (size_t)&vminfo;
		asm(INT10
		    : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
		    : : "ebx", "edx", "esi");

		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, bx, cx, di;
	int is_graphic;
	u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;

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

	ax = 0x4f01;
	cx = vesa_mode;
	di = (size_t)&vminfo;
	asm(INT10
	    : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
	    : : "ebx", "edx", "esi");

	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;
	bx = vesa_mode;
	di = 0;
	asm volatile(INT10
		     : "+a" (ax), "+b" (bx), "+D" (di)
		     : : "ecx", "edx", "esi");

	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), "=m" (boot_params.edid_info)
	    : "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,
};
