linux/drivers/video/fbdev/uvesafb.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * A framebuffer driver for VBE 2.0+ compliant video cards
 *
 * (c) 2007 Michal Januszewski <[email protected]>
 *     Loosely based upon the vesafb driver.
 *
 */

#define pr_fmt(fmt)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
#include <linux/completion.h>
#include <linux/connector.h>
#include <linux/random.h>
#include <linux/platform_device.h>
#include <linux/limits.h>
#include <linux/fb.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <video/edid.h>
#include <video/uvesafb.h>
#ifdef CONFIG_X86
#include <video/vga.h>
#endif
#include "edid.h"

static struct cb_id uvesafb_cn_id =;
static char v86d_path[PATH_MAX] =;
static char v86d_started;	/* has v86d been started by uvesafb? */

static const struct fb_fix_screeninfo uvesafb_fix =;

static int mtrr		=;	/* enable mtrr by default */
static bool blank	=;	/* enable blanking by default */
static int ypan		=;	/* 0: scroll, 1: ypan, 2: ywrap */
static bool pmi_setpal	=; /* use PMI for palette changes */
static bool nocrtc;		/* ignore CRTC settings */
static bool noedid;		/* don't try DDC transfers */
static int vram_remap;		/* set amt. of memory to be used */
static int vram_total;		/* set total amount of memory */
static u16 maxclk;		/* maximum pixel clock */
static u16 maxvf;		/* maximum vertical frequency */
static u16 maxhf;		/* maximum horizontal frequency */
static u16 vbemode;		/* force use of a specific VBE mode */
static char *mode_option;
static u8  dac_width	=;

static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
static DEFINE_MUTEX(uvfb_lock);

/*
 * A handler for replies from userspace.
 *
 * Make sure each message passes consistency checks and if it does,
 * find the kernel part of the task struct, copy the registers and
 * the buffer contents and then complete the task.
 */
static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{}

static int uvesafb_helper_start(void)
{}

/*
 * Execute a uvesafb task.
 *
 * Returns 0 if the task is executed successfully.
 *
 * A message sent to the userspace consists of the uvesafb_task
 * struct and (optionally) a buffer. The uvesafb_task struct is
 * a simplified version of uvesafb_ktask (its kernel counterpart)
 * containing only the register values, flags and the length of
 * the buffer.
 *
 * Each message is assigned a sequence number (increased linearly)
 * and a random ack number. The sequence number is used as a key
 * for the uvfb_tasks array which holds pointers to uvesafb_ktask
 * structs for all requests.
 */
static int uvesafb_exec(struct uvesafb_ktask *task)
{}

/*
 * Free a uvesafb_ktask struct.
 */
static void uvesafb_free(struct uvesafb_ktask *task)
{}

/*
 * Prepare a uvesafb_ktask struct to be used again.
 */
static void uvesafb_reset(struct uvesafb_ktask *task)
{}

/*
 * Allocate and prepare a uvesafb_ktask struct.
 */
static struct uvesafb_ktask *uvesafb_prep(void)
{}

static void uvesafb_setup_var(struct fb_var_screeninfo *var,
		struct fb_info *info, struct vbe_mode_ib *mode)
{}

static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
		int xres, int yres, int depth, unsigned char flags)
{}

static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
{}

static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
{}

static int uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
			       struct uvesafb_par *par)
{}

static int uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
				struct uvesafb_par *par)
{}

/*
 * The Protected Mode Interface is 32-bit x86 code, so we only run it on
 * x86 and not x86_64.
 */
#ifdef CONFIG_X86_32
static int uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
			      struct uvesafb_par *par)
{
	int i, err;

	uvesafb_reset(task);
	task->t.regs.eax = 0x4f0a;
	task->t.regs.ebx = 0x0;
	err = uvesafb_exec(task);
	if (err)
		return err;

	if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
		par->pmi_setpal = par->ypan = 0;
	} else {
		par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
						+ task->t.regs.edi);
		par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
		par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
		pr_info("protected mode interface info at %04x:%04x\n",
			(u16)task->t.regs.es, (u16)task->t.regs.edi);
		pr_info("pmi: set display start = %p, set palette = %p\n",
			par->pmi_start, par->pmi_pal);

		if (par->pmi_base[3]) {
			pr_info("pmi: ports =");
			for (i = par->pmi_base[3]/2;
					par->pmi_base[i] != 0xffff; i++)
				pr_cont(" %x", par->pmi_base[i]);
			pr_cont("\n");

			if (par->pmi_base[i] != 0xffff) {
				pr_info("can't handle memory requests, pmi disabled\n");
				par->ypan = par->pmi_setpal = 0;
			}
		}
	}
	return 0;
}
#endif /* CONFIG_X86_32 */

