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:
commit
d97a78423c
@ -19,7 +19,6 @@ Frame Buffer
|
||||
framebuffer
|
||||
gxfb
|
||||
intel810
|
||||
intelfb
|
||||
internals
|
||||
lxfb
|
||||
matroxfb
|
||||
|
@ -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
|
@ -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!
|
||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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, ®s);
|
||||
|
||||
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");
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
@ -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 */
|
@ -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
@ -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 */
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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
@ -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
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user