// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2014 Google, Inc
 *
 * From coreboot, originally based on the Linux kernel (drivers/pci/pci.c).
 *
 * Modifications are:
 * Copyright (C) 2003-2004 Linux Networx
 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
 * Copyright (C) 2003-2006 Ronald G. Minnich <rminnich@gmail.com>
 * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov>
 * Copyright (C) 2005-2006 Tyan
 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
 * Copyright (C) 2005-2009 coresystems GmbH
 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
 *
 * PCI Bus Services, see include/linux/pci.h for further explanation.
 *
 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
 * David Mosberger-Tang
 *
 * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
 */

#define LOG_CATEGORY UCLASS_PCI

#include <common.h>
#include <bios_emul.h>
#include <bootstage.h>
#include <dm.h>
#include <errno.h>
#include <init.h>
#include <log.h>
#include <malloc.h>
#include <pci.h>
#include <pci_rom.h>
#include <vbe.h>
#include <video.h>
#include <video_fb.h>
#include <acpi/acpi_s3.h>
#include <linux/screen_info.h>

DECLARE_GLOBAL_DATA_PTR;

__weak bool board_should_run_oprom(struct udevice *dev)
{
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_ACPI_RESUME)
	if (gd->arch.prev_sleep_state == ACPI_S3) {
		if (IS_ENABLED(CONFIG_S3_VGA_ROM_RUN))
			return true;
		else
			return false;
	}
#endif

	return true;
}

__weak bool board_should_load_oprom(struct udevice *dev)
{
	return true;
}

__weak uint32_t board_map_oprom_vendev(uint32_t vendev)
{
	return vendev;
}

static int pci_rom_probe(struct udevice *dev, struct pci_rom_header **hdrp)
{
	struct pci_child_plat *pplat = dev_get_parent_plat(dev);
	struct pci_rom_header *rom_header;
	struct pci_rom_data *rom_data;
	u16 rom_vendor, rom_device;
	u32 rom_class;
	u32 vendev;
	u32 mapped_vendev;
	u32 rom_address;

	vendev = pplat->vendor << 16 | pplat->device;
	mapped_vendev = board_map_oprom_vendev(vendev);
	if (vendev != mapped_vendev)
		debug("Device ID mapped to %#08x\n", mapped_vendev);

#ifdef CONFIG_VGA_BIOS_ADDR
	rom_address = CONFIG_VGA_BIOS_ADDR;
#else

	dm_pci_read_config32(dev, PCI_ROM_ADDRESS, &rom_address);
	if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
		debug("%s: rom_address=%x\n", __func__, rom_address);
		return -ENOENT;
	}

	/* Enable expansion ROM address decoding. */
	dm_pci_write_config32(dev, PCI_ROM_ADDRESS,
			      rom_address | PCI_ROM_ADDRESS_ENABLE);
#endif
	debug("Option ROM address %x\n", rom_address);
	rom_header = (struct pci_rom_header *)(unsigned long)rom_address;

	debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n",
	      le16_to_cpu(rom_header->signature),
	      rom_header->size * 512, le16_to_cpu(rom_header->data));

	if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
		printf("Incorrect expansion ROM header signature %04x\n",
		       le16_to_cpu(rom_header->signature));
#ifndef CONFIG_VGA_BIOS_ADDR
		/* Disable expansion ROM address decoding */
		dm_pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address);
#endif
		return -EINVAL;
	}

	rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data));
	rom_vendor = le16_to_cpu(rom_data->vendor);
	rom_device = le16_to_cpu(rom_data->device);

	debug("PCI ROM image, vendor ID %04x, device ID %04x,\n",
	      rom_vendor, rom_device);

	/* If the device id is mapped, a mismatch is expected */
	if ((pplat->vendor != rom_vendor || pplat->device != rom_device) &&
	    (vendev == mapped_vendev)) {
		printf("ID mismatch: vendor ID %04x, device ID %04x\n",
		       rom_vendor, rom_device);
		/* Continue anyway */
	}

	rom_class = (le16_to_cpu(rom_data->class_hi) << 8) | rom_data->class_lo;
	debug("PCI ROM image, Class Code %06x, Code Type %02x\n",
	      rom_class, rom_data->type);

	if (pplat->class != rom_class) {
		debug("Class Code mismatch ROM %06x, dev %06x\n",
		      rom_class, pplat->class);
	}
	*hdrp = rom_header;

	return 0;
}