/*
 * Check whether a video mode is supported by the Video BIOS and is
 * compatible with the monitor limits.
 */
static int uvesafb_is_valid_mode(struct fb_videomode *mode,
				 struct fb_info *info)
{}

static int uvesafb_vbe_getedid(struct uvesafb_ktask *task, struct fb_info *info)
{}

static void uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
				    struct fb_info *info)
{}

static void uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
				     struct uvesafb_par *par)
{}

static int uvesafb_vbe_init(struct fb_info *info)
{}

static int uvesafb_vbe_init_mode(struct fb_info *info)
{}

static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
		int start, struct fb_info *info)
{}

static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
		unsigned blue, unsigned transp,
		struct fb_info *info)
{}

static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{}

static int uvesafb_pan_display(struct fb_var_screeninfo *var,
		struct fb_info *info)
{}

static int uvesafb_blank(int blank, struct fb_info *info)
{}

static int uvesafb_open(struct fb_info *info, int user)
{}

static int uvesafb_release(struct fb_info *info, int user)
{}

static int uvesafb_set_par(struct fb_info *info)
{}

static void uvesafb_check_limits(struct fb_var_screeninfo *var,
		struct fb_info *info)
{}

static int uvesafb_check_var(struct fb_var_screeninfo *var,
		struct fb_info *info)
{}

static struct fb_ops uvesafb_ops =;

static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)
{}

static void uvesafb_init_mtrr(struct fb_info *info)
{}

static void uvesafb_ioremap(struct fb_info *info)
{}

static ssize_t uvesafb_show_vbe_ver(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);

static ssize_t uvesafb_show_vbe_modes(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);

static ssize_t uvesafb_show_vendor(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);

static ssize_t uvesafb_show_product_name(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);

static ssize_t uvesafb_show_product_rev(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);

static ssize_t uvesafb_show_oem_string(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);

static ssize_t uvesafb_show_nocrtc(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static ssize_t uvesafb_store_nocrtc(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{}

static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
			uvesafb_store_nocrtc);

static struct attribute *uvesafb_dev_attrs[] =;

static const struct attribute_group uvesafb_dev_attgrp =;

static int uvesafb_probe(struct platform_device *dev)
{}

static void uvesafb_remove(struct platform_device *dev)
{}

static struct platform_driver uvesafb_driver =;

static struct platform_device *uvesafb_device;

#ifndef MODULE
static int uvesafb_setup(char *options)
{}
#endif /* !MODULE */

static ssize_t v86d_show(struct device_driver *dev, char *buf)
{}

static ssize_t v86d_store(struct device_driver *dev, const char *buf,
		size_t count)
{}
static DRIVER_ATTR_RW(v86d);

static int uvesafb_init(void)
{}

module_init();

static void uvesafb_exit(void)
{}

module_exit(uvesafb_exit);

static int param_set_scroll(const char *val, const struct kernel_param *kp)
{}
static const struct kernel_param_ops param_ops_scroll =;
#define param_check_scroll(name, p)

module_param_named(scroll, ypan, scroll, 0);
MODULE_PARM_DESC();
module_param_named(vgapal, pmi_setpal, invbool, 0);
MODULE_PARM_DESC();
module_param_named(pmipal, pmi_setpal, bool, 0);
MODULE_PARM_DESC();
module_param(mtrr, uint, 0);
MODULE_PARM_DESC();
module_param(blank, bool, 0);
MODULE_PARM_DESC();
module_param(nocrtc, bool, 0);
MODULE_PARM_DESC();
module_param(noedid, bool, 0);
MODULE_PARM_DESC();
module_param(vram_remap, uint, 0);
MODULE_PARM_DESC();
module_param(vram_total, uint, 0);
MODULE_PARM_DESC();
module_param(maxclk, ushort, 0);
MODULE_PARM_DESC();
module_param(maxhf, ushort, 0);
MODULE_PARM_DESC();
module_param(maxvf, ushort, 0);
MODULE_PARM_DESC();
module_param(mode_option, charp, 0);
MODULE_PARM_DESC();
module_param(vbemode, ushort, 0);
MODULE_PARM_DESC();
module_param_string();
MODULE_PARM_DESC();

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();