fbdev fixes and cleanups for 6.8-rc1:

- Remove intelfb fbdev driver (Thomas Zimmermann)
 - Remove amba-clcd fbdev driver (Linus Walleij)
 - Remove vmlfb Carillo Ranch fbdev driver (Matthew Wilcox)
 - fb_deferred_io flushing fixes (Nam Cao)
 - imxfb code fixes and cleanups (Dario Binacchi)
 - stifb primary screen detection cleanups (Thomas Zimmermann)
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCZaEregAKCRD3ErUQojoP
 X0c9AP0ZdpE1zWFdjYg7ucKhNGrMfXWS8auvkC0qdd9Q0psnmQD/Z22JIl/fpgrk
 0T74KAEd7MwMXGIUm5VKMe/AZJtaBgs=
 =/sky
 -----END PGP SIGNATURE-----

Merge tag 'fbdev-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev

Pull fbdev updates from Helge Deller:
 "Three fbdev drivers (~8500 lines of code) removed. The Carillo Ranch
  fbdev driver is for an Intel product which was never shipped, and for
  the intelfb and the amba-clcd drivers the drm drivers can be used
  instead.

  The other code changes are minor: some fb_deferred_io flushing fixes,
  imxfb margin fixes and stifb cleanups.

  Summary:
   - Remove intelfb fbdev driver (Thomas Zimmermann)
   - Remove amba-clcd fbdev driver (Linus Walleij)
   - Remove vmlfb Carillo Ranch fbdev driver (Matthew Wilcox)
   - fb_deferred_io flushing fixes (Nam Cao)
   - imxfb code fixes and cleanups (Dario Binacchi)
   - stifb primary screen detection cleanups (Thomas Zimmermann)"

* tag 'fbdev-for-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev: (28 commits)
  fbdev/intelfb: Remove driver
  fbdev/hyperv_fb: Do not clear global screen_info
  firmware/sysfb: Clear screen_info state after consuming it
  fbdev/hyperv_fb: Remove firmware framebuffers with aperture helpers
  drm/hyperv: Remove firmware framebuffers with aperture helper
  fbdev/sis: Remove dependency on screen_info
  video/logo: use %u format specifier for unsigned int values
  video/sticore: Remove info field from STI struct
  arch/parisc: Detect primary video device from device instance
  fbdev/stifb: Allocate fb_info instance with framebuffer_alloc()
  video/sticore: Store ROM device in STI struct
  fbdev: flush deferred IO before closing
  fbdev: flush deferred work in fb_deferred_io_fsync()
  fbdev: amba-clcd: Delete the old CLCD driver
  fbdev: Remove support for Carillo Ranch driver
  fbdev: hgafb: fix kernel-doc comments
  fbdev: mmp: Fix typo and wording in code comment
  fbdev: fsl-diu-fb: Fix sparse warning due to virt_to_phys() prototype change
  fbdev: imxfb: add '*/' on a separate line in block comment
  fbdev: imxfb: use __func__ for function name
  ...
This commit is contained in:
Linus Torvalds 2024-01-12 14:38:08 -08:00
commit d97a78423c
37 changed files with 208 additions and 8708 deletions

View File

@ -19,7 +19,6 @@ Frame Buffer
framebuffer
gxfb
intel810
intelfb
internals
lxfb
matroxfb

View File

@ -1,155 +0,0 @@
=============================================================
Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver
=============================================================
A. Introduction
===============
This is a framebuffer driver for various Intel 8xx/9xx compatible
graphics devices. These would include:
- Intel 830M
- Intel 845G
- Intel 852GM
- Intel 855GM
- Intel 865G
- Intel 915G
- Intel 915GM
- Intel 945G
- Intel 945GM
- Intel 945GME
- Intel 965G
- Intel 965GM
B. List of available options
=============================
a. "video=intelfb"
enables the intelfb driver
Recommendation: required
b. "mode=<xres>x<yres>[-<bpp>][@<refresh>]"
select mode
Recommendation: user preference
(default = 1024x768-32@70)
c. "vram=<value>"
select amount of system RAM in MB to allocate for the video memory
if not enough RAM was already allocated by the BIOS.
Recommendation: 1 - 4 MB.
(default = 4 MB)
d. "voffset=<value>"
select at what offset in MB of the logical memory to allocate the
framebuffer memory. The intent is to avoid the memory blocks
used by standard graphics applications (XFree86). Depending on your
usage, adjust the value up or down, (0 for maximum usage, 63/127 MB
for the least amount). Note, an arbitrary setting may conflict
with XFree86.
Recommendation: do not set
(default = 48 MB)
e. "accel"
enable text acceleration. This can be enabled/reenabled anytime
by using 'fbset -accel true/false'.
Recommendation: enable
(default = set)
f. "hwcursor"
enable cursor acceleration.
Recommendation: enable
(default = set)
g. "mtrr"
enable MTRR. This allows data transfers to the framebuffer memory
to occur in bursts which can significantly increase performance.
Not very helpful with the intel chips because of 'shared memory'.
Recommendation: set
(default = set)
h. "fixed"
disable mode switching.
Recommendation: do not set
(default = not set)
The binary parameters can be unset with a "no" prefix, example "noaccel".
The default parameter (not named) is the mode.
C. Kernel booting
=================
Separate each option/option-pair by commas (,) and the option from its value
with an equals sign (=) as in the following::
video=intelfb:option1,option2=value2
Sample Usage
------------
In /etc/lilo.conf, add the line::
append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8"
This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
will be enabled.
Remarks
-------
If setting this parameter doesn't work (you stay in a 80x25 text-mode),
you might need to set the "vga=<mode>" parameter too - see vesafb.txt
in this directory.
D. Module options
==================
The module parameters are essentially similar to the kernel
parameters. The main difference is that you need to include a Boolean value
(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
Example, to enable MTRR, include "mtrr=1".
Sample Usage
------------
Using the same setup as described above, load the module like this::
modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
Or just add the following to a configuration file in /etc/modprobe.d/::
options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
and just do a::
modprobe intelfb
E. Acknowledgment:
===================
1. Geert Uytterhoeven - his excellent howto and the virtual
framebuffer driver code made this possible.
2. Jeff Hartmann for his agpgart code.
3. David Dawes for his original kernel 2.4 code.
4. The X developers. Insights were provided just by reading the
XFree86 source code.
5. Antonino A. Daplas for his inspiring i810fb driver.
6. Andrew Morton for his kernel patches maintenance.
Sylvain

View File

@ -128,7 +128,6 @@ Code Seq# Include File Comments
'F' all linux/fb.h conflict!
'F' 01-02 drivers/scsi/pmcraid.h conflict!
'F' 20 drivers/video/fsl-diu-fb.h conflict!
'F' 20 drivers/video/intelfb/intelfb.h conflict!
'F' 20 linux/ivtvfb.h conflict!
'F' 20 linux/matroxfb.h conflict!
'F' 20 drivers/video/aty/atyfb_base.c conflict!

View File

@ -1693,11 +1693,6 @@ S: Odd Fixes
F: drivers/amba/
F: include/linux/amba/bus.h
ARM PRIMECELL CLCD PL110 DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Odd Fixes
F: drivers/video/fbdev/amba-clcd.*
ARM PRIMECELL KMI PL050 DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Odd Fixes
@ -10732,13 +10727,6 @@ S: Supported
F: drivers/infiniband/hw/irdma/
F: include/uapi/rdma/irdma-abi.h
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
M: Maik Broemme <mbroemme@libmpq.org>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: Documentation/fb/intelfb.rst
F: drivers/video/fbdev/intelfb/
INTEL GPIO DRIVERS
M: Andy Shevchenko <andy@kernel.org>
L: linux-gpio@vger.kernel.org

View File

@ -21,6 +21,6 @@ int fb_is_primary_device(struct fb_info *info)
return true;
/* return true if it's the default built-in framebuffer driver */
return (sti->info == info);
return (sti->dev == info->device);
}
EXPORT_SYMBOL(fb_is_primary_device);

View File

@ -71,9 +71,8 @@ obj-y += gpu/
obj-$(CONFIG_CONNECTOR) += connector/
# i810fb and intelfb depend on char/agp/
# i810fb depends on char/agp/
obj-$(CONFIG_FB_I810) += video/fbdev/i810/
obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ nfc/

View File

@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(sysfb_disable);
static __init int sysfb_init(void)
{
struct screen_info *si = &screen_info;
const struct screen_info *si = &screen_info;
struct simplefb_platform_data mode;
const char *name;
bool compatible;
@ -119,6 +119,18 @@ static __init int sysfb_init(void)
if (ret)
goto err;
/*
* The firmware framebuffer is now maintained by the created
* device. Disable screen_info after we've consumed it. Prevents
* invalid access during kexec reboots.
*
* TODO: Vgacon still relies on the global screen_info. Make
* vgacon work with the platform device, so we can clear
* the screen_info unconditionally.
*/
if (strcmp(name, "platform-framebuffer"))
screen_info.orig_video_isVGA = 0;
goto unlock_mutex;
err:
platform_device_put(pd);

View File

@ -7,7 +7,6 @@
#include <linux/hyperv.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/screen_info.h>
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
@ -73,11 +72,6 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv,
struct drm_device *dev = &hv->dev;
int ret;
if (IS_ENABLED(CONFIG_SYSFB))
drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base,
screen_info.lfb_size,
&hyperv_driver);
hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024;
ret = vmbus_allocate_mmio(&hv->mem, hdev, 0, -1, hv->fb_size, 0x100000,
@ -130,6 +124,8 @@ static int hyperv_vmbus_probe(struct hv_device *hdev,
goto err_hv_set_drv_data;
}
drm_aperture_remove_framebuffers(&hyperv_driver);
ret = hyperv_setup_vram(hv, hdev);
if (ret)
goto err_vmbus_close;

View File

@ -235,13 +235,6 @@ config BACKLIGHT_HP700
If you have an HP Jornada 700 series,
say Y to include backlight control driver.
config BACKLIGHT_CARILLO_RANCH
tristate "Intel Carillo Ranch Backlight Driver"
depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
help
If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
backlight driver.
config BACKLIGHT_PWM
tristate "Generic PWM based Backlight Driver"
depends on PWM

View File

@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o

View File

@ -1,264 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Intel Corp. 2007.
* All Rights Reserved.
*
* Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
* develop this driver.
*
* This file is part of the Carillo Ranch video subsystem driver.
*
* Authors:
* Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
* Alan Hourihane <alanh-at-tungstengraphics-dot-com>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/lcd.h>
#include <linux/pci.h>
#include <linux/slab.h>
/* The LVDS- and panel power controls sits on the
* GPIO port of the ISA bridge.
*/
#define CRVML_DEVICE_LPC 0x27B8
#define CRVML_REG_GPIOBAR 0x48
#define CRVML_REG_GPIOEN 0x4C
#define CRVML_GPIOEN_BIT (1 << 4)
#define CRVML_PANEL_PORT 0x38
#define CRVML_LVDS_ON 0x00000001
#define CRVML_PANEL_ON 0x00000002
#define CRVML_BACKLIGHT_OFF 0x00000004
/* The PLL Clock register sits on Host bridge */
#define CRVML_DEVICE_MCH 0x5001
#define CRVML_REG_MCHBAR 0x44
#define CRVML_REG_MCHEN 0x54
#define CRVML_MCHEN_BIT (1 << 28)
#define CRVML_MCHMAP_SIZE 4096
#define CRVML_REG_CLOCK 0xc3c
#define CRVML_CLOCK_SHIFT 8
#define CRVML_CLOCK_MASK 0x00000f00
static struct pci_dev *lpc_dev;
static u32 gpio_bar;
struct cr_panel {
struct backlight_device *cr_backlight_device;
struct lcd_device *cr_lcd_device;
};
static int cr_backlight_set_intensity(struct backlight_device *bd)
{
u32 addr = gpio_bar + CRVML_PANEL_PORT;
u32 cur = inl(addr);
if (backlight_get_brightness(bd) == 0) {
/* OFF */
cur |= CRVML_BACKLIGHT_OFF;
outl(cur, addr);
} else {
/* FULL ON */
cur &= ~CRVML_BACKLIGHT_OFF;
outl(cur, addr);
}
return 0;
}
static int cr_backlight_get_intensity(struct backlight_device *bd)
{
u32 addr = gpio_bar + CRVML_PANEL_PORT;
u32 cur = inl(addr);
u8 intensity;
if (cur & CRVML_BACKLIGHT_OFF)
intensity = 0;
else
intensity = 1;
return intensity;
}
static const struct backlight_ops cr_backlight_ops = {
.get_brightness = cr_backlight_get_intensity,
.update_status = cr_backlight_set_intensity,
};
static void cr_panel_on(void)
{
u32 addr = gpio_bar + CRVML_PANEL_PORT;
u32 cur = inl(addr);
if (!(cur & CRVML_PANEL_ON)) {
/* Make sure LVDS controller is down. */
if (cur & 0x00000001) {
cur &= ~CRVML_LVDS_ON;
outl(cur, addr);
}
/* Power up Panel */
schedule_timeout(HZ / 10);
cur |= CRVML_PANEL_ON;
outl(cur, addr);
}
/* Power up LVDS controller */
if (!(cur & CRVML_LVDS_ON)) {
schedule_timeout(HZ / 10);
outl(cur | CRVML_LVDS_ON, addr);
}
}
static void cr_panel_off(void)
{
u32 addr = gpio_bar + CRVML_PANEL_PORT;
u32 cur = inl(addr);
/* Power down LVDS controller first to avoid high currents */
if (cur & CRVML_LVDS_ON) {
cur &= ~CRVML_LVDS_ON;
outl(cur, addr);
}
if (cur & CRVML_PANEL_ON) {
schedule_timeout(HZ / 10);
outl(cur & ~CRVML_PANEL_ON, addr);
}
}
static int cr_lcd_set_power(struct lcd_device *ld, int power)
{
if (power == FB_BLANK_UNBLANK)
cr_panel_on();
if (power == FB_BLANK_POWERDOWN)
cr_panel_off();
return 0;
}
static struct lcd_ops cr_lcd_ops = {
.set_power = cr_lcd_set_power,
};
static int cr_backlight_probe(struct platform_device *pdev)
{
struct backlight_properties props;
struct backlight_device *bdp;
struct lcd_device *ldp;
struct cr_panel *crp;
u8 dev_en;
lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
CRVML_DEVICE_LPC, NULL);
if (!lpc_dev) {
pr_err("INTEL CARILLO RANCH LPC not found.\n");
return -ENODEV;
}
pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en);
if (!(dev_en & CRVML_GPIOEN_BIT)) {
pr_err("Carillo Ranch GPIO device was not enabled.\n");
pci_dev_put(lpc_dev);
return -ENODEV;
}
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
bdp = devm_backlight_device_register(&pdev->dev, "cr-backlight",
&pdev->dev, NULL, &cr_backlight_ops,
&props);
if (IS_ERR(bdp)) {
pci_dev_put(lpc_dev);
return PTR_ERR(bdp);
}
ldp = devm_lcd_device_register(&pdev->dev, "cr-lcd", &pdev->dev, NULL,
&cr_lcd_ops);
if (IS_ERR(ldp)) {
pci_dev_put(lpc_dev);
return PTR_ERR(ldp);
}
pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
&gpio_bar);
gpio_bar &= ~0x3F;
crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);
if (!crp) {
pci_dev_put(lpc_dev);
return -ENOMEM;
}
crp->cr_backlight_device = bdp;
crp->cr_lcd_device = ldp;
crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
crp->cr_backlight_device->props.brightness = 0;
cr_backlight_set_intensity(crp->cr_backlight_device);
cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
platform_set_drvdata(pdev, crp);
return 0;
}
static void cr_backlight_remove(struct platform_device *pdev)
{
struct cr_panel *crp = platform_get_drvdata(pdev);
crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN;
crp->cr_backlight_device->props.brightness = 0;
crp->cr_backlight_device->props.max_brightness = 0;
cr_backlight_set_intensity(crp->cr_backlight_device);
cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN);
pci_dev_put(lpc_dev);
}
static struct platform_driver cr_backlight_driver = {
.probe = cr_backlight_probe,
.remove_new = cr_backlight_remove,
.driver = {
.name = "cr_backlight",
},
};
static struct platform_device *crp;
static int __init cr_backlight_init(void)
{
int ret = platform_driver_register(&cr_backlight_driver);
if (ret)
return ret;
crp = platform_device_register_simple("cr_backlight", -1, NULL, 0);
if (IS_ERR(crp)) {
platform_driver_unregister(&cr_backlight_driver);
return PTR_ERR(crp);
}
pr_info("Carillo Ranch Backlight Driver Initialized.\n");
return 0;
}
static void __exit cr_backlight_exit(void)
{
platform_device_unregister(crp);
platform_driver_unregister(&cr_backlight_driver);
}
module_init(cr_backlight_init);
module_exit(cr_backlight_exit);
MODULE_AUTHOR("Tungsten Graphics Inc.");
MODULE_DESCRIPTION("Carillo Ranch Backlight Driver");
MODULE_LICENSE("GPL");

View File

