// SPDX-License-Identifier: GPL-2.0-only
/*
 * framebuffer driver for VBE 2.0 compliant graphic boards
 *
 * switching to graphics mode happens at boot time (while
 * running in real mode, see arch/i386/boot/video.S).
 *
 * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
 *
 */

#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysfb.h>
#include <linux/io.h>

#include <video/vga.h>

#define dac_reg	(0x3c8)
#define dac_val	(0x3c9)

/* --------------------------------------------------------------------- */

struct vesafb_par {
	u32 pseudo_palette[256];
	resource_size_t base;
	resource_size_t size;
	int wc_cookie;
	struct resource *region;
};

static struct fb_var_screeninfo vesafb_defined = {
	.activate	= FB_ACTIVATE_NOW,
	.height		= -1,
	.width		= -1,
	.right_margin	= 32,
	.upper_margin	= 16,
	.lower_margin	= 4,
	.vsync_len	= 4,
	.vmode		= FB_VMODE_NONINTERLACED,
};

static struct fb_fix_screeninfo vesafb_fix = {
	.id	= "VESA VGA",
	.type	= FB_TYPE_PACKED_PIXELS,
	.accel	= FB_ACCEL_NONE,
};

static int   inverse    __read_mostly;
static int   mtrr       __read_mostly;		/* disable mtrr */
static int   vram_remap;			/* Set amount of memory to be used */
static int   vram_total;			/* Set total amount of memory */
static int   pmi_setpal __read_mostly = 1;	/* pmi for palette changes ??? */
static int   ypan       __read_mostly;		/* 0..nothing, 1..ypan, 2..ywrap */
static void  (*pmi_start)(void) __read_mostly;
static void  (*pmi_pal)  (void) __read_mostly;
static int   depth      __read_mostly;
static int   vga_compat __read_mostly;
/* --------------------------------------------------------------------- */

static int vesafb_pan_display(struct fb_var_screeninfo *var,
                              struct fb_info *info)
{
#ifdef __i386__
	int offset;

	offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;

        __asm__ __volatile__(
                "call *(%%edi)"
                : /* no return value */
                : "a" (0x4f07),         /* EAX */
                  "b" (0),              /* EBX */
                  "c" (offset),         /* ECX */
                  "d" (offset >> 16),   /* EDX */
                  "D" (&pmi_start));    /* EDI */
#endif
	return 0;
}

static int vesa_setpalette(int regno, unsigned red, unsigned green,
			    unsigned blue)
{
	int shift = 16 - depth;
	int err = -EINVAL;

/*
 * Try VGA registers first...
 */
	if (vga_compat) {
		outb_p(regno,       dac_reg);
		outb_p(red   >> shift, dac_val);
		outb_p(green >> shift, dac_val);
		outb_p(blue  >> shift, dac_val);
		err = 0;
	}

#ifdef __i386__
/*
 * Fallback to the PMI....
 */
	if (err && pmi_setpal) {
		struct { u_char blue, green, red, pad; } entry;

		entry.red   = red   >> shift;
		entry.green = green >> shift;
		entry.blue  = blue  >> shift;
		entry.pad   = 0;
	        __asm__ __volatile__(
                "call *(%%esi)"
                : /* no return value */
                : "a" (0x4f09),         /* EAX */
                  "b" (0),              /* EBX */
                  "c" (1),              /* ECX */
                  "d" (regno),          /* EDX */
                  "D" (&entry),         /* EDI */
                  "S" (&pmi_pal));      /* ESI */
		err = 0;
	}
#endif

	return err;
}

static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
			    unsigned blue, unsigned transp,
			    struct fb_info *info)
{
	int err = 0;

	/*
	 *  Set a single color register. The values supplied are
	 *  already rounded down to the hardware's capabilities
	 *  (according to the entries in the `var' structure). Return
	 *  != 0 for invalid regno.
	 */

	if (regno >= info->cmap.len)
		return 1;

