linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Fredrik Noring <noring@nocrew.org>
To: linux-mips@vger.kernel.org, Helge Deller <deller@gmx.de>
Cc: Daniel Vetter <daniel@ffwll.ch>, David Airlie <airlied@linux.ie>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Javier Martinez Canillas <javier@dowhile0.org>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Jiaxun Yang <jiaxun.yang@flygoat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org
Subject: Re: [PATCH 094/120] MIPS: PS2: FB: Frame buffer driver for the PlayStation 2
Date: Sat, 29 Jan 2022 12:23:06 +0100	[thread overview]
Message-ID: <YfUjmpjWD8C5b4iP@sx9> (raw)
In-Reply-To: <4927c42fb3401c42c4c5a077f272331ac79d80b1.1567326213.git.noring@nocrew.org>

Hi Helge,

Thank you for maintaining fbdev! The PlayStation 2 port makes heavy use of
it and its acceleration features[1], including tiling operations:

	info->flags = FBINFO_DEFAULT |
		      FBINFO_HWACCEL_COPYAREA |
		      FBINFO_HWACCEL_FILLRECT |
		      FBINFO_HWACCEL_IMAGEBLIT |
		      FBINFO_HWACCEL_XPAN |
		      FBINFO_HWACCEL_YPAN |
		      FBINFO_HWACCEL_YWRAP |
		      FBINFO_PARTIAL_PAN_OK |
		      FBINFO_READS_FAST;

	info->flags |= FBINFO_MISC_TILEBLITTING;
	info->tileops = &tileops;

I attempted a DRM port[2], but my impression is that the DRM subsystem has
grave problems in that

- fbset command timing mode settings are ignored;
- attempts to set modes with /sys/class/graphics/fb0/mode are ignored;
- /sys/class/graphics/fb0/modes outputs incorrect refresh rates and types;
- relevant modes are missing in /sys/class/graphics/fb0/modes;
- the standard DRM video modes seem to mix up the sync and front porch
  timings in struct drm_display_mode but this remains to be confirmed;
- the DRM seems to rely heavily on EDID to negotiate a video resolution,
  but EDID isn't available with vintage analogue display hardware.

This is only for a (fast and efficient) text console.

My impression is also that the DRM wouldn't do more than displaying a text
console, and perhaps an inefficient virtual frame buffer, due to the nature
of the Graphics Synthesizer hardware. The complete set of features of the
Graphics Synthesizer, and related vector and image processors, seem to go
beyond what the DRM subsystem can offer in its current form. I admit that
there may possibilities that I haven't seen yet, though. :-)

Some background on the Graphics Synthesizer can be found in [3], as well
as in official documentation[4][5]. Many of its command primitives are
defined in [6][7], and there is more to it with the data paths from
various co-processors, etc.

Note: The fbdev patch below was, at the time, submitted in a series of
18 patches related to fbdev for PlayStation 2. See the complete ps2fb.c[1].

References:

[1] https://github.com/frno7/linux/blob/ps2-main/drivers/video/fbdev/ps2fb.c
[2] https://github.com/frno7/linux/tree/ps2-main/drivers/gpu/drm/gs
[3] https://github.com/frno7/linux/wiki/The-Graphics-Synthesizer
[4] EE User's Manual, version 6.0, Sony Computer Entertainment Inc.
[5] GS User's Manual, version 6.0, Sony Computer Entertainment Inc.
[6] https://github.com/frno7/linux/blob/ps2-main/arch/mips/include/uapi/asm/gs.h
[7] https://github.com/frno7/linux/blob/ps2-main/arch/mips/include/uapi/asm/gif.h

Fredrik