@ -116,24 +116,6 @@ config FB_PM2_FIFO_DISCONNECT
help
Support the Permedia2 FIFO disconnect feature.
config FB_ARMCLCD
tristate "ARM PrimeCell PL110 support"
depends on ARM || ARM64 || COMPILE_TEST
depends on FB && ARM_AMBA && HAS_IOMEM
select FB_IOMEM_HELPERS
select FB_MODE_HELPERS if OF
select VIDEOMODE_HELPERS if OF
select BACKLIGHT_CLASS_DEVICE if OF
help
This framebuffer device driver is for the ARM PrimeCell PL110
Colour LCD controller. ARM PrimeCells provide the building
blocks for System on a Chip devices.
If you want to compile this as a module (=code which can be
inserted into and removed from the running kernel), say M
here and read <file:Documentation/kbuild/modules.rst>. The module
will be called amba-clcd.
config FB_ACORN
bool "Acorn VIDC support"
depends on (FB = y) && ARM && ARCH_ACORN
@ -839,60 +821,6 @@ config FB_I810_I2C
If unsure, say Y.
config FB_LE80578
tristate "Intel LE80578 (Vermilion) support"
depends on FB && PCI && X86
select FB_IOMEM_HELPERS
select FB_MODE_HELPERS
select VIDEO_NOMODESET
help
This driver supports the LE80578 (Vermilion Range) chipset
config FB_CARILLO_RANCH
tristate "Intel Carillo Ranch support"
depends on FB_LE80578 && FB && PCI && X86
help
This driver supports the LE80578 (Carillo Ranch) board
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
depends on FB && PCI && X86 && AGP_INTEL && EXPERT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_IOMEM_FOPS
select FB_MODE_HELPERS
select BOOT_VESA_SUPPORT if FB_INTEL = y
select VIDEO_NOMODESET
depends on !DRM_I915
help
This driver supports the on-board graphics built in to the Intel
830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
Say Y if you have and plan to use such a board.
To make FB_INTEL=Y work you need to say AGP_INTEL=y too.
To compile this driver as a module, choose M here: the
module will be called intelfb.
For more information, please read <file:Documentation/fb/intelfb.rst>
config FB_INTEL_DEBUG
bool "Intel driver Debug Messages"
depends on FB_INTEL
help
Say Y here if you want the Intel driver to output all sorts
of debugging information to provide to the maintainer when
something goes wrong.
config FB_INTEL_I2C
bool "DDC/I2C for Intel framebuffer support"
depends on FB_INTEL
select FB_DDC
default y
help
Say Y here if you want DDC/I2C support for your on-board Intel graphics.
config FB_MATROX
tristate "Matrox acceleration"
depends on FB && PCI

View File

@ -42,7 +42,6 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_VT8623) += vt8623fb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_LE80578) += vermilion/
obj-$(CONFIG_FB_S3) += s3fb.o
obj-$(CONFIG_FB_ARK) += arkfb.o
obj-$(CONFIG_FB_STI) += stifb.o
@ -75,7 +74,6 @@ obj-$(CONFIG_FB_HIT) += hitfb.o
obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
obj-$(CONFIG_FB_68328) += 68328fb.o
obj-$(CONFIG_FB_GBE) += gbefb.o

View File

@ -1,986 +0,0 @@
/*
* linux/drivers/video/amba-clcd.c
*
* Copyright (C) 2001 ARM Limited, by David A Rusling
* Updated to 2.5, Deep Blue Solutions Ltd.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*
* ARM PrimeCell PL110 Color LCD Controller
*/
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/backlight.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <video/display_timing.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>
#define to_clcd(info) container_of(info, struct clcd_fb, fb)
/* This is limited to 16 characters when displayed by X startup */
static const char *clcd_name = "CLCD FB";
static inline void clcdfb_set_start(struct clcd_fb *fb)
{
unsigned long ustart = fb->fb.fix.smem_start;
unsigned long lstart;
ustart += fb->fb.var.yoffset * fb->fb.fix.line_length;
lstart = ustart + fb->fb.var.yres * fb->fb.fix.line_length / 2;
writel(ustart, fb->regs + CLCD_UBAS);
writel(lstart, fb->regs + CLCD_LBAS);
}
static void clcdfb_disable(struct clcd_fb *fb)
{
u32 val;
if (fb->board->disable)
fb->board->disable(fb);
if (fb->panel->backlight) {
fb->panel->backlight->props.power = FB_BLANK_POWERDOWN;
backlight_update_status(fb->panel->backlight);
}
val = readl(fb->regs + fb->off_cntl);
if (val & CNTL_LCDPWR) {
val &= ~CNTL_LCDPWR;
writel(val, fb->regs + fb->off_cntl);
msleep(20);
}
if (val & CNTL_LCDEN) {
val &= ~CNTL_LCDEN;
writel(val, fb->regs + fb->off_cntl);
}
/*
* Disable CLCD clock source.
*/
if (fb->clk_enabled) {
fb->clk_enabled = false;
clk_disable(fb->clk);
}
}
static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
{
/*
* Enable the CLCD clock source.
*/
if (!fb->clk_enabled) {
fb->clk_enabled = true;
clk_enable(fb->clk);
}
/*
* Bring up by first enabling..
*/
cntl |= CNTL_LCDEN;
writel(cntl, fb->regs + fb->off_cntl);
msleep(20);
/*
* and now apply power.
*/
cntl |= CNTL_LCDPWR;
writel(cntl, fb->regs + fb->off_cntl);
/*
* Turn on backlight
*/
if (fb->panel->backlight) {
fb->panel->backlight->props.power = FB_BLANK_UNBLANK;
backlight_update_status(fb->panel->backlight);
}
/*
* finally, enable the interface.
*/
if (fb->board->enable)
fb->board->enable(fb);
}
static int
clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
{
u32 caps;
int ret = 0;
if (fb->panel->caps && fb->board->caps)
caps = fb->panel->caps & fb->board->caps;
else {
/* Old way of specifying what can be used */
caps = fb->panel->cntl & CNTL_BGR ?
CLCD_CAP_BGR : CLCD_CAP_RGB;
/* But mask out 444 modes as they weren't supported */
caps &= ~CLCD_CAP_444;
}
/* Only TFT panels can do RGB888/BGR888 */
if (!(fb->panel->cntl & CNTL_LCDTFT))
caps &= ~CLCD_CAP_888;
memset(&var->transp, 0, sizeof(var->transp));
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.msb_right = 0;
switch (var->bits_per_pixel) {
case 1:
case 2:
case 4:
case 8:
/* If we can't do 5551, reject */
caps &= CLCD_CAP_5551;
if (!caps) {
ret = -EINVAL;
break;
}
var->red.length = var->bits_per_pixel;
var->red.offset = 0;
var->green.length = var->bits_per_pixel;
var->green.offset = 0;
var->blue.length = var->bits_per_pixel;
var->blue.offset = 0;
break;
case 16:
/* If we can't do 444, 5551 or 565, reject */
if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
ret = -EINVAL;
break;
}
/*
* Green length can be 4, 5 or 6 depending whether
* we're operating in 444, 5551 or 565 mode.
*/
if (var->green.length == 4 && caps & CLCD_CAP_444)
caps &= CLCD_CAP_444;
if (var->green.length == 5 && caps & CLCD_CAP_5551)
caps &= CLCD_CAP_5551;
else if (var->green.length == 6 && caps & CLCD_CAP_565)
caps &= CLCD_CAP_565;
else {
/*
* PL110 officially only supports RGB555,
* but may be wired up to allow RGB565.
*/
if (caps & CLCD_CAP_565) {
var->green.length = 6;
caps &= CLCD_CAP_565;
} else if (caps & CLCD_CAP_5551) {
var->green.length = 5;
caps &= CLCD_CAP_5551;
} else {
var->green.length = 4;
caps &= CLCD_CAP_444;
}
}
if (var->green.length >= 5) {
var->red.length = 5;
var->blue.length = 5;
} else {
var->red.length = 4;
var->blue.length = 4;
}
break;
case 32:
/* If we can't do 888, reject */
caps &= CLCD_CAP_888;
if (!caps) {
ret = -EINVAL;
break;
}
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
break;
default:
ret = -EINVAL;
break;
}
/*
* >= 16bpp displays have separate colour component bitfields
* encoded in the pixel data. Calculate their position from
* the bitfield length defined above.
*/
if (ret == 0 && var->bits_per_pixel >= 16) {
bool bgr, rgb;
bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
if (!bgr && !rgb)
/*
* The requested format was not possible, try just
* our capabilities. One of BGR or RGB must be
* supported.
*/
bgr = caps & CLCD_CAP_BGR;
if (bgr) {
var->blue.offset = 0;
var->green.offset = var->blue.offset + var->blue.length;
var->red.offset = var->green.offset + var->green.length;
} else {
var->red.offset = 0;
var->green.offset = var->red.offset + var->red.length;
var->blue.offset = var->green.offset + var->green.length;
}
}
return ret;
}
static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct clcd_fb *fb = to_clcd(info);
int ret = -EINVAL;
if (fb->board->check)
ret = fb->board->check(fb, var);
if (ret == 0 &&
var->xres_virtual * var->bits_per_pixel / 8 *
var->yres_virtual > fb->fb.fix.smem_len)
ret = -EINVAL;
if (ret == 0)
ret = clcdfb_set_bitfields(fb, var);
return ret;
}
static int clcdfb_set_par(struct fb_info *info)
{
struct clcd_fb *fb = to_clcd(info);
struct clcd_regs regs;
fb->fb.fix.line_length = fb->fb.var.xres_virtual *
fb->fb.var.bits_per_pixel / 8;
if (fb->fb.var.bits_per_pixel <= 8)
fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
else
fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
fb->board->decode(fb, &regs);
clcdfb_disable(fb);
writel(regs.tim0, fb->regs + CLCD_TIM0);
writel(regs.tim1, fb->regs + CLCD_TIM1);
writel(regs.tim2, fb->regs + CLCD_TIM2);
writel(regs.tim3, fb->regs + CLCD_TIM3);
clcdfb_set_start(fb);
clk_set_rate(fb->clk, (1000000000 / regs.pixclock) * 1000);
fb->clcd_cntl = regs.cntl;
clcdfb_enable(fb, regs.cntl);
#ifdef DEBUG
printk(KERN_INFO
"CLCD: Registers set to\n"
" %08x %08x %08x %08x\n"
" %08x %08x %08x %08x\n",
readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl));
#endif
return 0;
}
static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
{
unsigned int mask = (1 << bf->length) - 1;
return (val >> (16 - bf->length) & mask) << bf->offset;
}
/*
* Set a single color register. The values supplied have a 16 bit
* magnitude. Return != 0 for invalid regno.
*/
static int
clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
unsigned int blue, unsigned int transp, struct fb_info *info)
{
struct clcd_fb *fb = to_clcd(info);
if (regno < 16)
fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
convert_bitfield(blue, &fb->fb.var.blue) |
convert_bitfield(green, &fb->fb.var.green) |
convert_bitfield(red, &fb->fb.var.red);
if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3);
u32 val, mask, newval;
newval = (red >> 11) & 0x001f;
newval |= (green >> 6) & 0x03e0;
newval |= (blue >> 1) & 0x7c00;
/*
* 3.2.11: if we're configured for big endian
* byte order, the palette entries are swapped.
*/
if (fb->clcd_cntl & CNTL_BEBO)
regno ^= 1;
if (regno & 1) {
newval <<= 16;
mask = 0x0000ffff;
} else {
mask = 0xffff0000;
}
val = readl(fb->regs + hw_reg) & mask;
writel(val | newval, fb->regs + hw_reg);
}
return regno > 255;
}
/*
* Blank the screen if blank_mode != 0, else unblank. If blank == NULL
* then the caller blanks by setting the CLUT (Color Look Up Table) to all
* black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
* to e.g. a video mode which doesn't support it. Implements VESA suspend
* and powerdown modes on hardware that supports disabling hsync/vsync:
* blank_mode == 2: suspend vsync
* blank_mode == 3: suspend hsync
* blank_mode == 4: powerdown
*/
static int clcdfb_blank(int blank_mode, struct fb_info *info)
{
struct clcd_fb *fb = to_clcd(info);
if (blank_mode != 0) {
clcdfb_disable(fb);
} else {
clcdfb_enable(fb, fb->clcd_cntl);
}
return 0;
}
static int clcdfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
struct clcd_fb *fb = to_clcd(info);
unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT;
int ret = -EINVAL;
len = info->fix.smem_len;
if (off <= len && vma->vm_end - vma->vm_start <= len - off &&
fb->board->mmap)
ret = fb->board->mmap(fb, vma);
return ret;
}
static const struct fb_ops clcdfb_ops = {
.owner = THIS_MODULE,
__FB_DEFAULT_IOMEM_OPS_RDWR,
.fb_check_var = clcdfb_check_var,
.fb_set_par = clcdfb_set_par,
.fb_setcolreg = clcdfb_setcolreg,
.fb_blank = clcdfb_blank,
__FB_DEFAULT_IOMEM_OPS_DRAW,
.fb_mmap = clcdfb_mmap,
};
static int clcdfb_register(struct clcd_fb *fb)
{
int ret;
/*
* ARM PL111 always has IENB at 0x1c; it's only PL110
* which is reversed on some platforms.
*/
if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
fb->off_ienb = CLCD_PL111_IENB;
fb->off_cntl = CLCD_PL111_CNTL;
} else {
fb->off_ienb = CLCD_PL110_IENB;
fb->off_cntl = CLCD_PL110_CNTL;
}
fb->clk = clk_get(&fb->dev->dev, NULL);
if (IS_ERR(fb->clk)) {
ret = PTR_ERR(fb->clk);
goto out;
}
ret = clk_prepare(fb->clk);
if (ret)
goto free_clk;
fb->fb.device = &fb->dev->dev;
fb->fb.fix.mmio_start = fb->dev->res.start;
fb->fb.fix.mmio_len = resource_size(&fb->dev->res);
fb->regs = ioremap(fb->fb.fix.mmio_start, fb->fb.fix.mmio_len);
if (!fb->regs) {
printk(KERN_ERR "CLCD: unable to remap registers\n");
ret = -ENOMEM;
goto clk_unprep;
}
fb->fb.fbops = &clcdfb_ops;
fb->fb.pseudo_palette = fb->cmap;
strncpy(fb->fb.fix.id, clcd_name, sizeof(fb->fb.fix.id));
fb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
fb->fb.fix.type_aux = 0;
fb->fb.fix.xpanstep = 0;
fb->fb.fix.ypanstep = 0;
fb->fb.fix.ywrapstep = 0;
fb->fb.fix.accel = FB_ACCEL_NONE;
fb->fb.var.xres = fb->panel->mode.xres;
fb->fb.var.yres = fb->panel->mode.yres;
fb->fb.var.xres_virtual = fb->panel->mode.xres;
fb->fb.var.yres_virtual = fb->panel->mode.yres;
fb->fb.var.bits_per_pixel = fb->panel->bpp;
fb->fb.var.grayscale = fb->panel->grayscale;
fb->fb.var.pixclock = fb->panel->mode.pixclock;
fb->fb.var.left_margin = fb->panel->mode.left_margin;
fb->fb.var.right_margin = fb->panel->mode.right_margin;
fb->fb.var.upper_margin = fb->panel->mode.upper_margin;
fb->fb.var.lower_margin = fb->panel->mode.lower_margin;
fb->fb.var.hsync_len = fb->panel->mode.hsync_len;
fb->fb.var.vsync_len = fb->panel->mode.vsync_len;
fb->fb.var.sync = fb->panel->mode.sync;
fb->fb.var.vmode = fb->panel->mode.vmode;
fb->fb.var.activate = FB_ACTIVATE_NOW;
fb->fb.var.nonstd = 0;
fb->fb.var.height = fb->panel->height;
fb->fb.var.width = fb->panel->width;
fb->fb.var.accel_flags = 0;
fb->fb.monspecs.hfmin = 0;
fb->fb.monspecs.hfmax = 100000;
fb->fb.monspecs.vfmin = 0;
fb->fb.monspecs.vfmax = 400;
fb->fb.monspecs.dclkmin = 1000000;
fb->fb.monspecs.dclkmax = 100000000;
/*
* Make sure that the bitfields are set appropriately.
*/
clcdfb_set_bitfields(fb, &fb->fb.var);
/*
* Allocate colourmap.
*/
ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0);
if (ret)
goto unmap;
/*
* Ensure interrupts are disabled.
*/
writel(0, fb->regs + fb->off_ienb);
fb_set_var(&fb->fb, &fb->fb.var);
dev_info(&fb->dev->dev, "%s hardware, %s display\n",
fb->board->name, fb->panel->mode.name);
ret = register_framebuffer(&fb->fb);
if (ret == 0)
goto out;
printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
fb_dealloc_cmap(&fb->fb.cmap);
unmap:
iounmap(fb->regs);
clk_unprep:
clk_unprepare(fb->clk);
free_clk:
clk_put(fb->clk);
out:
return ret;
}
#ifdef CONFIG_OF
static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
struct clcd_panel *clcd_panel)
{
int err;
struct display_timing timing;
struct videomode video;
err = of_get_display_timing(node, "panel-timing", &timing);
if (err) {
pr_err("%pOF: problems parsing panel-timing (%d)\n", node, err);
return err;
}
videomode_from_timing(&timing, &video);
err = fb_videomode_from_videomode(&video, &clcd_panel->mode);
if (err)
return err;
/* Set up some inversion flags */
if (timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
clcd_panel->tim2 |= TIM2_IPC;
else if (!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE))
/*
* To preserve backwards compatibility, the IPC (inverted
* pixel clock) flag needs to be set on any display that
* doesn't explicitly specify that the pixel clock is
* active on the negative or positive edge.
*/
clcd_panel->tim2 |= TIM2_IPC;
if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
clcd_panel->tim2 |= TIM2_IHS;
if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
clcd_panel->tim2 |= TIM2_IVS;
if (timing.flags & DISPLAY_FLAGS_DE_LOW)
clcd_panel->tim2 |= TIM2_IOE;
return 0;
}
static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
{
return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
mode->refresh);
}
static int clcdfb_of_get_backlight(struct device *dev,
struct clcd_panel *clcd_panel)
{
struct backlight_device *backlight;
/* Look up the optional backlight device */
backlight = devm_of_find_backlight(dev);
if (IS_ERR(backlight))
return PTR_ERR(backlight);
clcd_panel->backlight = backlight;
return 0;
}
static int clcdfb_of_get_mode(struct device *dev, struct device_node *panel,
struct clcd_panel *clcd_panel)
{
int err;
struct fb_videomode *mode;
char *name;
int len;
/* Only directly connected DPI panels supported for now */
if (of_device_is_compatible(panel, "panel-dpi"))
err = clcdfb_of_get_dpi_panel_mode(panel, clcd_panel);
else
err = -ENOENT;
if (err)
return err;
mode = &clcd_panel->mode;
len = clcdfb_snprintf_mode(NULL, 0, mode);
name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
if (!name)
return -ENOMEM;
clcdfb_snprintf_mode(name, len + 1, mode);
mode->name = name;
return 0;
}
static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
{
static struct {
unsigned int part;
u32 r0, g0, b0;
u32 caps;
} panels[] = {
{ 0x110, 1, 7, 13, CLCD_CAP_5551 },
{ 0x110, 0, 8, 16, CLCD_CAP_888 },
{ 0x110, 16, 8, 0, CLCD_CAP_888 },
{ 0x111, 4, 14, 20, CLCD_CAP_444 },
{ 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
{ 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
CLCD_CAP_565 },
{ 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
CLCD_CAP_565 | CLCD_CAP_888 },
};
int i;
/* Bypass pixel clock divider */
fb->panel->tim2 |= TIM2_BCD;
/* TFT display, vert. comp. interrupt at the start of the back porch */
fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
fb->panel->caps = 0;
/* Match the setup with known variants */
for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
if (amba_part(fb->dev) != panels[i].part)
continue;
if (g0 != panels[i].g0)
continue;
if (r0 == panels[i].r0 && b0 == panels[i].b0)
fb->panel->caps = panels[i].caps;
}
/*
* If we actually physically connected the R lines to B and
* vice versa
*/
if (r0 != 0 && b0 == 0)
fb->panel->bgr_connection = true;
return fb->panel->caps ? 0 : -EINVAL;
}
static int clcdfb_of_init_display(struct clcd_fb *fb)
{
struct device_node *endpoint, *panel;
int err;
unsigned int bpp;
u32 max_bandwidth;
u32 tft_r0b0g0[3];
fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
if (!fb->panel)
return -ENOMEM;
/*
* Fetch the panel endpoint.
*/
endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
if (!endpoint)
return -ENODEV;
panel = of_graph_get_remote_port_parent(endpoint);
if (!panel) {
err = -ENODEV;
goto out_endpoint_put;
}
err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel);
if (err)
goto out_panel_put;
err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel);
if (err)
goto out_panel_put;
err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
&max_bandwidth);
if (!err) {
/*
* max_bandwidth is in bytes per second and pixclock in
* pico-seconds, so the maximum allowed bits per pixel is
* 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000)
* Rearrange this calculation to avoid overflow and then ensure
* result is a valid format.
*/
bpp = max_bandwidth / (1000 / 8)
/ PICOS2KHZ(fb->panel->mode.pixclock);
bpp = rounddown_pow_of_two(bpp);
if (bpp > 32)
bpp = 32;
} else
bpp = 32;
fb->panel->bpp = bpp;
#ifdef CONFIG_CPU_BIG_ENDIAN
fb->panel->cntl |= CNTL_BEBO;
#endif
fb->panel->width = -1;
fb->panel->height = -1;
if (of_property_read_u32_array(endpoint,
"arm,pl11x,tft-r0g0b0-pads",
tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) {
err = -ENOENT;
goto out_panel_put;
}
of_node_put(panel);
of_node_put(endpoint);
return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
tft_r0b0g0[1], tft_r0b0g0[2]);
out_panel_put:
of_node_put(panel);
out_endpoint_put:
of_node_put(endpoint);
return err;
}
static int clcdfb_of_vram_setup(struct clcd_fb *fb)
{
int err;
struct device_node *memory;
u64 size;
err = clcdfb_of_init_display(fb);
if (err)
return err;
memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0);
if (!memory)
return -ENODEV;
fb->fb.screen_base = of_iomap(memory, 0);
if (!fb->fb.screen_base) {
of_node_put(memory);
return -ENOMEM;
}
fb->fb.fix.smem_start = of_translate_address(memory,
of_get_address(memory, 0, &size, NULL));
fb->fb.fix.smem_len = size;
of_node_put(memory);
return 0;
}
static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
{
unsigned long off, user_size, kernel_size;
off = vma->vm_pgoff << PAGE_SHIFT;
user_size = vma->vm_end - vma->vm_start;
kernel_size = fb->fb.fix.smem_len;
if (off >= kernel_size || user_size > (kernel_size - off))
return -ENXIO;
return remap_pfn_range(vma, vma->vm_start,
__phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
user_size,
pgprot_writecombine(vma->vm_page_prot));
}
static void clcdfb_of_vram_remove(struct clcd_fb *fb)
{
iounmap(fb->fb.screen_base);
}
static int clcdfb_of_dma_setup(struct clcd_fb *fb)
{
unsigned long framesize;
dma_addr_t dma;
int err;
err = clcdfb_of_init_display(fb);
if (err)
return err;
framesize = PAGE_ALIGN(fb->panel->mode.xres * fb->panel->mode.yres *
fb->panel->bpp / 8);
fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
&dma, GFP_KERNEL);
if (!fb->fb.screen_base)
return -ENOMEM;
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = framesize;
return 0;
}
static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
{
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
fb->fb.fix.smem_start, fb->fb.fix.smem_len);
}
static void clcdfb_of_dma_remove(struct clcd_fb *fb)
{
dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
}
static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
{
struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
GFP_KERNEL);
struct device_node *node = dev->dev.of_node;
if (!board)
return NULL;
board->name = of_node_full_name(node);
board->caps = CLCD_CAP_ALL;
board->check = clcdfb_check;
board->decode = clcdfb_decode;
if (of_property_present(node, "memory-region")) {
board->setup = clcdfb_of_vram_setup;
board->mmap = clcdfb_of_vram_mmap;
board->remove = clcdfb_of_vram_remove;
} else {
board->setup = clcdfb_of_dma_setup;
board->mmap = clcdfb_of_dma_mmap;
board->remove = clcdfb_of_dma_remove;
}
return board;
}
#else
static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
{
return NULL;
}
#endif
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct clcd_board *board = dev_get_platdata(&dev->dev);
struct clcd_fb *fb;
int ret;
if (!board)
board = clcdfb_of_get_board(dev);
if (!board)
return -EINVAL;
ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
if (ret)
goto out;
ret = amba_request_regions(dev, NULL);
if (ret) {
printk(KERN_ERR "CLCD: unable to reserve regs region\n");
goto out;
}
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb) {
ret = -ENOMEM;
goto free_region;
}
fb->dev = dev;
fb->board = board;
dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n",
amba_part(dev), amba_manf(dev), amba_rev(dev),
(unsigned long long)dev->res.start);
ret = fb->board->setup(fb);
if (ret)
goto free_fb;
ret = clcdfb_register(fb);
if (ret == 0) {
amba_set_drvdata(dev, fb);
goto out;
}
fb->board->remove(fb);
free_fb:
kfree(fb);
free_region:
amba_release_regions(dev);
out:
return ret;
}
static void clcdfb_remove(struct amba_device *dev)
{
struct clcd_fb *fb = amba_get_drvdata(dev);
clcdfb_disable(fb);
unregister_framebuffer(&fb->fb);
if (fb->fb.cmap.len)
fb_dealloc_cmap(&fb->fb.cmap);
iounmap(fb->regs);
clk_unprepare(fb->clk);
clk_put(fb->clk);
fb->board->remove(fb);
kfree(fb);
amba_release_regions(dev);
}
static const struct amba_id clcdfb_id_table[] = {
{
.id = 0x00041110,
.mask = 0x000ffffe,
},
{ 0, 0 },
};
MODULE_DEVICE_TABLE(amba, clcdfb_id_table);
static struct amba_driver clcd_driver = {
.drv = {
.name = "clcd-pl11x",
},
.probe = clcdfb_probe,
.remove = clcdfb_remove,
.id_table = clcdfb_id_table,
};
static int __init amba_clcdfb_init(void)
{
if (fb_get_options("ambafb", NULL))
return -ENODEV;
return amba_driver_register(&clcd_driver);
}
module_init(amba_clcdfb_init);
static void __exit amba_clcdfb_exit(void)
{
amba_driver_unregister(&clcd_driver);
}
module_exit(amba_clcdfb_exit);
MODULE_DESCRIPTION("ARM PrimeCell PL110 CLCD core driver");
MODULE_LICENSE("GPL");