	if (info->var.bits_per_pixel == 8)
		err = vesa_setpalette(regno,red,green,blue);
	else if (regno < 16) {
		switch (info->var.bits_per_pixel) {
		case 16:
			if (info->var.red.offset == 10) {
				/* 1:5:5:5 */
				((u32*) (info->pseudo_palette))[regno] =
					((red   & 0xf800) >>  1) |
					((green & 0xf800) >>  6) |
					((blue  & 0xf800) >> 11);
			} else {
				/* 0:5:6:5 */
				((u32*) (info->pseudo_palette))[regno] =
					((red   & 0xf800)      ) |
					((green & 0xfc00) >>  5) |
					((blue  & 0xf800) >> 11);
			}
			break;
		case 24:
		case 32:
			red   >>= 8;
			green >>= 8;
			blue  >>= 8;
			((u32 *)(info->pseudo_palette))[regno] =
				(red   << info->var.red.offset)   |
				(green << info->var.green.offset) |
				(blue  << info->var.blue.offset);
			break;
		}
	}

	return err;
}

/*
 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
 * of unregister_framebuffer() or fb_release(). Do any cleanup here.
 */
static void vesafb_destroy(struct fb_info *info)
{
	struct vesafb_par *par = info->par;

	fb_dealloc_cmap(&info->cmap);
	arch_phys_wc_del(par->wc_cookie);
	if (info->screen_base)
		iounmap(info->screen_base);
	release_mem_region(par->base, par->size);

	framebuffer_release(info);
}

static struct fb_ops vesafb_ops = {
	.owner		= THIS_MODULE,
	FB_DEFAULT_IOMEM_OPS,
	.fb_destroy     = vesafb_destroy,
	.fb_setcolreg	= vesafb_setcolreg,
	.fb_pan_display	= vesafb_pan_display,
};

static int vesafb_setup(char *options)
{
	char *this_opt;

	if (!options || !*options)
		return 0;

	while ((this_opt = strsep(&options, ",")) != NULL) {
		if (!*this_opt) continue;

		if (! strcmp(this_opt, "inverse"))
			inverse=1;
		else if (! strcmp(this_opt, "redraw"))
			ypan=0;
		else if (! strcmp(this_opt, "ypan"))
			ypan=1;
		else if (! strcmp(this_opt, "ywrap"))
			ypan=2;
		else if (! strcmp(this_opt, "vgapal"))
			pmi_setpal=0;
		else if (! strcmp(this_opt, "pmipal"))
			pmi_setpal=1;
		else if (! strncmp(this_opt, "mtrr:", 5))
			mtrr = simple_strtoul(this_opt+5, NULL, 0);
		else if (! strcmp(this_opt, "nomtrr"))
			mtrr=0;
		else if (! strncmp(this_opt, "vtotal:", 7))
			vram_total = simple_strtoul(this_opt+7, NULL, 0);
		else if (! strncmp(this_opt, "vremap:", 7))
			vram_remap = simple_strtoul(this_opt+7, NULL, 0);
	}
	return 0;
}