On Sunday, 1 September 2019, Fredrik Noring wrote:
> The main limitation is the lack of mmap, since the Graphics Synthesizer
> has local frame buffer memory that is not directly accessible from the
> main bus. The GS has 4 MiB of local memory.
> 
> The console drawing primitives are synchronous to allow printk at any
> time. This is highly useful for debugging but it is not the fastest
> possible implementation. The console is nevertheless very fast and
> makes use of several hardware accelerated features of the Graphics
> Synthesizer.
> 
> The maximum practical resolution is 1920x1080p at 16 bits per pixel that
> requires 4147200 bytes of local memory, leaving 47104 bytes for a tiled
> font, which at 8x8 pixels and a minimum 4 bits indexed texture palette is
> at most 1464 characters. The indexed palette makes switching colours easy.
> &struct fb_tile_ops is accelerated with GS texture sprites that are fast
> (GS local copy) for the kernel via simple DMA GS commands via the GIF.
> 
> Signed-off-by: Fredrik Noring <noring@nocrew.org>
> ---
>  drivers/video/fbdev/Kconfig    |  12 +
>  drivers/video/fbdev/Makefile   |   1 +
>  drivers/video/fbdev/ps2fb.c    | 533 +++++++++++++++++++++++++++++++++
>  include/linux/console_struct.h |   2 +
>  include/uapi/linux/fb.h        |   1 +
>  5 files changed, 549 insertions(+)
>  create mode 100644 drivers/video/fbdev/ps2fb.c
> 
> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
> index 6b2de93bd302..cc93cbd67b01 100644
> --- a/drivers/video/fbdev/Kconfig
> +++ b/drivers/video/fbdev/Kconfig
> @@ -1999,6 +1999,18 @@ config FB_IBM_GXT4500
>  	  doesn't use Geometry Engine GT1000. This driver also supports
>  	  AGP Fire GL2/3/4 cards on x86.
>  
> +# FIXME FB_SYS_*
> +config FB_PS2
> +	tristate "Frame buffer driver for Sony Playstation 2"
> +	depends on FB && SONY_PS2
> +	select PS2_GS
> +	select FB_TILEBLITTING
> +	default y
> +	help
> +	  Frame buffer driver for the Sony Playstation 2 Graphics Synthesizer.
> +	  Memory mapping is not supported since the frame buffer is local to
> +	  the GS.
> +
>  config FB_PS3
>  	tristate "PS3 GPU framebuffer driver"
>  	depends on FB && PS3_PS3AV
> diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
> index 7dc4861a93e6..1e55fa8ca4af 100644
> --- a/drivers/video/fbdev/Makefile
> +++ b/drivers/video/fbdev/Makefile
> @@ -105,6 +105,7 @@ obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
>  obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
>  obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
>  obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
> +obj-$(CONFIG_FB_PS2)		  += ps2fb.o
>  obj-$(CONFIG_FB_PS3)		  += ps3fb.o
>  obj-$(CONFIG_FB_SM501)            += sm501fb.o
>  obj-$(CONFIG_FB_UDL)		  += udlfb.o
> diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c
> new file mode 100644
> index 000000000000..7bfbc3c2aa4d
> --- /dev/null
> +++ b/drivers/video/fbdev/ps2fb.c
> @@ -0,0 +1,533 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PlayStation 2 frame buffer driver
> + *
> + * Copyright (C) 2019 Fredrik Noring
> + */
> +
> +/**
> + * DOC: The PlayStation 2 frame buffer console
> + *
> + * The frame buffer supports a tiled frame buffer console. The main limitation
> + * is the lack of memory mapping (mmap), since the Graphics Synthesizer has
> + * local frame buffer memory that is not directly accessible from the main bus.
> + * The GS has 4 MiB of local memory.
> + *
> + * The console drawing primitives are synchronous to allow printk at any time.
> + * This is highly useful for debugging but it is not the fastest possible
> + * implementation. The console is nevertheless very fast and makes use of
> + * several hardware accelerated features of the Graphics Synthesizer.
> + *
> + * The maximum practical resolution is 1920x1080p at 16 bits per pixel that
> + * requires 4147200 bytes of local memory, leaving 47104 bytes for a tiled
> + * font, which at 8x8 pixels and a minimum 4 bits indexed texture palette is
> + * at most 1464 characters. The indexed palette makes switching colours easy.
> + * &struct fb_tile_ops is accelerated with GS texture sprites that are fast
> + * (GS local copy) for the kernel via simple DMA GS commands via the GIF.
> + *
> + * The local memory is organised as follows: first comes the display buffer,
> + * then one block of a palette, and finally the font installed as a texture.
> + *
> + * All frame buffer transmissions are done by DMA via GIF PATH3.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/fb.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/string.h>
> +#include <linux/uaccess.h>
> +
> +#include <asm/io.h>
> +
> +#include <asm/mach-ps2/dmac.h>
> +#include <asm/mach-ps2/gif.h>
> +#include <asm/mach-ps2/gs.h>
> +#include <asm/mach-ps2/gs-registers.h>
> +
> +#include <uapi/asm/gif.h>
> +#include <uapi/asm/gs.h>
> +
> +#define DEVICE_NAME "ps2fb"
> +
> +#define PALETTE_BLOCK_COUNT 1	/* One block is used for the indexed colors */
> +
> +/* Module parameters */
> +static char *mode_option;
> +
> +union package {
> +	union gif_data gif;
> +	struct dma_tag dma;
> +};
> +
> +/**
> + * struct tile_texture - texture representing a tile
> + * @tbp: texture base pointer
> + * @u: texel u coordinate (x coordinate)
> + * @v: texel v coordinate (y coordinate)
> + */
> +struct tile_texture {
> +	u32 tbp;
> +	u32 u;
> +	u32 v;
> +};
> +
> +/**
> + * struct console_buffer - console buffer
> + * @block_count: number of frame buffer blocks
> + * @bg: background color index
> + * @fg: foreground color index
> + * @tile: tile dimensions
> + * @tile.width: width in pixels
> + * @tile.height: height in pixels
> + * @tile.width2: least width in pixels, power of 2
> + * @tile.height2: least height in pixels, power of 2
> + * @tile.block: tiles are stored as textures in the PSMT4 pixel storage format
> + * 	with both cols and rows as powers of 2
> + * @tile.block.cols: tile columns per GS block
> + * @tile.block.rows: tile rows per GS block
> + */
> +struct console_buffer {
> +	u32 block_count;
> +
> +	u32 bg;
> +	u32 fg;
> +
> +	struct cb_tile {
> +		u32 width;
> +		u32 height;
> +
> +		u32 width2;
> +		u32 height2;
> +
> +		struct {
> +			u32 cols;
> +			u32 rows;
> +		} block;
> +	} tile;
> +};
> +
> +/**
> + * struct ps2fb_par - driver specific structure
> + * @lock: spin lock to be taken for all structure operations
> + * @cb: console buffer definition
> + * @package: tags and datafor the GIF
> + * @package.capacity: maximum number of GIF packages in 16-byte unit
> + * @package.buffer: DMA buffer for GIF packages
> + */
> +struct ps2fb_par {
> +	spinlock_t lock;
> +
> +	struct console_buffer cb;
> +
> +	struct {
> +		size_t capacity;
> +		union package *buffer;
> +	} package;
> +};
> +
> +/**
> + * texture_least_power_of_2 - round up to a power of 2, not less than 8
> + * @n: integer to round up
> + *
> + * Return: least integer that is a power of 2 and not less than @n or 8
> + */
> +static u32 texture_least_power_of_2(u32 n)
> +{
> +	return max(1 << get_count_order(n), 8);
> +}
> +
> +/**
> + * cb_tile - create a console buffer tile object
> + * @width: width of tile in pixels
> + * @height: height of tile in pixels
> + *
> + * Return: a console buffer tile object with the given width and height
> + */
> +static struct cb_tile cb_tile(u32 width, u32 height)
> +{
> +	const u32 width2 = texture_least_power_of_2(width);
> +	const u32 height2 = texture_least_power_of_2(height);
> +
> +	return (struct cb_tile) {
> +		.width = width,
> +		.height = height,
> +
> +		.width2 = width2,
> +		.height2 = height2,
> +
> +		.block = {
> +			.cols = GS_PSMT4_BLOCK_WIDTH / width2,
> +			.rows = GS_PSMT4_BLOCK_HEIGHT / height2,
> +		},
> +	};
> +}
> +
> +/**
> + * display_buffer_size - display buffer size for a given video resolution
> + *
> + * This calculation is a lower bound estimate. A precise calculation would have
> + * to take memory pages, blocks and column arrangements into account. To choose
> + * the appropriate standard video mode such details can be disregarded, though.
> + *
> + * Return: the size in bytes of the display buffer
> + */
> +static u32 display_buffer_size(const u32 xres_virtual, const u32 yres_virtual,
> +      const u32 bits_per_pixel)
> +{
> +	return (xres_virtual * yres_virtual * bits_per_pixel) / 8;
> +}
> +
> +/**
> + * ps2fb_cb_get_tilemax - maximum number of tiles
> + * @info: frame buffer info object
> + *
> + * Return: the maximum number of tiles
> + */
> +static int ps2fb_cb_get_tilemax(struct fb_info *info)
> +{
> +	const struct ps2fb_par *par = info->par;
> +	const u32 block_tile_count =
> +		par->cb.tile.block.cols *
> +		par->cb.tile.block.rows;
> +	const s32 blocks_available =
> +		GS_BLOCK_COUNT - par->cb.block_count - PALETTE_BLOCK_COUNT;
> +
> +	return blocks_available > 0 ? blocks_available * block_tile_count : 0;
> +}
> +
> +/**
> + * bits_per_pixel_fits - does the given resolution fit the given buffer size?
> + * @xres_virtual: virtual x resolution in pixels
> + * @yres_virtual: virtual y resolution in pixels
> + * @bits_per_pixel: number of bits per pixel
> + * @buffer_size: size in bytes of display buffer
> + *
> + * The size calculation is approximate, but accurate enough for the standard
> + * video modes.
> + *
> + * Return: %true if the resolution fits the given buffer size, otherwise %false
> + */
> +static bool bits_per_pixel_fits(const u32 xres_virtual, const u32 yres_virtual,
> +      const int bits_per_pixel, const size_t buffer_size)
> +{
> +	return display_buffer_size(xres_virtual, yres_virtual,
> +		bits_per_pixel) <= buffer_size;
> +}
> +
> +/**
> + * default_bits_per_pixel - choose either 16 or 32 bits per pixel
> + * @xres_virtual: virtual x resolution in pixels
> + * @yres_virtual: virtual y resolution in pixels
> + * @buffer_size: size in bytes of display buffer
> + *
> + * 32 bits per pixel is returned unless this does not fit the given buffer size.
> + *
> + * The size calculation is approximate, but accurate enough for the standard
> + * video modes.
> + *
> + * Return: 16 or 32 bits per pixel
> + */
> +static int default_bits_per_pixel(
> +	const u32 xres_virtual, const u32 yres_virtual,
> +	const size_t buffer_size)
> +{
> +	return bits_per_pixel_fits(xres_virtual, yres_virtual,
> +		32, buffer_size) ? 32 : 16;
> +}
> +
> +/**
> + * filled_var_videomode - is the screen info video mode filled in?
> + * @var: screen info object to check
> + *
> + * Return: %true if the video mode is filled in, otherwise %false
> + */
> +static bool filled_var_videomode(const struct fb_var_screeninfo *var)
> +{
> +	return var->xres > 0 && var->hsync_len > 0 &&
> +	       var->yres > 0 && var->vsync_len > 0 && var->pixclock > 0;
> +}
> +
> +static int ps2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
> +{
> +	/* Check whether video mode defaults are needed. */
> +	if (!filled_var_videomode(var)) {
> +		const struct fb_videomode *vm =
> +			fb_find_best_mode(var, &info->modelist);
> +
> +		if (!vm)
> +			return -EINVAL;
> +
> +		fb_videomode_to_var(var, vm);
> +	}
> +
> +        /* GS video register resolution is limited to 2048. */
> +        if (var->xres < 1 || 2048 < var->xres ||
> +	    var->yres < 1 || 2048 < var->yres)
> +		return -EINVAL;
> +
> +	var->xres_virtual = var->xres;
> +	var->yres_virtual = var->yres;
> +	var->xoffset = 0;
> +	var->yoffset = 0;
> +
> +        /* Check bits per pixel. */
> +        if (!var->bits_per_pixel)
> +		var->bits_per_pixel = default_bits_per_pixel(
> +		     var->xres_virtual, var->yres_virtual, info->fix.smem_len);
> +	else if (var->bits_per_pixel != 16 &&
> +		 var->bits_per_pixel != 32)
> +		return -EINVAL;
> +        if (!bits_per_pixel_fits(var->xres_virtual, var->yres_virtual,
> +			var->bits_per_pixel, info->fix.smem_len))
> +		var->bits_per_pixel = default_bits_per_pixel(
> +		     var->xres_virtual, var->yres_virtual, info->fix.smem_len);
> +        if (!bits_per_pixel_fits(var->xres_virtual, var->yres_virtual,
> +			var->bits_per_pixel, info->fix.smem_len))
> +		return -ENOMEM;
> +	if (var->bits_per_pixel == 16) {
> +		var->red    = (struct fb_bitfield){ .offset =  0, .length = 5 };
> +		var->green  = (struct fb_bitfield){ .offset =  5, .length = 5 };
> +		var->blue   = (struct fb_bitfield){ .offset = 10, .length = 5 };
> +		var->transp = (struct fb_bitfield){ .offset = 15, .length = 1 };
> +	} else if (var->bits_per_pixel == 32) {
> +		var->red    = (struct fb_bitfield){ .offset =  0, .length = 8 };
> +		var->green  = (struct fb_bitfield){ .offset =  8, .length = 8 };
> +		var->blue   = (struct fb_bitfield){ .offset = 16, .length = 8 };
> +		var->transp = (struct fb_bitfield){ .offset = 24, .length = 8 };
> +	} else
> +		return -EINVAL;		/* Unsupported bits per pixel. */
> +
> +        /* Screen rotations are not supported. */
> +	if (var->rotate)
> +		return -EINVAL;
> +
> +        return 0;
> +}
> +
> +static int ps2fb_cb_check_var(
> +	struct fb_var_screeninfo *var, struct fb_info *info)
> +{
> +	struct ps2fb_par *par = info->par;
> +	unsigned long flags;
> +	int err;
> +
> +	spin_lock_irqsave(&par->lock, flags);
> +	err = ps2fb_check_var(var, info);
> +	spin_unlock_irqrestore(&par->lock, flags);
> +
> +	if (!err && info->tileops)
> +		if (info->tileops->fb_get_tilemax(info) < 256)
> +			err = -ENOMEM;
> +
> +	return err;
> +}
> +
> +static u32 block_dimensions(u32 dim, u32 alignment)
> +{
> +	u32 mask = 0;
> +	u32 d;
> +
> +	for (d = 1; d <= dim; d++)
> +		if (d % alignment == 0)
> +			mask |= 1 << (d - 1);
> +
> +	return mask;
> +}
> +
> +static int init_console_buffer(struct platform_device *pdev,
> +	struct fb_info *info)
> +{
> +	static struct fb_ops fbops = {
> +		.owner		= THIS_MODULE,
> +		.fb_check_var	= ps2fb_cb_check_var,
> +	};
> +
> +	static struct fb_tile_ops tileops = {
> +		.fb_get_tilemax = ps2fb_cb_get_tilemax
> +	};
> +
> +	struct ps2fb_par *par = info->par;
> +
> +	fb_info(info, "Graphics Synthesizer console frame buffer device\n");
> +
> +	info->screen_size = 0;
> +	info->screen_base = NULL;	/* mmap is unsupported by hardware */
> +
> +	info->fix.smem_start = 0;	/* GS frame buffer is local memory */
> +	info->fix.smem_len = GS_MEMORY_SIZE;
> +
> +	info->fbops = &fbops;
> +	info->flags = FBINFO_DEFAULT |
> +		      FBINFO_READS_FAST;
> +
> +	info->flags |= FBINFO_MISC_TILEBLITTING;
> +	info->tileops = &tileops;
> +
> +	/*
> +	 * BITBLTBUF for pixel format CT32 requires divisibility by 2,
> +	 * and CT16 requires divisibility by 4. So 4 is a safe choice.
> +	 */
> +	info->pixmap.blit_x = block_dimensions(GS_PSMT4_BLOCK_WIDTH, 4);
> +	info->pixmap.blit_y = block_dimensions(GS_PSMT4_BLOCK_HEIGHT, 1);
> +
> +	/* 8x8 default font tile size for fb_get_tilemax */
> +	par->cb.tile = cb_tile(8, 8);
> +
> +	return 0;
> +}
> +
> +static int ps2fb_probe(struct platform_device *pdev)
> +{
> +	struct ps2fb_par *par;
> +	struct fb_info *info;
> +	int err;
> +
> +	info = framebuffer_alloc(sizeof(*par), &pdev->dev);
> +	if (info == NULL) {
> +		dev_err(&pdev->dev, "framebuffer_alloc failed\n");
> +		err = -ENOMEM;
> +		goto err_framebuffer_alloc;
> +	}
> +
> +	par = info->par;
> +
> +	spin_lock_init(&par->lock);
> +
> +	par->package.buffer = (union package *)__get_free_page(GFP_DMA);
> +	if (!par->package.buffer) {
> +		dev_err(&pdev->dev, "Failed to allocate package buffer\n");
> +		err = -ENOMEM;
> +		goto err_package_buffer;
> +	}
> +	par->package.capacity = PAGE_SIZE / sizeof(union package);
> +
> +	strlcpy(info->fix.id, "PS2 GS", ARRAY_SIZE(info->fix.id));
> +	info->fix.accel = FB_ACCEL_PLAYSTATION_2;
> +
> +	err = init_console_buffer(pdev, info);
> +	if (err < 0)
> +		goto err_init_buffer;
> +
> +	info->mode = &par->mode;
> +
> +	if (register_framebuffer(info) < 0) {
> +		fb_err(info, "register_framebuffer failed\n");
> +		err = -EINVAL;
> +		goto err_register_framebuffer;
> +	}
> +
> +	platform_set_drvdata(pdev, info);
> +
> +	return 0;
> +
> +err_register_framebuffer:
> +err_init_buffer:
> +	free_page((unsigned long)par->package.buffer);
> +err_package_buffer:
> +	framebuffer_release(info);
> +err_framebuffer_alloc:
> +	return err;
> +}
> +
> +static int ps2fb_remove(struct platform_device *pdev)
> +{
> +	struct fb_info *info = platform_get_drvdata(pdev);
> +	struct ps2fb_par *par = info->par;
> +	int err = 0;
> +
> +	if (info != NULL) {
> +		unregister_framebuffer(info);
> +		fb_dealloc_cmap(&info->cmap);
> +
> +		framebuffer_release(info);
> +	}
> +
> +	if (!gif_wait()) {
> +		fb_err(info, "Failed to complete GIF DMA transfer\n");
> +		err = -EBUSY;
> +	}
> +	free_page((unsigned long)par->package.buffer);
> +
> +	return err;
> +}
> +
> +static struct platform_driver ps2fb_driver = {
> +	.probe		= ps2fb_probe,
> +	.remove		= ps2fb_remove,
> +	.driver = {
> +		.name	= DEVICE_NAME,
> +	},
> +};
> +
> +static struct platform_device *ps2fb_device;
> +
> +static int __init ps2fb_init(void)
> +{
> +	int err;
> +
> +#ifndef MODULE
> +	char *options = NULL;
> +	char *this_opt;
> +
> +	if (fb_get_options(DEVICE_NAME, &options))
> +		return -ENODEV;
> +	if (!options || !*options)
> +		goto no_options;
> +
> +	while ((this_opt = strsep(&options, ",")) != NULL) {
> +		if (!*this_opt)
> +			continue;
> +
> +		if (!strncmp(this_opt, "mode_option:", 12))
> +			mode_option = &this_opt[12];
> +		else if ('0' <= this_opt[0] && this_opt[0] <= '9')
> +			mode_option = this_opt;
> +		else
> +			pr_warn(DEVICE_NAME ": Unrecognized option \"%s\"\n",
> +				this_opt);
> +	}
> +
> +no_options:
> +#endif /* !MODULE */
> +
> +	/* Default to a suitable PAL or NTSC broadcast mode. */
> +	if (!mode_option)
> +		mode_option = gs_region_pal() ? "576x460i@50" : "576x384i@60";
> +
> +	ps2fb_device = platform_device_alloc("ps2fb", 0);
> +	if (!ps2fb_device)
> +		return -ENOMEM;
> +
> +	err = platform_device_add(ps2fb_device);
> +	if (err < 0) {
> +		platform_device_put(ps2fb_device);
> +		return err;
> +	}
> +
> +	return platform_driver_register(&ps2fb_driver);
> +}
> +
> +static void __exit ps2fb_exit(void)
> +{
> +	platform_driver_unregister(&ps2fb_driver);
> +	platform_device_unregister(ps2fb_device);
> +}
> +
> +module_init(ps2fb_init);
> +module_exit(ps2fb_exit);
> +
> +module_param(mode_option, charp, 0);
> +MODULE_PARM_DESC(mode_option,
> +	"Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
> +
> +MODULE_DESCRIPTION("PlayStation 2 frame buffer driver");
> +MODULE_AUTHOR("Fredrik Noring");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
> index 24d4c16e3ae0..cb562672cc3a 100644
> --- a/include/linux/console_struct.h
> +++ b/include/linux/console_struct.h
> @@ -13,9 +13,11 @@
>  #ifndef _LINUX_CONSOLE_STRUCT_H
>  #define _LINUX_CONSOLE_STRUCT_H
>  
> +#include <linux/tty.h>
>  #include <linux/wait.h>
>  #include <linux/vt.h>
>  #include <linux/workqueue.h>
> +#include <uapi/linux/kd.h>
>  
>  struct uni_pagedir;
>  struct uni_screen;
> diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
> index b6aac7ee1f67..38d88eebf651 100644
> --- a/include/uapi/linux/fb.h
> +++ b/include/uapi/linux/fb.h
> @@ -149,6 +149,7 @@
>  #define FB_ACCEL_SUPERSAVAGE    0x8c    /* S3 Supersavage               */
>  #define FB_ACCEL_PROSAVAGE_DDR  0x8d	/* S3 ProSavage DDR             */
>  #define FB_ACCEL_PROSAVAGE_DDRK 0x8e	/* S3 ProSavage DDR-K           */
> +#define FB_ACCEL_PLAYSTATION_2  0x8f	/* PlayStation 2                */
>  
>  #define FB_ACCEL_PUV3_UNIGFX	0xa0	/* PKUnity-v3 Unigfx		*/
>  
> -- 
> 2.21.0
> 

  parent reply	other threads:[~2022-01-29 11:31 UTC|newest]

Thread overview: 161+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-01 15:35 [PATCH 000/120] Linux for the PlayStation 2 Fredrik Noring
2019-09-01 15:35 ` [PATCH 001/120] MIPS: R5900: Initial support for the Emotion Engine in " Fredrik Noring
2019-09-01 21:14   ` Maciej W. Rozycki
2019-09-02 15:09     ` Fredrik Noring
2019-09-01 15:36 ` [PATCH 002/120] MIPS: R5900: Trap the RDHWR instruction as an SQ address exception Fredrik Noring
2019-09-01 22:00   ` Maciej W. Rozycki
2020-11-19  7:15   ` Philippe Mathieu-Daudé
2020-11-19 13:28     ` Maciej W. Rozycki
2020-11-19 13:42       ` Maciej W. Rozycki
2020-12-12 10:58       ` Fredrik Noring
2020-12-12 11:36         ` Maciej W. Rozycki
2020-12-12 12:14           ` Fredrik Noring
2020-12-13 11:43           ` Fredrik Noring
2019-09-01 15:36 ` [PATCH 003/120] MIPS: R5900: Sign-extend o32 system call registers Fredrik Noring
2019-09-01 15:37 ` [PATCH 004/120] MIPS: R5900: Reset bits 127..64 of GPRs in RESTORE_SOME Fredrik Noring
2019-09-01 15:38 ` [PATCH 005/120] MIPS: R5900: Reset the funnel shift amount (SA) register " Fredrik Noring
2019-09-01 15:38 ` [PATCH 006/120] MIPS: R5900: Workaround for the short loop bug Fredrik Noring
2019-09-01 15:39 ` [PATCH 007/120] MIPS: R5900: Add the SYNC.P instruction Fredrik Noring
2019-09-01 15:39 ` [PATCH 008/120] MIPS: R5900: Add implicit SYNC.P to the UASM_i_M[FT]C0 macros Fredrik Noring
2019-09-01 15:39 ` [PATCH 009/120] MIPS: R5900: Add mandatory SYNC.P to all M[FT]C0 instructions Fredrik Noring
2019-09-01 15:39 ` [PATCH 010/120] MIPS: R5900: Workaround exception NOP execution bug (FLX05) Fredrik Noring
2019-09-01 23:01   ` Philippe Mathieu-Daudé
2019-09-01 15:40 ` [PATCH 011/120] MIPS: R5900: Avoid pipeline hazard with the TLBP instruction Fredrik Noring
2019-09-01 17:15   ` Sergei Shtylyov
2019-09-01 17:36     ` Fredrik Noring
2019-09-01 15:40 ` [PATCH 012/120] MIPS: R5900: Avoid pipeline hazards with the TLBW[IR] instructions Fredrik Noring
2019-09-01 15:40 ` [PATCH 013/120] MIPS: R5900: Avoid pipeline hazard with the TLBR instruction Fredrik Noring
2019-09-01 15:41 ` [PATCH 014/120] MIPS: R5900: Install final length of TLB refill handler rather than 256 bytes Fredrik Noring
2019-09-01 15:41 ` [PATCH 015/120] MIPS: R5900: Verify that the TLB refill handler does not overflow Fredrik Noring
2019-09-01 15:41 ` [PATCH 016/120] MIPS: R5900: The ERET instruction has issues with delay slot and CACHE Fredrik Noring
2019-09-01 15:42 ` [PATCH 017/120] MIPS: R5900: Define CACHE instruction operation field encodings Fredrik Noring
2019-09-01 15:42 ` [PATCH 018/120] MIPS: R5900: Workaround where MSB must be 0 for the instruction cache Fredrik Noring
2019-09-01 15:42 ` [PATCH 019/120] MIPS: R5900: Use SYNC.L for data cache and SYNC.P for " Fredrik Noring
2019-09-01 15:43 ` [PATCH 020/120] MIPS: R5900: Define CP0.Config register fields Fredrik Noring
2019-09-01 23:04   ` Philippe Mathieu-Daudé
2019-09-01 15:43 ` [PATCH 021/120] MIPS: R5900: Workaround for CACHE instruction near branch delay slot Fredrik Noring
2019-09-01 15:46 ` [PATCH 022/120] MIPS: R5900: Support 64-bit inq() and outq() macros in 32-bit kernels Fredrik Noring
2019-09-04  1:04   ` Jiaxun Yang
2019-09-04 16:00     ` Maciej W. Rozycki
2019-09-01 15:46 ` [PATCH 023/120] MIPS: R5900: Add MFSA and MTSA instructions for the special SA register Fredrik Noring
2019-09-01 15:46 ` [PATCH 024/120] MIPS: PS2: Define PlayStation 2 I/O port, ROM and RAM address spaces Fredrik Noring
2019-09-01 15:47 ` [PATCH 025/120] MIPS: PS2: Define interrupt controller, DMA and timer IRQs Fredrik Noring
2019-09-01 15:47 ` [PATCH 026/120] MIPS: PS2: Interrupt controller (INTC) IRQ support Fredrik Noring
2019-09-01 15:47 ` [PATCH 027/120] MIPS: PS2: DMAC: Define DMA controller registers Fredrik Noring
2019-09-01 15:47 ` [PATCH 028/120] MIPS: PS2: DMAC: Define tag structures Fredrik Noring
2019-09-01 15:48 ` [PATCH 029/120] MIPS: PS2: DMAC: IRQ support Fredrik Noring
2019-09-01 15:48 ` [PATCH 030/120] MIPS: PS2: Timer support Fredrik Noring
2019-09-01 15:48 ` [PATCH 031/120] MIPS: PS2: SCMD: System command support Fredrik Noring
2019-09-01 15:48 ` [PATCH 032/120] MIPS: PS2: SCMD: System power off command Fredrik Noring
2019-09-01 15:48 ` [PATCH 033/120] MIPS: PS2: SCMD: Read system machine name command Fredrik Noring
2019-09-01 15:49 ` [PATCH 034/120] MIPS: PS2: SCMD: Read system command for the real-time clock (RTC) Fredrik Noring
2019-09-01 15:49 ` [PATCH 035/120] MIPS: PS2: SCMD: Set " Fredrik Noring
2019-09-01 15:49 ` [PATCH 036/120] MIPS: PS2: ROM: Iterate over the files in a given ROM directory Fredrik Noring
2019-09-01 15:49 ` [PATCH 037/120] MIPS: PS2: ROM: Find ROM files with a given name, if they exist Fredrik Noring
2019-09-01 15:50 ` [PATCH 038/120] MIPS: PS2: ROM: Read data for a given ROM file name Fredrik Noring
2019-09-02  9:05   ` Sergei Shtylyov
2019-09-04 11:46     ` Sergei Shtylyov
2019-09-06 13:07       ` Fredrik Noring
2019-09-01 15:50 ` [PATCH 039/120] MIPS: PS2: ROM: Read extended information for a given ROM file Fredrik Noring
2019-09-01 15:50 ` [PATCH 040/120] MIPS: PS2: ROM: Read and decode the ROMVER file Fredrik Noring
2019-09-01 15:52 ` [PATCH 041/120] MIPS: PS2: ROM: Resolve the name for the type in " Fredrik Noring
2019-09-01 15:52 ` [PATCH 042/120] MIPS: PS2: ROM: Resolve the name for the region " Fredrik Noring
2019-09-01 15:53 ` [PATCH 043/120] MIPS: PS2: ROM: Permit /dev/mem to access read-only memory Fredrik Noring
2019-09-01 15:53 ` [PATCH 044/120] MIPS: PS2: ROM: Sysfs module to inspect ROM files Fredrik Noring
2019-09-01 15:54 ` [PATCH 045/120] MIPS: PS2: ROM: Provide extended file information via sysfs Fredrik Noring
2019-09-01 15:54 ` [PATCH 046/120] MIPS: PS2: Identify the machine by model name Fredrik Noring
2019-09-01 15:54 ` [PATCH 047/120] MIPS: PS2: Let the system type be Sony PlayStation 2 Fredrik Noring
2019-09-01 23:09   ` Philippe Mathieu-Daudé
2019-09-01 15:55 ` [PATCH 048/120] MIPS: Define and use cpu_relax_forever() for various halting loops Fredrik Noring
2019-09-01 15:55 ` [PATCH 049/120] MIPS: PS2: Power off support Fredrik Noring
2019-09-01 15:55 ` [PATCH 050/120] MIPS: PS2: Real-time clock (RTC) driver Fredrik Noring
2019-09-01 15:56 ` [PATCH 051/120] MIPS: PS2: IOP: I/O processor DMA register PCR2 set and clear Fredrik Noring
2019-09-01 15:57 ` [PATCH 052/120] MIPS: PS2: SIF: Sub-system interface reset of the I/O processor (IOP) Fredrik Noring
2019-09-01 15:57 ` [PATCH 053/120] MIPS: PS2: IOP: Define error numbers, descriptions and errno mapping Fredrik Noring
2019-09-01 15:58 ` [PATCH 054/120] MIPS: PS2: SIF: SIF register write command support Fredrik Noring
2019-09-01 15:58 ` [PATCH 055/120] MIPS: PS2: SIF: Respond to remote procedure call (RPC) bind command Fredrik Noring
2019-09-01 15:58 ` [PATCH 056/120] MIPS: PS2: SIF: Respond to RPC bind end command Fredrik Noring
2019-09-01 15:59 ` [PATCH 057/120] MIPS: PS2: SIF: Reset the SIF0 (sub-to-main) DMA controller Fredrik Noring
2019-09-01 15:59 ` [PATCH 058/120] MIPS: PS2: SIF: Handle SIF0 (sub-to-main) RPCs via interrupts Fredrik Noring
2019-09-01 15:59 ` [PATCH 059/120] MIPS: PS2: SIF: Enable the IOP to issue SIF commands Fredrik Noring
2019-09-01 16:00 ` [PATCH 060/120] MIPS: PS2: SIF: Enable the IOP to issue SIF RPCs Fredrik Noring
2019-09-01 16:01 ` [PATCH 061/120] MIPS: PS2: SIF: sif_rpc_bind() to request an RPC server connection Fredrik Noring
2019-09-01 16:02 ` [PATCH 062/120] MIPS: PS2: SIF: sif_rpc_unbind() to release " Fredrik Noring
2019-09-01 16:02 ` [PATCH 063/120] MIPS: PS2: SIF: sif_rpc() to issue a remote procedure call Fredrik Noring
2019-09-01 16:03 ` [PATCH 064/120] MIPS: PS2: IOP: Permit /dev/mem to access IOP memory Fredrik Noring
2019-09-01 16:03 ` [PATCH 065/120] MIPS: PS2: IOP: I/O processor memory support Fredrik Noring
2019-09-01 16:10 ` [PATCH 066/120] FIXME: Export _dma_cache_{wback,wback_inv,inv} Fredrik Noring
2019-09-01 16:10 ` [PATCH 067/120] MIPS: PS2: IOP: Module linking support Fredrik Noring
2019-09-01 16:11 ` [PATCH 068/120] MIPS: PS2: IOP: Verify that modules are IRX objects Fredrik Noring
2019-09-01 16:11 ` [PATCH 069/120] MIPS: PS2: IOP: Module version compatibility verification Fredrik Noring
2019-09-01 16:11 ` [PATCH 070/120] MIPS: PS2: IOP: Avoid linking already linked library modules Fredrik Noring
2019-09-01 16:12 ` [PATCH 071/120] MIPS: PS2: IOP: Resolve module dependencies Fredrik Noring
2019-09-01 16:12 ` [PATCH 072/120] MIPS: PS2: IOP: SIF printk command support Fredrik Noring
2019-09-01 17:44   ` Sergei Shtylyov
2019-09-01 18:08     ` Fredrik Noring
2019-09-01 16:16 ` [PATCH 073/120] MIPS: PS2: IOP: Heap memory allocate and free Fredrik Noring
2019-09-01 16:16 ` [PATCH 074/120] MIPS: PS2: SIF: Request RPC IRQ command Fredrik Noring
2019-09-01 16:17 ` [PATCH 075/120] MIPS: PS2: IOP: IRQ support Fredrik Noring
2019-09-01 16:17 ` [PATCH 076/120] MIPS: PS2: GS: Define privileged Graphics Synthesizer registers Fredrik Noring
2019-09-01 16:18 ` [PATCH 077/120] MIPS: PS2: GS: Write privileged registers Fredrik Noring
2019-09-01 16:18 ` [PATCH 078/120] MIPS: PS2: GS: Read " Fredrik Noring
2019-09-01 16:18 ` [PATCH 079/120] MIPS: PS2: GS: Define privileged register structures Fredrik Noring
2019-09-01 16:19 ` [PATCH 080/120] MIPS: PS2: GS: Define gs_xorq_imr() Fredrik Noring
2019-09-01 16:20 ` [PATCH 081/120] MIPS: PS2: GS: Privileged register write macros with named fields Fredrik Noring
2019-09-01 16:20 ` [PATCH 082/120] MIPS: PS2: GS: IRQ support Fredrik Noring
2019-09-01 16:21 ` [PATCH 083/120] MIPS: PS2: GS: Define Graphics Synthesizer primitive structures Fredrik Noring
2019-09-01 16:21 ` [PATCH 084/120] MIPS: PS2: GIF: Define Graphics Synthesizer interface structures Fredrik Noring
2019-09-01 16:22 ` [PATCH 085/120] MIPS: PS2: GIF: Graphics Synthesizer interface support Fredrik Noring
2019-09-01 16:22 ` [PATCH 086/120] MIPS: PS2: GS: Graphics Synthesizer device init and video clock Fredrik Noring
2019-09-01 16:23 ` [PATCH 087/120] MIPS: PS2: GS: Compute block count and indices Fredrik Noring
2019-09-01 16:23 ` [PATCH 088/120] MIPS: PS2: GS: Primitive and texel coordinate transformations Fredrik Noring
2019-09-01 16:23 ` [PATCH 089/120] MIPS: PS2: GS: Approximate video region with ROM region Fredrik Noring
2019-09-01 16:24 ` [PATCH 090/120] macro: Extend COUNT_ARGS() from 12 to 32 arguments Fredrik Noring
2019-09-01 16:25 ` [PATCH 091/120] MIPS: PS2: GS: Show privileged registers with sysfs Fredrik Noring
2019-09-01 16:25 ` [PATCH 092/120] MIPS: PS2: GS: Store " Fredrik Noring
2019-09-01 16:25 ` [PATCH 093/120] fbdev: Add fb_warn_once() variant that only prints a warning once Fredrik Noring
2019-09-01 23:12   ` Philippe Mathieu-Daudé
2019-09-01 16:26 ` [PATCH 094/120] MIPS: PS2: FB: Frame buffer driver for the PlayStation 2 Fredrik Noring
2019-09-02  1:12   ` Jiaxun Yang
2019-09-02 14:40     ` Fredrik Noring
2019-09-02 17:47       ` Aaro Koskinen
2019-09-03 14:32         ` Fredrik Noring
2019-09-03  4:01       ` Jiaxun Yang
2019-09-03 17:42         ` Fredrik Noring
2019-09-03 17:59           ` Maciej W. Rozycki
2019-09-03 18:46             ` Fredrik Noring
2020-12-13 13:20     ` Fredrik Noring
2022-01-29 11:23   ` Fredrik Noring [this message]
2019-09-01 16:30 ` [PATCH 095/120] MIPS: PS2: FB: fb_set_par() standard-definition television support Fredrik Noring
2019-09-01 16:30 ` [PATCH 096/120] MIPS: PS2: FB: fb_set_par() high-definition " Fredrik Noring
2019-09-01 16:31 ` [PATCH 097/120] MIPS: PS2: FB: fb_set_par() VESA computer display mode support Fredrik Noring
2019-09-01 16:31 ` [PATCH 098/120] MIPS: PS2: FB: Preconfigure standard PAL, NTSC and VESA display modes Fredrik Noring
2019-09-01 16:31 ` [PATCH 099/120] MIPS: PS2: FB: Reset the Graphics Synthesizer drawing environment Fredrik Noring
2019-09-01 16:32 ` [PATCH 100/120] MIPS: PS2: FB: Clear the display buffer when changing video modes Fredrik Noring
2019-09-01 16:32 ` [PATCH 101/120] MIPS: PS2: FB: fb_setcolreg() 256 colour pseudo palette support Fredrik Noring
2019-09-01 16:32 ` [PATCH 102/120] MIPS: PS2: FB: fb_settile() with font stored as palette indexed textures Fredrik Noring
2019-09-01 16:32 ` [PATCH 103/120] MIPS: PS2: FB: Hardware accelerated fb_tilecopy() support Fredrik Noring
2019-09-01 16:33 ` [PATCH 104/120] MIPS: PS2: FB: Hardware accelerated fb_tilefill() support Fredrik Noring
2019-09-01 16:33 ` [PATCH 105/120] MIPS: PS2: FB: Simplified fb_tileblit() support Fredrik Noring
2019-09-01 16:33 ` [PATCH 106/120] MIPS: PS2: FB: fb_tilecursor() placeholder Fredrik Noring
2019-09-01 16:33 ` [PATCH 107/120] MIPS: PS2: FB: Hardware accelerated fb_pan_display() support Fredrik Noring
2019-09-01 16:34 ` [PATCH 108/120] MIPS: PS2: FB: fb_blank() display power management signaling (DPMS) Fredrik Noring
2019-09-01 16:34 ` [PATCH 109/120] MIPS: PS2: FB: Disable GIF DMA completion interrupts Fredrik Noring
2019-09-01 16:34 ` [PATCH 110/120] MIPS: PS2: FB: PAL and NTSC grayscale support Fredrik Noring
2019-09-01 16:34 ` [PATCH 111/120] MIPS: PS2: FB: Analogue display mode adjustment module parameter Fredrik Noring
2019-09-01 16:35 ` [PATCH 112/120] USB: OHCI: Support for the PlayStation 2 Fredrik Noring
2019-09-01 16:35 ` [PATCH 113/120] USB: OHCI: OHCI_INTR_MIE workaround for freeze on " Fredrik Noring
2019-09-01 16:35 ` [PATCH 114/120] MIPS: PS2: Workaround for unexpected uLaunchELF CP0 Status user mode Fredrik Noring
2019-09-01 16:35 ` [PATCH 115/120] MIPS: PS2: Define initial PlayStation 2 devices Fredrik Noring
2019-09-01 16:35 ` [PATCH 116/120] MIPS: PS2: Define workarounds related to the PlayStation 2 Fredrik Noring
2019-09-01 16:36 ` [PATCH 117/120] MIPS: PS2: Define R5900 feature overrides Fredrik Noring
2019-09-01 16:36 ` [PATCH 118/120] MIPS: PS2: Define the PlayStation 2 platform Fredrik Noring
2019-09-01 16:36 ` [PATCH 119/120] MIPS: PS2: Initial support for the Sony PlayStation 2 Fredrik Noring
2019-09-01 16:37 ` [PATCH 120/120] MIPS: Fix name of BOOT_MEM_ROM_DATA Fredrik Noring
2019-09-01 23:15   ` Philippe Mathieu-Daudé
2019-09-02  1:02   ` Jiaxun Yang
2019-09-02 15:26     ` Fredrik Noring
2019-09-03  3:50       ` Jiaxun Yang
2019-09-03 16:06         ` Fredrik Noring
2019-09-04 14:19 ` [PATCH 000/120] Linux for the PlayStation 2 Paul Burton
2019-09-05 18:32   ` Fredrik Noring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YfUjmpjWD8C5b4iP@sx9 \
    --to=noring@nocrew.org \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=deller@gmx.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=geert@linux-m68k.org \
    --cc=javier@dowhile0.org \
    --cc=jiaxun.yang@flygoat.com \
    --cc=kraxel@redhat.com \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).