View File

@ -132,11 +132,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy
return 0;
inode_lock(inode);
/* Kill off the delayed work */
cancel_delayed_work_sync(&info->deferred_work);
/* Run it immediately */
schedule_delayed_work(&info->deferred_work, 0);
flush_delayed_work(&info->deferred_work);
inode_unlock(inode);
return 0;
@ -319,7 +315,7 @@ static void fb_deferred_io_lastclose(struct fb_info *info)
struct page *page;
int i;
cancel_delayed_work_sync(&info->deferred_work);
flush_delayed_work(&info->deferred_work);
/* clear out the mapping that we setup */
for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {

View File

@ -877,7 +877,7 @@ static int map_video_memory(struct fb_info *info)
}
mutex_lock(&info->mm_lock);
info->screen_base = p;
info->fix.smem_start = virt_to_phys(info->screen_base);
info->fix.smem_start = virt_to_phys((__force const void *)info->screen_base);
info->fix.smem_len = smem_len;
mutex_unlock(&info->mm_lock);
info->screen_size = info->fix.smem_len;

View File

@ -364,6 +364,8 @@ error:
* hgafb_open - open the framebuffer device
* @info: pointer to fb_info object containing info for current hga board
* @init: open by console system or userland.
*
* Returns: %0
*/
static int hgafb_open(struct fb_info *info, int init)
@ -378,6 +380,8 @@ static int hgafb_open(struct fb_info *info, int init)
* hgafb_release - open the framebuffer device
* @info: pointer to fb_info object containing info for current hga board
* @init: open by console system or userland.
*
* Returns: %0
*/
static int hgafb_release(struct fb_info *info, int init)
@ -399,6 +403,8 @@ static int hgafb_release(struct fb_info *info, int init)
* This callback function is used to set the color registers of a HGA
* board. Since we have only two fixed colors only @regno is checked.
* A zero is returned on success and 1 for failure.
*
* Returns: %0
*/
static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@ -410,14 +416,15 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
}
/**
* hga_pan_display - pan or wrap the display
* hgafb_pan_display - pan or wrap the display
* @var:contains new xoffset, yoffset and vmode values
* @info:pointer to fb_info object containing info for current hga board
*
* This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP
* flag in @var. If input parameters are correct it calls hga_pan() to
* program the hardware. @info->var is updated to the new values.
* A zero is returned on success and %-EINVAL for failure.
*
* Returns: %0 on success or %-EINVAL for failure.
*/
static int hgafb_pan_display(struct fb_var_screeninfo *var,
@ -449,6 +456,8 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
* @blank_mode == 2 means suspend vsync,
* @blank_mode == 3 means suspend hsync,
* @blank_mode == 4 means powerdown.
*
* Returns: %0
*/
static int hgafb_blank(int blank_mode, struct fb_info *info)

View File

@ -48,7 +48,6 @@
#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/screen_info.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/completion.h>
@ -975,7 +974,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
struct pci_dev *pdev = NULL;
void __iomem *fb_virt;
int gen2vm = efi_enabled(EFI_BOOT);
resource_size_t base, size;
resource_size_t base = 0;
resource_size_t size = 0;
phys_addr_t paddr;
int ret;
@ -1010,9 +1010,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
goto getmem_done;
}
pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n");
} else if (IS_ENABLED(CONFIG_SYSFB)) {
base = screen_info.lfb_base;
size = screen_info.lfb_size;
} else {
goto err1;
}
@ -1056,16 +1053,13 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
info->screen_size = dio_fb_size;
getmem_done:
aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME);
if (base && size)
aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME);
else
aperture_remove_all_conflicting_devices(KBUILD_MODNAME);
if (!gen2vm) {
if (!gen2vm)
pci_dev_put(pdev);
} else if (IS_ENABLED(CONFIG_SYSFB)) {
/* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */
screen_info.lfb_size = 0;
screen_info.lfb_base = 0;
screen_info.orig_video_isVGA = 0;
}
return 0;

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Freescale i.MX Frame Buffer device driver
*
* Copyright (C) 2004 Sascha Hauer, Pengutronix
* Based on acornfb.c Copyright (C) Russell King.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* Please direct your questions and comments on this driver to the following
* email address:
*
@ -34,6 +31,7 @@
#include <linux/math64.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/bitfield.h>
#include <linux/regulator/consumer.h>
@ -41,12 +39,6 @@
#include <video/of_videomode.h>
#include <video/videomode.h>
#define PCR_TFT (1 << 31)
#define PCR_BPIX_8 (3 << 25)
#define PCR_BPIX_12 (4 << 25)
#define PCR_BPIX_16 (5 << 25)
#define PCR_BPIX_18 (6 << 25)
struct imx_fb_videomode {
struct fb_videomode mode;
u32 pcr;
@ -64,42 +56,50 @@ struct imx_fb_videomode {
#define LCDC_SSA 0x00
#define LCDC_SIZE 0x04
#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
#define SIZE_XMAX_MASK GENMASK(25, 20)
#define YMAX_MASK_IMX1 0x1ff
#define YMAX_MASK_IMX21 0x3ff
#define YMAX_MASK_IMX1 GENMASK(8, 0)
#define YMAX_MASK_IMX21 GENMASK(9, 0)
#define LCDC_VPW 0x08
#define VPW_VPW(x) ((x) & 0x3ff)
#define VPW_VPW_MASK GENMASK(9, 0)
#define LCDC_CPOS 0x0C
#define CPOS_CC1 (1<<31)
#define CPOS_CC0 (1<<30)
#define CPOS_OP (1<<28)
#define CPOS_CXP(x) (((x) & 3ff) << 16)
#define CPOS_CC1 BIT(31)
#define CPOS_CC0 BIT(30)
#define CPOS_OP BIT(28)
#define CPOS_CXP_MASK GENMASK(25, 16)
#define LCDC_LCWHB 0x10
#define LCWHB_BK_EN (1<<31)
#define LCWHB_CW(w) (((w) & 0x1f) << 24)
#define LCWHB_CH(h) (((h) & 0x1f) << 16)
#define LCWHB_BD(x) ((x) & 0xff)
#define LCWHB_BK_EN BIT(31)
#define LCWHB_CW_MASK GENMASK(28, 24)
#define LCWHB_CH_MASK GENMASK(20, 16)
#define LCWHB_BD_MASK GENMASK(7, 0)
#define LCDC_LCHCC 0x14
#define LCDC_PCR 0x18
#define PCR_TFT BIT(31)
#define PCR_COLOR BIT(30)
#define PCR_BPIX_MASK GENMASK(27, 25)
#define PCR_BPIX_8 3
#define PCR_BPIX_12 4
#define PCR_BPIX_16 5
#define PCR_BPIX_18 6
#define PCR_PCD_MASK GENMASK(5, 0)
#define LCDC_HCR 0x1C
#define HCR_H_WIDTH(x) (((x) & 0x3f) << 26)
#define HCR_H_WAIT_1(x) (((x) & 0xff) << 8)
#define HCR_H_WAIT_2(x) ((x) & 0xff)
#define HCR_H_WIDTH_MASK GENMASK(31, 26)
#define HCR_H_WAIT_1_MASK GENMASK(15, 8)
#define HCR_H_WAIT_2_MASK GENMASK(7, 0)
#define LCDC_VCR 0x20
#define VCR_V_WIDTH(x) (((x) & 0x3f) << 26)
#define VCR_V_WAIT_1(x) (((x) & 0xff) << 8)
#define VCR_V_WAIT_2(x) ((x) & 0xff)
#define VCR_V_WIDTH_MASK GENMASK(31, 26)
#define VCR_V_WAIT_1_MASK GENMASK(15, 8)
#define VCR_V_WAIT_2_MASK GENMASK(7, 0)
#define LCDC_POS 0x24
#define POS_POS(x) ((x) & 1f)
#define POS_POS_MASK GENMASK(4, 0)
#define LCDC_LSCR1 0x28
/* bit fields in imxfb.h */
@ -112,24 +112,24 @@ struct imx_fb_videomode {
#define LCDC_RMCR 0x34
#define RMCR_LCDC_EN_MX1 (1<<1)
#define RMCR_LCDC_EN_MX1 BIT(1)
#define RMCR_SELF_REF (1<<0)
#define RMCR_SELF_REF BIT(0)
#define LCDC_LCDICR 0x38
#define LCDICR_INT_SYN (1<<2)
#define LCDICR_INT_CON (1)
#define LCDICR_INT_SYN BIT(2)
#define LCDICR_INT_CON BIT(0)
#define LCDC_LCDISR 0x40
#define LCDISR_UDR_ERR (1<<3)
#define LCDISR_ERR_RES (1<<2)
#define LCDISR_EOF (1<<1)
#define LCDISR_BOF (1<<0)
#define LCDISR_UDR_ERR BIT(3)
#define LCDISR_ERR_RES BIT(2)
#define LCDISR_EOF BIT(1)
#define LCDISR_BOF BIT(0)
#define IMXFB_LSCR1_DEFAULT 0x00120300
#define LCDC_LAUSCR 0x80
#define LAUSCR_AUS_MODE (1<<31)
#define LAUSCR_AUS_MODE BIT(31)
/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
static const char *fb_mode;
@ -150,6 +150,12 @@ enum imxfb_type {
IMX21_FB,
};
enum imxfb_panel_type {
PANEL_TYPE_MONOCHROME,
PANEL_TYPE_CSTN,
PANEL_TYPE_TFT,
};
struct imxfb_info {
struct platform_device *pdev;
void __iomem *regs;
@ -157,6 +163,7 @@ struct imxfb_info {
struct clk *clk_ahb;
struct clk *clk_per;
enum imxfb_type devtype;
enum imxfb_panel_type panel_type;
bool enabled;
/*
@ -273,10 +280,10 @@ static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
struct imxfb_info *fbi = info->par;
u_int val, ret = 1;
#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
if (regno < fbi->palette_size) {
val = (CNVT_TOHW(red, 4) << 8) |
(CNVT_TOHW(green,4) << 4) |
(CNVT_TOHW(green, 4) << 4) |
CNVT_TOHW(blue, 4);
writel(val, fbi->regs + 0x800 + (regno << 2));
@ -405,23 +412,23 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
pcr = (unsigned int)tmp;
if (--pcr > 0x3F) {
pcr = 0x3F;
printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
lcd_clk / pcr);
if (--pcr > PCR_PCD_MASK) {
pcr = PCR_PCD_MASK;
dev_warn(&fbi->pdev->dev, "Must limit pixel clock to %luHz\n",
lcd_clk / pcr);
}
switch (var->bits_per_pixel) {
case 32:
pcr |= PCR_BPIX_18;
pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_18);
rgb = &def_rgb_18;
break;
case 16:
default:
if (is_imx1_fb(fbi))
pcr |= PCR_BPIX_12;
pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_12);
else
pcr |= PCR_BPIX_16;
pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_16);
if (imxfb_mode->pcr & PCR_TFT)
rgb = &def_rgb_16_tft;
@ -429,13 +436,13 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
rgb = &def_rgb_16_stn;
break;
case 8:
pcr |= PCR_BPIX_8;
pcr |= FIELD_PREP(PCR_BPIX_MASK, PCR_BPIX_8);
rgb = &def_rgb_8;
break;
}
/* add sync polarities */
pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25));
pcr |= imxfb_mode->pcr & ~(PCR_PCD_MASK | PCR_BPIX_MASK);
fbi->pcr = pcr;
/*
@ -444,6 +451,13 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (!is_imx1_fb(fbi) && imxfb_mode->aus_mode)
fbi->lauscr = LAUSCR_AUS_MODE;
if (imxfb_mode->pcr & PCR_TFT)
fbi->panel_type = PANEL_TYPE_TFT;
else if (imxfb_mode->pcr & PCR_COLOR)
fbi->panel_type = PANEL_TYPE_CSTN;
else
fbi->panel_type = PANEL_TYPE_MONOCHROME;
/*
* Copy the RGB parameters for this display
* from the machine specific parameters.
@ -506,7 +520,7 @@ static int imxfb_enable_controller(struct imxfb_info *fbi)
writel(fbi->map_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
writel(0x00000000, fbi->regs + LCDC_POS);
writel(FIELD_PREP(POS_POS_MASK, 0), fbi->regs + LCDC_POS);
/* disable hardware cursor */
writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
@ -562,7 +576,7 @@ static int imxfb_blank(int blank, struct fb_info *info)
{
struct imxfb_info *fbi = info->par;
pr_debug("imxfb_blank: blank=%d\n", blank);
pr_debug("%s: blank=%d\n", __func__, blank);
switch (blank) {
case FB_BLANK_POWERDOWN:
@ -596,6 +610,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
{
struct imxfb_info *fbi = info->par;
u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
u8 left_margin_low;
pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
var->xres, var->hsync_len,
@ -604,49 +619,59 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
var->yres, var->vsync_len,
var->upper_margin, var->lower_margin);
if (fbi->panel_type == PANEL_TYPE_TFT)
left_margin_low = 3;
else if (fbi->panel_type == PANEL_TYPE_CSTN)
left_margin_low = 2;
else
left_margin_low = 0;
#if DEBUG_VAR
if (var->xres < 16 || var->xres > 1024)
printk(KERN_ERR "%s: invalid xres %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid xres %d\n",
info->fix.id, var->xres);
if (var->hsync_len < 1 || var->hsync_len > 64)
printk(KERN_ERR "%s: invalid hsync_len %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid hsync_len %d\n",
info->fix.id, var->hsync_len);
if (var->left_margin < 3 || var->left_margin > 255)
printk(KERN_ERR "%s: invalid left_margin %d\n",
if (var->left_margin < left_margin_low || var->left_margin > 255)
dev_err(&fbi->pdev->dev, "%s: invalid left_margin %d\n",
info->fix.id, var->left_margin);
if (var->right_margin < 1 || var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid right_margin %d\n",
info->fix.id, var->right_margin);
if (var->yres < 1 || var->yres > ymax_mask)
printk(KERN_ERR "%s: invalid yres %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid yres %d\n",
info->fix.id, var->yres);
if (var->vsync_len > 100)
printk(KERN_ERR "%s: invalid vsync_len %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid vsync_len %d\n",
info->fix.id, var->vsync_len);
if (var->upper_margin > 63)
printk(KERN_ERR "%s: invalid upper_margin %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid upper_margin %d\n",
info->fix.id, var->upper_margin);
if (var->lower_margin > 255)
printk(KERN_ERR "%s: invalid lower_margin %d\n",
dev_err(&fbi->pdev->dev, "%s: invalid lower_margin %d\n",
info->fix.id, var->lower_margin);
#endif
/* physical screen start address */
writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
fbi->regs + LCDC_VPW);
writel(FIELD_PREP(VPW_VPW_MASK,
var->xres * var->bits_per_pixel / 8 / 4),
fbi->regs + LCDC_VPW);
writel(HCR_H_WIDTH(var->hsync_len - 1) |
HCR_H_WAIT_1(var->right_margin - 1) |
HCR_H_WAIT_2(var->left_margin - 3),
fbi->regs + LCDC_HCR);
writel(FIELD_PREP(HCR_H_WIDTH_MASK, var->hsync_len - 1) |
FIELD_PREP(HCR_H_WAIT_1_MASK, var->right_margin - 1) |
FIELD_PREP(HCR_H_WAIT_2_MASK,
var->left_margin - left_margin_low),
fbi->regs + LCDC_HCR);
writel(VCR_V_WIDTH(var->vsync_len) |
VCR_V_WAIT_1(var->lower_margin) |
VCR_V_WAIT_2(var->upper_margin),
fbi->regs + LCDC_VCR);
writel(FIELD_PREP(VCR_V_WIDTH_MASK, var->vsync_len) |
FIELD_PREP(VCR_V_WAIT_1_MASK, var->lower_margin) |
FIELD_PREP(VCR_V_WAIT_2_MASK, var->upper_margin),
fbi->regs + LCDC_VCR);
writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask),
fbi->regs + LCDC_SIZE);
writel(FIELD_PREP(SIZE_XMAX_MASK, var->xres >> 4) |
(var->yres & ymax_mask),
fbi->regs + LCDC_SIZE);
writel(fbi->pcr, fbi->regs + LCDC_PCR);
if (fbi->pwmr)
@ -669,8 +694,6 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
struct imxfb_info *fbi = info->par;
struct device_node *np;
pr_debug("%s\n",__func__);
info->pseudo_palette = devm_kmalloc_array(&pdev->dev, 16,
sizeof(u32), GFP_KERNEL);
if (!info->pseudo_palette)
@ -678,6 +701,7 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
memset(fbi, 0, sizeof(struct imxfb_info));
fbi->pdev = pdev;
fbi->devtype = pdev->id_entry->driver_data;
strscpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
@ -922,8 +946,10 @@ static int imxfb_probe(struct platform_device *pdev)
if (ret)
goto failed_init;
/* Calculate maximum bytes used per pixel. In most cases this should
* be the same as m->bpp/8 */
/*
* Calculate maximum bytes used per pixel. In most cases this should
* be the same as m->bpp/8
*/
m = &fbi->mode[0];
bytes_per_pixel = (m->bpp + 7) / 8;
for (i = 0; i < fbi->num_modes; i++, m++)
@ -1021,7 +1047,6 @@ static int imxfb_probe(struct platform_device *pdev)
lcd->props.max_contrast = 0xff;
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
return 0;

View File

@ -1,8 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_FB_INTEL) += intelfb.o
intelfb-y := intelfbdrv.o intelfbhw.o
intelfb-$(CONFIG_FB_INTEL_I2C) += intelfb_i2c.o
intelfb-objs := $(intelfb-y)
ccflags-$(CONFIG_FB_INTEL_DEBUG) := -DDEBUG -DREGDUMP

View File

@ -1,382 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _INTELFB_H
#define _INTELFB_H
/* $DHD: intelfb/intelfb.h,v 1.40 2003/06/27 15:06:25 dawes Exp $ */
#include <linux/agp_backend.h>
#include <linux/fb.h>
#ifdef CONFIG_FB_INTEL_I2C
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#endif
/*** Version/name ***/
#define INTELFB_VERSION "0.9.6"
#define INTELFB_MODULE_NAME "intelfb"
#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
/*** Debug/feature defines ***/
#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef VERBOSE
#define VERBOSE 0
#endif
#ifndef REGDUMP
#define REGDUMP 0
#endif
#ifndef DETECT_VGA_CLASS_ONLY
#define DETECT_VGA_CLASS_ONLY 1
#endif
#ifndef ALLOCATE_FOR_PANNING
#define ALLOCATE_FOR_PANNING 1
#endif
#ifndef PREFERRED_MODE
#define PREFERRED_MODE "1024x768-32@70"
#endif
/*** hw-related values ***/
/* Resource Allocation */
#define INTELFB_FB_ACQUIRED 1
#define INTELFB_MMIO_ACQUIRED 2
/* PCI ids for supported devices */
#define PCI_DEVICE_ID_INTEL_830M 0x3577
#define PCI_DEVICE_ID_INTEL_845G 0x2562
#define PCI_DEVICE_ID_INTEL_85XGM 0x3582
#define PCI_DEVICE_ID_INTEL_854 0x358E
#define PCI_DEVICE_ID_INTEL_865G 0x2572
#define PCI_DEVICE_ID_INTEL_915G 0x2582
#define PCI_DEVICE_ID_INTEL_915GM 0x2592
#define PCI_DEVICE_ID_INTEL_945G 0x2772
#define PCI_DEVICE_ID_INTEL_945GM 0x27A2
#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
#define PCI_DEVICE_ID_INTEL_965G 0x29A2
#define PCI_DEVICE_ID_INTEL_965GM 0x2A02
/* Size of MMIO region */
#define INTEL_REG_SIZE 0x80000
#define STRIDE_ALIGNMENT 16
#define STRIDE_ALIGNMENT_I9XX 64
#define PALETTE_8_ENTRIES 256
/*** Macros ***/
/* basic arithmetic */
#define KB(x) ((x) * 1024)
#define MB(x) ((x) * 1024 * 1024)
#define BtoKB(x) ((x) / 1024)
#define BtoMB(x) ((x) / 1024 / 1024)
#define GTT_PAGE_SIZE KB(4)
#define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y))
#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y))
#define ROUND_UP_TO_PAGE(x) ROUND_UP_TO((x), GTT_PAGE_SIZE)
#define ROUND_DOWN_TO_PAGE(x) ROUND_DOWN_TO((x), GTT_PAGE_SIZE)
/* messages */
#define PFX INTELFB_MODULE_NAME ": "
#define ERR_MSG(fmt, args...) printk(KERN_ERR PFX fmt, ## args)
#define WRN_MSG(fmt, args...) printk(KERN_WARNING PFX fmt, ## args)
#define NOT_MSG(fmt, args...) printk(KERN_NOTICE PFX fmt, ## args)
#define INF_MSG(fmt, args...) printk(KERN_INFO PFX fmt, ## args)
#if DEBUG
#define DBG_MSG(fmt, args...) printk(KERN_DEBUG PFX fmt, ## args)
#else
#define DBG_MSG(fmt, args...) while (0) printk(fmt, ## args)
#endif
/* get commonly used pointers */
#define GET_DINFO(info) (info)->par
/* misc macros */
#define ACCEL(d, i) \
((d)->accel && !(d)->ring_lockup && \
((i)->var.accel_flags & FB_ACCELF_TEXT))
/*#define NOACCEL_CHIPSET(d) \
((d)->chipset != INTEL_865G)*/
#define NOACCEL_CHIPSET(d) \
(0)
#define FIXED_MODE(d) ((d)->fixed_mode)
/*** Driver parameters ***/
#define RINGBUFFER_SIZE KB(64)
#define HW_CURSOR_SIZE KB(4)
/* Intel agpgart driver */
#define AGP_PHYSICAL_MEMORY 2
/* store information about an Ixxx DVO */
/* The i830->i865 use multiple DVOs with multiple i2cs */
/* the i915, i945 have a single sDVO i2c bus - which is different */
#define MAX_OUTPUTS 6
/* these are outputs from the chip - integrated only
external chips are via DVO or SDVO output */
#define INTELFB_OUTPUT_UNUSED 0
#define INTELFB_OUTPUT_ANALOG 1
#define INTELFB_OUTPUT_DVO 2
#define INTELFB_OUTPUT_SDVO 3
#define INTELFB_OUTPUT_LVDS 4
#define INTELFB_OUTPUT_TVOUT 5
#define INTELFB_DVO_CHIP_NONE 0
#define INTELFB_DVO_CHIP_LVDS 1
#define INTELFB_DVO_CHIP_TMDS 2
#define INTELFB_DVO_CHIP_TVOUT 4
#define INTELFB_OUTPUT_PIPE_NC 0
#define INTELFB_OUTPUT_PIPE_A 1
#define INTELFB_OUTPUT_PIPE_B 2
/*** Data Types ***/
/* supported chipsets */
enum intel_chips {
INTEL_830M,
INTEL_845G,
INTEL_85XGM,
INTEL_852GM,
INTEL_852GME,
INTEL_854,
INTEL_855GM,
INTEL_855GME,
INTEL_865G,
INTEL_915G,
INTEL_915GM,
INTEL_945G,
INTEL_945GM,
INTEL_945GME,
INTEL_965G,
INTEL_965GM,
};
struct intelfb_hwstate {
u32 vga0_divisor;
u32 vga1_divisor;
u32 vga_pd;
u32 dpll_a;
u32 dpll_b;
u32 fpa0;
u32 fpa1;
u32 fpb0;
u32 fpb1;
u32 palette_a[PALETTE_8_ENTRIES];
u32 palette_b[PALETTE_8_ENTRIES];
u32 htotal_a;
u32 hblank_a;
u32 hsync_a;
u32 vtotal_a;
u32 vblank_a;
u32 vsync_a;
u32 src_size_a;
u32 bclrpat_a;
u32 htotal_b;
u32 hblank_b;
u32 hsync_b;
u32 vtotal_b;
u32 vblank_b;
u32 vsync_b;
u32 src_size_b;
u32 bclrpat_b;
u32 adpa;
u32 dvoa;
u32 dvob;
u32 dvoc;
u32 dvoa_srcdim;
u32 dvob_srcdim;
u32 dvoc_srcdim;
u32 lvds;
u32 pipe_a_conf;
u32 pipe_b_conf;
u32 disp_arb;
u32 cursor_a_control;
u32 cursor_b_control;
u32 cursor_a_base;
u32 cursor_b_base;
u32 cursor_size;
u32 disp_a_ctrl;
u32 disp_b_ctrl;
u32 disp_a_base;
u32 disp_b_base;
u32 cursor_a_palette[4];
u32 cursor_b_palette[4];
u32 disp_a_stride;
u32 disp_b_stride;
u32 vgacntrl;
u32 add_id;
u32 swf0x[7];
u32 swf1x[7];
u32 swf3x[3];
u32 fence[8];
u32 instpm;
u32 mem_mode;
u32 fw_blc_0;
u32 fw_blc_1;
u16 hwstam;
u16 ier;
u16 iir;
u16 imr;
};
struct intelfb_heap_data {
u32 physical;
u8 __iomem *virtual;
u32 offset; /* in GATT pages */
u32 size; /* in bytes */
};
#ifdef CONFIG_FB_INTEL_I2C
struct intelfb_i2c_chan {
struct intelfb_info *dinfo;
u32 reg;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
};
#endif
struct intelfb_output_rec {
int type;
int pipe;
int flags;
#ifdef CONFIG_FB_INTEL_I2C
struct intelfb_i2c_chan i2c_bus;
struct intelfb_i2c_chan ddc_bus;
#endif
};
struct intelfb_vsync {
wait_queue_head_t wait;
unsigned int count;
int pan_display;
u32 pan_offset;
};
struct intelfb_info {
struct fb_info *info;
const struct fb_ops *fbops;
struct pci_dev *pdev;
struct intelfb_hwstate save_state;
/* agpgart structs */
struct agp_memory *gtt_fb_mem; /* use all stolen memory or vram */
struct agp_memory *gtt_ring_mem; /* ring buffer */
struct agp_memory *gtt_cursor_mem; /* hw cursor */
/* use a gart reserved fb mem */
u8 fbmem_gart;
int wc_cookie;
/* heap data */
struct intelfb_heap_data aperture;
struct intelfb_heap_data fb;
struct intelfb_heap_data ring;
struct intelfb_heap_data cursor;
/* mmio regs */
u32 mmio_base_phys;
u8 __iomem *mmio_base;
/* fb start offset (in bytes) */
u32 fb_start;
/* ring buffer */
u32 ring_head;
u32 ring_tail;
u32 ring_tail_mask;
u32 ring_space;
u32 ring_lockup;
/* palette */
u32 pseudo_palette[16];
/* chip info */
int pci_chipset;
int chipset;
const char *name;
int mobile;
/* current mode */
int bpp, depth;
u32 visual;
int xres, yres, pitch;
int pixclock;
/* current pipe */
int pipe;
/* some flags */
int accel;
int hwcursor;
int fixed_mode;
int ring_active;
int flag;
unsigned long irq_flags;
int open;
/* vsync */
struct intelfb_vsync vsync;
spinlock_t int_lock;
/* hw cursor */
int cursor_on;
int cursor_blanked;
u8 cursor_src[64];
/* initial parameters */
int initial_vga;
struct fb_var_screeninfo initial_var;
u32 initial_fb_base;
u32 initial_video_ram;
u32 initial_pitch;
/* driver registered */
int registered;
/* index into plls */
int pll_index;
/* outputs */
int num_outputs;
struct intelfb_output_rec output[MAX_OUTPUTS];
};
#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G) || \
((dinfo)->chipset == INTEL_915GM) || \
((dinfo)->chipset == INTEL_945G) || \
((dinfo)->chipset == INTEL_945GM) || \
((dinfo)->chipset == INTEL_945GME) || \
((dinfo)->chipset == INTEL_965G) || \
((dinfo)->chipset == INTEL_965GM))
/*** function prototypes ***/
extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var);
#ifdef CONFIG_FB_INTEL_I2C
extern void intelfb_create_i2c_busses(struct intelfb_info *dinfo);
extern void intelfb_delete_i2c_busses(struct intelfb_info *dinfo);
#endif
#endif /* _INTELFB_H */

View File

@ -1,209 +0,0 @@
/**************************************************************************
Copyright 2006 Dave Airlie <airlied@linux.ie>
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>
#include "intelfb.h"
#include "intelfbhw.h"
/* bit locations in the registers */
#define SCL_DIR_MASK 0x0001
#define SCL_DIR 0x0002
#define SCL_VAL_MASK 0x0004
#define SCL_VAL_OUT 0x0008
#define SCL_VAL_IN 0x0010
#define SDA_DIR_MASK 0x0100
#define SDA_DIR 0x0200
#define SDA_VAL_MASK 0x0400
#define SDA_VAL_OUT 0x0800
#define SDA_VAL_IN 0x1000
static void intelfb_gpio_setscl(void *data, int state)
{
struct intelfb_i2c_chan *chan = data;
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) |
SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
val = INREG(chan->reg);
}
static void intelfb_gpio_setsda(void *data, int state)
{
struct intelfb_i2c_chan *chan = data;
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) |
SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
val = INREG(chan->reg);
}
static int intelfb_gpio_getscl(void *data)
{
struct intelfb_i2c_chan *chan = data;
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
OUTREG(chan->reg, SCL_DIR_MASK);
OUTREG(chan->reg, 0);
val = INREG(chan->reg);
return ((val & SCL_VAL_IN) != 0);
}
static int intelfb_gpio_getsda(void *data)
{
struct intelfb_i2c_chan *chan = data;
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
OUTREG(chan->reg, SDA_DIR_MASK);
OUTREG(chan->reg, 0);
val = INREG(chan->reg);
return ((val & SDA_VAL_IN) != 0);
}
static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
struct intelfb_i2c_chan *chan,
const u32 reg, const char *name,
int class)
{
int rc;
chan->dinfo = dinfo;
chan->reg = reg;
snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"intelfb %s", name);
chan->adapter.class = class;
chan->adapter.owner = THIS_MODULE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
chan->algo.setsda = intelfb_gpio_setsda;
chan->algo.setscl = intelfb_gpio_setscl;
chan->algo.getsda = intelfb_gpio_getsda;
chan->algo.getscl = intelfb_gpio_getscl;
chan->algo.udelay = 40;
chan->algo.timeout = 20;
chan->algo.data = chan;
i2c_set_adapdata(&chan->adapter, chan);
/* Raise SCL and SDA */
intelfb_gpio_setsda(chan, 1);
intelfb_gpio_setscl(chan, 1);
udelay(20);
rc = i2c_bit_add_bus(&chan->adapter);
if (rc == 0)
DBG_MSG("I2C bus %s registered.\n", name);
else
WRN_MSG("Failed to register I2C bus %s.\n", name);
return rc;
}
void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
{
int i = 0;
/* everyone has at least a single analog output */
dinfo->num_outputs = 1;
dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
/* setup the DDC bus for analog output */
intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA,
"CRTDDC_A", I2C_CLASS_DDC);
i++;
/* need to add the output busses for each device
- this function is very incomplete
- i915GM has LVDS and TVOUT for example
*/
switch(dinfo->chipset) {
case INTEL_830M:
case INTEL_845G:
case INTEL_854:
case INTEL_855GM:
case INTEL_865G:
dinfo->output[i].type = INTELFB_OUTPUT_DVO;
intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus,
GPIOD, "DVODDC_D", I2C_CLASS_DDC);
intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
GPIOE, "DVOI2C_E", 0);
i++;
break;
case INTEL_915G:
case INTEL_915GM:
/* has some LVDS + tv-out */
case INTEL_945G:
case INTEL_945GM:
case INTEL_945GME:
case INTEL_965G:
case INTEL_965GM:
/* SDVO ports have a single control bus - 2 devices */
dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
GPIOE, "SDVOCTRL_E", 0);
/* TODO: initialize the SDVO */
/* I830SDVOInit(pScrn, i, DVOB); */
i++;
/* set up SDVOC */
dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
/* TODO: initialize the SDVO */
/* I830SDVOInit(pScrn, i, DVOC); */
i++;
break;
}
dinfo->num_outputs = i;
}
void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
{
int i;
for (i = 0; i < MAX_OUTPUTS; i++) {
if (dinfo->output[i].i2c_bus.dinfo) {
i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter);
dinfo->output[i].i2c_bus.dinfo = NULL;
}
if (dinfo->output[i].ddc_bus.dinfo) {
i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter);
dinfo->output[i].ddc_bus.dinfo = NULL;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,609 +0,0 @@
#ifndef _INTELFBHW_H
#define _INTELFBHW_H
/* $DHD: intelfb/intelfbhw.h,v 1.5 2003/06/27 15:06:25 dawes Exp $ */
/*** HW-specific data ***/
/* Information about the 852GM/855GM variants */
#define INTEL_85X_CAPID 0x44
#define INTEL_85X_VARIANT_MASK 0x7
#define INTEL_85X_VARIANT_SHIFT 5
#define INTEL_VAR_855GME 0x0
#define INTEL_VAR_855GM 0x4
#define INTEL_VAR_852GME 0x2
#define INTEL_VAR_852GM 0x5
/* Information about DVO/LVDS Ports */
#define DVOA_PORT 0x1
#define DVOB_PORT 0x2
#define DVOC_PORT 0x4
#define LVDS_PORT 0x8
/*
* The Bridge device's PCI config space has information about the
* fb aperture size and the amount of pre-reserved memory.
*/
#define INTEL_GMCH_CTRL 0x52
#define INTEL_GMCH_ENABLED 0x4
#define INTEL_GMCH_MEM_MASK 0x1
#define INTEL_GMCH_MEM_64M 0x1
#define INTEL_GMCH_MEM_128M 0
#define INTEL_830_GMCH_GMS_MASK (0x7 << 4)
#define INTEL_830_GMCH_GMS_DISABLED (0x0 << 4)
#define INTEL_830_GMCH_GMS_LOCAL (0x1 << 4)
#define INTEL_830_GMCH_GMS_STOLEN_512 (0x2 << 4)
#define INTEL_830_GMCH_GMS_STOLEN_1024 (0x3 << 4)
#define INTEL_830_GMCH_GMS_STOLEN_8192 (0x4 << 4)
#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
/* HW registers */
/* Fence registers */
#define FENCE 0x2000
#define FENCE_NUM 8
/* Primary ring buffer */
#define PRI_RING_TAIL 0x2030
#define RING_TAIL_MASK 0x001ffff8
#define RING_INUSE 0x1
#define PRI_RING_HEAD 0x2034
#define RING_HEAD_WRAP_MASK 0x7ff
#define RING_HEAD_WRAP_SHIFT 21
#define RING_HEAD_MASK 0x001ffffc
#define PRI_RING_START 0x2038
#define RING_START_MASK 0xfffff000
#define PRI_RING_LENGTH 0x203c
#define RING_LENGTH_MASK 0x001ff000
#define RING_REPORT_MASK (0x3 << 1)
#define RING_NO_REPORT (0x0 << 1)
#define RING_REPORT_64K (0x1 << 1)
#define RING_REPORT_4K (0x2 << 1)
#define RING_REPORT_128K (0x3 << 1)
#define RING_ENABLE 0x1
/*
* Tail can't wrap to any closer than RING_MIN_FREE bytes of the head,
* and the last RING_MIN_FREE bytes need to be padded with MI_NOOP
*/
#define RING_MIN_FREE 64
#define IPEHR 0x2088
#define INSTDONE 0x2090
#define PRI_RING_EMPTY 1
#define HWSTAM 0x2098
#define IER 0x20A0
#define IIR 0x20A4
#define IMR 0x20A8
#define VSYNC_PIPE_A_INTERRUPT (1 << 7)
#define PIPE_A_EVENT_INTERRUPT (1 << 6)
#define VSYNC_PIPE_B_INTERRUPT (1 << 5)
#define PIPE_B_EVENT_INTERRUPT (1 << 4)
#define HOST_PORT_EVENT_INTERRUPT (1 << 3)
#define CAPTURE_EVENT_INTERRUPT (1 << 2)
#define USER_DEFINED_INTERRUPT (1 << 1)
#define BREAKPOINT_INTERRUPT 1
#define INSTPM 0x20c0
#define SYNC_FLUSH_ENABLE (1 << 5)
#define INSTPS 0x20c4
#define MEM_MODE 0x20cc
#define MASK_SHIFT 16
#define FW_BLC_0 0x20d8
#define FW_DISPA_WM_SHIFT 0
#define FW_DISPA_WM_MASK 0x3f
#define FW_DISPA_BL_SHIFT 8
#define FW_DISPA_BL_MASK 0xf
#define FW_DISPB_WM_SHIFT 16
#define FW_DISPB_WM_MASK 0x1f
#define FW_DISPB_BL_SHIFT 24
#define FW_DISPB_BL_MASK 0x7
#define FW_BLC_1 0x20dc
#define FW_DISPC_WM_SHIFT 0
#define FW_DISPC_WM_MASK 0x1f
#define FW_DISPC_BL_SHIFT 8
#define FW_DISPC_BL_MASK 0x7
#define GPIOA 0x5010
#define GPIOB 0x5014
#define GPIOC 0x5018 /* this may be external DDC on i830 */
#define GPIOD 0x501C /* this is DVO DDC */
#define GPIOE 0x5020 /* this is DVO i2C */
#define GPIOF 0x5024
/* PLL registers */
#define VGA0_DIVISOR 0x06000
#define VGA1_DIVISOR 0x06004
#define VGAPD 0x06010
#define VGAPD_0_P1_SHIFT 0
#define VGAPD_0_P1_FORCE_DIV2 (1 << 5)
#define VGAPD_0_P2_SHIFT 7
#define VGAPD_1_P1_SHIFT 8
#define VGAPD_1_P1_FORCE_DIV2 (1 << 13)
#define VGAPD_1_P2_SHIFT 15
#define DPLL_A 0x06014
#define DPLL_B 0x06018
#define DPLL_VCO_ENABLE (1 << 31)
#define DPLL_2X_CLOCK_ENABLE (1 << 30)
#define DPLL_SYNCLOCK_ENABLE (1 << 29)
#define DPLL_VGA_MODE_DISABLE (1 << 28)
#define DPLL_P2_MASK 1
#define DPLL_P2_SHIFT 23
#define DPLL_I9XX_P2_SHIFT 24
#define DPLL_P1_FORCE_DIV2 (1 << 21)
#define DPLL_P1_MASK 0x1f
#define DPLL_P1_SHIFT 16
#define DPLL_REFERENCE_SELECT_MASK (0x3 << 13)
#define DPLL_REFERENCE_DEFAULT (0x0 << 13)
#define DPLL_REFERENCE_TVCLK (0x2 << 13)
#define DPLL_RATE_SELECT_MASK (1 << 8)
#define DPLL_RATE_SELECT_FP0 (0 << 8)
#define DPLL_RATE_SELECT_FP1 (1 << 8)
#define FPA0 0x06040
#define FPA1 0x06044
#define FPB0 0x06048
#define FPB1 0x0604c
#define FP_DIVISOR_MASK 0x3f
#define FP_N_DIVISOR_SHIFT 16
#define FP_M1_DIVISOR_SHIFT 8
#define FP_M2_DIVISOR_SHIFT 0
/* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */
/* Clock values are in units of kHz */
#define PLL_REFCLK 48000
#define MIN_CLOCK 25000
#define MAX_CLOCK 350000
/* Two pipes */
#define PIPE_A 0
#define PIPE_B 1
#define PIPE_MASK 1
/* palette registers */
#define PALETTE_A 0x0a000
#define PALETTE_B 0x0a800
#ifndef PALETTE_8_ENTRIES
#define PALETTE_8_ENTRIES 256
#endif
#define PALETTE_8_SIZE (PALETTE_8_ENTRIES * 4)
#define PALETTE_10_ENTRIES 128
#define PALETTE_10_SIZE (PALETTE_10_ENTRIES * 8)
#define PALETTE_8_MASK 0xff
#define PALETTE_8_RED_SHIFT 16
#define PALETTE_8_GREEN_SHIFT 8
#define PALETTE_8_BLUE_SHIFT 0
/* CRTC registers */
#define HTOTAL_A 0x60000
#define HBLANK_A 0x60004
#define HSYNC_A 0x60008
#define VTOTAL_A 0x6000c
#define VBLANK_A 0x60010
#define VSYNC_A 0x60014
#define SRC_SIZE_A 0x6001c
#define BCLRPAT_A 0x60020
#define HTOTAL_B 0x61000
#define HBLANK_B 0x61004
#define HSYNC_B 0x61008
#define VTOTAL_B 0x6100c
#define VBLANK_B 0x61010
#define VSYNC_B 0x61014
#define SRC_SIZE_B 0x6101c
#define BCLRPAT_B 0x61020
#define HTOTAL_MASK 0xfff
#define HTOTAL_SHIFT 16
#define HACTIVE_MASK 0x7ff
#define HACTIVE_SHIFT 0
#define HBLANKEND_MASK 0xfff
#define HBLANKEND_SHIFT 16
#define HBLANKSTART_MASK 0xfff
#define HBLANKSTART_SHIFT 0
#define HSYNCEND_MASK 0xfff
#define HSYNCEND_SHIFT 16
#define HSYNCSTART_MASK 0xfff
#define HSYNCSTART_SHIFT 0
#define VTOTAL_MASK 0xfff
#define VTOTAL_SHIFT 16
#define VACTIVE_MASK 0x7ff
#define VACTIVE_SHIFT 0
#define VBLANKEND_MASK 0xfff
#define VBLANKEND_SHIFT 16
#define VBLANKSTART_MASK 0xfff
#define VBLANKSTART_SHIFT 0
#define VSYNCEND_MASK 0xfff
#define VSYNCEND_SHIFT 16
#define VSYNCSTART_MASK 0xfff
#define VSYNCSTART_SHIFT 0
#define SRC_SIZE_HORIZ_MASK 0x7ff
#define SRC_SIZE_HORIZ_SHIFT 16
#define SRC_SIZE_VERT_MASK 0x7ff
#define SRC_SIZE_VERT_SHIFT 0
#define ADPA 0x61100
#define ADPA_DAC_ENABLE (1 << 31)
#define ADPA_DAC_DISABLE 0
#define ADPA_PIPE_SELECT_SHIFT 30
#define ADPA_USE_VGA_HVPOLARITY (1 << 15)
#define ADPA_SETS_HVPOLARITY 0
#define ADPA_DPMS_CONTROL_MASK (0x3 << 10)
#define ADPA_DPMS_D0 (0x0 << 10)
#define ADPA_DPMS_D2 (0x1 << 10)
#define ADPA_DPMS_D1 (0x2 << 10)
#define ADPA_DPMS_D3 (0x3 << 10)
#define ADPA_VSYNC_ACTIVE_SHIFT 4
#define ADPA_HSYNC_ACTIVE_SHIFT 3
#define ADPA_SYNC_ACTIVE_MASK 1
#define ADPA_SYNC_ACTIVE_HIGH 1
#define ADPA_SYNC_ACTIVE_LOW 0
#define DVOA 0x61120
#define DVOB 0x61140
#define DVOC 0x61160
#define LVDS 0x61180
#define PORT_ENABLE (1 << 31)
#define PORT_PIPE_SELECT_SHIFT 30
#define PORT_TV_FLAGS_MASK 0xFF
#define PORT_TV_FLAGS 0xC4 /* ripped from my BIOS
to understand and correct */
#define DVOA_SRCDIM 0x61124
#define DVOB_SRCDIM 0x61144
#define DVOC_SRCDIM 0x61164
#define PIPEA_DSL 0x70000
#define PIPEB_DSL 0x71000
#define PIPEACONF 0x70008
#define PIPEBCONF 0x71008
#define PIPEASTAT 0x70024 /* bits 0-15 are "write 1 to clear" */
#define PIPEBSTAT 0x71024
#define PIPECONF_ENABLE (1 << 31)
#define PIPECONF_DISABLE 0
#define PIPECONF_DOUBLE_WIDE (1 << 30)
#define PIPECONF_SINGLE_WIDE 0
#define PIPECONF_LOCKED (1 << 25)
#define PIPECONF_UNLOCKED 0
#define PIPECONF_GAMMA (1 << 24)
#define PIPECONF_PALETTE 0
#define PIPECONF_PROGRESSIVE (0 << 21)
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
#define PIPECONF_INTERLACE_MASK (7 << 21)
/* enable bits, write 1 to enable */
#define PIPESTAT_FIFO_UNDERRUN (1 << 31)
#define PIPESTAT_CRC_ERROR_EN (1 << 29)
#define PIPESTAT_CRC_DONE_EN (1 << 28)
#define PIPESTAT_HOTPLUG_EN (1 << 26)
#define PIPESTAT_VERTICAL_SYNC_EN (1 << 25)
#define PIPESTAT_DISPLINE_COMP_EN (1 << 24)
#define PIPESTAT_FLD_EVT_ODD_EN (1 << 21)
#define PIPESTAT_FLD_EVT_EVEN_EN (1 << 20)
#define PIPESTAT_TV_HOTPLUG_EN (1 << 18)
#define PIPESTAT_VBLANK_EN (1 << 17)
#define PIPESTAT_OVL_UPDATE_EN (1 << 16)
/* status bits, write 1 to clear */
#define PIPESTAT_HOTPLUG_STATE (1 << 15)
#define PIPESTAT_CRC_ERROR (1 << 13)
#define PIPESTAT_CRC_DONE (1 << 12)
#define PIPESTAT_HOTPLUG (1 << 10)
#define PIPESTAT_VSYNC (1 << 9)
#define PIPESTAT_DISPLINE_COMP (1 << 8)
#define PIPESTAT_FLD_EVT_ODD (1 << 5)
#define PIPESTAT_FLD_EVT_EVEN (1 << 4)
#define PIPESTAT_TV_HOTPLUG (1 << 2)
#define PIPESTAT_VBLANK (1 << 1)
#define PIPESTAT_OVL_UPDATE (1 << 0)
#define DISPARB 0x70030
#define DISPARB_AEND_MASK 0x1ff
#define DISPARB_AEND_SHIFT 0
#define DISPARB_BEND_MASK 0x3ff
#define DISPARB_BEND_SHIFT 9
/* Desktop HW cursor */
#define CURSOR_CONTROL 0x70080
#define CURSOR_ENABLE (1 << 31)
#define CURSOR_GAMMA_ENABLE (1 << 30)
#define CURSOR_STRIDE_MASK (0x3 << 28)
#define CURSOR_STRIDE_256 (0x0 << 28)
#define CURSOR_STRIDE_512 (0x1 << 28)
#define CURSOR_STRIDE_1K (0x2 << 28)
#define CURSOR_STRIDE_2K (0x3 << 28)
#define CURSOR_FORMAT_MASK (0x7 << 24)
#define CURSOR_FORMAT_2C (0x0 << 24)
#define CURSOR_FORMAT_3C (0x1 << 24)
#define CURSOR_FORMAT_4C (0x2 << 24)
#define CURSOR_FORMAT_ARGB (0x4 << 24)
#define CURSOR_FORMAT_XRGB (0x5 << 24)
/* Mobile HW cursor (and i810) */
#define CURSOR_A_CONTROL CURSOR_CONTROL
#define CURSOR_B_CONTROL 0x700c0
#define CURSOR_MODE_MASK 0x27
#define CURSOR_MODE_DISABLE 0
#define CURSOR_MODE_64_3C 0x04
#define CURSOR_MODE_64_4C_AX 0x05
#define CURSOR_MODE_64_4C 0x06
#define CURSOR_MODE_64_32B_AX 0x07
#define CURSOR_MODE_64_ARGB_AX 0x27
#define CURSOR_PIPE_SELECT_SHIFT 28
#define CURSOR_MOBILE_GAMMA_ENABLE (1 << 26)
#define CURSOR_MEM_TYPE_LOCAL (1 << 25)
/* All platforms (desktop has no pipe B) */
#define CURSOR_A_BASEADDR 0x70084
#define CURSOR_B_BASEADDR 0x700c4
#define CURSOR_BASE_MASK 0xffffff00
#define CURSOR_A_POSITION 0x70088
#define CURSOR_B_POSITION 0x700c8
#define CURSOR_POS_SIGN (1 << 15)
#define CURSOR_POS_MASK 0x7ff
#define CURSOR_X_SHIFT 0
#define CURSOR_Y_SHIFT 16
#define CURSOR_A_PALETTE0 0x70090
#define CURSOR_A_PALETTE1 0x70094
#define CURSOR_A_PALETTE2 0x70098
#define CURSOR_A_PALETTE3 0x7009c
#define CURSOR_B_PALETTE0 0x700d0
#define CURSOR_B_PALETTE1 0x700d4
#define CURSOR_B_PALETTE2 0x700d8
#define CURSOR_B_PALETTE3 0x700dc
#define CURSOR_COLOR_MASK 0xff
#define CURSOR_RED_SHIFT 16
#define CURSOR_GREEN_SHIFT 8
#define CURSOR_BLUE_SHIFT 0
#define CURSOR_PALETTE_MASK 0xffffff
/* Desktop only */
#define CURSOR_SIZE 0x700a0
#define CURSOR_SIZE_MASK 0x3ff
#define CURSOR_SIZE_H_SHIFT 0
#define CURSOR_SIZE_V_SHIFT 12
#define DSPACNTR 0x70180
#define DSPBCNTR 0x71180
#define DISPPLANE_PLANE_ENABLE (1 << 31)
#define DISPPLANE_PLANE_DISABLE 0
#define DISPPLANE_GAMMA_ENABLE (1<<30)
#define DISPPLANE_GAMMA_DISABLE 0
#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
#define DISPPLANE_8BPP (0x2<<26)
#define DISPPLANE_15_16BPP (0x4<<26)
#define DISPPLANE_16BPP (0x5<<26)
#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
#define DISPPLANE_32BPP (0x7<<26)
#define DISPPLANE_STEREO_ENABLE (1<<25)
#define DISPPLANE_STEREO_DISABLE 0
#define DISPPLANE_SEL_PIPE_SHIFT 24
#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
#define DISPPLANE_SRC_KEY_DISABLE 0
#define DISPPLANE_LINE_DOUBLE (1<<20)
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
/* plane B only */
#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
#define DISPPLANE_ALPHA_TRANS_DISABLE 0
#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
#define DISPPLANE_SPRITE_ABOVE_OVERLAY 1
#define DSPABASE 0x70184
#define DSPASTRIDE 0x70188
#define DSPBBASE 0x71184
#define DSPBSTRIDE 0x71188
#define VGACNTRL 0x71400
#define VGA_DISABLE (1 << 31)
#define VGA_ENABLE 0
#define VGA_PIPE_SELECT_SHIFT 29
#define VGA_PALETTE_READ_SELECT 23
#define VGA_PALETTE_A_WRITE_DISABLE (1 << 22)
#define VGA_PALETTE_B_WRITE_DISABLE (1 << 21)
#define VGA_LEGACY_PALETTE (1 << 20)
#define VGA_6BIT_DAC 0
#define VGA_8BIT_DAC (1 << 20)
#define ADD_ID 0x71408
#define ADD_ID_MASK 0xff
/* BIOS scratch area registers (830M and 845G). */
#define SWF0 0x71410
#define SWF1 0x71414
#define SWF2 0x71418
#define SWF3 0x7141c
#define SWF4 0x71420
#define SWF5 0x71424
#define SWF6 0x71428
/* BIOS scratch area registers (852GM, 855GM, 865G). */
#define SWF00 0x70410
#define SWF01 0x70414
#define SWF02 0x70418
#define SWF03 0x7041c
#define SWF04 0x70420
#define SWF05 0x70424
#define SWF06 0x70428
#define SWF10 SWF0
#define SWF11 SWF1
#define SWF12 SWF2
#define SWF13 SWF3
#define SWF14 SWF4
#define SWF15 SWF5
#define SWF16 SWF6
#define SWF30 0x72414
#define SWF31 0x72418
#define SWF32 0x7241c
/* Memory Commands */
#define MI_NOOP (0x00 << 23)
#define MI_NOOP_WRITE_ID (1 << 22)
#define MI_NOOP_ID_MASK ((1 << 22) - 1)
#define MI_FLUSH (0x04 << 23)
#define MI_WRITE_DIRTY_STATE (1 << 4)
#define MI_END_SCENE (1 << 3)
#define MI_INHIBIT_RENDER_CACHE_FLUSH (1 << 2)
#define MI_INVALIDATE_MAP_CACHE (1 << 0)
#define MI_STORE_DWORD_IMM ((0x20 << 23) | 1)
/* 2D Commands */
#define COLOR_BLT_CMD ((2 << 29) | (0x40 << 22) | 3)
#define XY_COLOR_BLT_CMD ((2 << 29) | (0x50 << 22) | 4)
#define XY_SETUP_CLIP_BLT_CMD ((2 << 29) | (0x03 << 22) | 1)
#define XY_SRC_COPY_BLT_CMD ((2 << 29) | (0x53 << 22) | 6)
#define SRC_COPY_BLT_CMD ((2 << 29) | (0x43 << 22) | 4)
#define XY_MONO_PAT_BLT_CMD ((2 << 29) | (0x52 << 22) | 7)
#define XY_MONO_SRC_BLT_CMD ((2 << 29) | (0x54 << 22) | 6)
#define XY_MONO_SRC_IMM_BLT_CMD ((2 << 29) | (0x71 << 22) | 5)
#define TXT_IMM_BLT_CMD ((2 << 29) | (0x30 << 22) | 2)
#define SETUP_BLT_CMD ((2 << 29) | (0x00 << 22) | 6)
#define DW_LENGTH_MASK 0xff
#define WRITE_ALPHA (1 << 21)
#define WRITE_RGB (1 << 20)
#define VERT_SEED (3 << 8)
#define HORIZ_SEED (3 << 12)
#define COLOR_DEPTH_8 (0 << 24)
#define COLOR_DEPTH_16 (1 << 24)
#define COLOR_DEPTH_32 (3 << 24)
#define SRC_ROP_GXCOPY 0xcc
#define SRC_ROP_GXXOR 0x66
#define PAT_ROP_GXCOPY 0xf0
#define PAT_ROP_GXXOR 0x5a
#define PITCH_SHIFT 0
#define ROP_SHIFT 16
#define WIDTH_SHIFT 0
#define HEIGHT_SHIFT 16
/* in bytes */
#define MAX_MONO_IMM_SIZE 128
/*** Macros ***/
/* I/O macros */
#define INREG8(addr) readb((u8 __iomem *)(dinfo->mmio_base + (addr)))
#define INREG16(addr) readw((u16 __iomem *)(dinfo->mmio_base + (addr)))
#define INREG(addr) readl((u32 __iomem *)(dinfo->mmio_base + (addr)))
#define OUTREG8(addr, val) writeb((val),(u8 __iomem *)(dinfo->mmio_base + \
(addr)))
#define OUTREG16(addr, val) writew((val),(u16 __iomem *)(dinfo->mmio_base + \
(addr)))
#define OUTREG(addr, val) writel((val),(u32 __iomem *)(dinfo->mmio_base + \
(addr)))
/* Ring buffer macros */
#define OUT_RING(n) do { \
writel((n), (u32 __iomem *)(dinfo->ring.virtual + dinfo->ring_tail));\
dinfo->ring_tail += 4; \
dinfo->ring_tail &= dinfo->ring_tail_mask; \
} while (0)
#define START_RING(n) do { \
if (dinfo->ring_space < (n) * 4) \
wait_ring(dinfo,(n) * 4); \
dinfo->ring_space -= (n) * 4; \
} while (0)
#define ADVANCE_RING() do { \
OUTREG(PRI_RING_TAIL, dinfo->ring_tail); \
} while (0)
#define DO_RING_IDLE() do { \
u32 head, tail; \
do { \
head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; \
tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; \
udelay(10); \
} while (head != tail); \
} while (0)
/* function protoypes */
extern int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo);
extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
int *stolen_size);
extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo);
extern const char *intelfbhw_dvo_to_string(int dvo);
extern int intelfbhw_validate_mode(struct intelfb_info *dinfo,
struct fb_var_screeninfo *var);
extern int intelfbhw_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
extern void intelfbhw_do_blank(int blank, struct fb_info *info);
extern void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
unsigned red, unsigned green, unsigned blue,
unsigned transp);
extern int intelfbhw_read_hw_state(struct intelfb_info *dinfo,
struct intelfb_hwstate *hw, int flag);
extern void intelfbhw_print_hw_state(struct intelfb_info *dinfo,
struct intelfb_hwstate *hw);
extern int intelfbhw_mode_to_hw(struct intelfb_info *dinfo,
struct intelfb_hwstate *hw,
struct fb_var_screeninfo *var);
extern int intelfbhw_program_mode(struct intelfb_info *dinfo,
const struct intelfb_hwstate *hw, int blank);
extern void intelfbhw_do_sync(struct intelfb_info *dinfo);
extern void intelfbhw_2d_stop(struct intelfb_info *dinfo);
extern void intelfbhw_2d_start(struct intelfb_info *dinfo);
extern void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y,
u32 w, u32 h, u32 color, u32 pitch, u32 bpp,
u32 rop);
extern void intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch,
u32 bpp);
extern int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg,
u32 w, u32 h, const u8* cdat, u32 x, u32 y,
u32 pitch, u32 bpp);
extern void intelfbhw_cursor_init(struct intelfb_info *dinfo);
extern void intelfbhw_cursor_hide(struct intelfb_info *dinfo);
extern void intelfbhw_cursor_show(struct intelfb_info *dinfo);
extern void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y);
extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
u32 fg);
extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
int height, u8 *data);
extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
extern int intelfbhw_enable_irq(struct intelfb_info *dinfo);
extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
extern int intelfbhw_active_pipe(const struct intelfb_hwstate *hw);
#endif /* _INTELFBHW_H */