/**
 * pci_rom_load() - Load a ROM image and return a pointer to it
 *
 * @rom_header:		Pointer to ROM image
 * @ram_headerp:	Returns a pointer to the image in RAM
 * @allocedp:		Returns true if @ram_headerp was allocated and needs
 *			to be freed
 * @return 0 if OK, -ve on error. Note that @allocedp is set up regardless of
 * the error state. Even if this function returns an error, it may have
 * allocated memory.
 */
static int pci_rom_load(struct pci_rom_header *rom_header,
			struct pci_rom_header **ram_headerp, bool *allocedp)
{
	struct pci_rom_data *rom_data;
	unsigned int rom_size;
	unsigned int image_size = 0;
	void *target;

	*allocedp = false;
	do {
		/* Get next image, until we see an x86 version */
		rom_header = (struct pci_rom_header *)((void *)rom_header +
							    image_size);

		rom_data = (struct pci_rom_data *)((void *)rom_header +
				le16_to_cpu(rom_header->data));

		image_size = le16_to_cpu(rom_data->ilen) * 512;
	} while ((rom_data->type != 0) && (rom_data->indicator == 0));

	if (rom_data->type != 0)
		return -EACCES;

	rom_size = rom_header->size * 512;

#ifdef PCI_VGA_RAM_IMAGE_START
	target = (void *)PCI_VGA_RAM_IMAGE_START;
#else
	target = (void *)malloc(rom_size);
	if (!target)
		return -ENOMEM;
	*allocedp = true;
#endif
	if (target != rom_header) {
		ulong start = get_timer(0);

		debug("Copying VGA ROM Image from %p to %p, 0x%x bytes\n",
		      rom_header, target, rom_size);
		memcpy(target, rom_header, rom_size);
		if (memcmp(target, rom_header, rom_size)) {
			printf("VGA ROM copy failed\n");
			return -EFAULT;
		}
		debug("Copy took %lums\n", get_timer(start));
	}
	*ram_headerp = target;

	return 0;
}

struct vbe_mode_info mode_info;

void setup_video(struct screen_info *screen_info)
{
	struct vesa_mode_info *vesa = &mode_info.vesa;

	/* Sanity test on VESA parameters */
	if (!vesa->x_resolution || !vesa->y_resolution)
		return;

	screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB;

	screen_info->lfb_width = vesa->x_resolution;
	screen_info->lfb_height = vesa->y_resolution;
	screen_info->lfb_depth = vesa->bits_per_pixel;
	screen_info->lfb_linelength = vesa->bytes_per_scanline;
	screen_info->lfb_base = vesa->phys_base_ptr;
	screen_info->lfb_size =
		ALIGN(screen_info->lfb_linelength * screen_info->lfb_height,
		      65536);
	screen_info->lfb_size >>= 16;
	screen_info->red_size = vesa->red_mask_size;
	screen_info->red_pos = vesa->red_mask_pos;
	screen_info->green_size = vesa->green_mask_size;
	screen_info->green_pos = vesa->green_mask_pos;
	screen_info->blue_size = vesa->blue_mask_size;
	screen_info->blue_pos = vesa->blue_mask_pos;
	screen_info->rsvd_size = vesa->reserved_mask_size;
	screen_info->rsvd_pos = vesa->reserved_mask_pos;
}

