mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'fbdev-for-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev
Pull fbdev updates from Helge Deller: "Beside the usual bunch of smaller bug fixes, the majority of changes were by Zsolt Kajtar to improve the s3fb driver. Bug fixes: - Bounds checking to fix vmalloc-out-of-bounds (Albin Babu Varghese) - Fix logic error in "offb" name match (Finn Thain) - simplefb: Fix use after free in (Janne Grunau) - s3fb: Various fixes and powersave improvements (Zsolt Kajtar) Enhancements & code cleanups: - Various fixes in the documentation (Bagas Sanjaya) - Use string choices helpers (Chelsy Ratnawat) - xenfb: Use vmalloc_array to simplify code (Qianfeng Rong) - mb862xxfb: use signed type for error codes (Qianfeng Rong) - Make drivers depend on LCD_CLASS_DEVICE (Thomas Zimmermann) - radeonfb: Remove stale product link in Kconfig (Sukrut Heroorkar)" * tag 'fbdev-for-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev: fbdev: Fix logic error in "offb" name match fbdev: Add bounds checking in bit_putcs to fix vmalloc-out-of-bounds fbdev: Make drivers depend on LCD_CLASS_DEVICE fbdev: radeonfb: Remove stale product link in Kconfig Documentation: fb: Retitle driver docs Documentation: fb: ep93xx: Demote section headings Documentation: fb: Split toctree fbdev: simplefb: Fix use after free in simplefb_detach_genpds() fbdev: s3fb: Revert mclk stop in suspend fbdev: mb862xxfb: Use int type to store negative error codes fbdev: Use string choices helpers fbdev: core: Fix ubsan warning in pixel_to_pat fbdev: s3fb: Implement 1 and 2 BPP modes, improve 4 BPP fbdev: s3fb: Implement powersave for S3 FB fbdev: xenfb: Use vmalloc_array to simplify code
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
=================
|
||||
What is aty128fb?
|
||||
=================
|
||||
|
||||
.. [This file is cloned from VesaFB/matroxfb]
|
||||
=========================================
|
||||
aty128fb - ATI Rage128 framebuffer driver
|
||||
=========================================
|
||||
|
||||
This is a driver for a graphic framebuffer for ATI Rage128 based devices
|
||||
on Intel and PPC boxes.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
==============
|
||||
What is efifb?
|
||||
==============
|
||||
===================================
|
||||
efifb - Generic EFI platform driver
|
||||
===================================
|
||||
|
||||
This is a generic EFI platform driver for systems with UEFI firmware. The
|
||||
system must be booted via the EFI stub for this to be usable. efifb supports
|
||||
|
||||
@@ -41,7 +41,6 @@ your board initialisation function::
|
||||
|
||||
ep93xx_register_fb(&some_board_fb_info);
|
||||
|
||||
=====================
|
||||
Video Attribute Flags
|
||||
=====================
|
||||
|
||||
@@ -79,7 +78,6 @@ EP93XXFB_USE_SDCSN2 Use SDCSn[2] for the framebuffer.
|
||||
EP93XXFB_USE_SDCSN3 Use SDCSn[3] for the framebuffer.
|
||||
=============================== ======================================
|
||||
|
||||
==================
|
||||
Platform callbacks
|
||||
==================
|
||||
|
||||
@@ -101,7 +99,6 @@ obtained as follows::
|
||||
/* Board specific framebuffer setup */
|
||||
}
|
||||
|
||||
======================
|
||||
Setting the video mode
|
||||
======================
|
||||
|
||||
@@ -119,7 +116,6 @@ set when the module is installed::
|
||||
|
||||
modprobe ep93xx-fb video=320x240
|
||||
|
||||
==============
|
||||
Screenpage bug
|
||||
==============
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
=============
|
||||
What is gxfb?
|
||||
=============
|
||||
|
||||
.. [This file is cloned from VesaFB/aty128fb]
|
||||
=======================================
|
||||
gxfb - AMD Geode GX2 framebuffer driver
|
||||
=======================================
|
||||
|
||||
This is a graphics framebuffer driver for AMD Geode GX2 based processors.
|
||||
|
||||
|
||||
@@ -4,42 +4,52 @@
|
||||
Frame Buffer
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
General information
|
||||
===================
|
||||
|
||||
api
|
||||
arkfb
|
||||
aty128fb
|
||||
cirrusfb
|
||||
cmap_xfbdev
|
||||
deferred_io
|
||||
efifb
|
||||
ep93xx-fb
|
||||
fbcon
|
||||
framebuffer
|
||||
gxfb
|
||||
intel810
|
||||
internals
|
||||
lxfb
|
||||
matroxfb
|
||||
metronomefb
|
||||
modedb
|
||||
pvr2fb
|
||||
pxafb
|
||||
s3fb
|
||||
sa1100fb
|
||||
sh7760fb
|
||||
sisfb
|
||||
sm501
|
||||
sm712fb
|
||||
sstfb
|
||||
tgafb
|
||||
tridentfb
|
||||
udlfb
|
||||
uvesafb
|
||||
vesafb
|
||||
viafb
|
||||
vt8623fb
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
api
|
||||
cmap_xfbdev
|
||||
deferred_io
|
||||
fbcon
|
||||
framebuffer
|
||||
internals
|
||||
modedb
|
||||
|
||||
Driver documentation
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
arkfb
|
||||
aty128fb
|
||||
cirrusfb
|
||||
efifb
|
||||
ep93xx-fb
|
||||
gxfb
|
||||
intel810
|
||||
lxfb
|
||||
matroxfb
|
||||
metronomefb
|
||||
pvr2fb
|
||||
pxafb
|
||||
s3fb
|
||||
sa1100fb
|
||||
sh7760fb
|
||||
sisfb
|
||||
sm501
|
||||
sm712fb
|
||||
sstfb
|
||||
tgafb
|
||||
tridentfb
|
||||
udlfb
|
||||
uvesafb
|
||||
vesafb
|
||||
viafb
|
||||
vt8623fb
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
=============
|
||||
What is lxfb?
|
||||
=============
|
||||
|
||||
.. [This file is cloned from VesaFB/aty128fb]
|
||||
|
||||
======================================
|
||||
lxfb - AMD Geode LX framebuffer driver
|
||||
======================================
|
||||
|
||||
This is a graphics framebuffer driver for AMD Geode LX based processors.
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
=================
|
||||
What is matroxfb?
|
||||
=================
|
||||
|
||||
.. [This file is cloned from VesaFB. Thanks go to Gerd Knorr]
|
||||
|
||||
================================================
|
||||
matroxfb - Framebuffer driver for Matrox devices
|
||||
================================================
|
||||
|
||||
This is a driver for a graphic framebuffer for Matrox devices on
|
||||
Alpha, Intel and PPC boxes.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
===============
|
||||
What is pvr2fb?
|
||||
===============
|
||||
===============================================
|
||||
pvr2fb - PowerVR 2 graphics frame buffer driver
|
||||
===============================================
|
||||
|
||||
This is a driver for PowerVR 2 based graphics frame buffers, such as the
|
||||
one found in the Dreamcast.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
=================
|
||||
What is sa1100fb?
|
||||
=================
|
||||
|
||||
.. [This file is cloned from VesaFB/matroxfb]
|
||||
|
||||
=================================================
|
||||
sa1100fb - SA-1100 LCD graphic framebuffer driver
|
||||
=================================================
|
||||
|
||||
This is a driver for a graphic framebuffer for the SA-1100 LCD
|
||||
controller.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
==============
|
||||
What is sisfb?
|
||||
==============
|
||||
=====================================
|
||||
sisfb - SiS framebuffer device driver
|
||||
=====================================
|
||||
|
||||
sisfb is a framebuffer device driver for SiS (Silicon Integrated Systems)
|
||||
graphics chips. Supported are:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
================
|
||||
What is sm712fb?
|
||||
================
|
||||
==========================================================
|
||||
sm712fb - Silicon Motion SM712 graphics framebuffer driver
|
||||
==========================================================
|
||||
|
||||
This is a graphics framebuffer driver for Silicon Motion SM712 based processors.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
==============
|
||||
What is tgafb?
|
||||
==============
|
||||
=======================================
|
||||
tgafb - TGA graphics framebuffer driver
|
||||
=======================================
|
||||
|
||||
This is a driver for DECChip 21030 based graphics framebuffers, a.k.a. TGA
|
||||
cards, which are usually found in older Digital Alpha systems. The
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
==============
|
||||
What is udlfb?
|
||||
==============
|
||||
==================================
|
||||
udlfb - DisplayLink USB 2.0 driver
|
||||
==================================
|
||||
|
||||
This is a driver for DisplayLink USB 2.0 era graphics chips.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
===============
|
||||
What is vesafb?
|
||||
===============
|
||||
===========================================
|
||||
vesafb - Generic graphic framebuffer driver
|
||||
===========================================
|
||||
|
||||
This is a generic driver for a graphic framebuffer on intel boxes.
|
||||
|
||||
|
||||
@@ -126,9 +126,9 @@ config FB_ACORN
|
||||
config FB_CLPS711X
|
||||
tristate "CLPS711X LCD support"
|
||||
depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
|
||||
depends on LCD_CLASS_DEVICE
|
||||
select FB_IOMEM_HELPERS
|
||||
select FB_MODE_HELPERS
|
||||
select LCD_CLASS_DEVICE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Say Y to enable the Framebuffer driver for the Cirrus Logic
|
||||
@@ -150,7 +150,7 @@ config FB_IMX
|
||||
tristate "Freescale i.MX1/21/25/27 LCD support"
|
||||
depends on FB && HAVE_CLK && HAS_IOMEM
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select LCD_CLASS_DEVICE
|
||||
depends on LCD_CLASS_DEVICE
|
||||
select FB_IOMEM_HELPERS
|
||||
select FB_MODE_HELPERS
|
||||
select VIDEOMODE_HELPERS
|
||||
@@ -948,9 +948,6 @@ config FB_RADEON
|
||||
a framebuffer device. There are both PCI and AGP versions. You
|
||||
don't need to choose this to run the Radeon in plain VGA mode.
|
||||
|
||||
There is a product page at
|
||||
https://products.amd.com/en-us/GraphicCardResult.aspx
|
||||
|
||||
config FB_RADEON_I2C
|
||||
bool "DDC/I2C for ATI Radeon support"
|
||||
depends on FB_RADEON
|
||||
@@ -1060,6 +1057,7 @@ config FB_S3
|
||||
select FB_TILEBLITTING
|
||||
select FB_SVGALIB
|
||||
select VGASTATE
|
||||
select FB_CFB_REV_PIXELS_IN_BYTE
|
||||
select FONT_8x16 if FRAMEBUFFER_CONSOLE
|
||||
help
|
||||
Driver for graphics boards with S3 Trio / S3 Virge chip.
|
||||
|
||||
@@ -160,6 +160,11 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
|
||||
image.height = vc->vc_font.height;
|
||||
image.depth = 1;
|
||||
|
||||
if (image.dy >= info->var.yres)
|
||||
return;
|
||||
|
||||
image.height = min(image.height, info->var.yres - image.dy);
|
||||
|
||||
if (attribute) {
|
||||
buf = kmalloc(cellsize, GFP_ATOMIC);
|
||||
if (!buf)
|
||||
@@ -173,6 +178,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
|
||||
cnt = count;
|
||||
|
||||
image.width = vc->vc_font.width * cnt;
|
||||
|
||||
if (image.dx >= info->var.xres)
|
||||
break;
|
||||
|
||||
if (image.dx + image.width > info->var.xres) {
|
||||
image.width = info->var.xres - image.dx;
|
||||
cnt = image.width / vc->vc_font.width;
|
||||
if (cnt == 0)
|
||||
break;
|
||||
image.width = cnt * vc->vc_font.width;
|
||||
}
|
||||
|
||||
pitch = DIV_ROUND_UP(image.width, 8) + scan_align;
|
||||
pitch &= ~scan_align;
|
||||
size = pitch * image.height + buf_align;
|
||||
|
||||
@@ -40,7 +40,7 @@ int fb_get_options(const char *name, char **option)
|
||||
bool enabled;
|
||||
|
||||
if (name)
|
||||
is_of = strncmp(name, "offb", 4);
|
||||
is_of = !strncmp(name, "offb", 4);
|
||||
|
||||
enabled = __video_get_options(name, &options, is_of);
|
||||
|
||||
|
||||
@@ -92,8 +92,7 @@ static unsigned long pixel_to_pat(int bpp, u32 color)
|
||||
pattern = pattern | pattern << bpp;
|
||||
break;
|
||||
default:
|
||||
pattern = color;
|
||||
break;
|
||||
return color;
|
||||
}
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
pattern <<= (BITS_PER_LONG % bpp);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <video/of_videomode.h>
|
||||
#include <video/videomode.h>
|
||||
#include "../edid.h"
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
/*
|
||||
* EDID parser
|
||||
@@ -320,9 +321,9 @@ static void get_dpms_capabilities(unsigned char flags,
|
||||
if (flags & DPMS_STANDBY)
|
||||
specs->dpms |= FB_DPMS_STANDBY;
|
||||
DPRINTK(" DPMS: Active %s, Suspend %s, Standby %s\n",
|
||||
(flags & DPMS_ACTIVE_OFF) ? "yes" : "no",
|
||||
(flags & DPMS_SUSPEND) ? "yes" : "no",
|
||||
(flags & DPMS_STANDBY) ? "yes" : "no");
|
||||
str_yes_no(flags & DPMS_ACTIVE_OFF),
|
||||
str_yes_no(flags & DPMS_SUSPEND),
|
||||
str_yes_no(flags & DPMS_STANDBY));
|
||||
}
|
||||
|
||||
static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
|
||||
|
||||
@@ -674,7 +674,7 @@ static int of_platform_mb862xx_probe(struct platform_device *ofdev)
|
||||
struct fb_info *info;
|
||||
struct resource res;
|
||||
resource_size_t res_size;
|
||||
unsigned long ret = -ENODEV;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (of_address_to_resource(np, 0, &res)) {
|
||||
dev_err(dev, "Invalid address\n");
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/string_choices.h>
|
||||
#ifdef CONFIG_BOOTX_TEXT
|
||||
#include <asm/btext.h>
|
||||
#endif
|
||||
@@ -622,7 +623,7 @@ static int nvidiafb_set_par(struct fb_info *info)
|
||||
else
|
||||
par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
|
||||
printk(KERN_INFO PFX "Flat panel dithering %s\n",
|
||||
par->FPDither ? "enabled" : "disabled");
|
||||
str_enabled_disabled(par->FPDither));
|
||||
}
|
||||
|
||||
info->fix.visual = (info->var.bits_per_pixel == 8) ?
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <linux/soc/pxa/cpu.h>
|
||||
#include <video/of_display_timing.h>
|
||||
#include <video/videomode.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -1419,7 +1420,7 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
|
||||
|
||||
if (ret < 0)
|
||||
pr_warn("Unable to %s LCD supply regulator: %d\n",
|
||||
on ? "enable" : "disable", ret);
|
||||
str_enable_disable(on), ret);
|
||||
else
|
||||
fbi->lcd_supply_enabled = on;
|
||||
}
|
||||
|
||||
@@ -50,10 +50,14 @@ struct s3fb_info {
|
||||
static const struct svga_fb_format s3fb_formats[] = {
|
||||
{ 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
|
||||
FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16},
|
||||
{ 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0,
|
||||
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16},
|
||||
{ 1, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0}, 2,
|
||||
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 32, 64},
|
||||
{ 2, {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, 2,
|
||||
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 16, 32},
|
||||
{ 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 1,
|
||||
FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16},
|
||||
{ 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 2,
|
||||
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16},
|
||||
{ 8, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
|
||||
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8},
|
||||
{16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0,
|
||||
@@ -557,7 +561,7 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
|
||||
/* 32bpp mode is not supported on VIRGE VX,
|
||||
24bpp is not supported on others */
|
||||
if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))
|
||||
if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 9) : (rv == 8))
|
||||
rv = -EINVAL;
|
||||
|
||||
if (rv < 0) {
|
||||
@@ -607,7 +611,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
struct s3fb_info *par = info->par;
|
||||
u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
|
||||
u32 bpp = info->var.bits_per_pixel;
|
||||
u32 htotal, hsstart;
|
||||
u32 htotal, hsstart, pel_msk;
|
||||
|
||||
if (bpp != 0) {
|
||||
info->fix.ypanstep = 1;
|
||||
@@ -617,9 +621,11 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
info->tileops = NULL;
|
||||
|
||||
/* in 4bpp supports 8p wide tiles only, any tiles otherwise */
|
||||
if (bpp == 4) {
|
||||
if (bpp == 4 && (info->var.nonstd & 1) != 0) {
|
||||
int i;
|
||||
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
|
||||
set_bit(8 - 1, info->pixmap.blit_x);
|
||||
for (i = 8; i <= FB_MAX_BLIT_WIDTH; i += 8)
|
||||
set_bit(i - 1, info->pixmap.blit_x);
|
||||
} else {
|
||||
bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
|
||||
}
|
||||
@@ -730,7 +736,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
vga_wcrt(par->state.vgabase, 0x50, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x67, 0x50);
|
||||
msleep(10); /* screen remains blank sometimes without this */
|
||||
vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
|
||||
vga_wcrt(par->state.vgabase, 0x63, (mode <= 4) ? 0x90 : 0x09);
|
||||
vga_wcrt(par->state.vgabase, 0x66, 0x90);
|
||||
}
|
||||
|
||||
@@ -763,12 +769,17 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
|
||||
multiplex = 0;
|
||||
hmul = 1;
|
||||
pel_msk = 0xff;
|
||||
|
||||
svga_wcrt_mask(par->state.vgabase, 0x08, 0x00, 0x60);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
|
||||
|
||||
/* Set mode-specific register values */
|
||||
switch (mode) {
|
||||
case 0:
|
||||
fb_dbg(info, "text mode\n");
|
||||
svga_set_textmode_vga_regs(par->state.vgabase);
|
||||
pel_msk = 0x0f;
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
@@ -783,8 +794,11 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
fb_dbg(info, "4 bit pseudocolor\n");
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
fb_dbg(info, "1 bit pseudocolor\n");
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x10, 0x14);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x08, 0x60, 0x60);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60);
|
||||
pel_msk = 0x01;
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
@@ -794,7 +808,13 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 2:
|
||||
fb_dbg(info, "4 bit pseudocolor, planar\n");
|
||||
fb_dbg(info, "2 bit pseudocolor\n");
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x04, 0x14);
|
||||
svga_wseq_mask(par->state.vgabase, 0x04, 0x08, 0x08);
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x08, 0x20, 0x60);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60);
|
||||
pel_msk = 0x03;
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
@@ -804,8 +824,35 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 3:
|
||||
fb_dbg(info, "4 bit pseudocolor, planar\n");
|
||||
pel_msk = 0x0f;
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60);
|
||||
|
||||
/* disable enhanced mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 4:
|
||||
fb_dbg(info, "4 bit pseudocolor\n");
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
svga_wattr(par->state.vgabase, 0x33, 0x01);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x40, 0x60);
|
||||
pel_msk = 0xf0;
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
|
||||
/* disable enhanced mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 5:
|
||||
fb_dbg(info, "8 bit pseudocolor\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x20, 0x60);
|
||||
if (info->var.pixclock > 20000 ||
|
||||
par->chip == CHIP_357_VIRGE_GX2 ||
|
||||
par->chip == CHIP_359_VIRGE_GX2P ||
|
||||
@@ -819,7 +866,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
multiplex = 1;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
fb_dbg(info, "5/5/5 truecolor\n");
|
||||
if (par->chip == CHIP_988_VIRGE_VX) {
|
||||
if (info->var.pixclock > 20000)
|
||||
@@ -847,7 +894,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
hmul = 2;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
fb_dbg(info, "5/6/5 truecolor\n");
|
||||
if (par->chip == CHIP_988_VIRGE_VX) {
|
||||
if (info->var.pixclock > 20000)
|
||||
@@ -875,12 +922,12 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
hmul = 2;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 8:
|
||||
/* VIRGE VX case */
|
||||
fb_dbg(info, "8/8/8 truecolor\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
|
||||
break;
|
||||
case 7:
|
||||
case 9:
|
||||
fb_dbg(info, "8/8/8/8 truecolor\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
|
||||
@@ -889,6 +936,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
fb_err(info, "unsupported mode - bug\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
vga_w(par->state.vgabase, VGA_PEL_MSK, pel_msk);
|
||||
|
||||
if (par->chip != CHIP_988_VIRGE_VX) {
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
|
||||
@@ -927,33 +975,26 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
u_int transp, struct fb_info *fb)
|
||||
{
|
||||
struct s3fb_info *par = fb->par;
|
||||
int cols;
|
||||
|
||||
switch (fb->var.bits_per_pixel) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
if (regno >= 16)
|
||||
return -EINVAL;
|
||||
|
||||
if ((fb->var.bits_per_pixel == 4) &&
|
||||
(fb->var.nonstd == 0)) {
|
||||
outb(0xF0, VGA_PEL_MSK);
|
||||
outb(regno*16, VGA_PEL_IW);
|
||||
} else {
|
||||
outb(0x0F, VGA_PEL_MSK);
|
||||
outb(regno, VGA_PEL_IW);
|
||||
}
|
||||
outb(red >> 10, VGA_PEL_D);
|
||||
outb(green >> 10, VGA_PEL_D);
|
||||
outb(blue >> 10, VGA_PEL_D);
|
||||
break;
|
||||
case 8:
|
||||
if (regno >= 256)
|
||||
cols = 1 << (fb->var.bits_per_pixel ? fb->var.bits_per_pixel : 4);
|
||||
if (regno >= cols)
|
||||
return -EINVAL;
|
||||
|
||||
outb(0xFF, VGA_PEL_MSK);
|
||||
outb(regno, VGA_PEL_IW);
|
||||
outb(red >> 10, VGA_PEL_D);
|
||||
outb(green >> 10, VGA_PEL_D);
|
||||
outb(blue >> 10, VGA_PEL_D);
|
||||
if ((fb->var.bits_per_pixel == 4) && ((fb->var.nonstd & 1) == 0))
|
||||
regno <<= 4;
|
||||
|
||||
vga_w(par->state.vgabase, VGA_PEL_IW, regno);
|
||||
vga_w(par->state.vgabase, VGA_PEL_D, red >> 10);
|
||||
vga_w(par->state.vgabase, VGA_PEL_D, green >> 10);
|
||||
vga_w(par->state.vgabase, VGA_PEL_D, blue >> 10);
|
||||
break;
|
||||
case 16:
|
||||
if (regno >= 16)
|
||||
@@ -988,34 +1029,30 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
static int s3fb_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
struct s3fb_info *par = info->par;
|
||||
u8 data;
|
||||
|
||||
data = (blank_mode == FB_BLANK_UNBLANK) ? 0x00 : 0x20;
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, data, 0x20);
|
||||
svga_wseq_mask(par->state.vgabase, 0x18, data, 0x20);
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
fb_dbg(info, "unblank\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
fb_dbg(info, "blank\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
default:
|
||||
data = 0x00;
|
||||
break;
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
fb_dbg(info, "hsync\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
data = 0x02;
|
||||
break;
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
fb_dbg(info, "vsync\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
data = 0x04;
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
fb_dbg(info, "sync down\n");
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
data = 0x06;
|
||||
break;
|
||||
}
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, data, 0x06);
|
||||
|
||||
data = (blank_mode == FB_BLANK_POWERDOWN) ? 0x01 : 0x00;
|
||||
svga_wseq_mask(par->state.vgabase, 0x14, data, 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1045,6 +1082,33 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get capabilities of accelerator based on the mode */
|
||||
|
||||
static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
|
||||
struct fb_var_screeninfo *var)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (var->bits_per_pixel == 0) {
|
||||
/* can only support 256 8x16 bitmap */
|
||||
bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH);
|
||||
set_bit(8 - 1, caps->x);
|
||||
bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT);
|
||||
set_bit(16 - 1, caps->y);
|
||||
caps->len = 256;
|
||||
} else {
|
||||
if (var->bits_per_pixel == 4 && (var->nonstd & 1) != 0) {
|
||||
bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH);
|
||||
for (i = 8; i <= FB_MAX_BLIT_WIDTH; i += 8)
|
||||
set_bit(i - 1, caps->x);
|
||||
} else {
|
||||
bitmap_fill(caps->x, FB_MAX_BLIT_WIDTH);
|
||||
}
|
||||
bitmap_fill(caps->y, FB_MAX_BLIT_HEIGHT);
|
||||
caps->len = ~(u32)0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Frame buffer operations */
|
||||
@@ -1063,7 +1127,7 @@ static const struct fb_ops s3fb_ops = {
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = s3fb_imageblit,
|
||||
__FB_DEFAULT_IOMEM_OPS_MMAP,
|
||||
.fb_get_caps = svga_get_caps,
|
||||
.fb_get_caps = s3fb_get_caps,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1445,6 +1509,8 @@ static int __maybe_unused s3_pci_suspend(struct device *dev)
|
||||
}
|
||||
|
||||
fb_set_suspend(info, 1);
|
||||
svga_wseq_mask(par->state.vgabase, 0x18, 0x20, 0x20);
|
||||
svga_wseq_mask(par->state.vgabase, 0x14, 0x01, 0x01);
|
||||
|
||||
mutex_unlock(&(par->open_lock));
|
||||
console_unlock();
|
||||
@@ -1471,6 +1537,9 @@ static int __maybe_unused s3_pci_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vga_wseq(par->state.vgabase, 0x08, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x18, 0x00, 0x20);
|
||||
svga_wseq_mask(par->state.vgabase, 0x14, 0x00, 0x01);
|
||||
s3fb_set_par(info);
|
||||
fb_set_suspend(info, 0);
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ struct simplefb_par {
|
||||
|
||||
static void simplefb_clocks_destroy(struct simplefb_par *par);
|
||||
static void simplefb_regulators_destroy(struct simplefb_par *par);
|
||||
static void simplefb_detach_genpds(void *res);
|
||||
|
||||
/*
|
||||
* fb_ops.fb_destroy is called by the last put_fb_info() call at the end
|
||||
@@ -105,6 +106,7 @@ static void simplefb_destroy(struct fb_info *info)
|
||||
|
||||
simplefb_regulators_destroy(info->par);
|
||||
simplefb_clocks_destroy(info->par);
|
||||
simplefb_detach_genpds(info->par);
|
||||
if (info->screen_base)
|
||||
iounmap(info->screen_base);
|
||||
|
||||
@@ -445,13 +447,14 @@ static void simplefb_detach_genpds(void *res)
|
||||
if (!IS_ERR_OR_NULL(par->genpds[i]))
|
||||
dev_pm_domain_detach(par->genpds[i], true);
|
||||
}
|
||||
par->num_genpds = 0;
|
||||
}
|
||||
|
||||
static int simplefb_attach_genpds(struct simplefb_par *par,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int i;
|
||||
unsigned int i, num_genpds;
|
||||
int err;
|
||||
|
||||
err = of_count_phandle_with_args(dev->of_node, "power-domains",
|
||||
@@ -465,26 +468,35 @@ static int simplefb_attach_genpds(struct simplefb_par *par,
|
||||
return err;
|
||||
}
|
||||
|
||||
par->num_genpds = err;
|
||||
num_genpds = err;
|
||||
|
||||
/*
|
||||
* Single power-domain devices are handled by the driver core, so
|
||||
* nothing to do here.
|
||||
*/
|
||||
if (par->num_genpds <= 1)
|
||||
if (num_genpds <= 1) {
|
||||
par->num_genpds = num_genpds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
par->genpds = devm_kcalloc(dev, par->num_genpds, sizeof(*par->genpds),
|
||||
par->genpds = devm_kcalloc(dev, num_genpds, sizeof(*par->genpds),
|
||||
GFP_KERNEL);
|
||||
if (!par->genpds)
|
||||
return -ENOMEM;
|
||||
|
||||
par->genpd_links = devm_kcalloc(dev, par->num_genpds,
|
||||
par->genpd_links = devm_kcalloc(dev, num_genpds,
|
||||
sizeof(*par->genpd_links),
|
||||
GFP_KERNEL);
|
||||
if (!par->genpd_links)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Set par->num_genpds only after genpds and genpd_links are allocated
|
||||
* to exit early from simplefb_detach_genpds() without full
|
||||
* initialisation.
|
||||
*/
|
||||
par->num_genpds = num_genpds;
|
||||
|
||||
for (i = 0; i < par->num_genpds; i++) {
|
||||
par->genpds[i] = dev_pm_domain_attach_by_id(dev, i);
|
||||
if (IS_ERR(par->genpds[i])) {
|
||||
@@ -506,9 +518,10 @@ static int simplefb_attach_genpds(struct simplefb_par *par,
|
||||
dev_warn(dev, "failed to link power-domain %u\n", i);
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, simplefb_detach_genpds, par);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static void simplefb_detach_genpds(void *res) { }
|
||||
static int simplefb_attach_genpds(struct simplefb_par *par,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
@@ -622,18 +635,20 @@ static int simplefb_probe(struct platform_device *pdev)
|
||||
ret = devm_aperture_acquire_for_platform_device(pdev, par->base, par->size);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to acquire aperture: %d\n", ret);
|
||||
goto error_regulators;
|
||||
goto error_genpds;
|
||||
}
|
||||
ret = register_framebuffer(info);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
|
||||
goto error_regulators;
|
||||
goto error_genpds;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
|
||||
|
||||
return 0;
|
||||
|
||||
error_genpds:
|
||||
simplefb_detach_genpds(par);
|
||||
error_regulators:
|
||||
simplefb_regulators_destroy(par);
|
||||
error_clocks:
|
||||
|
||||
@@ -390,7 +390,7 @@ static int xenfb_probe(struct xenbus_device *dev,
|
||||
|
||||
info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
|
||||
info->gfns = vmalloc(array_size(sizeof(unsigned long), info->nr_pages));
|
||||
info->gfns = vmalloc_array(info->nr_pages, sizeof(unsigned long));
|
||||
if (!info->gfns)
|
||||
goto error_nomem;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user