View File

@ -91,7 +91,7 @@ static int lcd_spi_setup(struct spi_device *spi)
writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
/*
* After set mode it need a time to pull up the spi singals,
* After set mode it needs some time to pull up the spi signals,
* or it would cause the wrong waveform when send spi command,
* especially on pxa910h
*/

View File

@ -27,7 +27,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/screen_info.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/selection.h>
@ -257,36 +256,6 @@ static void sisfb_search_mode(char *name, bool quiet)
printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
}
#ifndef MODULE
static void sisfb_get_vga_mode_from_kernel(void)
{
#ifdef CONFIG_X86
char mymode[32];
int mydepth = screen_info.lfb_depth;
if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) &&
(screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
(mydepth >= 8) && (mydepth <= 32) ) {
if(mydepth == 24) mydepth = 32;
sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
screen_info.lfb_height,
mydepth);
printk(KERN_DEBUG
"sisfb: Using vga mode %s pre-set by kernel as default\n",
mymode);
sisfb_search_mode(mymode, true);
}
#endif
return;
}
#endif
static void __init
sisfb_search_crt2type(const char *name)
{
@ -5901,12 +5870,6 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ivideo->subsysvendor = pdev->subsystem_vendor;
ivideo->subsysdevice = pdev->subsystem_device;
#ifndef MODULE
if(sisfb_mode_idx == -1) {
sisfb_get_vga_mode_from_kernel();
}
#endif
ivideo->chip = chipinfo->chip;
ivideo->chip_real_id = chipinfo->chip;
ivideo->sisvga_engine = chipinfo->vgaengine;

View File

@ -103,7 +103,7 @@ typedef struct {
} ngle_rom_t;
struct stifb_info {
struct fb_info info;
struct fb_info *info;
unsigned int id;
ngle_rom_t ngle_rom;
struct sti_struct *sti;
@ -153,15 +153,15 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
#define REG_44 0x210030
#define REG_45 0x210034
#define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg))
#define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg))
#define READ_BYTE(fb, reg) gsc_readb((fb)->info->fix.mmio_start + (reg))
#define READ_WORD(fb, reg) gsc_readl((fb)->info->fix.mmio_start + (reg))
#ifndef DEBUG_STIFB_REGS
# define DEBUG_OFF()
# define DEBUG_ON()
# define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg))
# define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg))
# define WRITE_BYTE(value, fb, reg) gsc_writeb((value), (fb)->info->fix.mmio_start + (reg))
# define WRITE_WORD(value, fb, reg) gsc_writel((value), (fb)->info->fix.mmio_start + (reg))
#else
static int debug_on = 1;
# define DEBUG_OFF() debug_on=0
@ -169,11 +169,11 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
# define WRITE_BYTE(value,fb,reg) do { if (debug_on) \
printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \
__func__, reg, value, READ_BYTE(fb,reg)); \
gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
gsc_writeb((value), (fb)->info->fix.mmio_start + (reg)); } while (0)
# define WRITE_WORD(value,fb,reg) do { if (debug_on) \
printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \
__func__, reg, value, READ_WORD(fb,reg)); \
gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
gsc_writel((value), (fb)->info->fix.mmio_start + (reg)); } while (0)
#endif /* DEBUG_STIFB_REGS */
@ -210,13 +210,13 @@ SETUP_FB(struct stifb_info *fb)
reg10_value = 0x13601000;
break;
case S9000_ID_A1439A:
if (fb->info.var.bits_per_pixel == 32)
if (fb->info->var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
else
reg10_value = 0x13601000;
break;
case S9000_ID_HCRX:
if (fb->info.var.bits_per_pixel == 32)
if (fb->info->var.bits_per_pixel == 32)
reg10_value = 0xBBA0A000;
else
reg10_value = 0x13602000;
@ -254,7 +254,7 @@ static void
FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
{
WRITE_WORD(0x400, fb, REG_2);
if (fb->info.var.bits_per_pixel == 32) {
if (fb->info->var.bits_per_pixel == 32) {
WRITE_WORD(0x83000100, fb, REG_1);
} else {
if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
@ -503,7 +503,7 @@ static void
ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
{
SETUP_ATTR_ACCESS(fb, BufferNumber);
SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres);
SET_ATTR_SIZE(fb, fb->info->var.xres, fb->info->var.yres);
FINISH_ATTR_ACCESS(fb);
SETUP_FB(fb);
}
@ -526,9 +526,9 @@ rattlerSetupPlanes(struct stifb_info *fb)
SETUP_FB(fb);
fb->id = saved_id;
for (y = 0; y < fb->info.var.yres; ++y)
fb_memset_io(fb->info.screen_base + y * fb->info.fix.line_length,
0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8);
for (y = 0; y < fb->info->var.yres; ++y)
fb_memset_io(fb->info->screen_base + y * fb->info->fix.line_length,
0xff, fb->info->var.xres * fb->info->var.bits_per_pixel/8);
CRX24_SET_OVLY_MASK(fb);
SETUP_FB(fb);
@ -607,7 +607,7 @@ setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
lutBltCtl.fields.lutType = HYPER_CMAP_TYPE;
/* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
if (fb->info.var.bits_per_pixel == 8)
if (fb->info->var.bits_per_pixel == 8)
lutBltCtl.fields.lutOffset = 2 * 256;
else
lutBltCtl.fields.lutOffset = 0 * 256;
@ -688,7 +688,7 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
DataDynamic, MaskOtc,
BGx(0), FGx(0)));
packed_dst = 0;
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
packed_len = (fb->info->var.xres << 16) | fb->info->var.yres;
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
NGLE_SET_DSTXY(fb, packed_dst);
SET_LENXY_START_RECFILL(fb, packed_len);
@ -738,7 +738,7 @@ ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
packed_dst = 0;
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
packed_len = (fb->info->var.xres << 16) | fb->info->var.yres;
NGLE_SET_DSTXY(fb, packed_dst);
/* Write zeroes to overlay planes */
@ -760,7 +760,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
NGLE_LOCK(fb);
if (IS_24_DEVICE(fb))
if (fb->info.var.bits_per_pixel == 32)
if (fb->info->var.bits_per_pixel == 32)
controlPlaneReg = 0x04000F00;
else
controlPlaneReg = 0x00000F00; /* 0x00000800 should be enough, but lets clear all 4 bits */
@ -890,7 +890,7 @@ SETUP_HCRX(struct stifb_info *fb)
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
if (IS_24_DEVICE(fb)) {
hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
hyperbowl = (fb->info->var.bits_per_pixel == 32) ?
HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
@ -924,21 +924,21 @@ SETUP_HCRX(struct stifb_info *fb)
static int
stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct stifb_info *fb = container_of(info, struct stifb_info, info);
struct stifb_info *fb = info->par;
if (var->xres != fb->info.var.xres ||
var->yres != fb->info.var.yres ||
var->bits_per_pixel != fb->info.var.bits_per_pixel)
if (var->xres != fb->info->var.xres ||
var->yres != fb->info->var.yres ||
var->bits_per_pixel != fb->info->var.bits_per_pixel)
return -EINVAL;
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
var->xoffset = 0;
var->yoffset = 0;
var->grayscale = fb->info.var.grayscale;
var->red.length = fb->info.var.red.length;
var->green.length = fb->info.var.green.length;
var->blue.length = fb->info.var.blue.length;
var->grayscale = fb->info->var.grayscale;
var->red.length = fb->info->var.red.length;
var->green.length = fb->info->var.green.length;
var->blue.length = fb->info->var.blue.length;
return 0;
}
@ -947,7 +947,7 @@ static int
stifb_setcolreg(u_int regno, u_int red, u_int green,
u_int blue, u_int transp, struct fb_info *info)
{
struct stifb_info *fb = container_of(info, struct stifb_info, info);
struct stifb_info *fb = info->par;
u32 color;
if (regno >= NR_PALETTE)
@ -961,7 +961,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
START_IMAGE_COLORMAP_ACCESS(fb);
if (unlikely(fb->info.var.grayscale)) {
if (unlikely(fb->info->var.grayscale)) {
/* gray = 0.30*R + 0.59*G + 0.11*B */
color = ((red * 77) +
(green * 151) +
@ -972,10 +972,10 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
(blue));
}
if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) {
struct fb_var_screeninfo *var = &fb->info.var;
if (fb->info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
struct fb_var_screeninfo *var = &fb->info->var;
if (regno < 16)
((u32 *)fb->info.pseudo_palette)[regno] =
((u32 *)fb->info->pseudo_palette)[regno] =
regno << var->red.offset |
regno << var->green.offset |
regno << var->blue.offset;
@ -1007,7 +1007,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
static int
stifb_blank(int blank_mode, struct fb_info *info)
{
struct stifb_info *fb = container_of(info, struct stifb_info, info);
struct stifb_info *fb = info->par;
int enable = (blank_mode == 0) ? ENABLE : DISABLE;
switch (fb->id) {
@ -1036,12 +1036,12 @@ stifb_blank(int blank_mode, struct fb_info *info)
static void
stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
struct stifb_info *fb = container_of(info, struct stifb_info, info);
struct stifb_info *fb = info->par;
SETUP_COPYAREA(fb);
SETUP_HW(fb);
if (fb->info.var.bits_per_pixel == 32) {
if (fb->info->var.bits_per_pixel == 32) {
WRITE_WORD(0xBBA0A000, fb, REG_10);
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff);
@ -1075,15 +1075,15 @@ stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
static void
stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct stifb_info *fb = container_of(info, struct stifb_info, info);
struct stifb_info *fb = info->par;
if (rect->rop != ROP_COPY ||
(fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32))
(fb->id == S9000_ID_HCRX && fb->info->var.bits_per_pixel == 32))
return cfb_fillrect(info, rect);
SETUP_HW(fb);
if (fb->info.var.bits_per_pixel == 32) {
if (fb->info->var.bits_per_pixel == 32) {
WRITE_WORD(0xBBA0A000, fb, REG_10);
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff);
@ -1141,7 +1141,7 @@ stifb_init_display(struct stifb_info *fb)
switch (id) {
case S9000_ID_A1659A:
case S9000_ID_A1439A:
if (fb->info.var.bits_per_pixel == 32)
if (fb->info->var.bits_per_pixel == 32)
ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
else {
ngleSetupAttrPlanes(fb, BUFF1_CMAP0);
@ -1151,7 +1151,7 @@ stifb_init_display(struct stifb_info *fb)
break;
case S9000_ID_ARTIST:
case CRT_ID_VISUALIZE_EG:
if (fb->info.var.bits_per_pixel == 32)
if (fb->info->var.bits_per_pixel == 32)
ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
else {
ngleSetupAttrPlanes(fb, ARTIST_CMAP0);
@ -1193,11 +1193,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
char *dev_name;
int bpp, xres, yres;
fb = kzalloc(sizeof(*fb), GFP_ATOMIC);
if (!fb)
info = framebuffer_alloc(sizeof(*fb), sti->dev);
if (!info)
return -ENOMEM;
info = &fb->info;
fb = info->par;
fb->info = info;
/* set struct to a known state */
fix = &info->fix;
@ -1389,11 +1389,10 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
}
/* save for primary gfx device detection & unregister_framebuffer() */
sti->info = info;
if (register_framebuffer(&fb->info) < 0)
if (register_framebuffer(fb->info) < 0)
goto out_err4;
fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
fb_info(fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
fix->id,
var->xres,
var->yres,
@ -1402,6 +1401,8 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb->id,
fix->mmio_start);
dev_set_drvdata(sti->dev, info);
return 0;
@ -1414,8 +1415,7 @@ out_err2:
out_err1:
iounmap(info->screen_base);
out_err0:
kfree(fb);
sti->info = NULL;
framebuffer_release(info);
return -ENXIO;
}
@ -1480,17 +1480,20 @@ stifb_cleanup(void)
sti = sti_get_rom(i);
if (!sti)
break;
if (sti->info) {
struct fb_info *info = sti->info;
unregister_framebuffer(sti->info);
if (sti->dev) {
struct fb_info *info = dev_get_drvdata(sti->dev);
if (!info)
continue;
unregister_framebuffer(info);
release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
release_mem_region(info->fix.smem_start, info->fix.smem_len);
if (info->screen_base)
iounmap(info->screen_base);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
dev_set_drvdata(sti->dev, NULL);
}
sti->info = NULL;
}
}

View File

@ -1,6 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_FB_LE80578) += vmlfb.o
obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o
vmlfb-objs := vermilion.o
crvml-objs := cr_pll.o

View File

@ -1,195 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Intel Corp. 2007.
* All Rights Reserved.
*
* Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
* develop this driver.
*
* This file is part of the Carillo Ranch video subsystem driver.
*
* Authors:
* Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
* Alan Hourihane <alanh-at-tungstengraphics-dot-com>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/errno.h>
#include <linux/fb.h>
#include "vermilion.h"
/* The PLL Clock register sits on Host bridge */
#define CRVML_DEVICE_MCH 0x5001
#define CRVML_REG_MCHBAR 0x44
#define CRVML_REG_MCHEN 0x54
#define CRVML_MCHEN_BIT (1 << 28)
#define CRVML_MCHMAP_SIZE 4096
#define CRVML_REG_CLOCK 0xc3c
#define CRVML_CLOCK_SHIFT 8
#define CRVML_CLOCK_MASK 0x00000f00
static struct pci_dev *mch_dev;
static u32 mch_bar;
static void __iomem *mch_regs_base;
static u32 saved_clock;
static const unsigned crvml_clocks[] = {
6750,
13500,
27000,
29700,
37125,
54000,
59400,
74250,
120000
/*
* There are more clocks, but they are disabled on the CR board.
*/
};
static const u32 crvml_clock_bits[] = {
0x0a,
0x09,
0x08,
0x07,
0x06,
0x05,
0x04,
0x03,
0x0b
};
static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks);
static int crvml_sys_restore(struct vml_sys *sys)
{
void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
iowrite32(saved_clock, clock_reg);
ioread32(clock_reg);
return 0;
}
static int crvml_sys_save(struct vml_sys *sys)
{
void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
saved_clock = ioread32(clock_reg);
return 0;
}
static int crvml_nearest_index(const struct vml_sys *sys, int clock)
{
int i;
int cur_index = 0;
int cur_diff;
int diff;
cur_diff = clock - crvml_clocks[0];
cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
for (i = 1; i < crvml_num_clocks; ++i) {
diff = clock - crvml_clocks[i];
diff = (diff < 0) ? -diff : diff;
if (diff < cur_diff) {
cur_index = i;
cur_diff = diff;
}
}
return cur_index;
}
static int crvml_nearest_clock(const struct vml_sys *sys, int clock)
{
return crvml_clocks[crvml_nearest_index(sys, clock)];
}
static int crvml_set_clock(struct vml_sys *sys, int clock)
{
void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
int index;
u32 clock_val;
index = crvml_nearest_index(sys, clock);
if (crvml_clocks[index] != clock)
return -EINVAL;
clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK;
clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT;
iowrite32(clock_val, clock_reg);
ioread32(clock_reg);
return 0;
}
static struct vml_sys cr_pll_ops = {
.name = "Carillo Ranch",
.save = crvml_sys_save,
.restore = crvml_sys_restore,
.set_clock = crvml_set_clock,
.nearest_clock = crvml_nearest_clock,
};
static int __init cr_pll_init(void)
{
int err;
u32 dev_en;
mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
CRVML_DEVICE_MCH, NULL);
if (!mch_dev) {
printk(KERN_ERR
"Could not find Carillo Ranch MCH device.\n");
return -ENODEV;
}
pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en);
if (!(dev_en & CRVML_MCHEN_BIT)) {
printk(KERN_ERR
"Carillo Ranch MCH device was not enabled.\n");
pci_dev_put(mch_dev);
return -ENODEV;
}
pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR,
&mch_bar);
mch_regs_base =
ioremap(mch_bar, CRVML_MCHMAP_SIZE);
if (!mch_regs_base) {
printk(KERN_ERR
"Carillo Ranch MCH device was not enabled.\n");
pci_dev_put(mch_dev);
return -ENODEV;
}
err = vmlfb_register_subsys(&cr_pll_ops);
if (err) {
printk(KERN_ERR
"Carillo Ranch failed to initialize vml_sys.\n");
iounmap(mch_regs_base);
pci_dev_put(mch_dev);
return err;
}
return 0;
}
static void __exit cr_pll_exit(void)
{
vmlfb_unregister_subsys(&cr_pll_ops);
iounmap(mch_regs_base);
pci_dev_put(mch_dev);
}
module_init(cr_pll_init);
module_exit(cr_pll_exit);
MODULE_AUTHOR("Tungsten Graphics Inc.");
MODULE_DESCRIPTION("Carillo Ranch PLL Driver");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@ -1,245 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) Intel Corp. 2007.
* All Rights Reserved.
*
* Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
* develop this driver.
*
* This file is part of the Vermilion Range fb driver.
*
* Authors:
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#ifndef _VERMILION_H_
#define _VERMILION_H_
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/atomic.h>
#include <linux/mutex.h>
#define VML_DEVICE_GPU 0x5002
#define VML_DEVICE_VDC 0x5009
#define VML_VRAM_AREAS 3
#define VML_MAX_XRES 1024
#define VML_MAX_YRES 768
#define VML_MAX_XRES_VIRTUAL 1040
/*
* Display controller registers:
*/
/* Display controller 10-bit color representation */
#define VML_R_MASK 0x3FF00000
#define VML_R_SHIFT 20
#define VML_G_MASK 0x000FFC00
#define VML_G_SHIFT 10
#define VML_B_MASK 0x000003FF
#define VML_B_SHIFT 0
/* Graphics plane control */
#define VML_DSPCCNTR 0x00072180
#define VML_GFX_ENABLE 0x80000000
#define VML_GFX_GAMMABYPASS 0x40000000
#define VML_GFX_ARGB1555 0x0C000000
#define VML_GFX_RGB0888 0x18000000
#define VML_GFX_ARGB8888 0x1C000000
#define VML_GFX_ALPHACONST 0x02000000
#define VML_GFX_ALPHAMULT 0x01000000
#define VML_GFX_CONST_ALPHA 0x000000FF
/* Graphics plane start address. Pixel aligned. */
#define VML_DSPCADDR 0x00072184
/* Graphics plane stride register. */
#define VML_DSPCSTRIDE 0x00072188
/* Graphics plane position register. */
#define VML_DSPCPOS 0x0007218C
#define VML_POS_YMASK 0x0FFF0000
#define VML_POS_YSHIFT 16
#define VML_POS_XMASK 0x00000FFF
#define VML_POS_XSHIFT 0
/* Graphics plane height and width */
#define VML_DSPCSIZE 0x00072190
#define VML_SIZE_HMASK 0x0FFF0000
#define VML_SIZE_HSHIFT 16
#define VML_SISE_WMASK 0x00000FFF
#define VML_SIZE_WSHIFT 0
/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */
#define VML_DSPCGAMLUT 0x00072200
/* Pixel video output configuration register */
#define VML_PVOCONFIG 0x00061140
#define VML_CONFIG_BASE 0x80000000
#define VML_CONFIG_PIXEL_SWAP 0x04000000
#define VML_CONFIG_DE_INV 0x01000000
#define VML_CONFIG_HREF_INV 0x00400000
#define VML_CONFIG_VREF_INV 0x00100000
#define VML_CONFIG_CLK_INV 0x00040000
#define VML_CONFIG_CLK_DIV2 0x00010000
#define VML_CONFIG_ESTRB_INV 0x00008000
/* Pipe A Horizontal total register */
#define VML_HTOTAL_A 0x00060000
#define VML_HTOTAL_MASK 0x1FFF0000
#define VML_HTOTAL_SHIFT 16
#define VML_HTOTAL_VAL 8192
#define VML_HACTIVE_MASK 0x000007FF
#define VML_HACTIVE_SHIFT 0
#define VML_HACTIVE_VAL 4096
/* Pipe A Horizontal Blank register */
#define VML_HBLANK_A 0x00060004
#define VML_HBLANK_END_MASK 0x1FFF0000
#define VML_HBLANK_END_SHIFT 16
#define VML_HBLANK_END_VAL 8192
#define VML_HBLANK_START_MASK 0x00001FFF
#define VML_HBLANK_START_SHIFT 0
#define VML_HBLANK_START_VAL 8192
/* Pipe A Horizontal Sync register */
#define VML_HSYNC_A 0x00060008
#define VML_HSYNC_END_MASK 0x1FFF0000
#define VML_HSYNC_END_SHIFT 16
#define VML_HSYNC_END_VAL 8192
#define VML_HSYNC_START_MASK 0x00001FFF
#define VML_HSYNC_START_SHIFT 0
#define VML_HSYNC_START_VAL 8192
/* Pipe A Vertical total register */
#define VML_VTOTAL_A 0x0006000C
#define VML_VTOTAL_MASK 0x1FFF0000
#define VML_VTOTAL_SHIFT 16
#define VML_VTOTAL_VAL 8192
#define VML_VACTIVE_MASK 0x000007FF
#define VML_VACTIVE_SHIFT 0
#define VML_VACTIVE_VAL 4096
/* Pipe A Vertical Blank register */
#define VML_VBLANK_A 0x00060010
#define VML_VBLANK_END_MASK 0x1FFF0000
#define VML_VBLANK_END_SHIFT 16
#define VML_VBLANK_END_VAL 8192
#define VML_VBLANK_START_MASK 0x00001FFF
#define VML_VBLANK_START_SHIFT 0
#define VML_VBLANK_START_VAL 8192
/* Pipe A Vertical Sync register */
#define VML_VSYNC_A 0x00060014
#define VML_VSYNC_END_MASK 0x1FFF0000
#define VML_VSYNC_END_SHIFT 16
#define VML_VSYNC_END_VAL 8192
#define VML_VSYNC_START_MASK 0x00001FFF
#define VML_VSYNC_START_SHIFT 0
#define VML_VSYNC_START_VAL 8192
/* Pipe A Source Image size (minus one - equal to active size)
* Programmable while pipe is enabled.
*/
#define VML_PIPEASRC 0x0006001C
#define VML_PIPEASRC_HMASK 0x0FFF0000
#define VML_PIPEASRC_HSHIFT 16
#define VML_PIPEASRC_VMASK 0x00000FFF
#define VML_PIPEASRC_VSHIFT 0
/* Pipe A Border Color Pattern register (10 bit color) */
#define VML_BCLRPAT_A 0x00060020
/* Pipe A Canvas Color register (10 bit color) */
#define VML_CANVSCLR_A 0x00060024
/* Pipe A Configuration register */
#define VML_PIPEACONF 0x00070008
#define VML_PIPE_BASE 0x00000000
#define VML_PIPE_ENABLE 0x80000000
#define VML_PIPE_FORCE_BORDER 0x02000000
#define VML_PIPE_PLANES_OFF 0x00080000
#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000
/* Pipe A FIFO setting */
#define VML_DSPARB 0x00070030
#define VML_FIFO_DEFAULT 0x00001D9C
/* MDVO rcomp status & pads control register */
#define VML_RCOMPSTAT 0x00070048
#define VML_MDVO_VDC_I_RCOMP 0x80000000
#define VML_MDVO_POWERSAVE_OFF 0x00000008
#define VML_MDVO_PAD_ENABLE 0x00000004
#define VML_MDVO_PULLDOWN_ENABLE 0x00000001
struct vml_par {
struct pci_dev *vdc;
u64 vdc_mem_base;
u64 vdc_mem_size;
char __iomem *vdc_mem;
struct pci_dev *gpu;
u64 gpu_mem_base;
u64 gpu_mem_size;
char __iomem *gpu_mem;
atomic_t refcount;
};
struct vram_area {
unsigned long logical;
unsigned long phys;
unsigned long size;
unsigned order;
};
struct vml_info {
struct fb_info info;
struct vml_par *par;
struct list_head head;
struct vram_area vram[VML_VRAM_AREAS];
u64 vram_start;
u64 vram_contig_size;
u32 num_areas;
void __iomem *vram_logical;
u32 pseudo_palette[16];
u32 stride;
u32 bytes_per_pixel;
atomic_t vmas;
int cur_blank_mode;
int pipe_disabled;
};
/*
* Subsystem
*/
struct vml_sys {
char *name;
/*
* Save / Restore;
*/
int (*save) (struct vml_sys * sys);
int (*restore) (struct vml_sys * sys);
/*
* PLL programming;
*/
int (*set_clock) (struct vml_sys * sys, int clock);
int (*nearest_clock) (const struct vml_sys * sys, int clock);
};
extern int vmlfb_register_subsys(struct vml_sys *sys);
extern void vmlfb_unregister_subsys(struct vml_sys *sys);
#define VML_READ32(_par, _offset) \
(ioread32((_par)->vdc_mem + (_offset)))
#define VML_WRITE32(_par, _offset, _value) \
iowrite32(_value, (_par)->vdc_mem + (_offset))
#endif

View File

@ -249,10 +249,10 @@ static void write_footer(void)
fputs("\n};\n\n", out);
fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
fprintf(out, "\t.width\t\t= %d,\n", logo_width);
fprintf(out, "\t.height\t\t= %d,\n", logo_height);
fprintf(out, "\t.width\t\t= %u,\n", logo_width);
fprintf(out, "\t.height\t\t= %u,\n", logo_height);
if (logo_type == LINUX_LOGO_CLUT224) {
fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize);
fprintf(out, "\t.clutsize\t= %u,\n", logo_clutsize);
fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname);
}
fprintf(out, "\t.data\t\t= %s_data\n", logoname);

View File

@ -1041,6 +1041,9 @@ static int __init sticore_pa_init(struct parisc_device *dev)
print_pa_hwpath(dev, sti->pa_path);
sticore_check_for_default_sti(sti, sti->pa_path);
sti->dev = &dev->dev;
return 0;
}
@ -1084,6 +1087,8 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
pr_warn("Unable to handle STI device '%s'\n", pci_name(pd));
return -ENODEV;
}
sti->dev = &pd->dev;
#endif /* CONFIG_PCI */
return 0;

