// 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 <bloblist.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 <spl.h>
#include <vesa.h>
#include <video.h>
#include <acpi/acpi_s3.h>
#include <asm/global_data.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 vesa_state 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 log_msg_ret("pro", ret);

	ret = pci_rom_load(rom, &ram, &alloced);
	if (ret) {
		ret = log_msg_ret("ld", ret);
		goto err;
	}

	if (!board_should_run_oprom(dev)) {
		ret = log_msg_ret("run", -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) {
		if (CONFIG_IS_ENABLED(BIOSEMU)) {
			BE_VGAInfo *info;

			log_debug("Running video BIOS with emulator...");
			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);
			log_debug("done\n");
			if (ret)
				goto err;
		}
	} else {
#if defined(CONFIG_X86) && (CONFIG_IS_ENABLED(X86_32BIT_INIT) || CONFIG_TPL)
		log_debug("Running video BIOS...");
		bios_set_interrupt_handler(0x15, int15_handler);

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

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

int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
			  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) && plat->base)
		plat->copy_base = fb;
	else
		plat->base = fb;
	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 vesa_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;
	}

	/* In U-Boot proper, collect the information added by SPL (see below) */
	if (IS_ENABLED(CONFIG_SPL_VIDEO) && spl_phase() > PHASE_SPL &&
	    CONFIG_IS_ENABLED(BLOBLIST)) {
		struct video_handoff *ho;

		ho = bloblist_find(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho));
		if (!ho)
			return log_msg_ret("blf", -ENOENT);
		plat->base = ho->fb;
		plat->size = ho->size;
		uc_priv->xsize = ho->xsize;
		uc_priv->ysize = ho->ysize;
		uc_priv->line_length = ho->line_length;
		uc_priv->bpix = ho->bpix;
	} else {
		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 = vesa_setup_video_priv(&mode_info.vesa,
					    mode_info.vesa.phys_base_ptr,
					    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);

	/* In SPL, store the information for use by U-Boot proper */
	if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(BLOBLIST)) {
		struct video_handoff *ho;

		ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0);
		if (!ho)
			return log_msg_ret("blc", -ENOMEM);

		ho->fb = plat->base;
		ho->size = plat->size;
		ho->xsize = uc_priv->xsize;
		ho->ysize = uc_priv->ysize;
		ho->line_length = uc_priv->line_length;
		ho->bpix = uc_priv->bpix;
	}

	return 0;
}