static int vesafb_probe(struct platform_device *dev)
{
	struct sysfb_display_info *dpy;
	struct screen_info *si;
	struct fb_info *info;
	struct vesafb_par *par;
	int i, err;
	unsigned int size_vmode;
	unsigned int size_remap;
	unsigned int size_total;
	char *option = NULL;

	/*
	 * If we fail probing the device, the kernel might try a different
	 * driver. We get a copy of the attached screen_info, so that we can
	 * modify its values without affecting later drivers.
	 */
	dpy = dev_get_platdata(&dev->dev);
	if (!dpy)
		return -ENODEV;

	si = devm_kmemdup(&dev->dev, &dpy->screen, sizeof(*si), GFP_KERNEL);
	if (!si)
		return -ENOMEM;

	/* ignore error return of fb_get_options */
	fb_get_options("vesafb", &option);
	vesafb_setup(option);

	if (si->orig_video_isVGA != VIDEO_TYPE_VLFB)
		return -ENODEV;

	vga_compat = !__screen_info_vbe_mode_nonvga(si);
	vesafb_fix.smem_start = si->lfb_base;
	vesafb_defined.bits_per_pixel = si->lfb_depth;
	if (15 == vesafb_defined.bits_per_pixel)
		vesafb_defined.bits_per_pixel = 16;
	vesafb_defined.xres = si->lfb_width;
	vesafb_defined.yres = si->lfb_height;
	vesafb_fix.line_length = si->lfb_linelength;
	vesafb_fix.visual   = (vesafb_defined.bits_per_pixel == 8) ?
		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;

	/*   size_vmode -- that is the amount of memory needed for the
	 *                 used video mode, i.e. the minimum amount of
	 *                 memory we need. */
	size_vmode = vesafb_defined.yres * vesafb_fix.line_length;

	/*   size_total -- all video memory we have. Used for mtrr
	 *                 entries, resource allocation and bounds
	 *                 checking. */
	size_total = si->lfb_size * 65536;
	if (vram_total)
		size_total = vram_total * 1024 * 1024;
	if (size_total < size_vmode)
		size_total = size_vmode;

	/*   size_remap -- the amount of video memory we are going to
	 *                 use for vesafb.  With modern cards it is no
	 *                 option to simply use size_total as that
	 *                 wastes plenty of kernel address space. */
	size_remap  = size_vmode * 2;
	if (vram_remap)
		size_remap = vram_remap * 1024 * 1024;
	if (size_remap < size_vmode)
		size_remap = size_vmode;
	if (size_remap > size_total)
		size_remap = size_total;
	vesafb_fix.smem_len = size_remap;

#ifndef __i386__
	si->vesapm_seg = 0;
#endif

	if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
		dev_warn(&dev->dev,
		       "cannot reserve video memory at 0x%lx\n",
			vesafb_fix.smem_start);
		/* We cannot make this fatal. Sometimes this comes from magic
		   spaces our resource handlers simply don't know about */
	}

	info = framebuffer_alloc(sizeof(struct vesafb_par), &dev->dev);
	if (!info) {
		release_mem_region(vesafb_fix.smem_start, size_total);
		return -ENOMEM;
	}
	platform_set_drvdata(dev, info);
	par = info->par;
	info->pseudo_palette = par->pseudo_palette;

	par->base = si->lfb_base;
	par->size = size_total;

	dev_info(&dev->dev, "mode is %dx%dx%d, linelength=%d, pages=%d\n",
	       vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,
	       vesafb_fix.line_length, si->pages);

	if (si->vesapm_seg) {
		dev_info(&dev->dev, "protected mode interface info at %04x:%04x\n",
		       si->vesapm_seg, si->vesapm_off);
	}

	if (si->vesapm_seg < 0xc000)
		ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */

	if (ypan || pmi_setpal) {
		unsigned long pmi_phys;
		unsigned short *pmi_base;
		pmi_phys  = ((unsigned long)si->vesapm_seg << 4) + si->vesapm_off;
		pmi_base  = (unsigned short *)phys_to_virt(pmi_phys);
		pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
		pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
		dev_info(&dev->dev, "pmi: set display start = %p, set palette = %p\n",
			 pmi_start, pmi_pal);
		if (pmi_base[3]) {
			dev_info(&dev->dev, "pmi: ports = ");
			for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
				printk("%x ", pmi_base[i]);
			printk("\n");
			if (pmi_base[i] != 0xffff) {
				/*
				 * memory areas not supported (yet?)
				 *
				 * Rules are: we have to set up a descriptor for the requested
				 * memory area and pass it in the ES register to the BIOS function.
				 */
				dev_info(&dev->dev, "can't handle memory requests, pmi disabled\n");
				ypan = pmi_setpal = 0;
			}
		}
	}

	if (vesafb_defined.bits_per_pixel == 8 && !pmi_setpal && !vga_compat) {
		dev_warn(&dev->dev, "hardware palette is unchangeable,\n"
		                    "        colors may be incorrect\n");
		vesafb_fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
	}

	vesafb_defined.xres_virtual = vesafb_defined.xres;
	vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length;
	if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) {
		dev_info(&dev->dev, "scrolling: %s using protected mode interface, yres_virtual=%d\n",
		       (ypan > 1) ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
	} else {
		dev_info(&dev->dev, "scrolling: redraw\n");
		vesafb_defined.yres_virtual = vesafb_defined.yres;
		ypan = 0;
	}

	/* some dummy values for timing to make fbset happy */
	vesafb_defined.pixclock     = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
	vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
	vesafb_defined.hsync_len    = (vesafb_defined.xres / 8) & 0xf8;

	vesafb_defined.red.offset    = si->red_pos;
	vesafb_defined.red.length    = si->red_size;
	vesafb_defined.green.offset  = si->green_pos;
	vesafb_defined.green.length  = si->green_size;
	vesafb_defined.blue.offset   = si->blue_pos;
	vesafb_defined.blue.length   = si->blue_size;
	vesafb_defined.transp.offset = si->rsvd_pos;
	vesafb_defined.transp.length = si->rsvd_size;

	if (vesafb_defined.bits_per_pixel <= 8) {
		depth = vesafb_defined.green.length;
		vesafb_defined.red.length =
		vesafb_defined.green.length =
		vesafb_defined.blue.length =
		vesafb_defined.bits_per_pixel;
	}

	dev_info(&dev->dev, "%s: "
	       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
	       (vesafb_defined.bits_per_pixel > 8) ?
	       "Truecolor" : (vga_compat || pmi_setpal) ?
	       "Pseudocolor" : "Static Pseudocolor",
	       si->rsvd_size,
	       si->red_size,
	       si->green_size,
	       si->blue_size,
	       si->rsvd_pos,
	       si->red_pos,
	       si->green_pos,
	       si->blue_pos);

	vesafb_fix.ypanstep  = ypan     ? 1 : 0;
	vesafb_fix.ywrapstep = (ypan>1) ? 1 : 0;

	/* request failure does not faze us, as vgacon probably has this
	 * region already (FIXME) */
	par->region = request_region(0x3c0, 32, "vesafb");

	if (mtrr == 3) {
		unsigned int temp_size = size_total;

		/* Find the largest power-of-two */
		temp_size = roundup_pow_of_two(temp_size);

		/* Try and find a power of two to add */
		do {
			par->wc_cookie =
				arch_phys_wc_add(vesafb_fix.smem_start,
						 temp_size);
			temp_size >>= 1;
		} while (temp_size >= PAGE_SIZE && par->wc_cookie < 0);

		info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
	} else {
		if (mtrr && mtrr != 3)
			WARN_ONCE(1, "Only MTRR_TYPE_WRCOMB (3) make sense\n");
		info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
	}

	if (!info->screen_base) {
		dev_err(&dev->dev,
		       "abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
			vesafb_fix.smem_len, vesafb_fix.smem_start);
		err = -EIO;
		goto err_release_region;
	}

	dev_info(&dev->dev, "framebuffer at 0x%lx, mapped to 0x%p, "
	       "using %dk, total %dk\n",
	       vesafb_fix.smem_start, info->screen_base,
	       size_remap/1024, size_total/1024);

	if (!ypan)
		vesafb_ops.fb_pan_display = NULL;

	info->fbops = &vesafb_ops;
	info->var = vesafb_defined;
	info->fix = vesafb_fix;
	info->flags = (ypan ? FBINFO_HWACCEL_YPAN : 0);

	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
		err = -ENOMEM;
		goto err_release_region;
	}
	err = devm_aperture_acquire_for_platform_device(dev, par->base, par->size);
	if (err)
		goto err_fb_dealloc_cmap;
	if (register_framebuffer(info)<0) {
		err = -EINVAL;
		goto err_fb_dealloc_cmap;
	}
	fb_info(info, "%s frame buffer device\n", info->fix.id);
	return 0;
err_fb_dealloc_cmap:
	fb_dealloc_cmap(&info->cmap);
err_release_region:
	arch_phys_wc_del(par->wc_cookie);
	if (info->screen_base)
		iounmap(info->screen_base);
	if (par->region)
		release_region(0x3c0, 32);
	framebuffer_release(info);
	release_mem_region(vesafb_fix.smem_start, size_total);
	return err;
}

static void vesafb_remove(struct platform_device *pdev)
{
	struct fb_info *info = platform_get_drvdata(pdev);

	if (((struct vesafb_par *)(info->par))->region)
		release_region(0x3c0, 32);

	/* vesafb_destroy takes care of info cleanup */
	unregister_framebuffer(info);
}

static struct platform_driver vesafb_driver = {
	.driver = {
		.name = "vesa-framebuffer",
	},
	.probe = vesafb_probe,
	.remove = vesafb_remove,
};

module_platform_driver(vesafb_driver);
MODULE_LICENSE("GPL");