View File

@ -1,87 +0,0 @@
/*
* David A Rusling
*
* Copyright (C) 2001 ARM Limited
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#ifndef AMBA_CLCD_REGS_H
#define AMBA_CLCD_REGS_H
/*
* CLCD Controller Internal Register addresses
*/
#define CLCD_TIM0 0x00000000
#define CLCD_TIM1 0x00000004
#define CLCD_TIM2 0x00000008
#define CLCD_TIM3 0x0000000c
#define CLCD_UBAS 0x00000010
#define CLCD_LBAS 0x00000014
#define CLCD_PL110_IENB 0x00000018
#define CLCD_PL110_CNTL 0x0000001c
#define CLCD_PL110_STAT 0x00000020
#define CLCD_PL110_INTR 0x00000024
#define CLCD_PL110_UCUR 0x00000028
#define CLCD_PL110_LCUR 0x0000002C
#define CLCD_PL111_CNTL 0x00000018
#define CLCD_PL111_IENB 0x0000001c
#define CLCD_PL111_RIS 0x00000020
#define CLCD_PL111_MIS 0x00000024
#define CLCD_PL111_ICR 0x00000028
#define CLCD_PL111_UCUR 0x0000002c
#define CLCD_PL111_LCUR 0x00000030
#define CLCD_PALL 0x00000200
#define CLCD_PALETTE 0x00000200
#define TIM2_PCD_LO_MASK GENMASK(4, 0)
#define TIM2_PCD_LO_BITS 5
#define TIM2_CLKSEL (1 << 5)
#define TIM2_ACB_MASK GENMASK(10, 6)
#define TIM2_IVS (1 << 11)
#define TIM2_IHS (1 << 12)
#define TIM2_IPC (1 << 13)
#define TIM2_IOE (1 << 14)
#define TIM2_BCD (1 << 26)
#define TIM2_PCD_HI_MASK GENMASK(31, 27)
#define TIM2_PCD_HI_BITS 5
#define TIM2_PCD_HI_SHIFT 27
#define CNTL_LCDEN (1 << 0)
#define CNTL_LCDBPP1 (0 << 1)
#define CNTL_LCDBPP2 (1 << 1)
#define CNTL_LCDBPP4 (2 << 1)
#define CNTL_LCDBPP8 (3 << 1)
#define CNTL_LCDBPP16 (4 << 1)
#define CNTL_LCDBPP16_565 (6 << 1)
#define CNTL_LCDBPP16_444 (7 << 1)
#define CNTL_LCDBPP24 (5 << 1)
#define CNTL_LCDBW (1 << 4)
#define CNTL_LCDTFT (1 << 5)
#define CNTL_LCDMONO8 (1 << 6)
#define CNTL_LCDDUAL (1 << 7)
#define CNTL_BGR (1 << 8)
#define CNTL_BEBO (1 << 9)
#define CNTL_BEPO (1 << 10)
#define CNTL_LCDPWR (1 << 11)
#define CNTL_LCDVCOMP(x) ((x) << 12)
#define CNTL_LDMAFIFOTIME (1 << 15)
#define CNTL_WATERMARK (1 << 16)
/* ST Microelectronics variant bits */
#define CNTL_ST_1XBPP_444 0x0
#define CNTL_ST_1XBPP_5551 (1 << 17)
#define CNTL_ST_1XBPP_565 (1 << 18)
#define CNTL_ST_CDWID_12 0x0
#define CNTL_ST_CDWID_16 (1 << 19)
#define CNTL_ST_CDWID_18 (1 << 20)
#define CNTL_ST_CDWID_24 ((1 << 19)|(1 << 20))
#define CNTL_ST_CEAEN (1 << 21)
#define CNTL_ST_LCDBPP24_PACKED (6 << 1)
#endif /* AMBA_CLCD_REGS_H */