int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void),
			int exec_method)
{
	struct pci_child_plat *pplat = dev_get_parent_plat(dev);
	struct pci_rom_header *rom = NULL, *ram = NULL;
	int vesa_mode = -1;
	bool emulate, alloced;
	int ret;

	/* Only execute VGA ROMs */
	if (((pplat->class >> 8) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) {
		debug("%s: Class %#x, should be %#x\n", __func__, pplat->class,
		      PCI_CLASS_DISPLAY_VGA);
		return -ENODEV;
	}

	if (!board_should_load_oprom(dev))
		return log_msg_ret("Should not load OPROM", -ENXIO);

	ret = pci_rom_probe(dev, &rom);
	if (ret)
		return ret;

	ret = pci_rom_load(rom, &ram, &alloced);
	if (ret)
		goto err;

	if (!board_should_run_oprom(dev)) {
		ret = -ENXIO;
		goto err;
	}

#if defined(CONFIG_FRAMEBUFFER_SET_VESA_MODE) && \
		defined(CONFIG_FRAMEBUFFER_VESA_MODE)
	vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE;
#endif
	debug("Selected vesa mode %#x\n", vesa_mode);

	if (exec_method & PCI_ROM_USE_NATIVE) {
#ifdef CONFIG_X86
		emulate = false;
#else
		if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
			printf("BIOS native execution is only available on x86\n");
			ret = -ENOSYS;
			goto err;
		}
		emulate = true;
#endif
	} else {
#ifdef CONFIG_BIOSEMU
		emulate = true;
#else
		if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
			printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
			ret = -ENOSYS;
			goto err;
		}
		emulate = false;
#endif
	}

	if (emulate) {
#ifdef CONFIG_BIOSEMU
		BE_VGAInfo *info;

		ret = biosemu_setup(dev, &info);
		if (ret)
			goto err;
		biosemu_set_interrupt_handler(0x15, int15_handler);
		ret = biosemu_run(dev, (uchar *)ram, 1 << 16, info,
				  true, vesa_mode, &mode_info);
		if (ret)
			goto err;
#endif
	} else {
#if defined(CONFIG_X86) && (CONFIG_IS_ENABLED(X86_32BIT_INIT) || CONFIG_TPL)
		bios_set_interrupt_handler(0x15, int15_handler);

		bios_run_on_x86(dev, (unsigned long)ram, vesa_mode,
				&mode_info);
#endif
	}
	debug("Final vesa mode %#x\n", mode_info.video_mode);
	ret = 0;

err:
	if (alloced)
		free(ram);
	return ret;
}

#ifdef CONFIG_DM_VIDEO
int vbe_setup_video_priv(struct vesa_mode_info *vesa,
			 struct video_priv *uc_priv,
			 struct video_uc_plat *plat)
{
	if (!vesa->x_resolution)
		return log_msg_ret("No x resolution", -ENXIO);
	uc_priv->xsize = vesa->x_resolution;
	uc_priv->ysize = vesa->y_resolution;
	uc_priv->line_length = vesa->bytes_per_scanline;
	switch (vesa->bits_per_pixel) {
	case 32:
	case 24:
		uc_priv->bpix = VIDEO_BPP32;
		break;
	case 16:
		uc_priv->bpix = VIDEO_BPP16;
		break;
	default:
		return -EPROTONOSUPPORT;
	}

	/* Use double buffering if enabled */
	if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
		if (!plat->base)
			return log_msg_ret("copy", -ENFILE);
		plat->copy_base = vesa->phys_base_ptr;
	} else {
		plat->base = vesa->phys_base_ptr;
	}
	log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
	plat->size = vesa->bytes_per_scanline * vesa->y_resolution;

	return 0;
}

int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
{
	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
	int ret;

	/* If we are running from EFI or coreboot, this can't work */
	if (!ll_boot_init()) {
		printf("Not available (previous bootloader prevents it)\n");
		return -EPERM;
	}
	bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display");
	ret = dm_pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE |
					PCI_ROM_ALLOW_FALLBACK);
	bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
	if (ret) {
		debug("failed to run video BIOS: %d\n", ret);
		return ret;
	}

	ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat);
	if (ret) {
		if (ret == -ENFILE) {
			/*
			 * See video-uclass.c for how to set up reserved memory
			 * in your video driver
			 */
			log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n",
				dev->driver->name);
		}

		debug("No video mode configured\n");
		return ret;
	}

	printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
	       mode_info.vesa.bits_per_pixel);

	return 0;
}
#endif