View File

@ -1,290 +0,0 @@
/*
* linux/include/asm-arm/hardware/amba_clcd.h -- Integrator LCD panel.
*
* David A Rusling
*
* Copyright (C) 2001 ARM Limited
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/fb.h>
#include <linux/amba/clcd-regs.h>
enum {
/* individual formats */
CLCD_CAP_RGB444 = (1 << 0),
CLCD_CAP_RGB5551 = (1 << 1),
CLCD_CAP_RGB565 = (1 << 2),
CLCD_CAP_RGB888 = (1 << 3),
CLCD_CAP_BGR444 = (1 << 4),
CLCD_CAP_BGR5551 = (1 << 5),
CLCD_CAP_BGR565 = (1 << 6),
CLCD_CAP_BGR888 = (1 << 7),
/* connection layouts */
CLCD_CAP_444 = CLCD_CAP_RGB444 | CLCD_CAP_BGR444,
CLCD_CAP_5551 = CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551,
CLCD_CAP_565 = CLCD_CAP_RGB565 | CLCD_CAP_BGR565,
CLCD_CAP_888 = CLCD_CAP_RGB888 | CLCD_CAP_BGR888,
/* red/blue ordering */
CLCD_CAP_RGB = CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 |
CLCD_CAP_RGB565 | CLCD_CAP_RGB888,
CLCD_CAP_BGR = CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 |
CLCD_CAP_BGR565 | CLCD_CAP_BGR888,
CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB,
};
struct backlight_device;
struct clcd_panel {
struct fb_videomode mode;
signed short width; /* width in mm */
signed short height; /* height in mm */
u32 tim2;
u32 tim3;
u32 cntl;
u32 caps;
unsigned int bpp:8,
fixedtimings:1,
grayscale:1;
unsigned int connector;
struct backlight_device *backlight;
/*
* If the B/R lines are switched between the CLCD
* and the panel we need to know this and not try to
* compensate with the BGR bit in the control register.
*/
bool bgr_connection;
};
struct clcd_regs {
u32 tim0;
u32 tim1;
u32 tim2;
u32 tim3;
u32 cntl;
unsigned long pixclock;
};
struct clcd_fb;
/*
* the board-type specific routines
*/
struct clcd_board {
const char *name;
/*
* Optional. Hardware capability flags.
*/
u32 caps;
/*
* Optional. Check whether the var structure is acceptable
* for this display.
*/
int (*check)(struct clcd_fb *fb, struct fb_var_screeninfo *var);
/*
* Compulsory. Decode fb->fb.var into regs->*. In the case of
* fixed timing, set regs->* to the register values required.
*/
void (*decode)(struct clcd_fb *fb, struct clcd_regs *regs);
/*
* Optional. Disable any extra display hardware.
*/
void (*disable)(struct clcd_fb *);
/*
* Optional. Enable any extra display hardware.
*/
void (*enable)(struct clcd_fb *);
/*
* Setup platform specific parts of CLCD driver
*/
int (*setup)(struct clcd_fb *);
/*
* mmap the framebuffer memory
*/
int (*mmap)(struct clcd_fb *, struct vm_area_struct *);
/*
* Remove platform specific parts of CLCD driver
*/
void (*remove)(struct clcd_fb *);
};
struct amba_device;
struct clk;
/* this data structure describes each frame buffer device we find */
struct clcd_fb {
struct fb_info fb;
struct amba_device *dev;
struct clk *clk;
struct clcd_panel *panel;
struct clcd_board *board;
void *board_data;
void __iomem *regs;
u16 off_ienb;
u16 off_cntl;
u32 clcd_cntl;
u32 cmap[16];
bool clk_enabled;
};
static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
{
struct fb_var_screeninfo *var = &fb->fb.var;
u32 val, cpl;
/*
* Program the CLCD controller registers and start the CLCD
*/
val = ((var->xres / 16) - 1) << 2;
val |= (var->hsync_len - 1) << 8;
val |= (var->right_margin - 1) << 16;
val |= (var->left_margin - 1) << 24;
regs->tim0 = val;
val = var->yres;
if (fb->panel->cntl & CNTL_LCDDUAL)
val /= 2;
val -= 1;
val |= (var->vsync_len - 1) << 10;
val |= var->lower_margin << 16;
val |= var->upper_margin << 24;
regs->tim1 = val;
val = fb->panel->tim2;
val |= var->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS;
val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS;
cpl = var->xres_virtual;
if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */
/* / 1 */;
else if (!var->grayscale) /* STN color */
cpl = cpl * 8 / 3;
else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
cpl /= 8;
else /* STN monochrome, 4bit */
cpl /= 4;
regs->tim2 = val | ((cpl - 1) << 16);
regs->tim3 = fb->panel->tim3;
val = fb->panel->cntl;
if (var->grayscale)
val |= CNTL_LCDBW;
if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) {
/*
* if board and panel supply capabilities, we can support
* changing BGR/RGB depending on supplied parameters. Here
* we switch to what the framebuffer is providing if need
* be, so if the framebuffer is BGR but the display connection
* is RGB (first case) we switch it around. Vice versa mutatis
* mutandis if the framebuffer is RGB but the display connection
* is BGR, we flip it around.
*/
if (var->red.offset == 0)
val &= ~CNTL_BGR;
else
val |= CNTL_BGR;
if (fb->panel->bgr_connection)
val ^= CNTL_BGR;
}
switch (var->bits_per_pixel) {
case 1:
val |= CNTL_LCDBPP1;
break;
case 2:
val |= CNTL_LCDBPP2;
break;
case 4:
val |= CNTL_LCDBPP4;
break;
case 8:
val |= CNTL_LCDBPP8;
break;
case 16:
/*
* PL110 cannot choose between 5551 and 565 modes in its
* control register. It is possible to use 565 with
* custom external wiring.
*/
if (amba_part(fb->dev) == 0x110 ||
var->green.length == 5)
val |= CNTL_LCDBPP16;
else if (var->green.length == 6)
val |= CNTL_LCDBPP16_565;
else
val |= CNTL_LCDBPP16_444;
break;
case 32:
val |= CNTL_LCDBPP24;
break;
}
regs->cntl = val;
regs->pixclock = var->pixclock;
}
static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
{
var->xres_virtual = var->xres = (var->xres + 15) & ~15;
var->yres_virtual = var->yres = (var->yres + 1) & ~1;
#define CHECK(e,l,h) (var->e < l || var->e > h)
if (CHECK(right_margin, (5+1), 256) || /* back porch */
CHECK(left_margin, (5+1), 256) || /* front porch */
CHECK(hsync_len, (5+1), 256) ||
var->xres > 4096 ||
var->lower_margin > 255 || /* back porch */
var->upper_margin > 255 || /* front porch */
var->vsync_len > 32 ||
var->yres > 1024)
return -EINVAL;
#undef CHECK
/* single panel mode: PCD = max(PCD, 1) */
/* dual panel mode: PCD = max(PCD, 5) */
/*
* You can't change the grayscale setting, and
* we can only do non-interlaced video.
*/
if (var->grayscale != fb->fb.var.grayscale ||
(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
return -EINVAL;
#define CHECK(e) (var->e != fb->fb.var.e)
if (fb->panel->fixedtimings &&
(CHECK(xres) ||
CHECK(yres) ||
CHECK(bits_per_pixel) ||
CHECK(pixclock) ||
CHECK(left_margin) ||
CHECK(right_margin) ||
CHECK(upper_margin) ||
CHECK(lower_margin) ||
CHECK(hsync_len) ||
CHECK(vsync_len) ||
CHECK(sync)))
return -EINVAL;
#undef CHECK
var->nonstd = 0;
var->accel_flags = 0;
return 0;
}

View File

@ -2,7 +2,7 @@
#ifndef STICORE_H
#define STICORE_H
struct fb_info;
struct device;
/* generic STI structures & functions */
@ -367,8 +367,8 @@ struct sti_struct {
/* PCI data structures (pg. 17ff from sti.pdf) */
u8 rm_entry[16]; /* pci region mapper array == pci config space offset */
/* pointer to the fb_info where this STI device is used */
struct fb_info *info;
/* pointer to the parent device */
struct device *dev;
/* pointer to all internal data */
struct sti_all_data *sti_data;