mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: Documentation/kernel-parameters.txt arch/sh/include/asm/elf.h
This commit is contained in:
commit
4cb40f795a
6752 changed files with 538692 additions and 172011 deletions
|
|
@ -76,6 +76,14 @@ config FB_DDC
|
|||
select I2C
|
||||
default n
|
||||
|
||||
config FB_BOOT_VESA_SUPPORT
|
||||
bool
|
||||
depends on FB
|
||||
default n
|
||||
---help---
|
||||
If true, at least one selected framebuffer driver can take advantage
|
||||
of VESA video modes set at an early boot stage via the vga= parameter.
|
||||
|
||||
config FB_CFB_FILLRECT
|
||||
tristate
|
||||
depends on FB
|
||||
|
|
@ -172,11 +180,6 @@ config FB_DEFERRED_IO
|
|||
bool
|
||||
depends on FB
|
||||
|
||||
config FB_METRONOME
|
||||
tristate
|
||||
depends on FB
|
||||
depends on FB_DEFERRED_IO
|
||||
|
||||
config FB_HECUBA
|
||||
tristate
|
||||
depends on FB
|
||||
|
|
@ -259,16 +262,24 @@ config FB_PM2
|
|||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
help
|
||||
This is the frame buffer device driver for the Permedia2 AGP frame
|
||||
buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a
|
||||
product page at
|
||||
<http://www.ask.com.hk/product/Permedia%202/permedia2.htm>.
|
||||
This is the frame buffer device driver for cards based on
|
||||
the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
|
||||
The driver was tested on the following cards:
|
||||
Diamond FireGL 1000 PRO AGP
|
||||
ELSA Gloria Synergy PCI
|
||||
Appian Jeronimo PRO (both heads) PCI
|
||||
3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
|
||||
Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
|
||||
ASK Graphic Blaster Exxtreme AGP
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pm2fb.
|
||||
|
||||
config FB_PM2_FIFO_DISCONNECT
|
||||
bool "enable FIFO disconnect feature"
|
||||
depends on FB_PM2 && PCI
|
||||
help
|
||||
Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2).
|
||||
Support the Permedia2 FIFO disconnect feature.
|
||||
|
||||
config FB_ARMCLCD
|
||||
tristate "ARM PrimeCell PL110 support"
|
||||
|
|
@ -678,7 +689,7 @@ config FB_VESA
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select VIDEO_SELECT
|
||||
select FB_BOOT_VESA_SUPPORT
|
||||
help
|
||||
This is the frame buffer device driver for generic VESA 2.0
|
||||
compliant graphic cards. The older VESA 1.2 cards are not supported.
|
||||
|
|
@ -687,23 +698,14 @@ config FB_VESA
|
|||
|
||||
config FB_EFI
|
||||
bool "EFI-based Framebuffer Support"
|
||||
depends on (FB = y) && X86
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
help
|
||||
This is the EFI frame buffer device driver. If the firmware on
|
||||
your platform is UEFI2.0, select Y to add support for
|
||||
Graphics Output Protocol for early console messages to appear.
|
||||
|
||||
config FB_IMAC
|
||||
bool "Intel-based Macintosh Framebuffer Support"
|
||||
depends on (FB = y) && X86 && EFI
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
help
|
||||
This is the frame buffer device driver for the Intel-based Macintosh
|
||||
This is the EFI frame buffer device driver. If the firmware on
|
||||
your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
|
||||
using the EFI framebuffer as your console.
|
||||
|
||||
config FB_N411
|
||||
tristate "N411 Apollo/Hecuba devkit support"
|
||||
|
|
@ -1124,6 +1126,7 @@ config FB_INTEL
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_BOOT_VESA_SUPPORT
|
||||
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.
|
||||
|
|
@ -1476,6 +1479,7 @@ config FB_SIS
|
|||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_BOOT_VESA_SUPPORT
|
||||
help
|
||||
This is the frame buffer device driver for the SiS 300, 315, 330
|
||||
and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
|
||||
|
|
@ -1498,6 +1502,24 @@ config FB_SIS_315
|
|||
(315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
|
||||
as XGI V3XT, V5, V8 and Z7.
|
||||
|
||||
config FB_VIA
|
||||
tristate "VIA UniChrome (Pro) and Chrome9 display support"
|
||||
depends on FB && PCI
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_SOFT_CURSOR
|
||||
select I2C_ALGOBIT
|
||||
select I2C
|
||||
help
|
||||
This is the frame buffer device driver for Graphics chips of VIA
|
||||
UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
|
||||
CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
|
||||
/P4M900,VX800)
|
||||
Say Y if you have a VIA UniChrome graphics board.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called viafb.
|
||||
config FB_NEOMAGIC
|
||||
tristate "NeoMagic display support"
|
||||
depends on FB && PCI
|
||||
|
|
@ -1527,25 +1549,25 @@ config FB_KYRO
|
|||
module will be called kyrofb.
|
||||
|
||||
config FB_3DFX
|
||||
tristate "3Dfx Banshee/Voodoo3 display support"
|
||||
tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
|
||||
depends on FB && PCI
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
help
|
||||
This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
|
||||
chips. Say Y if you have such a graphics board.
|
||||
This driver supports graphics boards with the 3Dfx Banshee,
|
||||
Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
|
||||
such a graphics board.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tdfxfb.
|
||||
|
||||
config FB_3DFX_ACCEL
|
||||
bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)"
|
||||
bool "3Dfx Acceleration functions (EXPERIMENTAL)"
|
||||
depends on FB_3DFX && EXPERIMENTAL
|
||||
---help---
|
||||
This will compile the 3Dfx Banshee/Voodoo3 frame buffer device
|
||||
with acceleration functions.
|
||||
|
||||
This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
|
||||
device driver with acceleration functions.
|
||||
|
||||
config FB_VOODOO1
|
||||
tristate "3Dfx Voodoo Graphics (sst1) support"
|
||||
|
|
@ -1583,7 +1605,6 @@ config FB_CYBLA
|
|||
tristate "Cyberblade/i1 support"
|
||||
depends on FB && PCI && X86_32 && !64BIT
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select VIDEO_SELECT
|
||||
---help---
|
||||
This driver is supposed to support the Trident Cyberblade/i1
|
||||
graphics core integrated in the VIA VT8601A North Bridge,
|
||||
|
|
@ -1611,17 +1632,16 @@ config FB_TRIDENT
|
|||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
---help---
|
||||
This driver is supposed to support graphics boards with the
|
||||
Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
|
||||
This is the frame buffer device driver for Trident PCI/AGP chipsets.
|
||||
Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
|
||||
and Blade XP.
|
||||
There are also integrated versions of these chips called CyberXXXX,
|
||||
CyberImage or CyberBlade. These chips are mostly found in laptops
|
||||
but also on some motherboards. For more information, read
|
||||
<file:Documentation/fb/tridentfb.txt>
|
||||
|
||||
Cyberblade/i1 support will be removed soon, use the cyblafb driver
|
||||
instead.
|
||||
|
||||
Say Y if you have such a graphics board.
|
||||
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tridentfb.
|
||||
|
||||
|
|
@ -1876,6 +1896,28 @@ config FB_SH_MOBILE_LCDC
|
|||
---help---
|
||||
Frame buffer driver for the on-chip SH-Mobile LCD controller.
|
||||
|
||||
config FB_TMIO
|
||||
tristate "Toshiba Mobile IO FrameBuffer support"
|
||||
depends on FB && MFD_CORE
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
---help---
|
||||
Frame buffer driver for the Toshiba Mobile IO integrated as found
|
||||
on the Sharp SL-6000 series
|
||||
|
||||
This driver is also available as a module ( = code which can be
|
||||
inserted and removed from the running kernel whenever you want). The
|
||||
module will be called tmiofb. If you want to compile it as a module,
|
||||
say M here and read <file:Documentation/kbuild/modules.txt>.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config FB_TMIO_ACCELL
|
||||
bool "tmiofb acceleration"
|
||||
depends on FB_TMIO
|
||||
default y
|
||||
|
||||
config FB_S3C2410
|
||||
tristate "S3C2410 LCD framebuffer support"
|
||||
depends on FB && ARCH_S3C2410
|
||||
|
|
@ -1974,19 +2016,6 @@ config FB_XILINX
|
|||
framebuffer. ML300 carries a 640*480 LCD display on the board,
|
||||
ML403 uses a standard DB15 VGA connector.
|
||||
|
||||
config FB_AM200EPD
|
||||
tristate "AM-200 E-Ink EPD devkit support"
|
||||
depends on FB && ARCH_PXA && MMU
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
select FB_DEFERRED_IO
|
||||
select FB_METRONOME
|
||||
help
|
||||
This enables support for the Metronome display controller used on
|
||||
the E-Ink AM-200 EPD devkit.
|
||||
|
||||
config FB_COBALT
|
||||
tristate "Cobalt server LCD frame buffer support"
|
||||
depends on FB && MIPS_COBALT
|
||||
|
|
@ -2041,6 +2070,19 @@ config XEN_FBDEV_FRONTEND
|
|||
frame buffer driver. It communicates with a back-end
|
||||
in another domain.
|
||||
|
||||
config FB_METRONOME
|
||||
tristate "E-Ink Metronome/8track controller support"
|
||||
depends on FB
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
select FB_DEFERRED_IO
|
||||
help
|
||||
This driver implements support for the E-Ink Metronome
|
||||
controller. The pre-release name for this device was 8track
|
||||
and could also have been called by some vendors as PVI-nnnn.
|
||||
|
||||
source "drivers/video/omap/Kconfig"
|
||||
|
||||
source "drivers/video/backlight/Kconfig"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
|
|||
|
||||
# Hardware specific drivers go first
|
||||
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
|
||||
obj-$(CONFIG_FB_AM200EPD) += am200epd.o
|
||||
obj-$(CONFIG_FB_ARC) += arcfb.o
|
||||
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
|
||||
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
|
||||
|
|
@ -43,6 +42,7 @@ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
|
|||
obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
|
||||
obj-$(CONFIG_FB_RADEON) += aty/
|
||||
obj-$(CONFIG_FB_SIS) += sis/
|
||||
obj-$(CONFIG_FB_VIA) += via/
|
||||
obj-$(CONFIG_FB_KYRO) += kyro/
|
||||
obj-$(CONFIG_FB_SAVAGE) += savage/
|
||||
obj-$(CONFIG_FB_GEODE) += geode/
|
||||
|
|
@ -98,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
|
|||
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
|
||||
obj-$(CONFIG_FB_PXA) += pxafb.o
|
||||
obj-$(CONFIG_FB_W100) += w100fb.o
|
||||
obj-$(CONFIG_FB_TMIO) += tmiofb.o
|
||||
obj-$(CONFIG_FB_AU1100) += au1100fb.o
|
||||
obj-$(CONFIG_FB_AU1200) += au1200fb.o
|
||||
obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
|
||||
|
|
@ -125,7 +126,6 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o
|
|||
# Platform or fallback drivers go here
|
||||
obj-$(CONFIG_FB_UVESA) += uvesafb.o
|
||||
obj-$(CONFIG_FB_VESA) += vesafb.o
|
||||
obj-$(CONFIG_FB_IMAC) += imacfb.o
|
||||
obj-$(CONFIG_FB_EFI) += efifb.o
|
||||
obj-$(CONFIG_FB_VGA16) += vga16fb.o
|
||||
obj-$(CONFIG_FB_OF) += offb.o
|
||||
|
|
|
|||
|
|
@ -1,295 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/video/am200epd.c -- Platform device for AM200 EPD kit
|
||||
*
|
||||
* Copyright (C) 2008, Jaya Kumar
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
|
||||
*
|
||||
* This work was made possible by help and equipment support from E-Ink
|
||||
* Corporation. http://support.eink.com/community
|
||||
*
|
||||
* This driver is written to be used with the Metronome display controller.
|
||||
* on the AM200 EPD prototype kit/development kit with an E-Ink 800x600
|
||||
* Vizplex EPD on a Gumstix board using the Lyre interface board.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <video/metronomefb.h>
|
||||
|
||||
#include <mach/pxa-regs.h>
|
||||
|
||||
/* register offsets for gpio control */
|
||||
#define LED_GPIO_PIN 51
|
||||
#define STDBY_GPIO_PIN 48
|
||||
#define RST_GPIO_PIN 49
|
||||
#define RDY_GPIO_PIN 32
|
||||
#define ERR_GPIO_PIN 17
|
||||
#define PCBPWR_GPIO_PIN 16
|
||||
|
||||
#define AF_SEL_GPIO_N 0x3
|
||||
#define GAFR0_U_OFFSET(pin) ((pin - 16) * 2)
|
||||
#define GAFR1_L_OFFSET(pin) ((pin - 32) * 2)
|
||||
#define GAFR1_U_OFFSET(pin) ((pin - 48) * 2)
|
||||
#define GPDR1_OFFSET(pin) (pin - 32)
|
||||
#define GPCR1_OFFSET(pin) (pin - 32)
|
||||
#define GPSR1_OFFSET(pin) (pin - 32)
|
||||
#define GPCR0_OFFSET(pin) (pin)
|
||||
#define GPSR0_OFFSET(pin) (pin)
|
||||
|
||||
static void am200_set_gpio_output(int pin, int val)
|
||||
{
|
||||
u8 index;
|
||||
|
||||
index = pin >> 4;
|
||||
|
||||
switch (index) {
|
||||
case 1:
|
||||
if (val)
|
||||
GPSR0 |= (1 << GPSR0_OFFSET(pin));
|
||||
else
|
||||
GPCR0 |= (1 << GPCR0_OFFSET(pin));
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
if (val)
|
||||
GPSR1 |= (1 << GPSR1_OFFSET(pin));
|
||||
else
|
||||
GPCR1 |= (1 << GPCR1_OFFSET(pin));
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "unimplemented\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void __devinit am200_init_gpio_pin(int pin, int dir)
|
||||
{
|
||||
u8 index;
|
||||
/* dir 0 is output, 1 is input
|
||||
- do 2 things here:
|
||||
- set gpio alternate function to standard gpio
|
||||
- set gpio direction to input or output */
|
||||
|
||||
index = pin >> 4;
|
||||
switch (index) {
|
||||
case 1:
|
||||
GAFR0_U &= ~(AF_SEL_GPIO_N << GAFR0_U_OFFSET(pin));
|
||||
|
||||
if (dir)
|
||||
GPDR0 &= ~(1 << pin);
|
||||
else
|
||||
GPDR0 |= (1 << pin);
|
||||
break;
|
||||
case 2:
|
||||
GAFR1_L &= ~(AF_SEL_GPIO_N << GAFR1_L_OFFSET(pin));
|
||||
|
||||
if (dir)
|
||||
GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
|
||||
else
|
||||
GPDR1 |= (1 << GPDR1_OFFSET(pin));
|
||||
break;
|
||||
case 3:
|
||||
GAFR1_U &= ~(AF_SEL_GPIO_N << GAFR1_U_OFFSET(pin));
|
||||
|
||||
if (dir)
|
||||
GPDR1 &= ~(1 << GPDR1_OFFSET(pin));
|
||||
else
|
||||
GPDR1 |= (1 << GPDR1_OFFSET(pin));
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "unimplemented\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void am200_init_gpio_regs(struct metronomefb_par *par)
|
||||
{
|
||||
am200_init_gpio_pin(LED_GPIO_PIN, 0);
|
||||
am200_set_gpio_output(LED_GPIO_PIN, 0);
|
||||
|
||||
am200_init_gpio_pin(STDBY_GPIO_PIN, 0);
|
||||
am200_set_gpio_output(STDBY_GPIO_PIN, 0);
|
||||
|
||||
am200_init_gpio_pin(RST_GPIO_PIN, 0);
|
||||
am200_set_gpio_output(RST_GPIO_PIN, 0);
|
||||
|
||||
am200_init_gpio_pin(RDY_GPIO_PIN, 1);
|
||||
|
||||
am200_init_gpio_pin(ERR_GPIO_PIN, 1);
|
||||
|
||||
am200_init_gpio_pin(PCBPWR_GPIO_PIN, 0);
|
||||
am200_set_gpio_output(PCBPWR_GPIO_PIN, 0);
|
||||
}
|
||||
|
||||
static void am200_disable_lcd_controller(struct metronomefb_par *par)
|
||||
{
|
||||
LCSR = 0xffffffff; /* Clear LCD Status Register */
|
||||
LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
|
||||
|
||||
/* we reset and just wait for things to settle */
|
||||
msleep(200);
|
||||
}
|
||||
|
||||
static void am200_enable_lcd_controller(struct metronomefb_par *par)
|
||||
{
|
||||
LCSR = 0xffffffff;
|
||||
FDADR0 = par->metromem_desc_dma;
|
||||
LCCR0 |= LCCR0_ENB;
|
||||
}
|
||||
|
||||
static void am200_init_lcdc_regs(struct metronomefb_par *par)
|
||||
{
|
||||
/* here we do:
|
||||
- disable the lcd controller
|
||||
- setup lcd control registers
|
||||
- setup dma descriptor
|
||||
- reenable lcd controller
|
||||
*/
|
||||
|
||||
/* disable the lcd controller */
|
||||
am200_disable_lcd_controller(par);
|
||||
|
||||
/* setup lcd control registers */
|
||||
LCCR0 = LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_PAS
|
||||
| LCCR0_QDM | LCCR0_BM | LCCR0_OUM;
|
||||
|
||||
LCCR1 = (par->info->var.xres/2 - 1) /* pixels per line */
|
||||
| (27 << 10) /* hsync pulse width - 1 */
|
||||
| (33 << 16) /* eol pixel count */
|
||||
| (33 << 24); /* bol pixel count */
|
||||
|
||||
LCCR2 = (par->info->var.yres - 1) /* lines per panel */
|
||||
| (24 << 10) /* vsync pulse width - 1 */
|
||||
| (2 << 16) /* eof pixel count */
|
||||
| (0 << 24); /* bof pixel count */
|
||||
|
||||
LCCR3 = 2 /* pixel clock divisor */
|
||||
| (24 << 8) /* AC Bias pin freq */
|
||||
| LCCR3_16BPP /* BPP */
|
||||
| LCCR3_PCP; /* PCP falling edge */
|
||||
|
||||
}
|
||||
|
||||
static void am200_post_dma_setup(struct metronomefb_par *par)
|
||||
{
|
||||
par->metromem_desc->mFDADR0 = par->metromem_desc_dma;
|
||||
par->metromem_desc->mFSADR0 = par->metromem_dma;
|
||||
par->metromem_desc->mFIDR0 = 0;
|
||||
par->metromem_desc->mLDCMD0 = par->info->var.xres
|
||||
* par->info->var.yres;
|
||||
am200_enable_lcd_controller(par);
|
||||
}
|
||||
|
||||
static void am200_free_irq(struct fb_info *info)
|
||||
{
|
||||
free_irq(IRQ_GPIO(RDY_GPIO_PIN), info);
|
||||
}
|
||||
|
||||
static irqreturn_t am200_handle_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct fb_info *info = dev_id;
|
||||
struct metronomefb_par *par = info->par;
|
||||
|
||||
wake_up_interruptible(&par->waitq);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int am200_setup_irq(struct fb_info *info)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq,
|
||||
IRQF_DISABLED, "AM200", info);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "am200epd: request_irq failed: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
static void am200_set_rst(struct metronomefb_par *par, int state)
|
||||
{
|
||||
am200_set_gpio_output(RST_GPIO_PIN, state);
|
||||
}
|
||||
|
||||
static void am200_set_stdby(struct metronomefb_par *par, int state)
|
||||
{
|
||||
am200_set_gpio_output(STDBY_GPIO_PIN, state);
|
||||
}
|
||||
|
||||
static int am200_wait_event(struct metronomefb_par *par)
|
||||
{
|
||||
return wait_event_timeout(par->waitq, (GPLR1 & 0x01), HZ);
|
||||
}
|
||||
|
||||
static int am200_wait_event_intr(struct metronomefb_par *par)
|
||||
{
|
||||
return wait_event_interruptible_timeout(par->waitq, (GPLR1 & 0x01), HZ);
|
||||
}
|
||||
|
||||
static struct metronome_board am200_board = {
|
||||
.owner = THIS_MODULE,
|
||||
.free_irq = am200_free_irq,
|
||||
.setup_irq = am200_setup_irq,
|
||||
.init_gpio_regs = am200_init_gpio_regs,
|
||||
.init_lcdc_regs = am200_init_lcdc_regs,
|
||||
.post_dma_setup = am200_post_dma_setup,
|
||||
.set_rst = am200_set_rst,
|
||||
.set_stdby = am200_set_stdby,
|
||||
.met_wait_event = am200_wait_event,
|
||||
.met_wait_event_intr = am200_wait_event_intr,
|
||||
};
|
||||
|
||||
static struct platform_device *am200_device;
|
||||
|
||||
static int __init am200_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* request our platform independent driver */
|
||||
request_module("metronomefb");
|
||||
|
||||
am200_device = platform_device_alloc("metronomefb", -1);
|
||||
if (!am200_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_device_add_data(am200_device, &am200_board,
|
||||
sizeof(am200_board));
|
||||
|
||||
/* this _add binds metronomefb to am200. metronomefb refcounts am200 */
|
||||
ret = platform_device_add(am200_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(am200_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit am200_exit(void)
|
||||
{
|
||||
platform_device_unregister(am200_device);
|
||||
}
|
||||
|
||||
module_init(am200_init);
|
||||
module_exit(am200_exit);
|
||||
|
||||
MODULE_DESCRIPTION("board driver for am200 metronome epd kit");
|
||||
MODULE_AUTHOR("Jaya Kumar");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
|
|||
return value;
|
||||
}
|
||||
|
||||
static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
/* Turn off the LCD controller and the DMA controller */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
|
||||
|
||||
/* Wait for the LCDC core to become idle */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
|
||||
msleep(10);
|
||||
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
|
||||
}
|
||||
|
||||
static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
atmel_lcdfb_stop_nowait(sinfo);
|
||||
|
||||
/* Wait for DMA engine to become idle... */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
|
||||
| ATMEL_LCDC_PWR);
|
||||
}
|
||||
|
||||
static void atmel_lcdfb_update_dma(struct fb_info *info,
|
||||
struct fb_var_screeninfo *var)
|
||||
{
|
||||
|
|
@ -342,6 +372,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
|
|||
var->transp.offset = var->transp.length = 0;
|
||||
var->xoffset = var->yoffset = 0;
|
||||
|
||||
if (info->fix.smem_len) {
|
||||
unsigned int smem_len = (var->xres_virtual * var->yres_virtual
|
||||
* ((var->bits_per_pixel + 7) / 8));
|
||||
if (smem_len > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Saturate vertical and horizontal timings at maximum values */
|
||||
var->vsync_len = min_t(u32, var->vsync_len,
|
||||
(ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
|
||||
|
|
@ -378,6 +415,10 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
|
|||
var->red.offset = 11;
|
||||
var->blue.offset = 0;
|
||||
var->green.length = 6;
|
||||
} else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
|
||||
var->red.offset = 10;
|
||||
var->blue.offset = 0;
|
||||
var->green.length = 5;
|
||||
} else {
|
||||
/* BGR:555 mode */
|
||||
var->red.offset = 0;
|
||||
|
|
@ -420,26 +461,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
|
|||
{
|
||||
might_sleep();
|
||||
|
||||
/* LCD power off */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
|
||||
|
||||
/* wait for the LCDC core to become idle */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
|
||||
msleep(10);
|
||||
|
||||
/* DMA disable */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
|
||||
|
||||
/* wait for DMA engine to become idle */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
|
||||
msleep(10);
|
||||
|
||||
/* LCD power on */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
|
||||
|
||||
/* DMA enable */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
|
||||
atmel_lcdfb_stop(sinfo);
|
||||
atmel_lcdfb_start(sinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -471,14 +494,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
|
|||
info->var.xres, info->var.yres,
|
||||
info->var.xres_virtual, info->var.yres_virtual);
|
||||
|
||||
/* Turn off the LCD controller and the DMA controller */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
|
||||
|
||||
/* Wait for the LCDC core to become idle */
|
||||
while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
|
||||
msleep(10);
|
||||
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
|
||||
atmel_lcdfb_stop_nowait(sinfo);
|
||||
|
||||
if (info->var.bits_per_pixel == 1)
|
||||
info->fix.visual = FB_VISUAL_MONO01;
|
||||
|
|
@ -583,13 +599,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
|
|||
while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
|
||||
msleep(10);
|
||||
|
||||
dev_dbg(info->device, " * re-enable DMA engine\n");
|
||||
/* ...and enable it with updated configuration */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
|
||||
|
||||
dev_dbg(info->device, " * re-enable LCDC core\n");
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
|
||||
(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
|
||||
atmel_lcdfb_start(sinfo);
|
||||
|
||||
dev_dbg(info->device, " * DONE\n");
|
||||
|
||||
|
|
@ -1032,11 +1042,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
|
|||
struct fb_info *info = platform_get_drvdata(pdev);
|
||||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
|
||||
/*
|
||||
* We don't want to handle interrupts while the clock is
|
||||
* stopped. It may take forever.
|
||||
*/
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
|
||||
|
||||
sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(0);
|
||||
|
||||
atmel_lcdfb_stop(sinfo);
|
||||
atmel_lcdfb_stop_clock(sinfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1046,9 +1065,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)
|
|||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
|
||||
atmel_lcdfb_start_clock(sinfo);
|
||||
atmel_lcdfb_start(sinfo);
|
||||
if (sinfo->atmel_lcdfb_power_control)
|
||||
sinfo->atmel_lcdfb_power_control(1);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
|
||||
|
||||
/* Enable FIFO & DMA errors */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
|
||||
| ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,61 +5,61 @@
|
|||
* --dte
|
||||
*/
|
||||
|
||||
static void radeon_fixup_offset(struct radeonfb_info *rinfo)
|
||||
#define FLUSH_CACHE_WORKAROUND 1
|
||||
|
||||
void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
|
||||
{
|
||||
u32 local_base;
|
||||
int i;
|
||||
|
||||
/* *** Ugly workaround *** */
|
||||
/*
|
||||
* On some platforms, the video memory is mapped at 0 in radeon chip space
|
||||
* (like PPCs) by the firmware. X will always move it up so that it's seen
|
||||
* by the chip to be at the same address as the PCI BAR.
|
||||
* That means that when switching back from X, there is a mismatch between
|
||||
* the offsets programmed into the engine. This means that potentially,
|
||||
* accel operations done before radeonfb has a chance to re-init the engine
|
||||
* will have incorrect offsets, and potentially trash system memory !
|
||||
*
|
||||
* The correct fix is for fbcon to never call any accel op before the engine
|
||||
* has properly been re-initialized (by a call to set_var), but this is a
|
||||
* complex fix. This workaround in the meantime, called before every accel
|
||||
* operation, makes sure the offsets are in sync.
|
||||
*/
|
||||
for (i=0; i<2000000; i++) {
|
||||
rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f;
|
||||
if (rinfo->fifo_free >= entries)
|
||||
return;
|
||||
udelay(10);
|
||||
}
|
||||
printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
|
||||
/* XXX Todo: attempt to reset the engine */
|
||||
}
|
||||
|
||||
radeon_fifo_wait (1);
|
||||
local_base = INREG(MC_FB_LOCATION) << 16;
|
||||
if (local_base == rinfo->fb_local_base)
|
||||
static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
|
||||
{
|
||||
if (entries <= rinfo->fifo_free)
|
||||
rinfo->fifo_free -= entries;
|
||||
else
|
||||
radeon_fifo_update_and_wait(rinfo, entries);
|
||||
}
|
||||
|
||||
static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg,
|
||||
u32 *cache, u32 new_val)
|
||||
{
|
||||
if (new_val == *cache)
|
||||
return;
|
||||
|
||||
rinfo->fb_local_base = local_base;
|
||||
|
||||
radeon_fifo_wait (3);
|
||||
OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
|
||||
(rinfo->fb_local_base >> 10));
|
||||
OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
|
||||
OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
|
||||
*cache = new_val;
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(reg, new_val);
|
||||
}
|
||||
|
||||
static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
|
||||
const struct fb_fillrect *region)
|
||||
{
|
||||
radeon_fifo_wait(4);
|
||||
|
||||
OUTREG(DP_GUI_MASTER_CNTL,
|
||||
rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */
|
||||
| GMC_BRUSH_SOLID_COLOR
|
||||
| ROP3_P);
|
||||
if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP)
|
||||
OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]);
|
||||
else
|
||||
OUTREG(DP_BRUSH_FRGD_CLR, region->color);
|
||||
OUTREG(DP_WRITE_MSK, 0xffffffff);
|
||||
OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
|
||||
radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
|
||||
rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P);
|
||||
radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
|
||||
DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
|
||||
radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache,
|
||||
region->color);
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
/* Ensure the dst cache is flushed and the engine idle before
|
||||
* issuing the operation.
|
||||
*
|
||||
* This works around engine lockups on some cards
|
||||
*/
|
||||
#if FLUSH_CACHE_WORKAROUND
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
|
||||
OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
#endif
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
|
||||
OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
|
||||
}
|
||||
|
|
@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
|
|||
struct fb_fillrect modded;
|
||||
int vxres, vyres;
|
||||
|
||||
if (info->state != FBINFO_STATE_RUNNING)
|
||||
WARN_ON(rinfo->gfx_mode);
|
||||
if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
|
||||
return;
|
||||
if (info->flags & FBINFO_HWACCEL_DISABLED) {
|
||||
cfb_fillrect(info, region);
|
||||
return;
|
||||
}
|
||||
|
||||
radeon_fixup_offset(rinfo);
|
||||
|
||||
vxres = info->var.xres_virtual;
|
||||
vyres = info->var.yres_virtual;
|
||||
|
||||
|
|
@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
|
|||
if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
|
||||
if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
|
||||
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR )
|
||||
modded.color = ((u32 *) (info->pseudo_palette))[region->color];
|
||||
|
||||
radeonfb_prim_fillrect(rinfo, &modded);
|
||||
}
|
||||
|
||||
|
|
@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
|
|||
if ( xdir < 0 ) { sx += w-1; dx += w-1; }
|
||||
if ( ydir < 0 ) { sy += h-1; dy += h-1; }
|
||||
|
||||
radeon_fifo_wait(3);
|
||||
OUTREG(DP_GUI_MASTER_CNTL,
|
||||
rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
|
||||
| GMC_BRUSH_NONE
|
||||
| GMC_SRC_DSTCOLOR
|
||||
| ROP3_S
|
||||
| DP_SRC_SOURCE_MEMORY );
|
||||
OUTREG(DP_WRITE_MSK, 0xffffffff);
|
||||
OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
|
||||
| (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
|
||||
radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
|
||||
rinfo->dp_gui_mc_base |
|
||||
GMC_BRUSH_NONE |
|
||||
GMC_SRC_DATATYPE_COLOR |
|
||||
ROP3_S |
|
||||
DP_SRC_SOURCE_MEMORY);
|
||||
radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
|
||||
(xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) |
|
||||
(ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
#if FLUSH_CACHE_WORKAROUND
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
|
||||
OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
|
||||
|
||||
radeon_fifo_wait(3);
|
||||
#endif
|
||||
radeon_fifo_wait(rinfo, 3);
|
||||
OUTREG(SRC_Y_X, (sy << 16) | sx);
|
||||
OUTREG(DST_Y_X, (dy << 16) | dx);
|
||||
OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
|
||||
|
|
@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
|
|||
modded.width = area->width;
|
||||
modded.height = area->height;
|
||||
|
||||
if (info->state != FBINFO_STATE_RUNNING)
|
||||
WARN_ON(rinfo->gfx_mode);
|
||||
if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
|
||||
return;
|
||||
if (info->flags & FBINFO_HWACCEL_DISABLED) {
|
||||
cfb_copyarea(info, area);
|
||||
return;
|
||||
}
|
||||
|
||||
radeon_fixup_offset(rinfo);
|
||||
|
||||
vxres = info->var.xres_virtual;
|
||||
vyres = info->var.yres_virtual;
|
||||
|
||||
|
|
@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
|
|||
radeonfb_prim_copyarea(rinfo, &modded);
|
||||
}
|
||||
|
||||
static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
|
||||
const struct fb_image *image,
|
||||
u32 fg, u32 bg)
|
||||
{
|
||||
unsigned int src_bytes, dwords;
|
||||
u32 *bits;
|
||||
|
||||
radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
|
||||
rinfo->dp_gui_mc_base |
|
||||
GMC_BRUSH_NONE |
|
||||
GMC_SRC_DATATYPE_MONO_FG_BG |
|
||||
ROP3_S |
|
||||
GMC_BYTE_ORDER_MSB_TO_LSB |
|
||||
DP_SRC_SOURCE_HOST_DATA);
|
||||
radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
|
||||
DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
|
||||
radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
|
||||
radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
|
||||
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
|
||||
|
||||
/* Ensure the dst cache is flushed and the engine idle before
|
||||
* issuing the operation.
|
||||
*
|
||||
* This works around engine lockups on some cards
|
||||
*/
|
||||
#if FLUSH_CACHE_WORKAROUND
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
|
||||
OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
|
||||
#endif
|
||||
|
||||
/* X here pads width to a multiple of 32 and uses the clipper to
|
||||
* adjust the result. Is that really necessary ? Things seem to
|
||||
* work ok for me without that and the doco doesn't seem to imply
|
||||
* there is such a restriction.
|
||||
*/
|
||||
OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height);
|
||||
|
||||
src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
|
||||
dwords = (src_bytes + 3) / 4;
|
||||
bits = (u32*)(image->data);
|
||||
|
||||
while(dwords >= 8) {
|
||||
radeon_fifo_wait(rinfo, 8);
|
||||
#if BITS_PER_LONG == 64
|
||||
__raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
|
||||
__raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
|
||||
__raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
|
||||
__raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
|
||||
bits += 8;
|
||||
#else
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
|
||||
#endif
|
||||
dwords -= 8;
|
||||
}
|
||||
while(dwords--) {
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
__raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
|
||||
}
|
||||
}
|
||||
|
||||
void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
|
||||
{
|
||||
struct radeonfb_info *rinfo = info->par;
|
||||
u32 fg, bg;
|
||||
|
||||
if (info->state != FBINFO_STATE_RUNNING)
|
||||
WARN_ON(rinfo->gfx_mode);
|
||||
if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
|
||||
return;
|
||||
radeon_engine_idle();
|
||||
|
||||
if (!image->width || !image->height)
|
||||
return;
|
||||
|
||||
/* We only do 1 bpp color expansion for now */
|
||||
if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
|
||||
goto fallback;
|
||||
|
||||
/* Fallback if running out of the screen. We may do clipping
|
||||
* in the future */
|
||||
if ((image->dx + image->width) > info->var.xres_virtual ||
|
||||
(image->dy + image->height) > info->var.yres_virtual)
|
||||
goto fallback;
|
||||
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
fg = ((u32*)(info->pseudo_palette))[image->fg_color];
|
||||
bg = ((u32*)(info->pseudo_palette))[image->bg_color];
|
||||
} else {
|
||||
fg = image->fg_color;
|
||||
bg = image->bg_color;
|
||||
}
|
||||
|
||||
radeonfb_prim_imageblit(rinfo, image, fg, bg);
|
||||
return;
|
||||
|
||||
fallback:
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
cfb_imageblit(info, image);
|
||||
}
|
||||
|
|
@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info)
|
|||
|
||||
if (info->state != FBINFO_STATE_RUNNING)
|
||||
return 0;
|
||||
radeon_engine_idle();
|
||||
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -211,9 +313,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
|
|||
host_path_cntl = INREG(HOST_PATH_CNTL);
|
||||
rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
|
||||
|
||||
if (rinfo->family == CHIP_FAMILY_R300 ||
|
||||
rinfo->family == CHIP_FAMILY_R350 ||
|
||||
rinfo->family == CHIP_FAMILY_RV350) {
|
||||
if (IS_R300_VARIANT(rinfo)) {
|
||||
u32 tmp;
|
||||
|
||||
OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
|
||||
|
|
@ -249,9 +349,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
|
|||
INREG(HOST_PATH_CNTL);
|
||||
OUTREG(HOST_PATH_CNTL, host_path_cntl);
|
||||
|
||||
if (rinfo->family != CHIP_FAMILY_R300 &&
|
||||
rinfo->family != CHIP_FAMILY_R350 &&
|
||||
rinfo->family != CHIP_FAMILY_RV350)
|
||||
if (!IS_R300_VARIANT(rinfo))
|
||||
OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
|
||||
|
||||
OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
|
||||
|
|
@ -265,15 +363,24 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
|
|||
/* disable 3D engine */
|
||||
OUTREG(RB3D_CNTL, 0);
|
||||
|
||||
rinfo->fifo_free = 0;
|
||||
radeonfb_engine_reset(rinfo);
|
||||
|
||||
radeon_fifo_wait (1);
|
||||
if ((rinfo->family != CHIP_FAMILY_R300) &&
|
||||
(rinfo->family != CHIP_FAMILY_R350) &&
|
||||
(rinfo->family != CHIP_FAMILY_RV350))
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
if (IS_R300_VARIANT(rinfo)) {
|
||||
OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
|
||||
RB2D_DC_AUTOFLUSH_ENABLE |
|
||||
RB2D_DC_DC_DISABLE_IGNORE_PE);
|
||||
} else {
|
||||
/* This needs to be double checked with ATI. Latest X driver
|
||||
* completely "forgets" to set this register on < r3xx, and
|
||||
* we used to just write 0 there... I'll keep the 0 and update
|
||||
* that when we have sorted things out on X side.
|
||||
*/
|
||||
OUTREG(RB2D_DSTCACHE_MODE, 0);
|
||||
}
|
||||
|
||||
radeon_fifo_wait (3);
|
||||
radeon_fifo_wait(rinfo, 3);
|
||||
/* We re-read MC_FB_LOCATION from card as it can have been
|
||||
* modified by XFree drivers (ouch !)
|
||||
*/
|
||||
|
|
@ -284,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
|
|||
OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
|
||||
OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
|
||||
|
||||
radeon_fifo_wait (1);
|
||||
#if defined(__BIG_ENDIAN)
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
#ifdef __BIG_ENDIAN
|
||||
OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
|
||||
#else
|
||||
OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
|
||||
#endif
|
||||
radeon_fifo_wait (2);
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DEFAULT_SC_TOP_LEFT, 0);
|
||||
OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
|
||||
DEFAULT_SC_BOTTOM_MAX));
|
||||
|
||||
/* set default DP_GUI_MASTER_CNTL */
|
||||
temp = radeon_get_dstbpp(rinfo->depth);
|
||||
rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
|
||||
rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
|
||||
|
||||
radeon_fifo_wait (1);
|
||||
OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
|
||||
GMC_BRUSH_SOLID_COLOR |
|
||||
GMC_SRC_DATATYPE_COLOR));
|
||||
rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base |
|
||||
GMC_BRUSH_SOLID_COLOR |
|
||||
GMC_SRC_DATATYPE_COLOR;
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
|
||||
|
||||
radeon_fifo_wait (7);
|
||||
|
||||
/* clear line drawing regs */
|
||||
radeon_fifo_wait(rinfo, 2);
|
||||
OUTREG(DST_LINE_START, 0);
|
||||
OUTREG(DST_LINE_END, 0);
|
||||
|
||||
/* set brush color regs */
|
||||
OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
|
||||
OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
|
||||
/* set brush and source color regs */
|
||||
rinfo->dp_brush_fg_cache = 0xffffffff;
|
||||
rinfo->dp_brush_bg_cache = 0x00000000;
|
||||
rinfo->dp_src_fg_cache = 0xffffffff;
|
||||
rinfo->dp_src_bg_cache = 0x00000000;
|
||||
radeon_fifo_wait(rinfo, 4);
|
||||
OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache);
|
||||
OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
|
||||
OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
|
||||
OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
|
||||
|
||||
/* set source color regs */
|
||||
OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
|
||||
OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
|
||||
/* Default direction */
|
||||
rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
|
||||
|
||||
/* default write mask */
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(DP_WRITE_MSK, 0xffffffff);
|
||||
|
||||
radeon_engine_idle ();
|
||||
/* Default to no swapping of host data */
|
||||
radeon_fifo_wait(rinfo, 1);
|
||||
OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
|
||||
|
||||
/* Make sure it's settled */
|
||||
radeon_engine_idle(rinfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd)
|
|||
level = bd->props.brightness;
|
||||
|
||||
del_timer_sync(&rinfo->lvds_timer);
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
|
||||
if (level > 0) {
|
||||
|
|
|
|||
|
|
@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
|
|||
if (rinfo->asleep)
|
||||
return 0;
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
|
||||
* var->bits_per_pixel / 8) & ~7);
|
||||
return 0;
|
||||
|
|
@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
if (value & 0x01) {
|
||||
tmp = INREG(LVDS_GEN_CNTL);
|
||||
|
||||
|
|
@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
|
|||
if (rinfo->lock_blank)
|
||||
return 0;
|
||||
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
val = INREG(CRTC_EXT_CNTL);
|
||||
val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
|
||||
|
|
@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
|
|||
|
||||
if (rinfo->asleep)
|
||||
return 0;
|
||||
|
||||
|
||||
return radeon_screen_blank(rinfo, blank, 0);
|
||||
}
|
||||
|
||||
|
|
@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
|
|||
pindex = regno;
|
||||
|
||||
if (!rinfo->asleep) {
|
||||
radeon_fifo_wait(9);
|
||||
|
||||
if (rinfo->bpp == 16) {
|
||||
pindex = regno * 8;
|
||||
|
||||
|
|
@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
|
|||
{
|
||||
int i;
|
||||
|
||||
radeon_fifo_wait(20);
|
||||
|
||||
/* Workaround from XFree */
|
||||
if (rinfo->is_mobility) {
|
||||
/* A temporal workaround for the occational blanking on certain laptop
|
||||
|
|
@ -1286,11 +1280,10 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
|
|||
radeon_pll_errata_after_data(rinfo);
|
||||
|
||||
/* Set PPLL ref. div */
|
||||
if (rinfo->family == CHIP_FAMILY_R300 ||
|
||||
if (IS_R300_VARIANT(rinfo) ||
|
||||
rinfo->family == CHIP_FAMILY_RS300 ||
|
||||
rinfo->family == CHIP_FAMILY_R350 ||
|
||||
rinfo->family == CHIP_FAMILY_RV350 ||
|
||||
rinfo->family == CHIP_FAMILY_RV380 ) {
|
||||
rinfo->family == CHIP_FAMILY_RS400 ||
|
||||
rinfo->family == CHIP_FAMILY_RS480) {
|
||||
if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
|
||||
/* When restoring console mode, use saved PPLL_REF_DIV
|
||||
* setting.
|
||||
|
|
@ -1342,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data)
|
|||
{
|
||||
struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
|
||||
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
|
||||
}
|
||||
|
|
@ -1360,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
|
|||
if (nomodeset)
|
||||
return;
|
||||
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
if (!regs_only)
|
||||
radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
|
||||
|
||||
radeon_fifo_wait(31);
|
||||
for (i=0; i<10; i++)
|
||||
OUTREG(common_regs[i].reg, common_regs[i].val);
|
||||
|
||||
|
|
@ -1391,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
|
|||
radeon_write_pll_regs(rinfo, mode);
|
||||
|
||||
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
|
||||
radeon_fifo_wait(10);
|
||||
OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
|
||||
OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
|
||||
OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
|
||||
|
|
@ -1406,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
|
|||
if (!regs_only)
|
||||
radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
|
||||
|
||||
radeon_fifo_wait(2);
|
||||
OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
|
||||
|
||||
return;
|
||||
|
|
@ -1461,10 +1453,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
|
|||
/* Not all chip revs have the same format for this register,
|
||||
* extract the source selection
|
||||
*/
|
||||
if (rinfo->family == CHIP_FAMILY_R200 ||
|
||||
rinfo->family == CHIP_FAMILY_R300 ||
|
||||
rinfo->family == CHIP_FAMILY_R350 ||
|
||||
rinfo->family == CHIP_FAMILY_RV350) {
|
||||
if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) {
|
||||
source = (fp2_gen_cntl >> 10) & 0x3;
|
||||
/* sourced from transform unit, check for transform unit
|
||||
* own source
|
||||
|
|
@ -1560,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info)
|
|||
/* We always want engine to be idle on a mode switch, even
|
||||
* if we won't actually change the mode
|
||||
*/
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
hSyncStart = mode->xres + mode->right_margin;
|
||||
hSyncEnd = hSyncStart + mode->hsync_len;
|
||||
|
|
@ -1855,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct fb_ops radeonfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_check_var = radeonfb_check_var,
|
||||
|
|
@ -1879,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
|
|||
info->par = rinfo;
|
||||
info->pseudo_palette = rinfo->pseudo_palette;
|
||||
info->flags = FBINFO_DEFAULT
|
||||
| FBINFO_HWACCEL_IMAGEBLIT
|
||||
| FBINFO_HWACCEL_COPYAREA
|
||||
| FBINFO_HWACCEL_FILLRECT
|
||||
| FBINFO_HWACCEL_XPAN
|
||||
|
|
@ -2005,11 +1994,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
|
|||
(rinfo->family == CHIP_FAMILY_RS200) ||
|
||||
(rinfo->family == CHIP_FAMILY_RS300) ||
|
||||
(rinfo->family == CHIP_FAMILY_RC410) ||
|
||||
(rinfo->family == CHIP_FAMILY_RS400) ||
|
||||
(rinfo->family == CHIP_FAMILY_RS480) ) {
|
||||
u32 tom = INREG(NB_TOM);
|
||||
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
|
||||
|
||||
radeon_fifo_wait(6);
|
||||
OUTREG(MC_FB_LOCATION, tom);
|
||||
OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
|
||||
OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
|
||||
|
|
|
|||
|
|
@ -139,12 +139,8 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
|
|||
int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
|
||||
u8 **out_edid)
|
||||
{
|
||||
u32 reg = rinfo->i2c[conn-1].ddc_reg;
|
||||
u8 *edid;
|
||||
|
||||
OUTREG(reg, INREG(reg) &
|
||||
~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
|
||||
|
||||
edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
|
||||
|
||||
if (out_edid)
|
||||
|
|
|
|||
|
|
@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
|||
|
||||
if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
|
||||
/* Make sure engine is reset */
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
radeonfb_engine_reset(rinfo);
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
}
|
||||
|
||||
/* Blank display and LCD */
|
||||
|
|
@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
|
|||
|
||||
rinfo->asleep = 0;
|
||||
} else
|
||||
radeon_engine_idle();
|
||||
radeon_engine_idle(rinfo);
|
||||
|
||||
/* Restore display & engine */
|
||||
radeon_write_mode (rinfo, &rinfo->state, 1);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ enum radeon_family {
|
|||
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
|
||||
CHIP_FAMILY_R420, /* R420/R423/M18 */
|
||||
CHIP_FAMILY_RC410,
|
||||
CHIP_FAMILY_RS400,
|
||||
CHIP_FAMILY_RS480,
|
||||
CHIP_FAMILY_LAST,
|
||||
};
|
||||
|
|
@ -335,7 +336,15 @@ struct radeonfb_info {
|
|||
int mon2_type;
|
||||
u8 *mon2_EDID;
|
||||
|
||||
u32 dp_gui_master_cntl;
|
||||
/* accel bits */
|
||||
u32 dp_gui_mc_base;
|
||||
u32 dp_gui_mc_cache;
|
||||
u32 dp_cntl_cache;
|
||||
u32 dp_brush_fg_cache;
|
||||
u32 dp_brush_bg_cache;
|
||||
u32 dp_src_fg_cache;
|
||||
u32 dp_src_bg_cache;
|
||||
u32 fifo_free;
|
||||
|
||||
struct pll_info pll;
|
||||
|
||||
|
|
@ -347,6 +356,7 @@ struct radeonfb_info {
|
|||
int lock_blank;
|
||||
int dynclk;
|
||||
int no_schedule;
|
||||
int gfx_mode;
|
||||
enum radeon_pm_mode pm_mode;
|
||||
reinit_function_ptr reinit_func;
|
||||
|
||||
|
|
@ -391,8 +401,14 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
|
|||
#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
|
||||
#define INREG16(addr) readw((rinfo->mmio_base)+addr)
|
||||
#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr)
|
||||
|
||||
#ifdef CONFIG_PPC
|
||||
#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); })
|
||||
#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0)
|
||||
#else
|
||||
#define INREG(addr) readl((rinfo->mmio_base)+addr)
|
||||
#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
|
||||
#endif
|
||||
|
||||
static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
|
||||
u32 val, u32 mask)
|
||||
|
|
@ -533,16 +549,25 @@ static inline u32 radeon_get_dstbpp(u16 depth)
|
|||
/*
|
||||
* 2D Engine helper routines
|
||||
*/
|
||||
|
||||
extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries);
|
||||
|
||||
static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* initiate flush */
|
||||
OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
|
||||
/* Initiate flush */
|
||||
OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
|
||||
~RB2D_DC_FLUSH_ALL);
|
||||
|
||||
/* Ensure FIFO is empty, ie, make sure the flush commands
|
||||
* has reached the cache
|
||||
*/
|
||||
radeon_fifo_update_and_wait(rinfo, 64);
|
||||
|
||||
/* Wait for the flush to complete */
|
||||
for (i=0; i < 2000000; i++) {
|
||||
if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
|
||||
if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
|
||||
return;
|
||||
udelay(1);
|
||||
}
|
||||
|
|
@ -550,25 +575,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
|
|||
}
|
||||
|
||||
|
||||
static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<2000000; i++) {
|
||||
if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
|
||||
return;
|
||||
udelay(1);
|
||||
}
|
||||
printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
|
||||
}
|
||||
|
||||
|
||||
static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
|
||||
static inline void radeon_engine_idle(struct radeonfb_info *rinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* ensure FIFO is empty before waiting for idle */
|
||||
_radeon_fifo_wait (rinfo, 64);
|
||||
radeon_fifo_update_and_wait (rinfo, 64);
|
||||
|
||||
for (i=0; i<2000000; i++) {
|
||||
if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
|
||||
|
|
@ -581,8 +593,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
|
|||
}
|
||||
|
||||
|
||||
#define radeon_engine_idle() _radeon_engine_idle(rinfo)
|
||||
#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
|
||||
#define radeon_msleep(ms) _radeon_msleep(rinfo,ms)
|
||||
|
||||
|
||||
|
|
@ -612,6 +622,7 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image);
|
|||
extern int radeonfb_sync(struct fb_info *info);
|
||||
extern void radeonfb_engine_init (struct radeonfb_info *rinfo);
|
||||
extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
|
||||
extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo);
|
||||
|
||||
/* Other functions */
|
||||
extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ config LCD_CLASS_DEVICE
|
|||
To have support for your specific LCD panel you will have to
|
||||
select the proper drivers which depend on this option.
|
||||
|
||||
config LCD_CORGI
|
||||
tristate "LCD Panel support for SHARP corgi/spitz model"
|
||||
depends on LCD_CLASS_DEVICE && SPI_MASTER && PXA_SHARPSL
|
||||
help
|
||||
Say y here to support the LCD panels usually found on SHARP
|
||||
corgi (C7x0) and spitz (Cxx00) models.
|
||||
|
||||
config LCD_LTV350QV
|
||||
tristate "Samsung LTV350QV LCD Panel"
|
||||
depends on LCD_CLASS_DEVICE && SPI_MASTER
|
||||
|
|
@ -44,6 +51,14 @@ config LCD_ILI9320
|
|||
If you have a panel based on the ILI9320 controller chip
|
||||
then say y to include a power driver for it.
|
||||
|
||||
config LCD_TDO24M
|
||||
tristate "Toppoly TDO24M LCD Panels support"
|
||||
depends on LCD_CLASS_DEVICE && SPI_MASTER
|
||||
default n
|
||||
help
|
||||
If you have a Toppoly TDO24M series LCD panel, say y here to
|
||||
include the support for it.
|
||||
|
||||
config LCD_VGG2432A4
|
||||
tristate "VGG2432A4 LCM device support"
|
||||
depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
# Backlight & LCD drivers
|
||||
|
||||
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
|
||||
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
|
||||
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
|
||||
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
|
||||
obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
|
||||
obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
|
||||
obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
|
||||
|
||||
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
|
||||
obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
|
||||
|
|
|
|||
641
drivers/video/backlight/corgi_lcd.c
Normal file
641
drivers/video/backlight/corgi_lcd.c
Normal file
|
|
@ -0,0 +1,641 @@
|
|||
/*
|
||||
* LCD/Backlight Driver for Sharp Zaurus Handhelds (various models)
|
||||
*
|
||||
* Copyright (c) 2004-2006 Richard Purdie
|
||||
*
|
||||
* Based on Sharp's 2.4 Backlight Driver
|
||||
*
|
||||
* Copyright (c) 2008 Marvell International Ltd.
|
||||
* Converted to SPI device based LCD/Backlight device driver
|
||||
* by Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/lcd.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/corgi_lcd.h>
|
||||
#include <asm/mach/sharpsl_param.h>
|
||||
|
||||
#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
|
||||
|
||||
/* Register Addresses */
|
||||
#define RESCTL_ADRS 0x00
|
||||
#define PHACTRL_ADRS 0x01
|
||||
#define DUTYCTRL_ADRS 0x02
|
||||
#define POWERREG0_ADRS 0x03
|
||||
#define POWERREG1_ADRS 0x04
|
||||
#define GPOR3_ADRS 0x05
|
||||
#define PICTRL_ADRS 0x06
|
||||
#define POLCTRL_ADRS 0x07
|
||||
|
||||
/* Register Bit Definitions */
|
||||
#define RESCTL_QVGA 0x01
|
||||
#define RESCTL_VGA 0x00
|
||||
|
||||
#define POWER1_VW_ON 0x01 /* VW Supply FET ON */
|
||||
#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
|
||||
#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
|
||||
|
||||
#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
|
||||
#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
|
||||
#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
|
||||
|
||||
#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
|
||||
#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
|
||||
#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
|
||||
#define POWER0_COM_ON 0x08 /* COM Power Supply ON */
|
||||
#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
|
||||
|
||||
#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
|
||||
#define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */
|
||||
#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
|
||||
|
||||
#define PICTRL_INIT_STATE 0x01
|
||||
#define PICTRL_INIOFF 0x02
|
||||
#define PICTRL_POWER_DOWN 0x04
|
||||
#define PICTRL_COM_SIGNAL_OFF 0x08
|
||||
#define PICTRL_DAC_SIGNAL_OFF 0x10
|
||||
|
||||
#define POLCTRL_SYNC_POL_FALL 0x01
|
||||
#define POLCTRL_EN_POL_FALL 0x02
|
||||
#define POLCTRL_DATA_POL_FALL 0x04
|
||||
#define POLCTRL_SYNC_ACT_H 0x08
|
||||
#define POLCTRL_EN_ACT_L 0x10
|
||||
|
||||
#define POLCTRL_SYNC_POL_RISE 0x00
|
||||
#define POLCTRL_EN_POL_RISE 0x00
|
||||
#define POLCTRL_DATA_POL_RISE 0x00
|
||||
#define POLCTRL_SYNC_ACT_L 0x00
|
||||
#define POLCTRL_EN_ACT_H 0x00
|
||||
|
||||
#define PHACTRL_PHASE_MANUAL 0x01
|
||||
#define DEFAULT_PHAD_QVGA (9)
|
||||
#define DEFAULT_COMADJ (125)
|
||||
|
||||
struct corgi_lcd {
|
||||
struct spi_device *spi_dev;
|
||||
struct lcd_device *lcd_dev;
|
||||
struct backlight_device *bl_dev;
|
||||
|
||||
int limit_mask;
|
||||
int intensity;
|
||||
int power;
|
||||
int mode;
|
||||
char buf[2];
|
||||
|
||||
int gpio_backlight_on;
|
||||
int gpio_backlight_cont;
|
||||
int gpio_backlight_cont_inverted;
|
||||
|
||||
void (*kick_battery)(void);
|
||||
};
|
||||
|
||||
static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int reg, uint8_t val);
|
||||
|
||||
static struct corgi_lcd *the_corgi_lcd;
|
||||
static unsigned long corgibl_flags;
|
||||
#define CORGIBL_SUSPENDED 0x01
|
||||
#define CORGIBL_BATTLOW 0x02
|
||||
|
||||
/*
|
||||
* This is only a psuedo I2C interface. We can't use the standard kernel
|
||||
* routines as the interface is write only. We just assume the data is acked...
|
||||
*/
|
||||
static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data)
|
||||
{
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, data);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_bit(struct corgi_lcd *lcd, uint8_t data)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(lcd, data);
|
||||
lcdtg_ssp_i2c_send(lcd, data | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(lcd, data);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_start(struct corgi_lcd *lcd, uint8_t base)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
|
||||
lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(lcd, base);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_stop(struct corgi_lcd *lcd, uint8_t base)
|
||||
{
|
||||
lcdtg_ssp_i2c_send(lcd, base);
|
||||
lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK);
|
||||
lcdtg_ssp_i2c_send(lcd, base | POWER0_COM_DCLK | POWER0_COM_DOUT);
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_send_byte(struct corgi_lcd *lcd,
|
||||
uint8_t base, uint8_t data)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (data & 0x80)
|
||||
lcdtg_i2c_send_bit(lcd, base | POWER0_COM_DOUT);
|
||||
else
|
||||
lcdtg_i2c_send_bit(lcd, base);
|
||||
data <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void lcdtg_i2c_wait_ack(struct corgi_lcd *lcd, uint8_t base)
|
||||
{
|
||||
lcdtg_i2c_send_bit(lcd, base);
|
||||
}
|
||||
|
||||
static void lcdtg_set_common_voltage(struct corgi_lcd *lcd,
|
||||
uint8_t base_data, uint8_t data)
|
||||
{
|
||||
/* Set Common Voltage to M62332FP via I2C */
|
||||
lcdtg_i2c_send_start(lcd, base_data);
|
||||
lcdtg_i2c_send_byte(lcd, base_data, 0x9c);
|
||||
lcdtg_i2c_wait_ack(lcd, base_data);
|
||||
lcdtg_i2c_send_byte(lcd, base_data, 0x00);
|
||||
lcdtg_i2c_wait_ack(lcd, base_data);
|
||||
lcdtg_i2c_send_byte(lcd, base_data, data);
|
||||
lcdtg_i2c_wait_ack(lcd, base_data);
|
||||
lcdtg_i2c_send_stop(lcd, base_data);
|
||||
}
|
||||
|
||||
static int corgi_ssp_lcdtg_send(struct corgi_lcd *lcd, int adrs, uint8_t data)
|
||||
{
|
||||
struct spi_message msg;
|
||||
struct spi_transfer xfer = {
|
||||
.len = 1,
|
||||
.cs_change = 1,
|
||||
.tx_buf = lcd->buf,
|
||||
};
|
||||
|
||||
lcd->buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
|
||||
spi_message_init(&msg);
|
||||
spi_message_add_tail(&xfer, &msg);
|
||||
|
||||
return spi_sync(lcd->spi_dev, &msg);
|
||||
}
|
||||
|
||||
/* Set Phase Adjust */
|
||||
static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode)
|
||||
{
|
||||
int adj;
|
||||
|
||||
switch(mode) {
|
||||
case CORGI_LCD_MODE_VGA:
|
||||
/* Setting for VGA */
|
||||
adj = sharpsl_param.phadadj;
|
||||
adj = (adj < 0) ? PHACTRL_PHASE_MANUAL :
|
||||
PHACTRL_PHASE_MANUAL | ((adj & 0xf) << 1);
|
||||
break;
|
||||
case CORGI_LCD_MODE_QVGA:
|
||||
default:
|
||||
/* Setting for QVGA */
|
||||
adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
|
||||
break;
|
||||
}
|
||||
|
||||
corgi_ssp_lcdtg_send(lcd, PHACTRL_ADRS, adj);
|
||||
}
|
||||
|
||||
static void corgi_lcd_power_on(struct corgi_lcd *lcd)
|
||||
{
|
||||
int comadj;
|
||||
|
||||
/* Initialize Internal Logic & Port */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
|
||||
PICTRL_POWER_DOWN | PICTRL_INIOFF |
|
||||
PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF |
|
||||
PICTRL_DAC_SIGNAL_OFF);
|
||||
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF |
|
||||
POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
|
||||
|
||||
/* VDD(+8V), SVSS(-4V) ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
|
||||
mdelay(3);
|
||||
|
||||
/* DAC ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
|
||||
POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* INIB = H, INI = L */
|
||||
/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
|
||||
PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
|
||||
|
||||
/* Set Common Voltage */
|
||||
comadj = sharpsl_param.comadj;
|
||||
if (comadj < 0)
|
||||
comadj = DEFAULT_COMADJ;
|
||||
|
||||
lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
|
||||
POWER0_VCC5_OFF, comadj);
|
||||
|
||||
/* VCC5 ON, DAC ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
|
||||
POWER0_COM_OFF | POWER0_VCC5_ON);
|
||||
|
||||
/* GVSS(-8V) ON, VDD ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
mdelay(2);
|
||||
|
||||
/* COM SIGNAL ON (PICTL[3] = L) */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIT_STATE);
|
||||
|
||||
/* COM ON, DAC ON, VCC5_ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
|
||||
POWER0_COM_ON | POWER0_VCC5_ON);
|
||||
|
||||
/* VW ON, GVSS ON, VDD ON */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
|
||||
/* Signals output enable */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, 0);
|
||||
|
||||
/* Set Phase Adjust */
|
||||
lcdtg_set_phadadj(lcd, lcd->mode);
|
||||
|
||||
/* Initialize for Input Signals from ATI */
|
||||
corgi_ssp_lcdtg_send(lcd, POLCTRL_ADRS,
|
||||
POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE |
|
||||
POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L |
|
||||
POLCTRL_EN_ACT_H);
|
||||
udelay(1000);
|
||||
|
||||
switch (lcd->mode) {
|
||||
case CORGI_LCD_MODE_VGA:
|
||||
corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
|
||||
break;
|
||||
case CORGI_LCD_MODE_QVGA:
|
||||
default:
|
||||
corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void corgi_lcd_power_off(struct corgi_lcd *lcd)
|
||||
{
|
||||
/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
|
||||
msleep(34);
|
||||
|
||||
/* (1)VW OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
|
||||
|
||||
/* (2)COM OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
|
||||
|
||||
/* (3)Set Common Voltage Bias 0V */
|
||||
lcdtg_set_common_voltage(lcd, POWER0_DAC_ON | POWER0_COM_OFF |
|
||||
POWER0_VCC5_ON, 0);
|
||||
|
||||
/* (4)GVSS OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
|
||||
|
||||
/* (5)VCC5 OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* (6)Set PDWN, INIOFF, DACOFF */
|
||||
corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS,
|
||||
PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
|
||||
PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
|
||||
|
||||
/* (7)DAC OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS,
|
||||
POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
|
||||
|
||||
/* (8)VDD OFF */
|
||||
corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS,
|
||||
POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
|
||||
}
|
||||
|
||||
static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
|
||||
int mode = CORGI_LCD_MODE_QVGA;
|
||||
|
||||
if (m->xres == 640 || m->xres == 480)
|
||||
mode = CORGI_LCD_MODE_VGA;
|
||||
|
||||
if (lcd->mode == mode)
|
||||
return 0;
|
||||
|
||||
lcdtg_set_phadadj(lcd, mode);
|
||||
|
||||
switch (mode) {
|
||||
case CORGI_LCD_MODE_VGA:
|
||||
corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA);
|
||||
break;
|
||||
case CORGI_LCD_MODE_QVGA:
|
||||
default:
|
||||
corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA);
|
||||
break;
|
||||
}
|
||||
|
||||
lcd->mode = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_lcd_set_power(struct lcd_device *ld, int power)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
|
||||
|
||||
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
|
||||
corgi_lcd_power_on(lcd);
|
||||
|
||||
if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
|
||||
corgi_lcd_power_off(lcd);
|
||||
|
||||
lcd->power = power;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_lcd_get_power(struct lcd_device *ld)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev);
|
||||
|
||||
return lcd->power;
|
||||
}
|
||||
|
||||
static struct lcd_ops corgi_lcd_ops = {
|
||||
.get_power = corgi_lcd_get_power,
|
||||
.set_power = corgi_lcd_set_power,
|
||||
.set_mode = corgi_lcd_set_mode,
|
||||
};
|
||||
|
||||
static int corgi_bl_get_intensity(struct backlight_device *bd)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
|
||||
|
||||
return lcd->intensity;
|
||||
}
|
||||
|
||||
static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
|
||||
{
|
||||
int cont;
|
||||
|
||||
if (intensity > 0x10)
|
||||
intensity += 0x10;
|
||||
|
||||
corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity);
|
||||
|
||||
/* Bit 5 via GPIO_BACKLIGHT_CONT */
|
||||
cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_cont))
|
||||
gpio_set_value(lcd->gpio_backlight_cont, cont);
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_on))
|
||||
gpio_set_value(lcd->gpio_backlight_on, intensity);
|
||||
|
||||
if (lcd->kick_battery)
|
||||
lcd->kick_battery();
|
||||
|
||||
lcd->intensity = intensity;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_bl_update_status(struct backlight_device *bd)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev);
|
||||
int intensity = bd->props.brightness;
|
||||
|
||||
if (bd->props.power != FB_BLANK_UNBLANK)
|
||||
intensity = 0;
|
||||
|
||||
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
|
||||
intensity = 0;
|
||||
|
||||
if (corgibl_flags & CORGIBL_SUSPENDED)
|
||||
intensity = 0;
|
||||
if (corgibl_flags & CORGIBL_BATTLOW)
|
||||
intensity &= lcd->limit_mask;
|
||||
|
||||
return corgi_bl_set_intensity(lcd, intensity);
|
||||
}
|
||||
|
||||
void corgibl_limit_intensity(int limit)
|
||||
{
|
||||
if (limit)
|
||||
corgibl_flags |= CORGIBL_BATTLOW;
|
||||
else
|
||||
corgibl_flags &= ~CORGIBL_BATTLOW;
|
||||
|
||||
backlight_update_status(the_corgi_lcd->bl_dev);
|
||||
}
|
||||
EXPORT_SYMBOL(corgibl_limit_intensity);
|
||||
|
||||
static struct backlight_ops corgi_bl_ops = {
|
||||
.get_brightness = corgi_bl_get_intensity,
|
||||
.update_status = corgi_bl_update_status,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
corgibl_flags |= CORGIBL_SUSPENDED;
|
||||
corgi_bl_set_intensity(lcd, 0);
|
||||
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_lcd_resume(struct spi_device *spi)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
corgibl_flags &= ~CORGIBL_SUSPENDED;
|
||||
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
|
||||
backlight_update_status(lcd->bl_dev);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define corgi_lcd_suspend NULL
|
||||
#define corgi_lcd_resume NULL
|
||||
#endif
|
||||
|
||||
static int setup_gpio_backlight(struct corgi_lcd *lcd,
|
||||
struct corgi_lcd_platform_data *pdata)
|
||||
{
|
||||
struct spi_device *spi = lcd->spi_dev;
|
||||
int err;
|
||||
|
||||
lcd->gpio_backlight_on = -1;
|
||||
lcd->gpio_backlight_cont = -1;
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_backlight_on)) {
|
||||
err = gpio_request(pdata->gpio_backlight_on, "BL_ON");
|
||||
if (err) {
|
||||
dev_err(&spi->dev, "failed to request GPIO%d for "
|
||||
"backlight_on\n", pdata->gpio_backlight_on);
|
||||
return err;
|
||||
}
|
||||
|
||||
lcd->gpio_backlight_on = pdata->gpio_backlight_on;
|
||||
gpio_direction_output(lcd->gpio_backlight_on, 0);
|
||||
}
|
||||
|
||||
if (gpio_is_valid(pdata->gpio_backlight_cont)) {
|
||||
err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT");
|
||||
if (err) {
|
||||
dev_err(&spi->dev, "failed to request GPIO%d for "
|
||||
"backlight_cont\n", pdata->gpio_backlight_cont);
|
||||
goto err_free_backlight_on;
|
||||
}
|
||||
|
||||
lcd->gpio_backlight_cont = pdata->gpio_backlight_cont;
|
||||
|
||||
/* spitz and akita use both GPIOs for backlight, and
|
||||
* have inverted polarity of GPIO_BACKLIGHT_CONT
|
||||
*/
|
||||
if (gpio_is_valid(lcd->gpio_backlight_on)) {
|
||||
lcd->gpio_backlight_cont_inverted = 1;
|
||||
gpio_direction_output(lcd->gpio_backlight_cont, 1);
|
||||
} else {
|
||||
lcd->gpio_backlight_cont_inverted = 0;
|
||||
gpio_direction_output(lcd->gpio_backlight_cont, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_free_backlight_on:
|
||||
if (gpio_is_valid(lcd->gpio_backlight_on))
|
||||
gpio_free(lcd->gpio_backlight_on);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devinit corgi_lcd_probe(struct spi_device *spi)
|
||||
{
|
||||
struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
|
||||
struct corgi_lcd *lcd;
|
||||
int ret = 0;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(&spi->dev, "platform data not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL);
|
||||
if (!lcd) {
|
||||
dev_err(&spi->dev, "failed to allocate memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lcd->spi_dev = spi;
|
||||
|
||||
lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev,
|
||||
lcd, &corgi_lcd_ops);
|
||||
if (IS_ERR(lcd->lcd_dev)) {
|
||||
ret = PTR_ERR(lcd->lcd_dev);
|
||||
goto err_free_lcd;
|
||||
}
|
||||
lcd->power = FB_BLANK_POWERDOWN;
|
||||
lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
|
||||
|
||||
lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
|
||||
lcd, &corgi_bl_ops);
|
||||
if (IS_ERR(lcd->bl_dev)) {
|
||||
ret = PTR_ERR(lcd->bl_dev);
|
||||
goto err_unregister_lcd;
|
||||
}
|
||||
lcd->bl_dev->props.max_brightness = pdata->max_intensity;
|
||||
lcd->bl_dev->props.brightness = pdata->default_intensity;
|
||||
lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
|
||||
|
||||
ret = setup_gpio_backlight(lcd, pdata);
|
||||
if (ret)
|
||||
goto err_unregister_bl;
|
||||
|
||||
lcd->kick_battery = pdata->kick_battery;
|
||||
|
||||
dev_set_drvdata(&spi->dev, lcd);
|
||||
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK);
|
||||
backlight_update_status(lcd->bl_dev);
|
||||
|
||||
lcd->limit_mask = pdata->limit_mask;
|
||||
the_corgi_lcd = lcd;
|
||||
return 0;
|
||||
|
||||
err_unregister_bl:
|
||||
backlight_device_unregister(lcd->bl_dev);
|
||||
err_unregister_lcd:
|
||||
lcd_device_unregister(lcd->lcd_dev);
|
||||
err_free_lcd:
|
||||
kfree(lcd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit corgi_lcd_remove(struct spi_device *spi)
|
||||
{
|
||||
struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
|
||||
lcd->bl_dev->props.brightness = 0;
|
||||
backlight_update_status(lcd->bl_dev);
|
||||
backlight_device_unregister(lcd->bl_dev);
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_on))
|
||||
gpio_free(lcd->gpio_backlight_on);
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_cont))
|
||||
gpio_free(lcd->gpio_backlight_cont);
|
||||
|
||||
corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
|
||||
lcd_device_unregister(lcd->lcd_dev);
|
||||
kfree(lcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver corgi_lcd_driver = {
|
||||
.driver = {
|
||||
.name = "corgi-lcd",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = corgi_lcd_probe,
|
||||
.remove = __devexit_p(corgi_lcd_remove),
|
||||
.suspend = corgi_lcd_suspend,
|
||||
.resume = corgi_lcd_resume,
|
||||
};
|
||||
|
||||
static int __init corgi_lcd_init(void)
|
||||
{
|
||||
return spi_register_driver(&corgi_lcd_driver);
|
||||
}
|
||||
module_init(corgi_lcd_init);
|
||||
|
||||
static void __exit corgi_lcd_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&corgi_lcd_driver);
|
||||
}
|
||||
module_exit(corgi_lcd_exit);
|
||||
|
||||
MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
|
||||
MODULE_AUTHOR("Eric Miao <[email protected]>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -27,14 +27,26 @@ static int fb_notifier_callback(struct notifier_block *self,
|
|||
struct fb_event *evdata = data;
|
||||
|
||||
/* If we aren't interested in this event, skip it immediately ... */
|
||||
if (event != FB_EVENT_BLANK)
|
||||
switch (event) {
|
||||
case FB_EVENT_BLANK:
|
||||
case FB_EVENT_MODE_CHANGE:
|
||||
case FB_EVENT_MODE_CHANGE_ALL:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ld = container_of(self, struct lcd_device, fb_notif);
|
||||
if (!ld->ops)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ld->ops_lock);
|
||||
if (ld->ops)
|
||||
if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info))
|
||||
if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
|
||||
if (event == FB_EVENT_BLANK)
|
||||
ld->ops->set_power(ld, *(int *)evdata->data);
|
||||
else
|
||||
ld->ops->set_mode(ld, evdata->data);
|
||||
}
|
||||
mutex_unlock(&ld->ops_lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,4 @@ module_exit(mbp_exit);
|
|||
MODULE_AUTHOR("Matthew Garrett <[email protected]>");
|
||||
MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1");
|
||||
MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2");
|
||||
MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1");
|
||||
MODULE_DEVICE_TABLE(dmi, mbp_device_table);
|
||||
|
|
|
|||
396
drivers/video/backlight/tdo24m.c
Normal file
396
drivers/video/backlight/tdo24m.c
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels
|
||||
*
|
||||
* Copyright (C) 2008 Marvell International Ltd.
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* publishhed by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/lcd.h>
|
||||
|
||||
#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
|
||||
|
||||
#define TDO24M_SPI_BUFF_SIZE (4)
|
||||
#define MODE_QVGA 0
|
||||
#define MODE_VGA 1
|
||||
|
||||
struct tdo24m {
|
||||
struct spi_device *spi_dev;
|
||||
struct lcd_device *lcd_dev;
|
||||
|
||||
struct spi_message msg;
|
||||
struct spi_transfer xfer;
|
||||
uint8_t *buf;
|
||||
|
||||
int power;
|
||||
int mode;
|
||||
};
|
||||
|
||||
/* use bit 30, 31 as the indicator of command parameter number */
|
||||
#define CMD0(x) ((0 << 30) | (x))
|
||||
#define CMD1(x, x1) ((1 << 30) | ((x) << 9) | 0x100 | (x1))
|
||||
#define CMD2(x, x1, x2) ((2 << 30) | ((x) << 18) | 0x20000 |\
|
||||
((x1) << 9) | 0x100 | (x2))
|
||||
#define CMD_NULL (-1)
|
||||
|
||||
static uint32_t lcd_panel_reset[] = {
|
||||
CMD0(0x1), /* reset */
|
||||
CMD0(0x0), /* nop */
|
||||
CMD0(0x0), /* nop */
|
||||
CMD0(0x0), /* nop */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_on[] = {
|
||||
CMD0(0x29), /* Display ON */
|
||||
CMD2(0xB8, 0xFF, 0xF9), /* Output Control */
|
||||
CMD0(0x11), /* Sleep out */
|
||||
CMD1(0xB0, 0x16), /* Wake */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_off[] = {
|
||||
CMD0(0x28), /* Display OFF */
|
||||
CMD2(0xB8, 0x80, 0x02), /* Output Control */
|
||||
CMD0(0x10), /* Sleep in */
|
||||
CMD1(0xB0, 0x00), /* Deep stand by in */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_pass_through[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x80),
|
||||
CMD1(0xE1, 0x00),
|
||||
CMD1(0x36, 0x50),
|
||||
CMD1(0x3B, 0x00),
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_qvga_pass_through[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x81),
|
||||
CMD1(0xE1, 0x00),
|
||||
CMD1(0x36, 0x50),
|
||||
CMD1(0x3B, 0x22),
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_transfer[] = {
|
||||
CMD1(0xcf, 0x02), /* Blanking period control (1) */
|
||||
CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
|
||||
CMD1(0xd1, 0x01), /* CKV timing control on/off */
|
||||
CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */
|
||||
CMD2(0xd3, 0x1a, 0x0f), /* OEV timing control */
|
||||
CMD2(0xd4, 0x1f, 0xaf), /* ASW timing control (1) */
|
||||
CMD1(0xd5, 0x14), /* ASW timing control (2) */
|
||||
CMD0(0x21), /* Invert for normally black display */
|
||||
CMD0(0x29), /* Display on */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_qvga_transfer[] = {
|
||||
CMD1(0xd6, 0x02), /* Blanking period control (1) */
|
||||
CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */
|
||||
CMD1(0xd8, 0x01), /* CKV timing control on/off */
|
||||
CMD2(0xd9, 0x00, 0x08), /* CKV 1,2 timing control */
|
||||
CMD2(0xde, 0x05, 0x0a), /* OEV timing control */
|
||||
CMD2(0xdf, 0x0a, 0x19), /* ASW timing control (1) */
|
||||
CMD1(0xe0, 0x0a), /* ASW timing control (2) */
|
||||
CMD0(0x21), /* Invert for normally black display */
|
||||
CMD0(0x29), /* Display on */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_config[] = {
|
||||
CMD2(0xb8, 0xff, 0xf9), /* Output control */
|
||||
CMD0(0x11), /* sleep out */
|
||||
CMD1(0xba, 0x01), /* Display mode (1) */
|
||||
CMD1(0xbb, 0x00), /* Display mode (2) */
|
||||
CMD1(0x3a, 0x60), /* Display mode 18-bit RGB */
|
||||
CMD1(0xbf, 0x10), /* Drive system change control */
|
||||
CMD1(0xb1, 0x56), /* Booster operation setup */
|
||||
CMD1(0xb2, 0x33), /* Booster mode setup */
|
||||
CMD1(0xb3, 0x11), /* Booster frequency setup */
|
||||
CMD1(0xb4, 0x02), /* Op amp/system clock */
|
||||
CMD1(0xb5, 0x35), /* VCS voltage */
|
||||
CMD1(0xb6, 0x40), /* VCOM voltage */
|
||||
CMD1(0xb7, 0x03), /* External display signal */
|
||||
CMD1(0xbd, 0x00), /* ASW slew rate */
|
||||
CMD1(0xbe, 0x00), /* Dummy data for QuadData operation */
|
||||
CMD1(0xc0, 0x11), /* Sleep out FR count (A) */
|
||||
CMD1(0xc1, 0x11), /* Sleep out FR count (B) */
|
||||
CMD1(0xc2, 0x11), /* Sleep out FR count (C) */
|
||||
CMD2(0xc3, 0x20, 0x40), /* Sleep out FR count (D) */
|
||||
CMD2(0xc4, 0x60, 0xc0), /* Sleep out FR count (E) */
|
||||
CMD2(0xc5, 0x10, 0x20), /* Sleep out FR count (F) */
|
||||
CMD1(0xc6, 0xc0), /* Sleep out FR count (G) */
|
||||
CMD2(0xc7, 0x33, 0x43), /* Gamma 1 fine tuning (1) */
|
||||
CMD1(0xc8, 0x44), /* Gamma 1 fine tuning (2) */
|
||||
CMD1(0xc9, 0x33), /* Gamma 1 inclination adjustment */
|
||||
CMD1(0xca, 0x00), /* Gamma 1 blue offset adjustment */
|
||||
CMD2(0xec, 0x01, 0xf0), /* Horizontal clock cycles */
|
||||
CMD_NULL,
|
||||
};
|
||||
|
||||
static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
|
||||
{
|
||||
struct spi_transfer *x = &lcd->xfer;
|
||||
uint32_t data, *p = array;
|
||||
int nparams, err = 0;
|
||||
|
||||
for (; *p != CMD_NULL; p++) {
|
||||
|
||||
nparams = (*p >> 30) & 0x3;
|
||||
|
||||
data = *p << (7 - nparams);
|
||||
switch (nparams) {
|
||||
case 0:
|
||||
lcd->buf[0] = (data >> 8) & 0xff;
|
||||
lcd->buf[1] = data & 0xff;
|
||||
break;
|
||||
case 1:
|
||||
lcd->buf[0] = (data >> 16) & 0xff;
|
||||
lcd->buf[1] = (data >> 8) & 0xff;
|
||||
lcd->buf[2] = data & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
lcd->buf[0] = (data >> 24) & 0xff;
|
||||
lcd->buf[1] = (data >> 16) & 0xff;
|
||||
lcd->buf[2] = (data >> 8) & 0xff;
|
||||
lcd->buf[3] = data & 0xff;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
x->len = nparams + 2;
|
||||
err = spi_sync(lcd->spi_dev, &lcd->msg);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tdo24m_adj_mode(struct tdo24m *lcd, int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case MODE_VGA:
|
||||
tdo24m_writes(lcd, lcd_vga_pass_through);
|
||||
tdo24m_writes(lcd, lcd_panel_config);
|
||||
tdo24m_writes(lcd, lcd_vga_transfer);
|
||||
break;
|
||||
case MODE_QVGA:
|
||||
tdo24m_writes(lcd, lcd_qvga_pass_through);
|
||||
tdo24m_writes(lcd, lcd_panel_config);
|
||||
tdo24m_writes(lcd, lcd_qvga_transfer);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lcd->mode = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdo24m_power_on(struct tdo24m *lcd)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = tdo24m_writes(lcd, lcd_panel_on);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = tdo24m_writes(lcd, lcd_panel_reset);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = tdo24m_adj_mode(lcd, lcd->mode);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tdo24m_power_off(struct tdo24m *lcd)
|
||||
{
|
||||
return tdo24m_writes(lcd, lcd_panel_off);
|
||||
}
|
||||
|
||||
static int tdo24m_power(struct tdo24m *lcd, int power)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
|
||||
ret = tdo24m_power_on(lcd);
|
||||
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
|
||||
ret = tdo24m_power_off(lcd);
|
||||
|
||||
if (!ret)
|
||||
lcd->power = power;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int tdo24m_set_power(struct lcd_device *ld, int power)
|
||||
{
|
||||
struct tdo24m *lcd = lcd_get_data(ld);
|
||||
return tdo24m_power(lcd, power);
|
||||
}
|
||||
|
||||
static int tdo24m_get_power(struct lcd_device *ld)
|
||||
{
|
||||
struct tdo24m *lcd = lcd_get_data(ld);
|
||||
return lcd->power;
|
||||
}
|
||||
|
||||
static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m)
|
||||
{
|
||||
struct tdo24m *lcd = lcd_get_data(ld);
|
||||
int mode = MODE_QVGA;
|
||||
|
||||
if (m->xres == 640 || m->xres == 480)
|
||||
mode = MODE_VGA;
|
||||
|
||||
if (lcd->mode == mode)
|
||||
return 0;
|
||||
|
||||
return tdo24m_adj_mode(lcd, mode);
|
||||
}
|
||||
|
||||
static struct lcd_ops tdo24m_ops = {
|
||||
.get_power = tdo24m_get_power,
|
||||
.set_power = tdo24m_set_power,
|
||||
.set_mode = tdo24m_set_mode,
|
||||
};
|
||||
|
||||
static int __devinit tdo24m_probe(struct spi_device *spi)
|
||||
{
|
||||
struct tdo24m *lcd;
|
||||
struct spi_message *m;
|
||||
struct spi_transfer *x;
|
||||
int err;
|
||||
|
||||
spi->bits_per_word = 8;
|
||||
spi->mode = SPI_MODE_3;
|
||||
err = spi_setup(spi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
lcd = kzalloc(sizeof(struct tdo24m), GFP_KERNEL);
|
||||
if (!lcd)
|
||||
return -ENOMEM;
|
||||
|
||||
lcd->spi_dev = spi;
|
||||
lcd->power = FB_BLANK_POWERDOWN;
|
||||
lcd->mode = MODE_VGA; /* default to VGA */
|
||||
|
||||
lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL));
|
||||
if (lcd->buf == NULL) {
|
||||
kfree(lcd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
m = &lcd->msg;
|
||||
x = &lcd->xfer;
|
||||
|
||||
spi_message_init(m);
|
||||
|
||||
x->tx_buf = &lcd->buf[0];
|
||||
spi_message_add_tail(x, m);
|
||||
|
||||
lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev,
|
||||
lcd, &tdo24m_ops);
|
||||
if (IS_ERR(lcd->lcd_dev)) {
|
||||
err = PTR_ERR(lcd->lcd_dev);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&spi->dev, lcd);
|
||||
err = tdo24m_power(lcd, FB_BLANK_UNBLANK);
|
||||
if (err)
|
||||
goto out_unregister;
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
lcd_device_unregister(lcd->lcd_dev);
|
||||
out_free:
|
||||
kfree(lcd->buf);
|
||||
kfree(lcd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit tdo24m_remove(struct spi_device *spi)
|
||||
{
|
||||
struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
tdo24m_power(lcd, FB_BLANK_POWERDOWN);
|
||||
lcd_device_unregister(lcd->lcd_dev);
|
||||
kfree(lcd->buf);
|
||||
kfree(lcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int tdo24m_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
return tdo24m_power(lcd, FB_BLANK_POWERDOWN);
|
||||
}
|
||||
|
||||
static int tdo24m_resume(struct spi_device *spi)
|
||||
{
|
||||
struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
return tdo24m_power(lcd, FB_BLANK_UNBLANK);
|
||||
}
|
||||
#else
|
||||
#define tdo24m_suspend NULL
|
||||
#define tdo24m_resume NULL
|
||||
#endif
|
||||
|
||||
/* Power down all displays on reboot, poweroff or halt */
|
||||
static void tdo24m_shutdown(struct spi_device *spi)
|
||||
{
|
||||
struct tdo24m *lcd = dev_get_drvdata(&spi->dev);
|
||||
|
||||
tdo24m_power(lcd, FB_BLANK_POWERDOWN);
|
||||
}
|
||||
|
||||
static struct spi_driver tdo24m_driver = {
|
||||
.driver = {
|
||||
.name = "tdo24m",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = tdo24m_probe,
|
||||
.remove = __devexit_p(tdo24m_remove),
|
||||
.shutdown = tdo24m_shutdown,
|
||||
.suspend = tdo24m_suspend,
|
||||
.resume = tdo24m_resume,
|
||||
};
|
||||
|
||||
static int __init tdo24m_init(void)
|
||||
{
|
||||
return spi_register_driver(&tdo24m_driver);
|
||||
}
|
||||
module_init(tdo24m_init);
|
||||
|
||||
static void __exit tdo24m_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&tdo24m_driver);
|
||||
}
|
||||
module_exit(tdo24m_exit);
|
||||
|
||||
MODULE_AUTHOR("Eric Miao <[email protected]>");
|
||||
MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -372,7 +372,7 @@ static int __devexit bw2_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id bw2_match[] = {
|
||||
static const struct of_device_id bw2_match[] = {
|
||||
{
|
||||
.name = "bwtwo",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = {
|
|||
.fb_setcolreg = carmine_setcolreg,
|
||||
};
|
||||
|
||||
static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
|
||||
static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
|
||||
int smem_offset, struct device *device, struct fb_info **rinfo)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ static int __devexit cg14_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id cg14_match[] = {
|
||||
static const struct of_device_id cg14_match[] = {
|
||||
{
|
||||
.name = "cgfourteen",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ static int __devexit cg3_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id cg3_match[] = {
|
||||
static const struct of_device_id cg3_match[] = {
|
||||
{
|
||||
.name = "cgthree",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@ static int cg6_blank(int, struct fb_info *);
|
|||
|
||||
static void cg6_imageblit(struct fb_info *, const struct fb_image *);
|
||||
static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *);
|
||||
static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area);
|
||||
static int cg6_sync(struct fb_info *);
|
||||
static int cg6_mmap(struct fb_info *, struct vm_area_struct *);
|
||||
static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long);
|
||||
static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area);
|
||||
static int cg6_pan_display(struct fb_var_screeninfo *, struct fb_info *);
|
||||
|
||||
/*
|
||||
* Frame buffer operations
|
||||
|
|
@ -47,6 +48,7 @@ static struct fb_ops cg6_ops = {
|
|||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = cg6_setcolreg,
|
||||
.fb_blank = cg6_blank,
|
||||
.fb_pan_display = cg6_pan_display,
|
||||
.fb_fillrect = cg6_fillrect,
|
||||
.fb_copyarea = cg6_copyarea,
|
||||
.fb_imageblit = cg6_imageblit,
|
||||
|
|
@ -161,6 +163,7 @@ static struct fb_ops cg6_ops = {
|
|||
#define CG6_THC_MISC_INT_ENAB (1 << 5)
|
||||
#define CG6_THC_MISC_INT (1 << 4)
|
||||
#define CG6_THC_MISC_INIT 0x9f
|
||||
#define CG6_THC_CURSOFF ((65536-32) | ((65536-32) << 16))
|
||||
|
||||
/* The contents are unknown */
|
||||
struct cg6_tec {
|
||||
|
|
@ -280,6 +283,33 @@ static int cg6_sync(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cg6_switch_from_graph(struct cg6_par *par)
|
||||
{
|
||||
struct cg6_thc __iomem *thc = par->thc;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&par->lock, flags);
|
||||
|
||||
/* Hide the cursor. */
|
||||
sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy);
|
||||
|
||||
spin_unlock_irqrestore(&par->lock, flags);
|
||||
}
|
||||
|
||||
static int cg6_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
struct cg6_par *par = (struct cg6_par *)info->par;
|
||||
|
||||
/* We just use this to catch switches out of
|
||||
* graphics mode.
|
||||
*/
|
||||
cg6_switch_from_graph(par);
|
||||
|
||||
if (var->xoffset || var->yoffset || var->vmode)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cg6_fillrect - Draws a rectangle on the screen.
|
||||
*
|
||||
|
|
@ -643,9 +673,13 @@ static void __devinit cg6_chip_init(struct fb_info *info)
|
|||
struct cg6_par *par = (struct cg6_par *)info->par;
|
||||
struct cg6_tec __iomem *tec = par->tec;
|
||||
struct cg6_fbc __iomem *fbc = par->fbc;
|
||||
struct cg6_thc __iomem *thc = par->thc;
|
||||
u32 rev, conf, mode;
|
||||
int i;
|
||||
|
||||
/* Hide the cursor. */
|
||||
sbus_writel(CG6_THC_CURSOFF, &thc->thc_cursxy);
|
||||
|
||||
/* Turn off stuff in the Transform Engine. */
|
||||
sbus_writel(0, &tec->tec_matrix);
|
||||
sbus_writel(0, &tec->tec_clip);
|
||||
|
|
@ -814,7 +848,7 @@ static int __devexit cg6_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id cg6_match[] = {
|
||||
static const struct of_device_id cg6_match[] = {
|
||||
{
|
||||
.name = "cgsix",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -327,29 +327,7 @@ static const struct {
|
|||
#endif /* CONFIG_ZORRO */
|
||||
|
||||
struct cirrusfb_regs {
|
||||
long freq;
|
||||
long nom;
|
||||
long den;
|
||||
long div;
|
||||
long multiplexing;
|
||||
long mclk;
|
||||
long divMCLK;
|
||||
|
||||
long HorizRes; /* The x resolution in pixel */
|
||||
long HorizTotal;
|
||||
long HorizDispEnd;
|
||||
long HorizBlankStart;
|
||||
long HorizBlankEnd;
|
||||
long HorizSyncStart;
|
||||
long HorizSyncEnd;
|
||||
|
||||
long VertRes; /* the physical y resolution in scanlines */
|
||||
long VertTotal;
|
||||
long VertDispEnd;
|
||||
long VertSyncStart;
|
||||
long VertSyncEnd;
|
||||
long VertBlankStart;
|
||||
long VertBlankEnd;
|
||||
int multiplexing;
|
||||
};
|
||||
|
||||
#ifdef CIRRUSFB_DEBUG
|
||||
|
|
@ -367,110 +345,13 @@ struct cirrusfb_info {
|
|||
|
||||
struct cirrusfb_regs currentmode;
|
||||
int blank_mode;
|
||||
u32 pseudo_palette[16];
|
||||
|
||||
u32 pseudo_palette[16];
|
||||
|
||||
#ifdef CONFIG_ZORRO
|
||||
struct zorro_dev *zdev;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_dev *pdev;
|
||||
#endif
|
||||
void (*unmap)(struct fb_info *info);
|
||||
};
|
||||
|
||||
static unsigned cirrusfb_def_mode = 1;
|
||||
static int noaccel;
|
||||
|
||||
/*
|
||||
* Predefined Video Modes
|
||||
*/
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
struct fb_var_screeninfo var;
|
||||
} cirrusfb_predefined[] = {
|
||||
{
|
||||
/* autodetect mode */
|
||||
.name = "Autodetect",
|
||||
}, {
|
||||
/* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
|
||||
.name = "640x480",
|
||||
.var = {
|
||||
.xres = 640,
|
||||
.yres = 480,
|
||||
.xres_virtual = 640,
|
||||
.yres_virtual = 480,
|
||||
.bits_per_pixel = 8,
|
||||
.red = { .length = 8 },
|
||||
.green = { .length = 8 },
|
||||
.blue = { .length = 8 },
|
||||
.width = -1,
|
||||
.height = -1,
|
||||
.pixclock = 40000,
|
||||
.left_margin = 48,
|
||||
.right_margin = 16,
|
||||
.upper_margin = 32,
|
||||
.lower_margin = 8,
|
||||
.hsync_len = 96,
|
||||
.vsync_len = 4,
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.vmode = FB_VMODE_NONINTERLACED
|
||||
}
|
||||
}, {
|
||||
/* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
|
||||
.name = "800x600",
|
||||
.var = {
|
||||
.xres = 800,
|
||||
.yres = 600,
|
||||
.xres_virtual = 800,
|
||||
.yres_virtual = 600,
|
||||
.bits_per_pixel = 8,
|
||||
.red = { .length = 8 },
|
||||
.green = { .length = 8 },
|
||||
.blue = { .length = 8 },
|
||||
.width = -1,
|
||||
.height = -1,
|
||||
.pixclock = 20000,
|
||||
.left_margin = 128,
|
||||
.right_margin = 16,
|
||||
.upper_margin = 24,
|
||||
.lower_margin = 2,
|
||||
.hsync_len = 96,
|
||||
.vsync_len = 6,
|
||||
.vmode = FB_VMODE_NONINTERLACED
|
||||
}
|
||||
}, {
|
||||
/*
|
||||
* Modeline from XF86Config:
|
||||
* Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
|
||||
*/
|
||||
/* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
|
||||
.name = "1024x768",
|
||||
.var = {
|
||||
.xres = 1024,
|
||||
.yres = 768,
|
||||
.xres_virtual = 1024,
|
||||
.yres_virtual = 768,
|
||||
.bits_per_pixel = 8,
|
||||
.red = { .length = 8 },
|
||||
.green = { .length = 8 },
|
||||
.blue = { .length = 8 },
|
||||
.width = -1,
|
||||
.height = -1,
|
||||
.pixclock = 12500,
|
||||
.left_margin = 144,
|
||||
.right_margin = 32,
|
||||
.upper_margin = 30,
|
||||
.lower_margin = 2,
|
||||
.hsync_len = 192,
|
||||
.vsync_len = 6,
|
||||
.vmode = FB_VMODE_NONINTERLACED
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined)
|
||||
static int noaccel __devinitdata;
|
||||
static char *mode_option __devinitdata = "640x480@60";
|
||||
|
||||
/****************************************************************************/
|
||||
/**** BEGIN PROTOTYPES ******************************************************/
|
||||
|
|
@ -514,10 +395,6 @@ static struct fb_ops cirrusfb_ops = {
|
|||
.fb_imageblit = cirrusfb_imageblit,
|
||||
};
|
||||
|
||||
/*--- Hardware Specific Routines -------------------------------------------*/
|
||||
static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
|
||||
struct cirrusfb_regs *regs,
|
||||
struct fb_info *info);
|
||||
/*--- Internal routines ----------------------------------------------------*/
|
||||
static void init_vgachip(struct fb_info *info);
|
||||
static void switch_monitor(struct cirrusfb_info *cinfo, int on);
|
||||
|
|
@ -546,9 +423,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
|
|||
u_short width, u_short height,
|
||||
u_char color, u_short line_length);
|
||||
|
||||
static void bestclock(long freq, long *best,
|
||||
long *nom, long *den,
|
||||
long *div, long maxfreq);
|
||||
static void bestclock(long freq, int *nom, int *den, int *div);
|
||||
|
||||
#ifdef CIRRUSFB_DEBUG
|
||||
static void cirrusfb_dump(void);
|
||||
|
|
@ -584,45 +459,28 @@ static int cirrusfb_release(struct fb_info *info, int user)
|
|||
/****************************************************************************/
|
||||
/**** BEGIN Hardware specific Routines **************************************/
|
||||
|
||||
/* Get a good MCLK value */
|
||||
static long cirrusfb_get_mclk(long freq, int bpp, long *div)
|
||||
/* Check if the MCLK is not a better clock source */
|
||||
static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
|
||||
{
|
||||
long mclk;
|
||||
long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
|
||||
|
||||
assert(div != NULL);
|
||||
|
||||
/* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
|
||||
* Assume a 64-bit data path for now. The formula is:
|
||||
* ((B * PCLK * 2)/W) * 1.2
|
||||
* B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
|
||||
mclk = ((bpp / 8) * freq * 2) / 4;
|
||||
mclk = (mclk * 12) / 10;
|
||||
if (mclk < 50000)
|
||||
mclk = 50000;
|
||||
DPRINTK("Use MCLK of %ld kHz\n", mclk);
|
||||
|
||||
/* Calculate value for SR1F. Multiply by 2 so we can round up. */
|
||||
mclk = ((mclk * 16) / 14318);
|
||||
mclk = (mclk + 1) / 2;
|
||||
DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
|
||||
/* Read MCLK value */
|
||||
mclk = (14318 * mclk) >> 3;
|
||||
DPRINTK("Read MCLK of %ld kHz\n", mclk);
|
||||
|
||||
/* Determine if we should use MCLK instead of VCLK, and if so, what we
|
||||
* should divide it by to get VCLK */
|
||||
switch (freq) {
|
||||
case 24751 ... 25249:
|
||||
*div = 2;
|
||||
DPRINTK("Using VCLK = MCLK/2\n");
|
||||
break;
|
||||
case 49501 ... 50499:
|
||||
*div = 1;
|
||||
* should divide it by to get VCLK
|
||||
*/
|
||||
|
||||
if (abs(freq - mclk) < 250) {
|
||||
DPRINTK("Using VCLK = MCLK\n");
|
||||
break;
|
||||
default:
|
||||
*div = 0;
|
||||
break;
|
||||
return 1;
|
||||
} else if (abs(freq - (mclk / 2)) < 250) {
|
||||
DPRINTK("Using VCLK = MCLK/2\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
return mclk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
||||
|
|
@ -638,7 +496,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
|||
break; /* 8 pixel per byte, only 1/4th of mem usable */
|
||||
case 8:
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break; /* 1 pixel == 1 byte */
|
||||
default:
|
||||
|
|
@ -713,7 +570,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
|
|||
var->blue.length = 5;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
if (isPReP) {
|
||||
var->red.offset = 8;
|
||||
|
|
@ -767,8 +623,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
|
|||
long maxclock;
|
||||
int maxclockidx = var->bits_per_pixel >> 3;
|
||||
struct cirrusfb_info *cinfo = info->par;
|
||||
int xres, hfront, hsync, hback;
|
||||
int yres, vfront, vsync, vback;
|
||||
|
||||
switch (var->bits_per_pixel) {
|
||||
case 1:
|
||||
|
|
@ -782,10 +636,9 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
|
|||
break;
|
||||
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
info->fix.line_length = var->xres_virtual * maxclockidx;
|
||||
info->fix.visual = FB_VISUAL_DIRECTCOLOR;
|
||||
info->fix.visual = FB_VISUAL_TRUECOLOR;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -827,90 +680,33 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
|
|||
switch (var->bits_per_pixel) {
|
||||
case 16:
|
||||
case 32:
|
||||
if (regs->HorizRes <= 800)
|
||||
if (var->xres <= 800)
|
||||
/* Xbh has this type of clock for 32-bit */
|
||||
freq /= 2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
bestclock(freq, ®s->freq, ®s->nom, ®s->den, ®s->div,
|
||||
maxclock);
|
||||
regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
|
||||
®s->divMCLK);
|
||||
|
||||
xres = var->xres;
|
||||
hfront = var->right_margin;
|
||||
hsync = var->hsync_len;
|
||||
hback = var->left_margin;
|
||||
|
||||
yres = var->yres;
|
||||
vfront = var->lower_margin;
|
||||
vsync = var->vsync_len;
|
||||
vback = var->upper_margin;
|
||||
|
||||
if (var->vmode & FB_VMODE_DOUBLE) {
|
||||
yres *= 2;
|
||||
vfront *= 2;
|
||||
vsync *= 2;
|
||||
vback *= 2;
|
||||
} else if (var->vmode & FB_VMODE_INTERLACED) {
|
||||
yres = (yres + 1) / 2;
|
||||
vfront = (vfront + 1) / 2;
|
||||
vsync = (vsync + 1) / 2;
|
||||
vback = (vback + 1) / 2;
|
||||
}
|
||||
regs->HorizRes = xres;
|
||||
regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
|
||||
regs->HorizDispEnd = xres / 8 - 1;
|
||||
regs->HorizBlankStart = xres / 8;
|
||||
/* does not count with "-5" */
|
||||
regs->HorizBlankEnd = regs->HorizTotal + 5;
|
||||
regs->HorizSyncStart = (xres + hfront) / 8 + 1;
|
||||
regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
|
||||
|
||||
regs->VertRes = yres;
|
||||
regs->VertTotal = yres + vfront + vsync + vback - 2;
|
||||
regs->VertDispEnd = yres - 1;
|
||||
regs->VertBlankStart = yres;
|
||||
regs->VertBlankEnd = regs->VertTotal;
|
||||
regs->VertSyncStart = yres + vfront - 1;
|
||||
regs->VertSyncEnd = yres + vfront + vsync - 1;
|
||||
|
||||
if (regs->VertRes >= 1024) {
|
||||
regs->VertTotal /= 2;
|
||||
regs->VertSyncStart /= 2;
|
||||
regs->VertSyncEnd /= 2;
|
||||
regs->VertDispEnd /= 2;
|
||||
}
|
||||
if (regs->multiplexing) {
|
||||
regs->HorizTotal /= 2;
|
||||
regs->HorizSyncStart /= 2;
|
||||
regs->HorizSyncEnd /= 2;
|
||||
regs->HorizDispEnd /= 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
|
||||
int div)
|
||||
static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
|
||||
int div)
|
||||
{
|
||||
unsigned char old1f, old1e;
|
||||
assert(cinfo != NULL);
|
||||
old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
|
||||
|
||||
if (div == 2) {
|
||||
/* VCLK = MCLK/2 */
|
||||
unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
|
||||
} else if (div == 1) {
|
||||
/* VCLK = MCLK */
|
||||
unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
|
||||
} else {
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
|
||||
if (div) {
|
||||
DPRINTK("Set %s as pixclock source.\n",
|
||||
(div == 2) ? "MCLK/2" : "MCLK");
|
||||
old1f |= 0x40;
|
||||
old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
|
||||
if (div == 2)
|
||||
old1e |= 1;
|
||||
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
|
||||
}
|
||||
vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
@ -927,6 +723,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
unsigned char tmp;
|
||||
int offset = 0, err;
|
||||
const struct cirrusfb_board_info_rec *bi;
|
||||
int hdispend, hsyncstart, hsyncend, htotal;
|
||||
int yres, vdispend, vsyncstart, vsyncend, vtotal;
|
||||
long freq;
|
||||
int nom, den, div;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
DPRINTK("Requested mode: %dx%dx%d\n",
|
||||
|
|
@ -944,76 +744,117 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
|
||||
bi = &cirrusfb_board_info[cinfo->btype];
|
||||
|
||||
hsyncstart = var->xres + var->right_margin;
|
||||
hsyncend = hsyncstart + var->hsync_len;
|
||||
htotal = (hsyncend + var->left_margin) / 8 - 5;
|
||||
hdispend = var->xres / 8 - 1;
|
||||
hsyncstart = hsyncstart / 8 + 1;
|
||||
hsyncend = hsyncend / 8 + 1;
|
||||
|
||||
yres = var->yres;
|
||||
vsyncstart = yres + var->lower_margin;
|
||||
vsyncend = vsyncstart + var->vsync_len;
|
||||
vtotal = vsyncend + var->upper_margin;
|
||||
vdispend = yres - 1;
|
||||
|
||||
if (var->vmode & FB_VMODE_DOUBLE) {
|
||||
yres *= 2;
|
||||
vsyncstart *= 2;
|
||||
vsyncend *= 2;
|
||||
vtotal *= 2;
|
||||
} else if (var->vmode & FB_VMODE_INTERLACED) {
|
||||
yres = (yres + 1) / 2;
|
||||
vsyncstart = (vsyncstart + 1) / 2;
|
||||
vsyncend = (vsyncend + 1) / 2;
|
||||
vtotal = (vtotal + 1) / 2;
|
||||
}
|
||||
|
||||
vtotal -= 2;
|
||||
vsyncstart -= 1;
|
||||
vsyncend -= 1;
|
||||
|
||||
if (yres >= 1024) {
|
||||
vtotal /= 2;
|
||||
vsyncstart /= 2;
|
||||
vsyncend /= 2;
|
||||
vdispend /= 2;
|
||||
}
|
||||
if (regs.multiplexing) {
|
||||
htotal /= 2;
|
||||
hsyncstart /= 2;
|
||||
hsyncend /= 2;
|
||||
hdispend /= 2;
|
||||
}
|
||||
/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
|
||||
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
|
||||
|
||||
/* if debugging is enabled, all parameters get output before writing */
|
||||
DPRINTK("CRT0: %ld\n", regs.HorizTotal);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
|
||||
DPRINTK("CRT0: %d\n", htotal);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
|
||||
|
||||
DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
|
||||
DPRINTK("CRT1: %d\n", hdispend);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
|
||||
|
||||
DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
|
||||
DPRINTK("CRT2: %d\n", var->xres / 8);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
|
||||
|
||||
/* + 128: Compatible read */
|
||||
DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
|
||||
DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
|
||||
128 + (regs.HorizBlankEnd % 32));
|
||||
128 + ((htotal + 5) % 32));
|
||||
|
||||
DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
|
||||
DPRINTK("CRT4: %d\n", hsyncstart);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
|
||||
|
||||
tmp = regs.HorizSyncEnd % 32;
|
||||
if (regs.HorizBlankEnd & 32)
|
||||
tmp = hsyncend % 32;
|
||||
if ((htotal + 5) & 32)
|
||||
tmp += 128;
|
||||
DPRINTK("CRT5: %d\n", tmp);
|
||||
vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
|
||||
|
||||
DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
|
||||
DPRINTK("CRT6: %d\n", vtotal & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
|
||||
|
||||
tmp = 16; /* LineCompare bit #9 */
|
||||
if (regs.VertTotal & 256)
|
||||
if (vtotal & 256)
|
||||
tmp |= 1;
|
||||
if (regs.VertDispEnd & 256)
|
||||
if (vdispend & 256)
|
||||
tmp |= 2;
|
||||
if (regs.VertSyncStart & 256)
|
||||
if (vsyncstart & 256)
|
||||
tmp |= 4;
|
||||
if (regs.VertBlankStart & 256)
|
||||
if ((vdispend + 1) & 256)
|
||||
tmp |= 8;
|
||||
if (regs.VertTotal & 512)
|
||||
if (vtotal & 512)
|
||||
tmp |= 32;
|
||||
if (regs.VertDispEnd & 512)
|
||||
if (vdispend & 512)
|
||||
tmp |= 64;
|
||||
if (regs.VertSyncStart & 512)
|
||||
if (vsyncstart & 512)
|
||||
tmp |= 128;
|
||||
DPRINTK("CRT7: %d\n", tmp);
|
||||
vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
|
||||
|
||||
tmp = 0x40; /* LineCompare bit #8 */
|
||||
if (regs.VertBlankStart & 512)
|
||||
if ((vdispend + 1) & 512)
|
||||
tmp |= 0x20;
|
||||
if (var->vmode & FB_VMODE_DOUBLE)
|
||||
tmp |= 0x80;
|
||||
DPRINTK("CRT9: %d\n", tmp);
|
||||
vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
|
||||
|
||||
DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
|
||||
DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
|
||||
|
||||
DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
|
||||
DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
|
||||
|
||||
DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
|
||||
DPRINTK("CRT12: %d\n", vdispend & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
|
||||
|
||||
DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
|
||||
DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
|
||||
|
||||
DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
|
||||
DPRINTK("CRT16: %d\n", vtotal & 0xff);
|
||||
vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
|
||||
|
||||
DPRINTK("CRT18: 0xff\n");
|
||||
vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
|
||||
|
|
@ -1021,38 +862,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
tmp = 0;
|
||||
if (var->vmode & FB_VMODE_INTERLACED)
|
||||
tmp |= 1;
|
||||
if (regs.HorizBlankEnd & 64)
|
||||
if ((htotal + 5) & 64)
|
||||
tmp |= 16;
|
||||
if (regs.HorizBlankEnd & 128)
|
||||
if ((htotal + 5) & 128)
|
||||
tmp |= 32;
|
||||
if (regs.VertBlankEnd & 256)
|
||||
if (vtotal & 256)
|
||||
tmp |= 64;
|
||||
if (regs.VertBlankEnd & 512)
|
||||
if (vtotal & 512)
|
||||
tmp |= 128;
|
||||
|
||||
DPRINTK("CRT1a: %d\n", tmp);
|
||||
vga_wcrt(regbase, CL_CRT1A, tmp);
|
||||
|
||||
freq = PICOS2KHZ(var->pixclock);
|
||||
bestclock(freq, &nom, &den, &div);
|
||||
|
||||
/* set VCLK0 */
|
||||
/* hardware RefClock: 14.31818 MHz */
|
||||
/* formula: VClk = (OSC * N) / (D * (1+P)) */
|
||||
/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
|
||||
|
||||
vga_wseq(regbase, CL_SEQRB, regs.nom);
|
||||
tmp = regs.den << 1;
|
||||
if (regs.div != 0)
|
||||
tmp |= 1;
|
||||
if (cinfo->btype == BT_ALPINE) {
|
||||
/* if freq is close to mclk or mclk/2 select mclk
|
||||
* as clock source
|
||||
*/
|
||||
int divMCLK = cirrusfb_check_mclk(cinfo, freq);
|
||||
if (divMCLK) {
|
||||
nom = 0;
|
||||
cirrusfb_set_mclk_as_source(cinfo, divMCLK);
|
||||
}
|
||||
}
|
||||
if (nom) {
|
||||
vga_wseq(regbase, CL_SEQRB, nom);
|
||||
tmp = den << 1;
|
||||
if (div != 0)
|
||||
tmp |= 1;
|
||||
|
||||
/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
|
||||
if ((cinfo->btype == BT_SD64) ||
|
||||
(cinfo->btype == BT_ALPINE) ||
|
||||
(cinfo->btype == BT_GD5480))
|
||||
tmp |= 0x80;
|
||||
/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
|
||||
if ((cinfo->btype == BT_SD64) ||
|
||||
(cinfo->btype == BT_ALPINE) ||
|
||||
(cinfo->btype == BT_GD5480))
|
||||
tmp |= 0x80;
|
||||
|
||||
DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
|
||||
vga_wseq(regbase, CL_SEQR1B, tmp);
|
||||
DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
|
||||
vga_wseq(regbase, CL_SEQR1B, tmp);
|
||||
}
|
||||
|
||||
if (regs.VertRes >= 1024)
|
||||
if (yres >= 1024)
|
||||
/* 1280x1024 */
|
||||
vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
|
||||
else
|
||||
|
|
@ -1066,7 +922,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
/* don't know if it would hurt to also program this if no interlaced */
|
||||
/* mode is used, but I feel better this way.. :-) */
|
||||
if (var->vmode & FB_VMODE_INTERLACED)
|
||||
vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
|
||||
vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
|
||||
else
|
||||
vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
|
||||
|
||||
|
|
@ -1240,7 +1096,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
|
||||
case BT_ALPINE:
|
||||
DPRINTK(" (for GD543x)\n");
|
||||
cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
|
||||
/* We already set SRF and SR1F */
|
||||
break;
|
||||
|
||||
|
|
@ -1312,11 +1167,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
|
||||
case BT_ALPINE:
|
||||
DPRINTK(" (for GD543x)\n");
|
||||
if (regs.HorizRes >= 1024)
|
||||
vga_wseq(regbase, CL_SEQR7, 0xa7);
|
||||
else
|
||||
vga_wseq(regbase, CL_SEQR7, 0xa3);
|
||||
cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
|
||||
vga_wseq(regbase, CL_SEQR7, 0xa7);
|
||||
break;
|
||||
|
||||
case BT_GD5480:
|
||||
|
|
@ -1360,7 +1211,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
*/
|
||||
|
||||
else if (var->bits_per_pixel == 32) {
|
||||
DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
|
||||
DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
|
||||
switch (cinfo->btype) {
|
||||
case BT_SD64:
|
||||
/* Extended Sequencer Mode: 256c col. mode */
|
||||
|
|
@ -1394,7 +1245,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
|
|||
case BT_ALPINE:
|
||||
DPRINTK(" (for GD543x)\n");
|
||||
vga_wseq(regbase, CL_SEQR7, 0xa9);
|
||||
cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
|
||||
break;
|
||||
|
||||
case BT_GD5480:
|
||||
|
|
@ -1949,8 +1799,6 @@ static void init_vgachip(struct fb_info *info)
|
|||
/* misc... */
|
||||
WHDR(cinfo, 0); /* Hidden DAC register: - */
|
||||
|
||||
printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
|
||||
info->screen_size);
|
||||
DPRINTK("EXIT\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -2122,7 +1970,7 @@ static int release_io_ports;
|
|||
* based on the DRAM bandwidth bit and DRAM bank switching bit. This
|
||||
* works with 1MB, 2MB and 4MB configurations (which the Motorola boards
|
||||
* seem to have. */
|
||||
static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
|
||||
static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
|
||||
{
|
||||
unsigned long mem;
|
||||
unsigned char SRF;
|
||||
|
|
@ -2188,8 +2036,7 @@ static void get_pci_addrs(const struct pci_dev *pdev,
|
|||
|
||||
static void cirrusfb_pci_unmap(struct fb_info *info)
|
||||
{
|
||||
struct cirrusfb_info *cinfo = info->par;
|
||||
struct pci_dev *pdev = cinfo->pdev;
|
||||
struct pci_dev *pdev = to_pci_dev(info->device);
|
||||
|
||||
iounmap(info->screen_base);
|
||||
#if 0 /* if system didn't claim this region, we would... */
|
||||
|
|
@ -2205,20 +2052,22 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
|
|||
static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
|
||||
{
|
||||
struct cirrusfb_info *cinfo = info->par;
|
||||
zorro_release_device(cinfo->zdev);
|
||||
struct zorro_dev *zdev = to_zorro_dev(info->device);
|
||||
|
||||
zorro_release_device(zdev);
|
||||
|
||||
if (cinfo->btype == BT_PICASSO4) {
|
||||
cinfo->regbase -= 0x600000;
|
||||
iounmap((void *)cinfo->regbase);
|
||||
iounmap(info->screen_base);
|
||||
} else {
|
||||
if (zorro_resource_start(cinfo->zdev) > 0x01000000)
|
||||
if (zorro_resource_start(zdev) > 0x01000000)
|
||||
iounmap(info->screen_base);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ZORRO */
|
||||
|
||||
static int cirrusfb_set_fbinfo(struct fb_info *info)
|
||||
static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
|
||||
{
|
||||
struct cirrusfb_info *cinfo = info->par;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
|
|
@ -2235,7 +2084,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
|
|||
if (cinfo->btype == BT_GD5480) {
|
||||
if (var->bits_per_pixel == 16)
|
||||
info->screen_base += 1 * MB_;
|
||||
if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
|
||||
if (var->bits_per_pixel == 32)
|
||||
info->screen_base += 2 * MB_;
|
||||
}
|
||||
|
||||
|
|
@ -2262,7 +2111,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cirrusfb_register(struct fb_info *info)
|
||||
static int __devinit cirrusfb_register(struct fb_info *info)
|
||||
{
|
||||
struct cirrusfb_info *cinfo = info->par;
|
||||
int err;
|
||||
|
|
@ -2278,23 +2127,27 @@ static int cirrusfb_register(struct fb_info *info)
|
|||
/* sanity checks */
|
||||
assert(btype != BT_NONE);
|
||||
|
||||
/* set all the vital stuff */
|
||||
cirrusfb_set_fbinfo(info);
|
||||
|
||||
DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
|
||||
|
||||
/* Make pretend we've set the var so our structures are in a "good" */
|
||||
/* state, even though we haven't written the mode to the hw yet... */
|
||||
info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
|
||||
err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
|
||||
if (!err) {
|
||||
DPRINTK("wrong initial video mode\n");
|
||||
err = -EINVAL;
|
||||
goto err_dealloc_cmap;
|
||||
}
|
||||
|
||||
info->var.activate = FB_ACTIVATE_NOW;
|
||||
|
||||
err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
|
||||
if (err < 0) {
|
||||
/* should never happen */
|
||||
DPRINTK("choking on default var... umm, no good.\n");
|
||||
goto err_unmap_cirrusfb;
|
||||
goto err_dealloc_cmap;
|
||||
}
|
||||
|
||||
/* set all the vital stuff */
|
||||
cirrusfb_set_fbinfo(info);
|
||||
|
||||
err = register_framebuffer(info);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "cirrusfb: could not register "
|
||||
|
|
@ -2307,7 +2160,6 @@ static int cirrusfb_register(struct fb_info *info)
|
|||
|
||||
err_dealloc_cmap:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err_unmap_cirrusfb:
|
||||
cinfo->unmap(info);
|
||||
framebuffer_release(info);
|
||||
return err;
|
||||
|
|
@ -2330,8 +2182,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int cirrusfb_pci_register(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct cirrusfb_info *cinfo;
|
||||
struct fb_info *info;
|
||||
|
|
@ -2353,7 +2205,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
cinfo = info->par;
|
||||
cinfo->pdev = pdev;
|
||||
cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
|
||||
|
||||
DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
|
||||
|
|
@ -2459,8 +2310,8 @@ static struct pci_driver cirrusfb_pci_driver = {
|
|||
#endif /* CONFIG_PCI */
|
||||
|
||||
#ifdef CONFIG_ZORRO
|
||||
static int cirrusfb_zorro_register(struct zorro_dev *z,
|
||||
const struct zorro_device_id *ent)
|
||||
static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
|
||||
const struct zorro_device_id *ent)
|
||||
{
|
||||
struct cirrusfb_info *cinfo;
|
||||
struct fb_info *info;
|
||||
|
|
@ -2489,7 +2340,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
|
|||
assert(z);
|
||||
assert(btype != BT_NONE);
|
||||
|
||||
cinfo->zdev = z;
|
||||
board_addr = zorro_resource_start(z);
|
||||
board_size = zorro_resource_len(z);
|
||||
info->screen_size = size;
|
||||
|
|
@ -2621,17 +2471,17 @@ static int __init cirrusfb_setup(char *options) {
|
|||
return 0;
|
||||
|
||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||
if (!*this_opt) continue;
|
||||
if (!*this_opt)
|
||||
continue;
|
||||
|
||||
DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
|
||||
|
||||
for (i = 0; i < NUM_TOTAL_MODES; i++) {
|
||||
sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
|
||||
if (strcmp(this_opt, s) == 0)
|
||||
cirrusfb_def_mode = i;
|
||||
}
|
||||
if (!strcmp(this_opt, "noaccel"))
|
||||
noaccel = 1;
|
||||
else if (!strncmp(this_opt, "mode:", 5))
|
||||
mode_option = this_opt + 5;
|
||||
else
|
||||
mode_option = this_opt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2657,6 +2507,11 @@ static void __exit cirrusfb_exit(void)
|
|||
|
||||
module_init(cirrusfb_init);
|
||||
|
||||
module_param(mode_option, charp, 0);
|
||||
MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
|
||||
module_param(noaccel, bool, 0);
|
||||
MODULE_PARM_DESC(noaccel, "Disable acceleration");
|
||||
|
||||
#ifdef MODULE
|
||||
module_exit(cirrusfb_exit);
|
||||
#endif
|
||||
|
|
@ -3050,16 +2905,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
|
|||
* bestclock() - determine closest possible clock lower(?) than the
|
||||
* desired pixel clock
|
||||
**************************************************************************/
|
||||
static void bestclock(long freq, long *best, long *nom,
|
||||
long *den, long *div, long maxfreq)
|
||||
static void bestclock(long freq, int *nom, int *den, int *div)
|
||||
{
|
||||
long n, h, d, f;
|
||||
int n, d;
|
||||
long h, diff;
|
||||
|
||||
assert(best != NULL);
|
||||
assert(nom != NULL);
|
||||
assert(den != NULL);
|
||||
assert(div != NULL);
|
||||
assert(maxfreq > 0);
|
||||
|
||||
*nom = 0;
|
||||
*den = 0;
|
||||
|
|
@ -3070,51 +2923,47 @@ static void bestclock(long freq, long *best, long *nom,
|
|||
if (freq < 8000)
|
||||
freq = 8000;
|
||||
|
||||
if (freq > maxfreq)
|
||||
freq = maxfreq;
|
||||
|
||||
*best = 0;
|
||||
f = freq * 10;
|
||||
diff = freq;
|
||||
|
||||
for (n = 32; n < 128; n++) {
|
||||
d = (143181 * n) / f;
|
||||
int s = 0;
|
||||
|
||||
d = (14318 * n) / freq;
|
||||
if ((d >= 7) && (d <= 63)) {
|
||||
if (d > 31)
|
||||
d = (d / 2) * 2;
|
||||
h = (14318 * n) / d;
|
||||
if (abs(h - freq) < abs(*best - freq)) {
|
||||
*best = h;
|
||||
int temp = d;
|
||||
|
||||
if (temp > 31) {
|
||||
s = 1;
|
||||
temp >>= 1;
|
||||
}
|
||||
h = ((14318 * n) / temp) >> s;
|
||||
h = h > freq ? h - freq : freq - h;
|
||||
if (h < diff) {
|
||||
diff = h;
|
||||
*nom = n;
|
||||
if (d < 32) {
|
||||
*den = d;
|
||||
*div = 0;
|
||||
} else {
|
||||
*den = d / 2;
|
||||
*div = 1;
|
||||
}
|
||||
*den = temp;
|
||||
*div = s;
|
||||
}
|
||||
}
|
||||
d = DIV_ROUND_UP(143181 * n, f);
|
||||
d++;
|
||||
if ((d >= 7) && (d <= 63)) {
|
||||
if (d > 31)
|
||||
d = (d / 2) * 2;
|
||||
h = (14318 * n) / d;
|
||||
if (abs(h - freq) < abs(*best - freq)) {
|
||||
*best = h;
|
||||
if (d > 31) {
|
||||
s = 1;
|
||||
d >>= 1;
|
||||
}
|
||||
h = ((14318 * n) / d) >> s;
|
||||
h = h > freq ? h - freq : freq - h;
|
||||
if (h < diff) {
|
||||
diff = h;
|
||||
*nom = n;
|
||||
if (d < 32) {
|
||||
*den = d;
|
||||
*div = 0;
|
||||
} else {
|
||||
*den = d / 2;
|
||||
*div = 1;
|
||||
}
|
||||
*den = d;
|
||||
*div = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTK("Best possible values for given frequency:\n");
|
||||
DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
|
||||
DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
|
||||
freq, *nom, *den, *div);
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
|
|
|
|||
|
|
@ -43,22 +43,6 @@ config VGACON_SOFT_SCROLLBACK_SIZE
|
|||
buffer. Each 64KB will give you approximately 16 80x25
|
||||
screenfuls of scrollback buffer
|
||||
|
||||
config VIDEO_SELECT
|
||||
bool "Video mode selection support"
|
||||
depends on X86 && VGA_CONSOLE
|
||||
---help---
|
||||
This enables support for text mode selection on kernel startup. If
|
||||
you want to take advantage of some high-resolution text mode your
|
||||
card's BIOS offers, but the traditional Linux utilities like
|
||||
SVGATextMode don't, you can say Y here and set the mode using the
|
||||
"vga=" option from your boot loader (lilo or loadlin) or set
|
||||
"vga=ask" which brings up a video mode menu on kernel startup. (Try
|
||||
"man bootparam" or see the documentation of your boot loader about
|
||||
how to pass options to the kernel.)
|
||||
|
||||
Read the file <file:Documentation/svga.txt> for more information
|
||||
about the Video mode selection support. If unsure, say N.
|
||||
|
||||
config MDA_CONSOLE
|
||||
depends on !M68K && !PARISC && ISA
|
||||
tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
|
||||
|
|
|
|||
|
|
@ -1855,8 +1855,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
|
||||
struct display *p = &fb_display[vc->vc_num];
|
||||
int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
|
||||
unsigned short saved_ec;
|
||||
int ret;
|
||||
|
||||
if (fbcon_is_inactive(vc, info))
|
||||
return -EINVAL;
|
||||
|
|
@ -1869,11 +1867,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
* whole screen (prevents flicker).
|
||||
*/
|
||||
|
||||
saved_ec = vc->vc_video_erase_char;
|
||||
vc->vc_video_erase_char = vc->vc_scrl_erase_char;
|
||||
|
||||
ret = 0;
|
||||
|
||||
switch (dir) {
|
||||
case SM_UP:
|
||||
if (count > vc->vc_rows) /* Maximum realistic size */
|
||||
|
|
@ -1890,9 +1883,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
(b - count)),
|
||||
vc->vc_scrl_erase_char,
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
ret = 1;
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case SCROLL_WRAP_MOVE:
|
||||
|
|
@ -1962,10 +1955,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
(b - count)),
|
||||
vc->vc_scrl_erase_char,
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
ret = 1;
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1982,9 +1974,9 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
t),
|
||||
vc->vc_scrl_erase_char,
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
ret = 1;
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case SCROLL_WRAP_MOVE:
|
||||
|
|
@ -2052,15 +2044,12 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
|||
scr_memsetw((unsigned short *) (vc->vc_origin +
|
||||
vc->vc_size_row *
|
||||
t),
|
||||
vc->vc_scrl_erase_char,
|
||||
vc->vc_video_erase_char,
|
||||
vc->vc_size_row * count);
|
||||
ret = 1;
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
vc->vc_video_erase_char = saved_ec;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2400,11 +2389,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
|
|||
|
||||
if (!fbcon_is_inactive(vc, info)) {
|
||||
if (ops->blank_state != blank) {
|
||||
int ret = 1;
|
||||
|
||||
ops->blank_state = blank;
|
||||
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
|
||||
ops->cursor_flash = (!blank);
|
||||
|
||||
if (fb_blank(info, blank))
|
||||
if (info->fbops->fb_blank)
|
||||
ret = info->fbops->fb_blank(blank, info);
|
||||
if (ret)
|
||||
fbcon_generic_blank(vc, info, blank);
|
||||
}
|
||||
|
||||
|
|
@ -2518,9 +2511,6 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
|||
c = vc->vc_video_erase_char;
|
||||
vc->vc_video_erase_char =
|
||||
((c & 0xfe00) >> 1) | (c & 0xff);
|
||||
c = vc->vc_scrl_erase_char;
|
||||
vc->vc_scrl_erase_char =
|
||||
((c & 0xFE00) >> 1) | (c & 0xFF);
|
||||
vc->vc_attr >>= 1;
|
||||
}
|
||||
} else if (!vc->vc_hi_font_mask && cnt == 512) {
|
||||
|
|
@ -2551,14 +2541,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
|||
if (vc->vc_can_do_color) {
|
||||
vc->vc_video_erase_char =
|
||||
((c & 0xff00) << 1) | (c & 0xff);
|
||||
c = vc->vc_scrl_erase_char;
|
||||
vc->vc_scrl_erase_char =
|
||||
((c & 0xFF00) << 1) | (c & 0xFF);
|
||||
vc->vc_attr <<= 1;
|
||||
} else {
|
||||
} else
|
||||
vc->vc_video_erase_char = c & ~0x100;
|
||||
vc->vc_scrl_erase_char = c & ~0x100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2992,8 +2977,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
|
|||
p = &fb_display[vc->vc_num];
|
||||
set_blitting_type(vc, info);
|
||||
var_to_display(p, &info->var, info);
|
||||
cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
|
||||
rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
|
||||
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
|
||||
rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
|
||||
cols /= vc->vc_font.width;
|
||||
rows /= vc->vc_font.height;
|
||||
vc_resize(vc, cols, rows);
|
||||
|
|
@ -3588,8 +3573,8 @@ static int __init fb_console_init(void)
|
|||
|
||||
acquire_console_sem();
|
||||
fb_register_client(&fbcon_event_notifier);
|
||||
fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
|
||||
NULL, "fbcon");
|
||||
fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
|
||||
"fbcon");
|
||||
|
||||
if (IS_ERR(fbcon_device)) {
|
||||
printk(KERN_WARNING "Unable to create device "
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ static inline int mono_col(const struct fb_info *info)
|
|||
__u32 max_len;
|
||||
max_len = max(info->var.green.length, info->var.red.length);
|
||||
max_len = max(info->var.blue.length, max_len);
|
||||
return ~(0xfff << (max_len & 0xff));
|
||||
return (~(0xfff << max_len)) & 0xff;
|
||||
}
|
||||
|
||||
static inline int attr_col_ec(int shift, struct vc_data *vc,
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ static void mdacon_cursor(struct vc_data *c, int mode)
|
|||
|
||||
static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
|
||||
{
|
||||
u16 eattr = mda_convert_attr(c->vc_scrl_erase_char);
|
||||
u16 eattr = mda_convert_attr(c->vc_video_erase_char);
|
||||
|
||||
if (!lines)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -170,12 +170,12 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
|
|||
switch (dir) {
|
||||
case SM_UP:
|
||||
sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols);
|
||||
sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_scrl_erase_char);
|
||||
sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char);
|
||||
break;
|
||||
|
||||
case SM_DOWN:
|
||||
sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols);
|
||||
sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_scrl_erase_char);
|
||||
sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,8 +239,7 @@ static void vgacon_restore_screen(struct vc_data *c)
|
|||
|
||||
static int vgacon_scrolldelta(struct vc_data *c, int lines)
|
||||
{
|
||||
int start, end, count, soff, diff;
|
||||
void *d, *s;
|
||||
int start, end, count, soff;
|
||||
|
||||
if (!lines) {
|
||||
c->vc_visible_origin = c->vc_origin;
|
||||
|
|
@ -287,29 +286,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
|
|||
if (count > c->vc_rows)
|
||||
count = c->vc_rows;
|
||||
|
||||
diff = c->vc_rows - count;
|
||||
if (count) {
|
||||
int copysize;
|
||||
|
||||
d = (void *) c->vc_origin;
|
||||
s = (void *) c->vc_screenbuf;
|
||||
int diff = c->vc_rows - count;
|
||||
void *d = (void *) c->vc_origin;
|
||||
void *s = (void *) c->vc_screenbuf;
|
||||
|
||||
while (count--) {
|
||||
scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row);
|
||||
d += c->vc_size_row;
|
||||
soff += c->vc_size_row;
|
||||
count *= c->vc_size_row;
|
||||
/* how much memory to end of buffer left? */
|
||||
copysize = min(count, vgacon_scrollback_size - soff);
|
||||
scr_memcpyw(d, vgacon_scrollback + soff, copysize);
|
||||
d += copysize;
|
||||
count -= copysize;
|
||||
|
||||
if (soff >= vgacon_scrollback_size)
|
||||
soff = 0;
|
||||
}
|
||||
|
||||
if (diff == c->vc_rows) {
|
||||
vgacon_cursor(c, CM_MOVE);
|
||||
} else {
|
||||
while (diff--) {
|
||||
scr_memcpyw(d, s, c->vc_size_row);
|
||||
d += c->vc_size_row;
|
||||
s += c->vc_size_row;
|
||||
if (count) {
|
||||
scr_memcpyw(d, vgacon_scrollback, count);
|
||||
d += count;
|
||||
}
|
||||
}
|
||||
|
||||
if (diff)
|
||||
scr_memcpyw(d, s, diff * c->vc_size_row);
|
||||
} else
|
||||
vgacon_cursor(c, CM_MOVE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1350,7 +1349,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
|
|||
} else
|
||||
c->vc_origin += delta;
|
||||
scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size -
|
||||
delta), c->vc_scrl_erase_char,
|
||||
delta), c->vc_video_erase_char,
|
||||
delta);
|
||||
} else {
|
||||
if (oldo - delta < vga_vram_base) {
|
||||
|
|
@ -1363,7 +1362,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
|
|||
} else
|
||||
c->vc_origin -= delta;
|
||||
c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
|
||||
scr_memsetw((u16 *) (c->vc_origin), c->vc_scrl_erase_char,
|
||||
scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
|
||||
delta);
|
||||
}
|
||||
c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
|
||||
|
|
|
|||
|
|
@ -153,12 +153,9 @@ struct display_device *display_device_register(struct display_driver *driver,
|
|||
mutex_unlock(&allocated_dsp_lock);
|
||||
|
||||
if (!ret) {
|
||||
new_dev->dev = device_create_drvdata(display_class,
|
||||
parent,
|
||||
MKDEV(0,0),
|
||||
new_dev,
|
||||
"display%d",
|
||||
new_dev->idx);
|
||||
new_dev->dev = device_create(display_class, parent,
|
||||
MKDEV(0, 0), new_dev,
|
||||
"display%d", new_dev->idx);
|
||||
if (!IS_ERR(new_dev->dev)) {
|
||||
new_dev->parent = parent;
|
||||
new_dev->driver = driver;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/fb.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <video/vga.h>
|
||||
|
||||
|
|
@ -33,6 +34,105 @@ static struct fb_fix_screeninfo efifb_fix __initdata = {
|
|||
.visual = FB_VISUAL_TRUECOLOR,
|
||||
};
|
||||
|
||||
enum {
|
||||
M_I17, /* 17-Inch iMac */
|
||||
M_I20, /* 20-Inch iMac */
|
||||
M_I20_SR, /* 20-Inch iMac (Santa Rosa) */
|
||||
M_I24, /* 24-Inch iMac */
|
||||
M_MINI, /* Mac Mini */
|
||||
M_MB, /* MacBook */
|
||||
M_MB_2, /* MacBook, 2nd rev. */
|
||||
M_MB_3, /* MacBook, 3rd rev. */
|
||||
M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
|
||||
M_MBA, /* MacBook Air */
|
||||
M_MBP, /* MacBook Pro */
|
||||
M_MBP_2, /* MacBook Pro 2nd gen */
|
||||
M_MBP_SR, /* MacBook Pro (Santa Rosa) */
|
||||
M_MBP_4, /* MacBook Pro, 4th gen */
|
||||
M_UNKNOWN /* placeholder */
|
||||
};
|
||||
|
||||
static struct efifb_dmi_info {
|
||||
char *optname;
|
||||
unsigned long base;
|
||||
int stride;
|
||||
int width;
|
||||
int height;
|
||||
} dmi_list[] = {
|
||||
[M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
|
||||
[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
|
||||
[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
|
||||
[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
|
||||
[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
|
||||
[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
|
||||
[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
|
||||
[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
|
||||
[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
|
||||
[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
|
||||
[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
|
||||
[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static int set_system(const struct dmi_system_id *id);
|
||||
|
||||
#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \
|
||||
{ set_system, name, { \
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, vendor), \
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, name) }, \
|
||||
&dmi_list[enumid] }
|
||||
|
||||
static struct dmi_system_id __initdata dmi_system_table[] = {
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
|
||||
/* At least one of these two will be right; maybe both? */
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20),
|
||||
/* At least one of these two will be right; maybe both? */
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
|
||||
/* At least one of these two will be right; maybe both? */
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB),
|
||||
/* At least one of these two will be right; maybe both? */
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
|
||||
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
|
||||
{},
|
||||
};
|
||||
|
||||
static int set_system(const struct dmi_system_id *id)
|
||||
{
|
||||
struct efifb_dmi_info *info = id->driver_data;
|
||||
if (info->base == 0)
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
|
||||
"(%dx%d, stride %d)\n", id->ident,
|
||||
(void *)info->base, info->width, info->height,
|
||||
info->stride);
|
||||
|
||||
/* Trust the bootloader over the DMI tables */
|
||||
if (screen_info.lfb_base == 0)
|
||||
screen_info.lfb_base = info->base;
|
||||
if (screen_info.lfb_linelength == 0)
|
||||
screen_info.lfb_linelength = info->stride;
|
||||
if (screen_info.lfb_width == 0)
|
||||
screen_info.lfb_width = info->width;
|
||||
if (screen_info.lfb_height == 0)
|
||||
screen_info.lfb_height = info->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
unsigned blue, unsigned transp,
|
||||
struct fb_info *info)
|
||||
|
|
@ -67,6 +167,38 @@ static struct fb_ops efifb_ops = {
|
|||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
static int __init efifb_setup(char *options)
|
||||
{
|
||||
char *this_opt;
|
||||
int i;
|
||||
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||
if (!*this_opt) continue;
|
||||
|
||||
for (i = 0; i < M_UNKNOWN; i++) {
|
||||
if (!strcmp(this_opt, dmi_list[i].optname) &&
|
||||
dmi_list[i].base != 0) {
|
||||
screen_info.lfb_base = dmi_list[i].base;
|
||||
screen_info.lfb_linelength = dmi_list[i].stride;
|
||||
screen_info.lfb_width = dmi_list[i].width;
|
||||
screen_info.lfb_height = dmi_list[i].height;
|
||||
}
|
||||
}
|
||||
if (!strncmp(this_opt, "base:", 5))
|
||||
screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
|
||||
else if (!strncmp(this_opt, "stride:", 7))
|
||||
screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
|
||||
else if (!strncmp(this_opt, "height:", 7))
|
||||
screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
|
||||
else if (!strncmp(this_opt, "width:", 6))
|
||||
screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init efifb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
|
@ -74,6 +206,26 @@ static int __init efifb_probe(struct platform_device *dev)
|
|||
unsigned int size_vmode;
|
||||
unsigned int size_remap;
|
||||
unsigned int size_total;
|
||||
int request_succeeded = 0;
|
||||
|
||||
printk(KERN_INFO "efifb: probing for efifb\n");
|
||||
|
||||
if (!screen_info.lfb_depth)
|
||||
screen_info.lfb_depth = 32;
|
||||
if (!screen_info.pages)
|
||||
screen_info.pages = 1;
|
||||
|
||||
/* just assume they're all unset if any are */
|
||||
if (!screen_info.blue_size) {
|
||||
screen_info.blue_size = 8;
|
||||
screen_info.blue_pos = 0;
|
||||
screen_info.green_size = 8;
|
||||
screen_info.green_pos = 8;
|
||||
screen_info.red_size = 8;
|
||||
screen_info.red_pos = 16;
|
||||
screen_info.rsvd_size = 8;
|
||||
screen_info.rsvd_pos = 24;
|
||||
}
|
||||
|
||||
efifb_fix.smem_start = screen_info.lfb_base;
|
||||
efifb_defined.bits_per_pixel = screen_info.lfb_depth;
|
||||
|
|
@ -98,21 +250,25 @@ static int __init efifb_probe(struct platform_device *dev)
|
|||
* option to simply use size_total as that
|
||||
* wastes plenty of kernel address space. */
|
||||
size_remap = size_vmode * 2;
|
||||
if (size_remap < size_vmode)
|
||||
size_remap = size_vmode;
|
||||
if (size_remap > size_total)
|
||||
size_remap = size_total;
|
||||
if (size_remap % PAGE_SIZE)
|
||||
size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
|
||||
efifb_fix.smem_len = size_remap;
|
||||
|
||||
if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb"))
|
||||
if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
|
||||
request_succeeded = 1;
|
||||
} else {
|
||||
/* We cannot make this fatal. Sometimes this comes from magic
|
||||
spaces our resource handlers simply don't know about */
|
||||
printk(KERN_WARNING
|
||||
"efifb: cannot reserve video memory at 0x%lx\n",
|
||||
efifb_fix.smem_start);
|
||||
}
|
||||
|
||||
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
|
||||
if (!info) {
|
||||
printk(KERN_ERR "efifb: cannot allocate framebuffer\n");
|
||||
err = -ENOMEM;
|
||||
goto err_release_mem;
|
||||
}
|
||||
|
|
@ -125,7 +281,7 @@ static int __init efifb_probe(struct platform_device *dev)
|
|||
"0x%x @ 0x%lx\n",
|
||||
efifb_fix.smem_len, efifb_fix.smem_start);
|
||||
err = -EIO;
|
||||
goto err_unmap;
|
||||
goto err_release_fb;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
|
||||
|
|
@ -178,25 +334,27 @@ static int __init efifb_probe(struct platform_device *dev)
|
|||
info->fix = efifb_fix;
|
||||
info->flags = FBINFO_FLAG_DEFAULT;
|
||||
|
||||
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
|
||||
err = -ENOMEM;
|
||||
if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
|
||||
printk(KERN_ERR "efifb: cannot allocate colormap\n");
|
||||
goto err_unmap;
|
||||
}
|
||||
if (register_framebuffer(info) < 0) {
|
||||
err = -EINVAL;
|
||||
if ((err = register_framebuffer(info)) < 0) {
|
||||
printk(KERN_ERR "efifb: cannot register framebuffer\n");
|
||||
goto err_fb_dealoc;
|
||||
}
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
info->node, info->fix.id);
|
||||
return 0;
|
||||
|
||||
err_fb_dealoc:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err_unmap:
|
||||
iounmap(info->screen_base);
|
||||
err_release_fb:
|
||||
framebuffer_release(info);
|
||||
err_release_mem:
|
||||
release_mem_region(efifb_fix.smem_start, size_total);
|
||||
if (request_succeeded)
|
||||
release_mem_region(efifb_fix.smem_start, size_total);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -214,9 +372,22 @@ static struct platform_device efifb_device = {
|
|||
static int __init efifb_init(void)
|
||||
{
|
||||
int ret;
|
||||
char *option = NULL;
|
||||
|
||||
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||
return -ENODEV;
|
||||
dmi_check_system(dmi_system_table);
|
||||
|
||||
if (fb_get_options("efifb", &option))
|
||||
return -ENODEV;
|
||||
efifb_setup(option);
|
||||
|
||||
/* We don't get linelength from UGA Draw Protocol, only from
|
||||
* EFI Graphics Protocol. So if it's not in DMI, and it's not
|
||||
* passed in from the user, we really can't use the framebuffer.
|
||||
*/
|
||||
if (!screen_info.lfb_linelength)
|
||||
return -ENODEV;
|
||||
|
||||
ret = platform_driver_register(&efifb_driver);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/console.h>
|
||||
#ifdef CONFIG_KMOD
|
||||
#include <linux/kmod.h>
|
||||
#endif
|
||||
#include <linux/err.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/efi.h>
|
||||
|
|
@ -837,13 +835,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
return (cnt) ? cnt : err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KMOD
|
||||
static void try_to_load(int fb)
|
||||
{
|
||||
request_module("fb%d", fb);
|
||||
}
|
||||
#endif /* CONFIG_KMOD */
|
||||
|
||||
int
|
||||
fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
|
||||
{
|
||||
|
|
@ -979,6 +970,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
|
|||
|
||||
info->flags &= ~FBINFO_MISC_USEREVENT;
|
||||
event.info = info;
|
||||
event.data = &mode;
|
||||
fb_notifier_call_chain(evnt, &event);
|
||||
}
|
||||
}
|
||||
|
|
@ -1085,10 +1077,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
|||
return -EINVAL;
|
||||
if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
|
||||
return -EINVAL;
|
||||
#ifdef CONFIG_KMOD
|
||||
if (!registered_fb[con2fb.framebuffer])
|
||||
try_to_load(con2fb.framebuffer);
|
||||
#endif /* CONFIG_KMOD */
|
||||
request_module("fb%d", con2fb.framebuffer);
|
||||
if (!registered_fb[con2fb.framebuffer])
|
||||
return -EINVAL;
|
||||
event.info = info;
|
||||
|
|
@ -1326,10 +1316,8 @@ fb_open(struct inode *inode, struct file *file)
|
|||
if (fbidx >= FB_MAX)
|
||||
return -ENODEV;
|
||||
lock_kernel();
|
||||
#ifdef CONFIG_KMOD
|
||||
if (!(info = registered_fb[fbidx]))
|
||||
try_to_load(fbidx);
|
||||
#endif /* CONFIG_KMOD */
|
||||
request_module("fb%d", fbidx);
|
||||
if (!(info = registered_fb[fbidx])) {
|
||||
res = -ENODEV;
|
||||
goto out;
|
||||
|
|
@ -1442,9 +1430,8 @@ register_framebuffer(struct fb_info *fb_info)
|
|||
break;
|
||||
fb_info->node = i;
|
||||
|
||||
fb_info->dev = device_create_drvdata(fb_class, fb_info->device,
|
||||
MKDEV(FB_MAJOR, i), NULL,
|
||||
"fb%d", i);
|
||||
fb_info->dev = device_create(fb_class, fb_info->device,
|
||||
MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
|
||||
if (IS_ERR(fb_info->dev)) {
|
||||
/* Not fatal */
|
||||
printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
|
||||
|
|
|
|||
|
|
@ -564,7 +564,13 @@ static void get_detailed_timing(unsigned char *block,
|
|||
mode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
|
||||
(V_ACTIVE + V_BLANKING));
|
||||
mode->vmode = 0;
|
||||
if (INTERLACED) {
|
||||
mode->yres *= 2;
|
||||
mode->upper_margin *= 2;
|
||||
mode->lower_margin *= 2;
|
||||
mode->vsync_len *= 2;
|
||||
mode->vmode |= FB_VMODE_INTERLACED;
|
||||
}
|
||||
mode->flag = FB_MODE_IS_DETAILED;
|
||||
|
||||
DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
|
||||
|
|
|
|||
|
|
@ -1042,7 +1042,7 @@ static int __devexit ffb_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id ffb_match[] = {
|
||||
static const struct of_device_id ffb_match[] = {
|
||||
{
|
||||
.name = "SUNW,ffb",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,376 +0,0 @@
|
|||
/*
|
||||
* framebuffer driver for Intel Based Mac's
|
||||
*
|
||||
* (c) 2006 Edgar Hucek <gimli@dark-green.com>
|
||||
* Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/efi.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <video/vga.h>
|
||||
|
||||
typedef enum _MAC_TYPE {
|
||||
M_I17,
|
||||
M_I20,
|
||||
M_MINI,
|
||||
M_MACBOOK,
|
||||
M_UNKNOWN
|
||||
} MAC_TYPE;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct fb_var_screeninfo imacfb_defined __initdata = {
|
||||
.activate = FB_ACTIVATE_NOW,
|
||||
.height = -1,
|
||||
.width = -1,
|
||||
.right_margin = 32,
|
||||
.upper_margin = 16,
|
||||
.lower_margin = 4,
|
||||
.vsync_len = 4,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
};
|
||||
|
||||
static struct fb_fix_screeninfo imacfb_fix __initdata = {
|
||||
.id = "IMAC VGA",
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
.accel = FB_ACCEL_NONE,
|
||||
.visual = FB_VISUAL_TRUECOLOR,
|
||||
};
|
||||
|
||||
static int inverse;
|
||||
static int model = M_UNKNOWN;
|
||||
static int manual_height;
|
||||
static int manual_width;
|
||||
|
||||
static int set_system(const struct dmi_system_id *id)
|
||||
{
|
||||
printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
|
||||
id->ident, (long)id->driver_data);
|
||||
|
||||
model = (long)id->driver_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dmi_system_id __initdata dmi_system_table[] = {
|
||||
{ set_system, "iMac4,1", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
|
||||
{ set_system, "MacBookPro1,1", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
|
||||
{ set_system, "MacBook1,1", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
|
||||
{ set_system, "Macmini1,1", {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
|
||||
{},
|
||||
};
|
||||
|
||||
#define DEFAULT_FB_MEM 1024*1024*16
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
unsigned blue, unsigned transp,
|
||||
struct fb_info *info)
|
||||
{
|
||||
/*
|
||||
* Set a single color register. The values supplied are
|
||||
* already rounded down to the hardware's capabilities
|
||||
* (according to the entries in the `var' structure). Return
|
||||
* != 0 for invalid regno.
|
||||
*/
|
||||
|
||||
if (regno >= info->cmap.len)
|
||||
return 1;
|
||||
|
||||
if (regno < 16) {
|
||||
red >>= 8;
|
||||
green >>= 8;
|
||||
blue >>= 8;
|
||||
((u32 *)(info->pseudo_palette))[regno] =
|
||||
(red << info->var.red.offset) |
|
||||
(green << info->var.green.offset) |
|
||||
(blue << info->var.blue.offset);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops imacfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = imacfb_setcolreg,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
static int __init imacfb_setup(char *options)
|
||||
{
|
||||
char *this_opt;
|
||||
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||
if (!*this_opt) continue;
|
||||
|
||||
if (!strcmp(this_opt, "inverse"))
|
||||
inverse = 1;
|
||||
else if (!strcmp(this_opt, "i17"))
|
||||
model = M_I17;
|
||||
else if (!strcmp(this_opt, "i20"))
|
||||
model = M_I20;
|
||||
else if (!strcmp(this_opt, "mini"))
|
||||
model = M_MINI;
|
||||
else if (!strcmp(this_opt, "macbook"))
|
||||
model = M_MACBOOK;
|
||||
else if (!strncmp(this_opt, "height:", 7))
|
||||
manual_height = simple_strtoul(this_opt+7, NULL, 0);
|
||||
else if (!strncmp(this_opt, "width:", 6))
|
||||
manual_width = simple_strtoul(this_opt+6, NULL, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init imacfb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int err;
|
||||
unsigned int size_vmode;
|
||||
unsigned int size_remap;
|
||||
unsigned int size_total;
|
||||
|
||||
screen_info.lfb_depth = 32;
|
||||
screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
|
||||
screen_info.pages=1;
|
||||
screen_info.blue_size = 8;
|
||||
screen_info.blue_pos = 0;
|
||||
screen_info.green_size = 8;
|
||||
screen_info.green_pos = 8;
|
||||
screen_info.red_size = 8;
|
||||
screen_info.red_pos = 16;
|
||||
screen_info.rsvd_size = 8;
|
||||
screen_info.rsvd_pos = 24;
|
||||
|
||||
switch (model) {
|
||||
case M_I17:
|
||||
screen_info.lfb_width = 1440;
|
||||
screen_info.lfb_height = 900;
|
||||
screen_info.lfb_linelength = 1472 * 4;
|
||||
screen_info.lfb_base = 0x80010000;
|
||||
break;
|
||||
case M_I20:
|
||||
screen_info.lfb_width = 1680;
|
||||
screen_info.lfb_height = 1050;
|
||||
screen_info.lfb_linelength = 1728 * 4;
|
||||
screen_info.lfb_base = 0x80010000;
|
||||
break;
|
||||
case M_MINI:
|
||||
screen_info.lfb_width = 1024;
|
||||
screen_info.lfb_height = 768;
|
||||
screen_info.lfb_linelength = 2048 * 4;
|
||||
screen_info.lfb_base = 0x80000000;
|
||||
break;
|
||||
case M_MACBOOK:
|
||||
screen_info.lfb_width = 1280;
|
||||
screen_info.lfb_height = 800;
|
||||
screen_info.lfb_linelength = 2048 * 4;
|
||||
screen_info.lfb_base = 0x80000000;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if the user wants to manually specify height/width,
|
||||
we will override the defaults */
|
||||
/* TODO: eventually get auto-detection working */
|
||||
if (manual_height > 0)
|
||||
screen_info.lfb_height = manual_height;
|
||||
if (manual_width > 0)
|
||||
screen_info.lfb_width = manual_width;
|
||||
|
||||
imacfb_fix.smem_start = screen_info.lfb_base;
|
||||
imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
|
||||
imacfb_defined.xres = screen_info.lfb_width;
|
||||
imacfb_defined.yres = screen_info.lfb_height;
|
||||
imacfb_fix.line_length = screen_info.lfb_linelength;
|
||||
|
||||
/* size_vmode -- that is the amount of memory needed for the
|
||||
* used video mode, i.e. the minimum amount of
|
||||
* memory we need. */
|
||||
size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
|
||||
|
||||
/* size_total -- all video memory we have. Used for
|
||||
* entries, ressource allocation and bounds
|
||||
* checking. */
|
||||
size_total = screen_info.lfb_size * 65536;
|
||||
if (size_total < size_vmode)
|
||||
size_total = size_vmode;
|
||||
|
||||
/* size_remap -- the amount of video memory we are going to
|
||||
* use for imacfb. With modern cards it is no
|
||||
* option to simply use size_total as that
|
||||
* wastes plenty of kernel address space. */
|
||||
size_remap = size_vmode * 2;
|
||||
if (size_remap < size_vmode)
|
||||
size_remap = size_vmode;
|
||||
if (size_remap > size_total)
|
||||
size_remap = size_total;
|
||||
imacfb_fix.smem_len = size_remap;
|
||||
|
||||
if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
|
||||
printk(KERN_WARNING
|
||||
"imacfb: cannot reserve video memory at 0x%lx\n",
|
||||
imacfb_fix.smem_start);
|
||||
/* We cannot make this fatal. Sometimes this comes from magic
|
||||
spaces our resource handlers simply don't know about */
|
||||
}
|
||||
|
||||
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
|
||||
if (!info) {
|
||||
err = -ENOMEM;
|
||||
goto err_release_mem;
|
||||
}
|
||||
info->pseudo_palette = info->par;
|
||||
info->par = NULL;
|
||||
|
||||
info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
|
||||
"0x%x @ 0x%lx\n",
|
||||
imacfb_fix.smem_len, imacfb_fix.smem_start);
|
||||
err = -EIO;
|
||||
goto err_unmap;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
|
||||
"using %dk, total %dk\n",
|
||||
imacfb_fix.smem_start, info->screen_base,
|
||||
size_remap/1024, size_total/1024);
|
||||
printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
|
||||
imacfb_defined.xres, imacfb_defined.yres,
|
||||
imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
|
||||
screen_info.pages);
|
||||
|
||||
imacfb_defined.xres_virtual = imacfb_defined.xres;
|
||||
imacfb_defined.yres_virtual = imacfb_fix.smem_len /
|
||||
imacfb_fix.line_length;
|
||||
printk(KERN_INFO "imacfb: scrolling: redraw\n");
|
||||
imacfb_defined.yres_virtual = imacfb_defined.yres;
|
||||
|
||||
/* some dummy values for timing to make fbset happy */
|
||||
imacfb_defined.pixclock = 10000000 / imacfb_defined.xres *
|
||||
1000 / imacfb_defined.yres;
|
||||
imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8;
|
||||
imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8;
|
||||
|
||||
imacfb_defined.red.offset = screen_info.red_pos;
|
||||
imacfb_defined.red.length = screen_info.red_size;
|
||||
imacfb_defined.green.offset = screen_info.green_pos;
|
||||
imacfb_defined.green.length = screen_info.green_size;
|
||||
imacfb_defined.blue.offset = screen_info.blue_pos;
|
||||
imacfb_defined.blue.length = screen_info.blue_size;
|
||||
imacfb_defined.transp.offset = screen_info.rsvd_pos;
|
||||
imacfb_defined.transp.length = screen_info.rsvd_size;
|
||||
|
||||
printk(KERN_INFO "imacfb: %s: "
|
||||
"size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
|
||||
"Truecolor",
|
||||
screen_info.rsvd_size,
|
||||
screen_info.red_size,
|
||||
screen_info.green_size,
|
||||
screen_info.blue_size,
|
||||
screen_info.rsvd_pos,
|
||||
screen_info.red_pos,
|
||||
screen_info.green_pos,
|
||||
screen_info.blue_pos);
|
||||
|
||||
imacfb_fix.ypanstep = 0;
|
||||
imacfb_fix.ywrapstep = 0;
|
||||
|
||||
/* request failure does not faze us, as vgacon probably has this
|
||||
* region already (FIXME) */
|
||||
request_region(0x3c0, 32, "imacfb");
|
||||
|
||||
info->fbops = &imacfb_ops;
|
||||
info->var = imacfb_defined;
|
||||
info->fix = imacfb_fix;
|
||||
info->flags = FBINFO_FLAG_DEFAULT;
|
||||
|
||||
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
|
||||
err = -ENOMEM;
|
||||
goto err_unmap;
|
||||
}
|
||||
if (register_framebuffer(info)<0) {
|
||||
err = -EINVAL;
|
||||
goto err_fb_dealoc;
|
||||
}
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
info->node, info->fix.id);
|
||||
return 0;
|
||||
|
||||
err_fb_dealoc:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err_unmap:
|
||||
iounmap(info->screen_base);
|
||||
framebuffer_release(info);
|
||||
err_release_mem:
|
||||
release_mem_region(imacfb_fix.smem_start, size_total);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver imacfb_driver = {
|
||||
.probe = imacfb_probe,
|
||||
.driver = {
|
||||
.name = "imacfb",
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device imacfb_device = {
|
||||
.name = "imacfb",
|
||||
};
|
||||
|
||||
static int __init imacfb_init(void)
|
||||
{
|
||||
int ret;
|
||||
char *option = NULL;
|
||||
|
||||
if (!efi_enabled)
|
||||
return -ENODEV;
|
||||
if (!dmi_check_system(dmi_system_table))
|
||||
return -ENODEV;
|
||||
if (model == M_UNKNOWN)
|
||||
return -ENODEV;
|
||||
|
||||
if (fb_get_options("imacfb", &option))
|
||||
return -ENODEV;
|
||||
|
||||
imacfb_setup(option);
|
||||
ret = platform_driver_register(&imacfb_driver);
|
||||
|
||||
if (!ret) {
|
||||
ret = platform_device_register(&imacfb_device);
|
||||
if (ret)
|
||||
platform_driver_unregister(&imacfb_driver);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
module_init(imacfb_init);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -12,9 +12,9 @@
|
|||
#endif
|
||||
|
||||
/*** Version/name ***/
|
||||
#define INTELFB_VERSION "0.9.5"
|
||||
#define INTELFB_VERSION "0.9.6"
|
||||
#define INTELFB_MODULE_NAME "intelfb"
|
||||
#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
|
||||
#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
|
||||
|
||||
|
||||
/*** Debug/feature defines ***/
|
||||
|
|
@ -58,6 +58,7 @@
|
|||
#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
|
||||
|
||||
|
|
@ -160,6 +161,7 @@ enum intel_chips {
|
|||
INTEL_915GM,
|
||||
INTEL_945G,
|
||||
INTEL_945GM,
|
||||
INTEL_945GME,
|
||||
INTEL_965G,
|
||||
INTEL_965GM,
|
||||
};
|
||||
|
|
@ -363,6 +365,7 @@ struct intelfb_info {
|
|||
((dinfo)->chipset == INTEL_915GM) || \
|
||||
((dinfo)->chipset == INTEL_945G) || \
|
||||
((dinfo)->chipset == INTEL_945GM) || \
|
||||
((dinfo)->chipset == INTEL_945GME) || \
|
||||
((dinfo)->chipset == INTEL_965G) || \
|
||||
((dinfo)->chipset == INTEL_965GM))
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
|
|||
/* 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 */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* intelfb
|
||||
*
|
||||
* Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
|
||||
* 945G/945GM/965G/965GM integrated graphics chips.
|
||||
* 945G/945GM/945GME/965G/965GM integrated graphics chips.
|
||||
*
|
||||
* Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
|
||||
* 2004 Sylvain Meyer
|
||||
|
|
@ -102,6 +102,9 @@
|
|||
*
|
||||
* 04/2008 - Version 0.9.5
|
||||
* Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
|
||||
*
|
||||
* 08/2008 - Version 0.9.6
|
||||
* Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
|
|||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
|
||||
{ 0, }
|
||||
|
|
@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
|
|||
(ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
|
||||
(ent->device == PCI_DEVICE_ID_INTEL_945G) ||
|
||||
(ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
|
||||
(ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
|
||||
(ent->device == PCI_DEVICE_ID_INTEL_965G) ||
|
||||
(ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
|
|||
dinfo->mobile = 1;
|
||||
dinfo->pll_index = PLLS_I9xx;
|
||||
return 0;
|
||||
case PCI_DEVICE_ID_INTEL_945GME:
|
||||
dinfo->name = "Intel(R) 945GME";
|
||||
dinfo->chipset = INTEL_945GME;
|
||||
dinfo->mobile = 1;
|
||||
dinfo->pll_index = PLLS_I9xx;
|
||||
return 0;
|
||||
case PCI_DEVICE_ID_INTEL_965G:
|
||||
dinfo->name = "Intel(R) 965G";
|
||||
dinfo->chipset = INTEL_965G;
|
||||
|
|
@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
|
|||
case PCI_DEVICE_ID_INTEL_915GM:
|
||||
case PCI_DEVICE_ID_INTEL_945G:
|
||||
case PCI_DEVICE_ID_INTEL_945GM:
|
||||
case PCI_DEVICE_ID_INTEL_945GME:
|
||||
case PCI_DEVICE_ID_INTEL_965G:
|
||||
case PCI_DEVICE_ID_INTEL_965GM:
|
||||
/* 915, 945 and 965 chipsets support a 256MB aperture.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ static int leo_blank(int, struct fb_info *);
|
|||
|
||||
static int leo_mmap(struct fb_info *, struct vm_area_struct *);
|
||||
static int leo_ioctl(struct fb_info *, unsigned int, unsigned long);
|
||||
static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *);
|
||||
|
||||
/*
|
||||
* Frame buffer operations
|
||||
|
|
@ -42,6 +43,7 @@ static struct fb_ops leo_ops = {
|
|||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = leo_setcolreg,
|
||||
.fb_blank = leo_blank,
|
||||
.fb_pan_display = leo_pan_display,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
|
|
@ -206,6 +208,60 @@ static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
|
|||
return;
|
||||
}
|
||||
|
||||
static void leo_switch_from_graph(struct fb_info *info)
|
||||
{
|
||||
struct leo_par *par = (struct leo_par *) info->par;
|
||||
struct leo_ld_ss0 __iomem *ss = par->ld_ss0;
|
||||
struct leo_cursor __iomem *cursor = par->cursor;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&par->lock, flags);
|
||||
|
||||
par->extent = ((info->var.xres - 1) |
|
||||
((info->var.yres - 1) << 16));
|
||||
|
||||
sbus_writel(0xffffffff, &ss->wid);
|
||||
sbus_writel(0xffff, &ss->wmask);
|
||||
sbus_writel(0, &ss->vclipmin);
|
||||
sbus_writel(par->extent, &ss->vclipmax);
|
||||
sbus_writel(0, &ss->fg);
|
||||
sbus_writel(0xff000000, &ss->planemask);
|
||||
sbus_writel(0x310850, &ss->rop);
|
||||
sbus_writel(0, &ss->widclip);
|
||||
sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11),
|
||||
&par->lc_ss0_usr->extent);
|
||||
sbus_writel(4, &par->lc_ss0_usr->addrspace);
|
||||
sbus_writel(0x80000000, &par->lc_ss0_usr->fill);
|
||||
sbus_writel(0, &par->lc_ss0_usr->fontt);
|
||||
do {
|
||||
val = sbus_readl(&par->lc_ss0_usr->csr);
|
||||
} while (val & 0x20000000);
|
||||
|
||||
/* setup screen buffer for cfb_* functions */
|
||||
sbus_writel(1, &ss->wid);
|
||||
sbus_writel(0x00ffffff, &ss->planemask);
|
||||
sbus_writel(0x310b90, &ss->rop);
|
||||
sbus_writel(0, &par->lc_ss0_usr->addrspace);
|
||||
|
||||
/* hide cursor */
|
||||
sbus_writel(sbus_readl(&cursor->cur_misc) & ~LEO_CUR_ENABLE, &cursor->cur_misc);
|
||||
|
||||
spin_unlock_irqrestore(&par->lock, flags);
|
||||
}
|
||||
|
||||
static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
/* We just use this to catch switches out of
|
||||
* graphics mode.
|
||||
*/
|
||||
leo_switch_from_graph(info);
|
||||
|
||||
if (var->xoffset || var->yoffset || var->vmode)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* leo_setcolreg - Optional function. Sets a color register.
|
||||
* @regno: boolean, 0 copy local, 1 get_user() function
|
||||
|
|
@ -454,44 +510,6 @@ static void leo_init_wids(struct fb_info *info)
|
|||
leo_wid_put(info, &wl);
|
||||
}
|
||||
|
||||
static void leo_switch_from_graph(struct fb_info *info)
|
||||
{
|
||||
struct leo_par *par = (struct leo_par *) info->par;
|
||||
struct leo_ld_ss0 __iomem *ss = par->ld_ss0;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&par->lock, flags);
|
||||
|
||||
par->extent = ((info->var.xres - 1) |
|
||||
((info->var.yres - 1) << 16));
|
||||
|
||||
sbus_writel(0xffffffff, &ss->wid);
|
||||
sbus_writel(0xffff, &ss->wmask);
|
||||
sbus_writel(0, &ss->vclipmin);
|
||||
sbus_writel(par->extent, &ss->vclipmax);
|
||||
sbus_writel(0, &ss->fg);
|
||||
sbus_writel(0xff000000, &ss->planemask);
|
||||
sbus_writel(0x310850, &ss->rop);
|
||||
sbus_writel(0, &ss->widclip);
|
||||
sbus_writel((info->var.xres-1) | ((info->var.yres-1) << 11),
|
||||
&par->lc_ss0_usr->extent);
|
||||
sbus_writel(4, &par->lc_ss0_usr->addrspace);
|
||||
sbus_writel(0x80000000, &par->lc_ss0_usr->fill);
|
||||
sbus_writel(0, &par->lc_ss0_usr->fontt);
|
||||
do {
|
||||
val = sbus_readl(&par->lc_ss0_usr->csr);
|
||||
} while (val & 0x20000000);
|
||||
|
||||
/* setup screen buffer for cfb_* functions */
|
||||
sbus_writel(1, &ss->wid);
|
||||
sbus_writel(0x00ffffff, &ss->planemask);
|
||||
sbus_writel(0x310b90, &ss->rop);
|
||||
sbus_writel(0, &par->lc_ss0_usr->addrspace);
|
||||
|
||||
spin_unlock_irqrestore(&par->lock, flags);
|
||||
}
|
||||
|
||||
static void leo_init_hw(struct fb_info *info)
|
||||
{
|
||||
struct leo_par *par = (struct leo_par *) info->par;
|
||||
|
|
@ -641,7 +659,7 @@ static int __devexit leo_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id leo_match[] = {
|
||||
static const struct of_device_id leo_match[] = {
|
||||
{
|
||||
.name = "SUNW,leo",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1453,6 +1453,13 @@ static struct board {
|
|||
MGA_G100,
|
||||
&vbG100,
|
||||
"MGA-G100 (AGP)"},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF,
|
||||
0, 0,
|
||||
DEVF_G200,
|
||||
230000,
|
||||
MGA_G200,
|
||||
&vbG200,
|
||||
"MGA-G200eV (PCI)"},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
|
||||
0, 0,
|
||||
DEVF_G200,
|
||||
|
|
@ -2118,6 +2125,8 @@ static struct pci_device_id matroxfb_devices[] = {
|
|||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
|
||||
|
|
|
|||
|
|
@ -40,29 +40,63 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
||||
#define DEBUG 1
|
||||
#ifdef DEBUG
|
||||
#define DPRINTK(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
|
||||
#else
|
||||
#define DPRINTK(f, a...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Display specific information */
|
||||
#define DPY_W 832
|
||||
#define DPY_H 622
|
||||
|
||||
static int user_wfm_size;
|
||||
|
||||
/* frame differs from image. frame includes non-visible pixels */
|
||||
struct epd_frame {
|
||||
int fw; /* frame width */
|
||||
int fh; /* frame height */
|
||||
u16 config[4];
|
||||
int wfm_size;
|
||||
};
|
||||
|
||||
static struct epd_frame epd_frame_table[] = {
|
||||
{
|
||||
.fw = 832,
|
||||
.fh = 622
|
||||
.fw = 832,
|
||||
.fh = 622,
|
||||
.config = {
|
||||
15 /* sdlew */
|
||||
| 2 << 8 /* sdosz */
|
||||
| 0 << 11 /* sdor */
|
||||
| 0 << 12 /* sdces */
|
||||
| 0 << 15, /* sdcer */
|
||||
42 /* gdspl */
|
||||
| 1 << 8 /* gdr1 */
|
||||
| 1 << 9 /* sdshr */
|
||||
| 0 << 15, /* gdspp */
|
||||
18 /* gdspw */
|
||||
| 0 << 15, /* dispc */
|
||||
599 /* vdlc */
|
||||
| 0 << 11 /* dsi */
|
||||
| 0 << 12, /* dsic */
|
||||
},
|
||||
.wfm_size = 47001,
|
||||
},
|
||||
{
|
||||
.fw = 1088,
|
||||
.fh = 791,
|
||||
.config = {
|
||||
0x0104,
|
||||
0x031f,
|
||||
0x0088,
|
||||
0x02ff,
|
||||
},
|
||||
.wfm_size = 46770,
|
||||
},
|
||||
{
|
||||
.fw = 1200,
|
||||
.fh = 842,
|
||||
.config = {
|
||||
0x0101,
|
||||
0x030e,
|
||||
0x0012,
|
||||
0x0280,
|
||||
},
|
||||
.wfm_size = 46770,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -134,9 +168,8 @@ static u16 calc_img_cksum(u16 *start, int length)
|
|||
}
|
||||
|
||||
/* here we decode the incoming waveform file and populate metromem */
|
||||
#define EXP_WFORM_SIZE 47001
|
||||
static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
||||
u8 *frame_count)
|
||||
static int __devinit load_waveform(u8 *mem, size_t size, int m, int t,
|
||||
struct metronomefb_par *par)
|
||||
{
|
||||
int tta;
|
||||
int wmta;
|
||||
|
|
@ -148,26 +181,31 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
int wfm_idx, owfm_idx;
|
||||
int mem_idx = 0;
|
||||
struct waveform_hdr *wfm_hdr;
|
||||
u8 *metromem = par->metromem_wfm;
|
||||
struct device *dev = par->info->dev;
|
||||
|
||||
if (size != EXP_WFORM_SIZE) {
|
||||
printk(KERN_ERR "Error: unexpected size %d != %d\n", size,
|
||||
EXP_WFORM_SIZE);
|
||||
if (user_wfm_size)
|
||||
epd_frame_table[par->dt].wfm_size = user_wfm_size;
|
||||
|
||||
if (size != epd_frame_table[par->dt].wfm_size) {
|
||||
dev_err(dev, "Error: unexpected size %Zd != %d\n", size,
|
||||
epd_frame_table[par->dt].wfm_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wfm_hdr = (struct waveform_hdr *) mem;
|
||||
|
||||
if (wfm_hdr->fvsn != 1) {
|
||||
printk(KERN_ERR "Error: bad fvsn %x\n", wfm_hdr->fvsn);
|
||||
dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (wfm_hdr->luts != 0) {
|
||||
printk(KERN_ERR "Error: bad luts %x\n", wfm_hdr->luts);
|
||||
dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts);
|
||||
return -EINVAL;
|
||||
}
|
||||
cksum = calc_cksum(32, 47, mem);
|
||||
if (cksum != wfm_hdr->wfm_cs) {
|
||||
printk(KERN_ERR "Error: bad cksum %x != %x\n", cksum,
|
||||
dev_err(dev, "Error: bad cksum %x != %x\n", cksum,
|
||||
wfm_hdr->wfm_cs);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -175,7 +213,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
wfm_hdr->trc += 1;
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (*(wfm_hdr->stuff2a + i) != 0) {
|
||||
printk(KERN_ERR "Error: unexpected value in padding\n");
|
||||
dev_err(dev, "Error: unexpected value in padding\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -200,7 +238,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
return -EINVAL;
|
||||
cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
|
||||
if (cksum != mem[cksum_idx]) {
|
||||
printk(KERN_ERR "Error: bad temperature range table cksum"
|
||||
dev_err(dev, "Error: bad temperature range table cksum"
|
||||
" %x != %x\n", cksum, mem[cksum_idx]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -212,7 +250,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
return -EINVAL;
|
||||
cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
|
||||
if (cksum != mem[cksum_idx]) {
|
||||
printk(KERN_ERR "Error: bad mode table address cksum"
|
||||
dev_err(dev, "Error: bad mode table address cksum"
|
||||
" %x != %x\n", cksum, mem[cksum_idx]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -224,7 +262,7 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
return -EINVAL;
|
||||
cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
|
||||
if (cksum != mem[cksum_idx]) {
|
||||
printk(KERN_ERR "Error: bad temperature table address cksum"
|
||||
dev_err(dev, "Error: bad temperature table address cksum"
|
||||
" %x != %x\n", cksum, mem[cksum_idx]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -259,11 +297,11 @@ static int load_waveform(u8 *mem, size_t size, u8 *metromem, int m, int t,
|
|||
return -EINVAL;
|
||||
cksum = calc_cksum(owfm_idx, cksum_idx, mem);
|
||||
if (cksum != mem[cksum_idx]) {
|
||||
printk(KERN_ERR "Error: bad waveform data cksum"
|
||||
dev_err(dev, "Error: bad waveform data cksum"
|
||||
" %x != %x\n", cksum, mem[cksum_idx]);
|
||||
return -EINVAL;
|
||||
}
|
||||
*frame_count = (mem_idx/64);
|
||||
par->frame_count = (mem_idx/64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -274,15 +312,12 @@ static int metronome_display_cmd(struct metronomefb_par *par)
|
|||
u16 cs;
|
||||
u16 opcode;
|
||||
static u8 borderval;
|
||||
u8 *ptr;
|
||||
|
||||
/* setup display command
|
||||
we can't immediately set the opcode since the controller
|
||||
will try parse the command before we've set it all up
|
||||
so we just set cs here and set the opcode at the end */
|
||||
|
||||
ptr = par->metromem;
|
||||
|
||||
if (par->metromem_cmd->opcode == 0xCC40)
|
||||
opcode = cs = 0xCC41;
|
||||
else
|
||||
|
|
@ -335,44 +370,17 @@ static int __devinit metronome_powerup_cmd(struct metronomefb_par *par)
|
|||
|
||||
static int __devinit metronome_config_cmd(struct metronomefb_par *par)
|
||||
{
|
||||
int i;
|
||||
u16 cs;
|
||||
|
||||
/* setup config command
|
||||
we can't immediately set the opcode since the controller
|
||||
will try parse the command before we've set it all up
|
||||
so we just set cs here and set the opcode at the end */
|
||||
|
||||
cs = 0xCC10;
|
||||
|
||||
/* set the 12 args ( 8 bytes ) for config. see spec for meanings */
|
||||
i = 0;
|
||||
par->metromem_cmd->args[i] = 15 /* sdlew */
|
||||
| 2 << 8 /* sdosz */
|
||||
| 0 << 11 /* sdor */
|
||||
| 0 << 12 /* sdces */
|
||||
| 0 << 15; /* sdcer */
|
||||
cs += par->metromem_cmd->args[i++];
|
||||
|
||||
par->metromem_cmd->args[i] = 42 /* gdspl */
|
||||
| 1 << 8 /* gdr1 */
|
||||
| 1 << 9 /* sdshr */
|
||||
| 0 << 15; /* gdspp */
|
||||
cs += par->metromem_cmd->args[i++];
|
||||
|
||||
par->metromem_cmd->args[i] = 18 /* gdspw */
|
||||
| 0 << 15; /* dispc */
|
||||
cs += par->metromem_cmd->args[i++];
|
||||
|
||||
par->metromem_cmd->args[i] = 599 /* vdlc */
|
||||
| 0 << 11 /* dsi */
|
||||
| 0 << 12; /* dsic */
|
||||
cs += par->metromem_cmd->args[i++];
|
||||
will try parse the command before we've set it all up */
|
||||
|
||||
memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config,
|
||||
sizeof(epd_frame_table[par->dt].config));
|
||||
/* the rest are 0 */
|
||||
memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
|
||||
memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
|
||||
|
||||
par->metromem_cmd->csum = cs;
|
||||
par->metromem_cmd->csum = 0xCC10;
|
||||
par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4);
|
||||
par->metromem_cmd->opcode = 0xCC10; /* config cmd */
|
||||
|
||||
return par->board->met_wait_event(par);
|
||||
|
|
@ -408,12 +416,9 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par)
|
|||
{
|
||||
int res;
|
||||
|
||||
par->board->init_gpio_regs(par);
|
||||
|
||||
par->board->init_lcdc_regs(par);
|
||||
|
||||
/* now that lcd is setup, setup dma descriptor */
|
||||
par->board->post_dma_setup(par);
|
||||
res = par->board->setup_io(par);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = metronome_powerup_cmd(par);
|
||||
if (res)
|
||||
|
|
@ -430,16 +435,16 @@ static int __devinit metronome_init_regs(struct metronomefb_par *par)
|
|||
|
||||
static void metronomefb_dpy_update(struct metronomefb_par *par)
|
||||
{
|
||||
int fbsize;
|
||||
u16 cksum;
|
||||
unsigned char *buf = (unsigned char __force *)par->info->screen_base;
|
||||
|
||||
fbsize = par->info->fix.smem_len;
|
||||
/* copy from vm to metromem */
|
||||
memcpy(par->metromem_img, buf, DPY_W*DPY_H);
|
||||
memcpy(par->metromem_img, buf, fbsize);
|
||||
|
||||
cksum = calc_img_cksum((u16 *) par->metromem_img,
|
||||
(epd_frame_table[0].fw * DPY_H)/2);
|
||||
*((u16 *)(par->metromem_img) +
|
||||
(epd_frame_table[0].fw * DPY_H)/2) = cksum;
|
||||
cksum = calc_img_cksum((u16 *) par->metromem_img, fbsize/2);
|
||||
*((u16 *)(par->metromem_img) + fbsize/2) = cksum;
|
||||
metronome_display_cmd(par);
|
||||
}
|
||||
|
||||
|
|
@ -574,8 +579,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
|||
unsigned char *videomemory;
|
||||
struct metronomefb_par *par;
|
||||
const struct firmware *fw_entry;
|
||||
int cmd_size, wfm_size, img_size, padding_size, totalsize;
|
||||
int i;
|
||||
int panel_type;
|
||||
int fw, fh;
|
||||
int epd_dt_index;
|
||||
|
||||
/* pick up board specific routines */
|
||||
board = dev->dev.platform_data;
|
||||
|
|
@ -586,96 +593,108 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
|||
if (!try_module_get(board->owner))
|
||||
return -ENODEV;
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
|
||||
if (!info)
|
||||
goto err;
|
||||
|
||||
/* we have two blocks of memory.
|
||||
info->screen_base which is vm, and is the fb used by apps.
|
||||
par->metromem which is physically contiguous memory and
|
||||
contains the display controller commands, waveform,
|
||||
processed image data and padding. this is the data pulled
|
||||
by the device's LCD controller and pushed to Metronome */
|
||||
by the device's LCD controller and pushed to Metronome.
|
||||
the metromem memory is allocated by the board driver and
|
||||
is provided to us */
|
||||
|
||||
videomemorysize = (DPY_W*DPY_H);
|
||||
panel_type = board->get_panel_type();
|
||||
switch (panel_type) {
|
||||
case 6:
|
||||
epd_dt_index = 0;
|
||||
break;
|
||||
case 8:
|
||||
epd_dt_index = 1;
|
||||
break;
|
||||
case 97:
|
||||
epd_dt_index = 2;
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n");
|
||||
epd_dt_index = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
fw = epd_frame_table[epd_dt_index].fw;
|
||||
fh = epd_frame_table[epd_dt_index].fh;
|
||||
|
||||
/* we need to add a spare page because our csum caching scheme walks
|
||||
* to the end of the page */
|
||||
videomemorysize = PAGE_SIZE + (fw * fh);
|
||||
videomemory = vmalloc(videomemorysize);
|
||||
if (!videomemory)
|
||||
return -ENOMEM;
|
||||
goto err_fb_rel;
|
||||
|
||||
memset(videomemory, 0, videomemorysize);
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev);
|
||||
if (!info)
|
||||
goto err_vfree;
|
||||
|
||||
info->screen_base = (char __force __iomem *)videomemory;
|
||||
info->fbops = &metronomefb_ops;
|
||||
|
||||
metronomefb_fix.line_length = fw;
|
||||
metronomefb_var.xres = fw;
|
||||
metronomefb_var.yres = fh;
|
||||
metronomefb_var.xres_virtual = fw;
|
||||
metronomefb_var.yres_virtual = fh;
|
||||
info->var = metronomefb_var;
|
||||
info->fix = metronomefb_fix;
|
||||
info->fix.smem_len = videomemorysize;
|
||||
par = info->par;
|
||||
par->info = info;
|
||||
par->board = board;
|
||||
par->dt = epd_dt_index;
|
||||
init_waitqueue_head(&par->waitq);
|
||||
|
||||
/* this table caches per page csum values. */
|
||||
par->csum_table = vmalloc(videomemorysize/PAGE_SIZE);
|
||||
if (!par->csum_table)
|
||||
goto err_csum_table;
|
||||
|
||||
/* the metromem buffer is divided as follows:
|
||||
command | CRC | padding
|
||||
16kb waveform data | CRC | padding
|
||||
image data | CRC
|
||||
and an extra 256 bytes for dma descriptors
|
||||
eg: IW=832 IH=622 WS=128
|
||||
*/
|
||||
|
||||
cmd_size = 1 * epd_frame_table[0].fw;
|
||||
wfm_size = ((16*1024 + 2 + epd_frame_table[0].fw - 1)
|
||||
/ epd_frame_table[0].fw) * epd_frame_table[0].fw;
|
||||
img_size = epd_frame_table[0].fh * epd_frame_table[0].fw;
|
||||
padding_size = 4 * epd_frame_table[0].fw;
|
||||
totalsize = cmd_size + wfm_size + img_size + padding_size;
|
||||
par->metromemsize = PAGE_ALIGN(totalsize + 256);
|
||||
DPRINTK("desired memory size = %d\n", par->metromemsize);
|
||||
dev->dev.coherent_dma_mask = 0xffffffffull;
|
||||
par->metromem = dma_alloc_writecombine(&dev->dev, par->metromemsize,
|
||||
&par->metromem_dma, GFP_KERNEL);
|
||||
if (!par->metromem) {
|
||||
printk(KERN_ERR
|
||||
"metronomefb: unable to allocate dma buffer\n");
|
||||
goto err_vfree;
|
||||
|
||||
/* the physical framebuffer that we use is setup by
|
||||
* the platform device driver. It will provide us
|
||||
* with cmd, wfm and image memory in a contiguous area. */
|
||||
retval = board->setup_fb(par);
|
||||
if (retval) {
|
||||
dev_err(&dev->dev, "Failed to setup fb\n");
|
||||
goto err_csum_table;
|
||||
}
|
||||
|
||||
/* after this point we should have a framebuffer */
|
||||
if ((!par->metromem_wfm) || (!par->metromem_img) ||
|
||||
(!par->metromem_dma)) {
|
||||
dev_err(&dev->dev, "fb access failure\n");
|
||||
retval = -EINVAL;
|
||||
goto err_csum_table;
|
||||
}
|
||||
|
||||
info->fix.smem_start = par->metromem_dma;
|
||||
par->metromem_cmd = (struct metromem_cmd *) par->metromem;
|
||||
par->metromem_wfm = par->metromem + cmd_size;
|
||||
par->metromem_img = par->metromem + cmd_size + wfm_size;
|
||||
par->metromem_img_csum = (u16 *) (par->metromem_img +
|
||||
(epd_frame_table[0].fw * DPY_H));
|
||||
DPRINTK("img offset=0x%x\n", cmd_size + wfm_size);
|
||||
par->metromem_desc = (struct metromem_desc *) (par->metromem + cmd_size
|
||||
+ wfm_size + img_size + padding_size);
|
||||
par->metromem_desc_dma = par->metromem_dma + cmd_size + wfm_size
|
||||
+ img_size + padding_size;
|
||||
|
||||
/* load the waveform in. assume mode 3, temp 31 for now
|
||||
a) request the waveform file from userspace
|
||||
b) process waveform and decode into metromem */
|
||||
retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev);
|
||||
if (retval < 0) {
|
||||
printk(KERN_ERR "metronomefb: couldn't get waveform\n");
|
||||
goto err_dma_free;
|
||||
dev_err(&dev->dev, "Failed to get waveform\n");
|
||||
goto err_csum_table;
|
||||
}
|
||||
|
||||
retval = load_waveform((u8 *) fw_entry->data, fw_entry->size,
|
||||
par->metromem_wfm, 3, 31, &par->frame_count);
|
||||
retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31,
|
||||
par);
|
||||
release_firmware(fw_entry);
|
||||
if (retval < 0) {
|
||||
printk(KERN_ERR "metronomefb: couldn't process waveform\n");
|
||||
goto err_dma_free;
|
||||
dev_err(&dev->dev, "Failed processing waveform\n");
|
||||
goto err_csum_table;
|
||||
}
|
||||
|
||||
if (board->setup_irq(info))
|
||||
goto err_dma_free;
|
||||
goto err_csum_table;
|
||||
|
||||
retval = metronome_init_regs(par);
|
||||
if (retval < 0)
|
||||
|
|
@ -688,8 +707,8 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
|||
|
||||
retval = fb_alloc_cmap(&info->cmap, 8, 0);
|
||||
if (retval < 0) {
|
||||
printk(KERN_ERR "Failed to allocate colormap\n");
|
||||
goto err_fb_rel;
|
||||
dev_err(&dev->dev, "Failed to allocate colormap\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
/* set cmap */
|
||||
|
|
@ -704,7 +723,7 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
|||
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
printk(KERN_INFO
|
||||
dev_dbg(&dev->dev,
|
||||
"fb%d: Metronome frame buffer device, using %dK of video"
|
||||
" memory\n", info->node, videomemorysize >> 10);
|
||||
|
||||
|
|
@ -712,17 +731,15 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
|
|||
|
||||
err_cmap:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
err_fb_rel:
|
||||
framebuffer_release(info);
|
||||
err_free_irq:
|
||||
board->free_irq(info);
|
||||
err_dma_free:
|
||||
dma_free_writecombine(&dev->dev, par->metromemsize, par->metromem,
|
||||
par->metromem_dma);
|
||||
board->cleanup(par);
|
||||
err_csum_table:
|
||||
vfree(par->csum_table);
|
||||
err_vfree:
|
||||
vfree(videomemory);
|
||||
err_fb_rel:
|
||||
framebuffer_release(info);
|
||||
err:
|
||||
module_put(board->owner);
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -733,15 +750,15 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
|
|||
|
||||
if (info) {
|
||||
struct metronomefb_par *par = info->par;
|
||||
fb_deferred_io_cleanup(info);
|
||||
dma_free_writecombine(&dev->dev, par->metromemsize,
|
||||
par->metromem, par->metromem_dma);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
vfree(par->csum_table);
|
||||
|
||||
unregister_framebuffer(info);
|
||||
fb_deferred_io_cleanup(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
par->board->cleanup(par);
|
||||
vfree(par->csum_table);
|
||||
vfree((void __force *)info->screen_base);
|
||||
par->board->free_irq(info);
|
||||
module_put(par->board->owner);
|
||||
dev_dbg(&dev->dev, "calling release\n");
|
||||
framebuffer_release(info);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -766,6 +783,9 @@ static void __exit metronomefb_exit(void)
|
|||
platform_driver_unregister(&metronomefb_driver);
|
||||
}
|
||||
|
||||
module_param(user_wfm_size, uint, 0);
|
||||
MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size");
|
||||
|
||||
module_init(metronomefb_init);
|
||||
module_exit(metronomefb_exit);
|
||||
|
||||
|
|
|
|||
|
|
@ -426,11 +426,11 @@ static void vgaHWProtect(int on)
|
|||
{
|
||||
unsigned char tmp;
|
||||
|
||||
tmp = vga_rseq(NULL, 0x01);
|
||||
if (on) {
|
||||
/*
|
||||
* Turn off screen and disable sequencer.
|
||||
*/
|
||||
tmp = vga_rseq(NULL, 0x01);
|
||||
vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */
|
||||
vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */
|
||||
|
||||
|
|
@ -439,7 +439,6 @@ static void vgaHWProtect(int on)
|
|||
/*
|
||||
* Reenable sequencer, then turn on screen.
|
||||
*/
|
||||
tmp = vga_rseq(NULL, 0x01);
|
||||
vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */
|
||||
vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */
|
||||
|
||||
|
|
@ -558,14 +557,12 @@ neofb_open(struct fb_info *info, int user)
|
|||
{
|
||||
struct neofb_par *par = info->par;
|
||||
|
||||
mutex_lock(&par->open_lock);
|
||||
if (!par->ref_count) {
|
||||
memset(&par->state, 0, sizeof(struct vgastate));
|
||||
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
|
||||
save_vga(&par->state);
|
||||
}
|
||||
par->ref_count++;
|
||||
mutex_unlock(&par->open_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -575,16 +572,13 @@ neofb_release(struct fb_info *info, int user)
|
|||
{
|
||||
struct neofb_par *par = info->par;
|
||||
|
||||
mutex_lock(&par->open_lock);
|
||||
if (!par->ref_count) {
|
||||
mutex_unlock(&par->open_lock);
|
||||
if (!par->ref_count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (par->ref_count == 1) {
|
||||
restore_vga(&par->state);
|
||||
}
|
||||
par->ref_count--;
|
||||
mutex_unlock(&par->open_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -648,10 +642,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
var->blue.msb_right = 0;
|
||||
var->transp.msb_right = 0;
|
||||
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
switch (var->bits_per_pixel) {
|
||||
case 8: /* PSEUDOCOLOUR, 256 */
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 0;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 0;
|
||||
|
|
@ -661,8 +655,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
break;
|
||||
|
||||
case 16: /* DIRECTCOLOUR, 64k */
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 11;
|
||||
var->red.length = 5;
|
||||
var->green.offset = 5;
|
||||
|
|
@ -672,8 +664,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
break;
|
||||
|
||||
case 24: /* TRUECOLOUR, 16m */
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 16;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 8;
|
||||
|
|
@ -704,8 +694,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
if (vramlen > 4 * 1024 * 1024)
|
||||
vramlen = 4 * 1024 * 1024;
|
||||
|
||||
if (var->yres_virtual < var->yres)
|
||||
var->yres_virtual = var->yres;
|
||||
if (var->xres_virtual < var->xres)
|
||||
var->xres_virtual = var->xres;
|
||||
|
||||
|
|
@ -722,8 +710,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
if it was possible. We should return -EINVAL, but I disagree */
|
||||
if (var->yres_virtual < var->yres)
|
||||
var->yres = var->yres_virtual;
|
||||
if (var->xres_virtual < var->xres)
|
||||
var->xres = var->xres_virtual;
|
||||
if (var->xoffset + var->xres > var->xres_virtual)
|
||||
var->xoffset = var->xres_virtual - var->xres;
|
||||
if (var->yoffset + var->yres > var->yres_virtual)
|
||||
|
|
@ -1186,8 +1172,11 @@ static int neofb_set_par(struct fb_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void neofb_update_start(struct fb_info *info,
|
||||
struct fb_var_screeninfo *var)
|
||||
/*
|
||||
* Pan or Wrap the Display
|
||||
*/
|
||||
static int neofb_pan_display(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct neofb_par *par = info->par;
|
||||
struct vgastate *state = &par->state;
|
||||
|
|
@ -1216,35 +1205,7 @@ static void neofb_update_start(struct fb_info *info,
|
|||
vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
|
||||
|
||||
neoLock(state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pan or Wrap the Display
|
||||
*/
|
||||
static int neofb_pan_display(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
u_int y_bottom;
|
||||
|
||||
y_bottom = var->yoffset;
|
||||
|
||||
if (!(var->vmode & FB_VMODE_YWRAP))
|
||||
y_bottom += var->yres;
|
||||
|
||||
if (var->xoffset > (var->xres_virtual - var->xres))
|
||||
return -EINVAL;
|
||||
if (y_bottom > info->var.yres_virtual)
|
||||
return -EINVAL;
|
||||
|
||||
neofb_update_start(info, var);
|
||||
|
||||
info->var.xoffset = var->xoffset;
|
||||
info->var.yoffset = var->yoffset;
|
||||
|
||||
if (var->vmode & FB_VMODE_YWRAP)
|
||||
info->var.vmode |= FB_VMODE_YWRAP;
|
||||
else
|
||||
info->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1992,7 +1953,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
|
|||
|
||||
info->fix.accel = id->driver_data;
|
||||
|
||||
mutex_init(&par->open_lock);
|
||||
par->pci_burst = !nopciburst;
|
||||
par->lcd_stretch = !nostretch;
|
||||
par->libretto = libretto;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ struct resmap {
|
|||
};
|
||||
|
||||
static struct {
|
||||
u32 base;
|
||||
void __iomem *base;
|
||||
|
||||
struct omapfb_mem_desc mem_desc;
|
||||
struct resmap *res_map[DISPC_MEMTYPE_NUM];
|
||||
|
|
@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable)
|
|||
dispc_write_reg(DISPC_CONTROL, l);
|
||||
|
||||
/* Set bypass mode in RFBI module */
|
||||
l = __raw_readl(io_p2v(RFBI_CONTROL));
|
||||
l = __raw_readl(IO_ADDRESS(RFBI_CONTROL));
|
||||
l |= enable ? 0 : (1 << 1);
|
||||
__raw_writel(l, io_p2v(RFBI_CONTROL));
|
||||
__raw_writel(l, IO_ADDRESS(RFBI_CONTROL));
|
||||
}
|
||||
|
||||
static void set_lcd_data_lines(int data_lines)
|
||||
|
|
@ -1349,14 +1349,19 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
|
|||
|
||||
memset(&dispc, 0, sizeof(dispc));
|
||||
|
||||
dispc.base = io_p2v(DISPC_BASE);
|
||||
dispc.base = ioremap(DISPC_BASE, SZ_1K);
|
||||
if (!dispc.base) {
|
||||
dev_err(fbdev->dev, "can't ioremap DISPC\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dispc.fbdev = fbdev;
|
||||
dispc.ext_mode = ext_mode;
|
||||
|
||||
init_completion(&dispc.frame_done);
|
||||
|
||||
if ((r = get_dss_clocks()) < 0)
|
||||
return r;
|
||||
goto fail0;
|
||||
|
||||
enable_interface_clocks(1);
|
||||
enable_lcd_clocks(1);
|
||||
|
|
@ -1414,7 +1419,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
|
|||
}
|
||||
|
||||
/* L3 firewall setting: enable access to OCM RAM */
|
||||
__raw_writel(0x402000b0, io_p2v(0x680050a0));
|
||||
__raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
|
||||
|
||||
if ((r = alloc_palette_ram()) < 0)
|
||||
goto fail2;
|
||||
|
|
@ -1464,7 +1469,8 @@ fail1:
|
|||
enable_lcd_clocks(0);
|
||||
enable_interface_clocks(0);
|
||||
put_dss_clocks();
|
||||
|
||||
fail0:
|
||||
iounmap(dispc.base);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
@ -1481,6 +1487,7 @@ static void omap_dispc_cleanup(void)
|
|||
free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
|
||||
enable_interface_clocks(0);
|
||||
put_dss_clocks();
|
||||
iounmap(dispc.base);
|
||||
}
|
||||
|
||||
const struct lcd_ctrl omap2_int_ctrl = {
|
||||
|
|
|
|||
|
|
@ -40,4 +40,6 @@ extern void omap_dispc_enable_digit_out(int enable);
|
|||
extern int omap_dispc_request_irq(void (*callback)(void *data), void *data);
|
||||
extern void omap_dispc_free_irq(void);
|
||||
|
||||
extern const struct lcd_ctrl omap2_int_ctrl;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct lcd_panel h4_panel = {
|
||||
static struct lcd_panel h4_panel = {
|
||||
.name = "h4",
|
||||
.config = OMAP_LCDC_PANEL_TFT,
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ static int h4_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver h4_panel_driver = {
|
||||
static struct platform_driver h4_panel_driver = {
|
||||
.probe = h4_panel_probe,
|
||||
.remove = h4_panel_remove,
|
||||
.suspend = h4_panel_suspend,
|
||||
|
|
|
|||
|
|
@ -32,43 +32,43 @@ static int innovator1610_panel_init(struct lcd_panel *panel,
|
|||
{
|
||||
int r = 0;
|
||||
|
||||
if (omap_request_gpio(14)) {
|
||||
if (gpio_request(14, "lcd_en0")) {
|
||||
pr_err(MODULE_NAME ": can't request GPIO 14\n");
|
||||
r = -1;
|
||||
goto exit;
|
||||
}
|
||||
if (omap_request_gpio(15)) {
|
||||
if (gpio_request(15, "lcd_en1")) {
|
||||
pr_err(MODULE_NAME ": can't request GPIO 15\n");
|
||||
omap_free_gpio(14);
|
||||
gpio_free(14);
|
||||
r = -1;
|
||||
goto exit;
|
||||
}
|
||||
/* configure GPIO(14, 15) as outputs */
|
||||
omap_set_gpio_direction(14, 0);
|
||||
omap_set_gpio_direction(15, 0);
|
||||
gpio_direction_output(14, 0);
|
||||
gpio_direction_output(15, 0);
|
||||
exit:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void innovator1610_panel_cleanup(struct lcd_panel *panel)
|
||||
{
|
||||
omap_free_gpio(15);
|
||||
omap_free_gpio(14);
|
||||
gpio_free(15);
|
||||
gpio_free(14);
|
||||
}
|
||||
|
||||
static int innovator1610_panel_enable(struct lcd_panel *panel)
|
||||
{
|
||||
/* set GPIO14 and GPIO15 high */
|
||||
omap_set_gpio_dataout(14, 1);
|
||||
omap_set_gpio_dataout(15, 1);
|
||||
gpio_set_value(14, 1);
|
||||
gpio_set_value(15, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void innovator1610_panel_disable(struct lcd_panel *panel)
|
||||
{
|
||||
/* set GPIO13, GPIO14 and GPIO15 low */
|
||||
omap_set_gpio_dataout(14, 0);
|
||||
omap_set_gpio_dataout(15, 0);
|
||||
gpio_set_value(14, 0);
|
||||
gpio_set_value(15, 0);
|
||||
}
|
||||
|
||||
static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
|
||||
{
|
||||
/* gpio2 was allocated in board init */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -47,11 +48,8 @@ static int osk_panel_enable(struct lcd_panel *panel)
|
|||
/* Set PWL level */
|
||||
omap_writeb(0xFF, OMAP_PWL_ENABLE);
|
||||
|
||||
/* configure GPIO2 as output */
|
||||
omap_set_gpio_direction(2, 0);
|
||||
|
||||
/* set GPIO2 high */
|
||||
omap_set_gpio_dataout(2, 1);
|
||||
/* set GPIO2 high (lcd power enabled) */
|
||||
gpio_set_value(2, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -65,7 +63,7 @@ static void osk_panel_disable(struct lcd_panel *panel)
|
|||
omap_writeb(0x00, OMAP_PWL_CLK_ENABLE);
|
||||
|
||||
/* set GPIO2 low */
|
||||
omap_set_gpio_dataout(2, 0);
|
||||
gpio_set_value(2, 0);
|
||||
}
|
||||
|
||||
static unsigned long osk_panel_get_caps(struct lcd_panel *panel)
|
||||
|
|
|
|||
|
|
@ -81,21 +81,21 @@ static void epson_sendbyte(int flag, unsigned char byte)
|
|||
int i, shifter = 0x80;
|
||||
|
||||
if (!flag)
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_A0, 0);
|
||||
gpio_set_value(_A_LCD_SSC_A0, 0);
|
||||
mdelay(2);
|
||||
omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
|
||||
gpio_set_value(A_LCD_SSC_RD, 1);
|
||||
|
||||
omap_set_gpio_dataout(A_LCD_SSC_SD, flag);
|
||||
gpio_set_value(A_LCD_SSC_SD, flag);
|
||||
|
||||
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
|
||||
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
|
||||
for (i = 0; i < 8; i++) {
|
||||
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
|
||||
omap_set_gpio_dataout(A_LCD_SSC_SD, shifter & byte);
|
||||
gpio_set_value(A_LCD_SSC_SD, shifter & byte);
|
||||
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
|
||||
shifter >>= 1;
|
||||
}
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
|
||||
gpio_set_value(_A_LCD_SSC_A0, 1);
|
||||
}
|
||||
|
||||
static void init_system(void)
|
||||
|
|
@ -107,25 +107,18 @@ static void init_system(void)
|
|||
static void setup_GPIO(void)
|
||||
{
|
||||
/* new wave */
|
||||
omap_request_gpio(A_LCD_SSC_RD);
|
||||
omap_request_gpio(A_LCD_SSC_SD);
|
||||
omap_request_gpio(_A_LCD_RESET);
|
||||
omap_request_gpio(_A_LCD_SSC_CS);
|
||||
omap_request_gpio(_A_LCD_SSC_A0);
|
||||
gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd");
|
||||
gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd");
|
||||
gpio_request(_A_LCD_RESET, "lcd_reset");
|
||||
gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs");
|
||||
gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0");
|
||||
|
||||
/* set all GPIOs to output */
|
||||
omap_set_gpio_direction(A_LCD_SSC_RD, 0);
|
||||
omap_set_gpio_direction(A_LCD_SSC_SD, 0);
|
||||
omap_set_gpio_direction(_A_LCD_RESET, 0);
|
||||
omap_set_gpio_direction(_A_LCD_SSC_CS, 0);
|
||||
omap_set_gpio_direction(_A_LCD_SSC_A0, 0);
|
||||
|
||||
/* set GPIO data */
|
||||
omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
|
||||
omap_set_gpio_dataout(A_LCD_SSC_SD, 0);
|
||||
omap_set_gpio_dataout(_A_LCD_RESET, 0);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
|
||||
/* set GPIOs to output, with initial data */
|
||||
gpio_direction_output(A_LCD_SSC_RD, 1);
|
||||
gpio_direction_output(A_LCD_SSC_SD, 0);
|
||||
gpio_direction_output(_A_LCD_RESET, 0);
|
||||
gpio_direction_output(_A_LCD_SSC_CS, 1);
|
||||
gpio_direction_output(_A_LCD_SSC_A0, 1);
|
||||
}
|
||||
|
||||
static void display_init(void)
|
||||
|
|
@ -139,61 +132,61 @@ static void display_init(void)
|
|||
mdelay(2);
|
||||
|
||||
/* reset LCD */
|
||||
omap_set_gpio_dataout(A_LCD_SSC_SD, 1);
|
||||
gpio_set_value(A_LCD_SSC_SD, 1);
|
||||
epson_sendbyte(0, 0x25);
|
||||
|
||||
omap_set_gpio_dataout(_A_LCD_RESET, 0);
|
||||
gpio_set_value(_A_LCD_RESET, 0);
|
||||
mdelay(10);
|
||||
omap_set_gpio_dataout(_A_LCD_RESET, 1);
|
||||
gpio_set_value(_A_LCD_RESET, 1);
|
||||
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
mdelay(2);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD, phase 1 */
|
||||
epson_sendbyte(0, 0xCA);
|
||||
for (i = 0; i < 10; i++)
|
||||
epson_sendbyte(1, INIT_1[i]);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 2 */
|
||||
epson_sendbyte(0, 0xCB);
|
||||
for (i = 0; i < 125; i++)
|
||||
epson_sendbyte(1, INIT_2[i]);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 2a */
|
||||
epson_sendbyte(0, 0xCC);
|
||||
for (i = 0; i < 14; i++)
|
||||
epson_sendbyte(1, INIT_3[i]);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 3 */
|
||||
epson_sendbyte(0, 0xBC);
|
||||
epson_sendbyte(1, 0x08);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 4 */
|
||||
epson_sendbyte(0, 0x07);
|
||||
epson_sendbyte(1, 0x05);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 5 */
|
||||
epson_sendbyte(0, 0x94);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 6 */
|
||||
epson_sendbyte(0, 0xC6);
|
||||
epson_sendbyte(1, 0x80);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
mdelay(100); /* used to be 1000 */
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 7 */
|
||||
epson_sendbyte(0, 0x16);
|
||||
|
|
@ -201,8 +194,8 @@ static void display_init(void)
|
|||
epson_sendbyte(1, 0x00);
|
||||
epson_sendbyte(1, 0xB1);
|
||||
epson_sendbyte(1, 0x00);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 8 */
|
||||
epson_sendbyte(0, 0x76);
|
||||
|
|
@ -210,12 +203,12 @@ static void display_init(void)
|
|||
epson_sendbyte(1, 0x00);
|
||||
epson_sendbyte(1, 0xDB);
|
||||
epson_sendbyte(1, 0x00);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
/* init LCD phase 9 */
|
||||
epson_sendbyte(0, 0xAF);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
}
|
||||
|
||||
static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
|
||||
|
|
@ -231,18 +224,18 @@ static void sx1_panel_disable(struct lcd_panel *panel)
|
|||
{
|
||||
printk(KERN_INFO "SX1: LCD panel disable\n");
|
||||
sx1_setmmipower(0);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
|
||||
epson_sendbyte(0, 0x25);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
epson_sendbyte(0, 0xAE);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
mdelay(100);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 0);
|
||||
|
||||
epson_sendbyte(0, 0x95);
|
||||
omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
|
||||
gpio_set_value(_A_LCD_SSC_CS, 1);
|
||||
}
|
||||
|
||||
static int sx1_panel_enable(struct lcd_panel *panel)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "lcdc.h"
|
||||
|
||||
#define MODULE_NAME "lcdc"
|
||||
|
||||
#define OMAP_LCDC_BASE 0xfffec000
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@
|
|||
int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data);
|
||||
void omap_lcdc_free_dma_callback(void);
|
||||
|
||||
extern const struct lcd_ctrl omap1_int_ctrl;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,11 +31,14 @@
|
|||
#include <mach/dma.h>
|
||||
#include <mach/omapfb.h>
|
||||
|
||||
#include "lcdc.h"
|
||||
#include "dispc.h"
|
||||
|
||||
#define MODULE_NAME "omapfb"
|
||||
|
||||
static unsigned int def_accel;
|
||||
static unsigned long def_vram[OMAPFB_PLANE_NUM];
|
||||
static int def_vram_cnt;
|
||||
static unsigned int def_vram_cnt;
|
||||
static unsigned long def_vxres;
|
||||
static unsigned long def_vyres;
|
||||
static unsigned int def_rotate;
|
||||
|
|
@ -84,12 +87,10 @@ static struct caps_table_struct color_caps[] = {
|
|||
* LCD panel
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
extern struct lcd_ctrl omap1_int_ctrl;
|
||||
extern struct lcd_ctrl omap2_int_ctrl;
|
||||
extern struct lcd_ctrl hwa742_ctrl;
|
||||
extern struct lcd_ctrl blizzard_ctrl;
|
||||
|
||||
static struct lcd_ctrl *ctrls[] = {
|
||||
static const struct lcd_ctrl *ctrls[] = {
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
&omap1_int_ctrl,
|
||||
#else
|
||||
|
|
@ -740,7 +741,7 @@ static int omapfb_update_win(struct fb_info *fbi,
|
|||
int ret;
|
||||
|
||||
omapfb_rqueue_lock(plane->fbdev);
|
||||
ret = omapfb_update_window_async(fbi, win, NULL, 0);
|
||||
ret = omapfb_update_window_async(fbi, win, NULL, NULL);
|
||||
omapfb_rqueue_unlock(plane->fbdev);
|
||||
|
||||
return ret;
|
||||
|
|
@ -768,7 +769,7 @@ static int omapfb_update_full_screen(struct fb_info *fbi)
|
|||
win.format = 0;
|
||||
|
||||
omapfb_rqueue_lock(fbdev);
|
||||
r = fbdev->ctrl->update_window(fbi, &win, NULL, 0);
|
||||
r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL);
|
||||
omapfb_rqueue_unlock(fbdev);
|
||||
|
||||
return r;
|
||||
|
|
@ -1047,7 +1048,7 @@ void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval)
|
|||
win.height = 2;
|
||||
win.out_width = 2;
|
||||
win.out_height = 2;
|
||||
fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, 0);
|
||||
fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL);
|
||||
}
|
||||
omapfb_rqueue_unlock(fbdev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
#define DISPC_CONTROL 0x0040
|
||||
|
||||
static struct {
|
||||
u32 base;
|
||||
void __iomem *base;
|
||||
void (*lcdc_callback)(void *data);
|
||||
void *lcdc_callback_data;
|
||||
unsigned long l4_khz;
|
||||
|
|
@ -518,7 +518,11 @@ static int rfbi_init(struct omapfb_device *fbdev)
|
|||
int r;
|
||||
|
||||
rfbi.fbdev = fbdev;
|
||||
rfbi.base = io_p2v(RFBI_BASE);
|
||||
rfbi.base = ioremap(RFBI_BASE, SZ_1K);
|
||||
if (!rfbi.base) {
|
||||
dev_err(fbdev->dev, "can't ioremap RFBI\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if ((r = rfbi_get_clocks()) < 0)
|
||||
return r;
|
||||
|
|
@ -566,6 +570,7 @@ static void rfbi_cleanup(void)
|
|||
{
|
||||
omap_dispc_free_irq();
|
||||
rfbi_put_clocks();
|
||||
iounmap(rfbi.base);
|
||||
}
|
||||
|
||||
const struct lcd_ctrl_extif omap2_ext_if = {
|
||||
|
|
|
|||
|
|
@ -574,7 +574,12 @@ static int sossi_init(struct omapfb_device *fbdev)
|
|||
struct clk *dpll1out_ck;
|
||||
int r;
|
||||
|
||||
sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE);
|
||||
sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K);
|
||||
if (!sossi.base) {
|
||||
dev_err(fbdev->dev, "can't ioremap SoSSI\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sossi.fbdev = fbdev;
|
||||
spin_lock_init(&sossi.lock);
|
||||
|
||||
|
|
@ -665,6 +670,7 @@ static void sossi_cleanup(void)
|
|||
{
|
||||
omap_lcdc_free_dma_callback();
|
||||
clk_put(sossi.fck);
|
||||
iounmap(sossi.base);
|
||||
}
|
||||
|
||||
struct lcd_ctrl_extif omap1_ext_if = {
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ static int __devexit p9100_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id p9100_match[] = {
|
||||
static const struct of_device_id p9100_match[] = {
|
||||
{
|
||||
.name = "p9100",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@
|
|||
#define dbg(fmt, args...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static const int __devinitconst s1d13xxxfb_revisions[] = {
|
||||
S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */
|
||||
S1D13806_CHIP_REV, /* Rev.7 on .. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Here we define the default struct fb_fix_screeninfo
|
||||
*/
|
||||
|
|
@ -538,6 +543,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
|
|||
struct fb_info *info;
|
||||
struct s1d13xxxfb_pdata *pdata = NULL;
|
||||
int ret = 0;
|
||||
int i;
|
||||
u8 revision;
|
||||
|
||||
dbg("probe called: device is %p\n", pdev);
|
||||
|
|
@ -607,10 +613,19 @@ s1d13xxxfb_probe(struct platform_device *pdev)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE);
|
||||
if ((revision >> 2) != S1D_CHIP_REV) {
|
||||
printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2));
|
||||
ret = -ENODEV;
|
||||
revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
|
||||
|
||||
ret = -ENODEV;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
|
||||
if (revision == s1d13xxxfb_revisions[i])
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
printk(KERN_INFO PFX "chip revision %i\n", revision);
|
||||
else {
|
||||
printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ static int __devexit tcx_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id tcx_match[] = {
|
||||
static const struct of_device_id tcx_match[] = {
|
||||
{
|
||||
.name = "SUNW,tcx",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1195,57 +1195,58 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
|
|||
return -ENOMEM;
|
||||
|
||||
default_par = info->par;
|
||||
info->fix = tdfx_fix;
|
||||
|
||||
/* Configure the default fb_fix_screeninfo first */
|
||||
switch (pdev->device) {
|
||||
case PCI_DEVICE_ID_3DFX_BANSHEE:
|
||||
strcpy(tdfx_fix.id, "3Dfx Banshee");
|
||||
strcpy(info->fix.id, "3Dfx Banshee");
|
||||
default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
|
||||
break;
|
||||
case PCI_DEVICE_ID_3DFX_VOODOO3:
|
||||
strcpy(tdfx_fix.id, "3Dfx Voodoo3");
|
||||
strcpy(info->fix.id, "3Dfx Voodoo3");
|
||||
default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
|
||||
break;
|
||||
case PCI_DEVICE_ID_3DFX_VOODOO5:
|
||||
strcpy(tdfx_fix.id, "3Dfx Voodoo5");
|
||||
strcpy(info->fix.id, "3Dfx Voodoo5");
|
||||
default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
|
||||
tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
|
||||
if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
|
||||
info->fix.mmio_start = pci_resource_start(pdev, 0);
|
||||
info->fix.mmio_len = pci_resource_len(pdev, 0);
|
||||
if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len,
|
||||
"tdfx regbase")) {
|
||||
printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
default_par->regbase_virt =
|
||||
ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
|
||||
ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
|
||||
if (!default_par->regbase_virt) {
|
||||
printk(KERN_ERR "fb: Can't remap %s register area.\n",
|
||||
tdfx_fix.id);
|
||||
info->fix.id);
|
||||
goto out_err_regbase;
|
||||
}
|
||||
|
||||
tdfx_fix.smem_start = pci_resource_start(pdev, 1);
|
||||
tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
|
||||
if (!tdfx_fix.smem_len) {
|
||||
printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
|
||||
info->fix.smem_start = pci_resource_start(pdev, 1);
|
||||
info->fix.smem_len = do_lfb_size(default_par, pdev->device);
|
||||
if (!info->fix.smem_len) {
|
||||
printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id);
|
||||
goto out_err_regbase;
|
||||
}
|
||||
|
||||
if (!request_mem_region(tdfx_fix.smem_start,
|
||||
if (!request_mem_region(info->fix.smem_start,
|
||||
pci_resource_len(pdev, 1), "tdfx smem")) {
|
||||
printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
|
||||
goto out_err_regbase;
|
||||
}
|
||||
|
||||
info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
|
||||
tdfx_fix.smem_len);
|
||||
info->screen_base = ioremap_nocache(info->fix.smem_start,
|
||||
info->fix.smem_len);
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
|
||||
tdfx_fix.id);
|
||||
info->fix.id);
|
||||
goto out_err_screenbase;
|
||||
}
|
||||
|
||||
|
|
@ -1257,20 +1258,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
|
|||
goto out_err_screenbase;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
|
||||
tdfx_fix.smem_len >> 10);
|
||||
printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
|
||||
info->fix.smem_len >> 10);
|
||||
|
||||
default_par->mtrr_handle = -1;
|
||||
if (!nomtrr)
|
||||
default_par->mtrr_handle =
|
||||
mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
|
||||
mtrr_add(info->fix.smem_start, info->fix.smem_len,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
|
||||
tdfx_fix.ypanstep = nopan ? 0 : 1;
|
||||
tdfx_fix.ywrapstep = nowrap ? 0 : 1;
|
||||
info->fix.ypanstep = nopan ? 0 : 1;
|
||||
info->fix.ywrapstep = nowrap ? 0 : 1;
|
||||
|
||||
info->fbops = &tdfxfb_ops;
|
||||
info->fix = tdfx_fix;
|
||||
info->pseudo_palette = default_par->palette;
|
||||
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
|
||||
#ifdef CONFIG_FB_3DFX_ACCEL
|
||||
|
|
@ -1323,14 +1323,14 @@ out_err_iobase:
|
|||
out_err_screenbase:
|
||||
if (info->screen_base)
|
||||
iounmap(info->screen_base);
|
||||
release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
|
||||
release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1));
|
||||
out_err_regbase:
|
||||
/*
|
||||
* Cleanup after anything that was remapped/allocated.
|
||||
*/
|
||||
if (default_par->regbase_virt)
|
||||
iounmap(default_par->regbase_virt);
|
||||
release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
|
||||
release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
|
||||
out_err:
|
||||
framebuffer_release(info);
|
||||
return -ENXIO;
|
||||
|
|
|
|||
1050
drivers/video/tmiofb.c
Normal file
1050
drivers/video/tmiofb.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -516,10 +516,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
|
|||
|
||||
err = uvesafb_exec(task);
|
||||
if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
|
||||
printk(KERN_ERR "uvesafb: Getting mode info block "
|
||||
printk(KERN_WARNING "uvesafb: Getting mode info block "
|
||||
"for mode 0x%x failed (eax=0x%x, err=%d)\n",
|
||||
*mode, (u32)task->t.regs.eax, err);
|
||||
return -EINVAL;
|
||||
mode++;
|
||||
par->vbe_modes_cnt--;
|
||||
continue;
|
||||
}
|
||||
|
||||
mib = task->buf;
|
||||
|
|
@ -548,7 +550,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
|
|||
mib->depth = mib->bits_per_pixel;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (par->vbe_modes_cnt > 0)
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ struct vga16fb_par {
|
|||
unsigned char ClockingMode; /* Seq-Controller:01h */
|
||||
} vga_state;
|
||||
struct vgastate state;
|
||||
struct mutex open_lock;
|
||||
unsigned int ref_count;
|
||||
int palette_blanked, vesa_blanked, mode, isVGA;
|
||||
u8 misc, pel_msk, vss, clkdiv;
|
||||
|
|
@ -286,7 +285,6 @@ static int vga16fb_open(struct fb_info *info, int user)
|
|||
{
|
||||
struct vga16fb_par *par = info->par;
|
||||
|
||||
mutex_lock(&par->open_lock);
|
||||
if (!par->ref_count) {
|
||||
memset(&par->state, 0, sizeof(struct vgastate));
|
||||
par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
|
||||
|
|
@ -294,7 +292,6 @@ static int vga16fb_open(struct fb_info *info, int user)
|
|||
save_vga(&par->state);
|
||||
}
|
||||
par->ref_count++;
|
||||
mutex_unlock(&par->open_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -303,15 +300,12 @@ static int vga16fb_release(struct fb_info *info, int user)
|
|||
{
|
||||
struct vga16fb_par *par = info->par;
|
||||
|
||||
mutex_lock(&par->open_lock);
|
||||
if (!par->ref_count) {
|
||||
mutex_unlock(&par->open_lock);
|
||||
if (!par->ref_count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (par->ref_count == 1)
|
||||
restore_vga(&par->state);
|
||||
par->ref_count--;
|
||||
mutex_unlock(&par->open_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1326,7 +1320,6 @@ static int __init vga16fb_probe(struct platform_device *dev)
|
|||
printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
|
||||
par = info->par;
|
||||
|
||||
mutex_init(&par->open_lock);
|
||||
par->isVGA = screen_info.orig_video_isVGA;
|
||||
par->palette_blanked = 0;
|
||||
par->vesa_blanked = 0;
|
||||
|
|
|
|||
7
drivers/video/via/Makefile
Normal file
7
drivers/video/via/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the VIA framebuffer driver (for Linux Kernel 2.6)
|
||||
#
|
||||
|
||||
obj-$(CONFIG_FB_VIA) += viafb.o
|
||||
|
||||
viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
|
||||
279
drivers/video/via/accel.c
Normal file
279
drivers/video/via/accel.c
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "global.h"
|
||||
|
||||
void viafb_init_accel(void)
|
||||
{
|
||||
viaparinfo->fbmem_free -= CURSOR_SIZE;
|
||||
viaparinfo->cursor_start = viaparinfo->fbmem_free;
|
||||
viaparinfo->fbmem_used += CURSOR_SIZE;
|
||||
|
||||
/* Reverse 8*1024 memory space for cursor image */
|
||||
viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
|
||||
viaparinfo->VQ_start = viaparinfo->fbmem_free;
|
||||
viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
|
||||
viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
|
||||
|
||||
void viafb_init_2d_engine(void)
|
||||
{
|
||||
u32 dwVQStartAddr, dwVQEndAddr;
|
||||
u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
|
||||
|
||||
/* init 2D engine regs to reset 2D engine */
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
|
||||
|
||||
/* Init AGP and VQ regs */
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M900:
|
||||
writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
|
||||
writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
break;
|
||||
|
||||
default:
|
||||
writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
|
||||
writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
|
||||
writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
|
||||
writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
break;
|
||||
}
|
||||
if (viaparinfo->VQ_start != 0) {
|
||||
/* Enable VQ */
|
||||
dwVQStartAddr = viaparinfo->VQ_start;
|
||||
dwVQEndAddr = viaparinfo->VQ_end;
|
||||
|
||||
dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
|
||||
dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
|
||||
dwVQStartEndH = 0x52000000 |
|
||||
((dwVQStartAddr & 0xFF000000) >> 24) |
|
||||
((dwVQEndAddr & 0xFF000000) >> 16);
|
||||
dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M900:
|
||||
dwVQStartL |= 0x20000000;
|
||||
dwVQEndL |= 0x20000000;
|
||||
dwVQStartEndH |= 0x20000000;
|
||||
dwVQLen |= 0x20000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M900:
|
||||
writel(0x00100000,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSET);
|
||||
writel(dwVQStartEndH,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(dwVQStartL,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(dwVQEndL,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(dwVQLen,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(0x74301001,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
writel(0x00000000,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
break;
|
||||
default:
|
||||
writel(0x00FE0000,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSET);
|
||||
writel(0x080003FE,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0A00027C,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0B000260,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0C000274,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0D000264,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0E000000,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x0F000020,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x1000027E,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x110002FE,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x200F0060,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
|
||||
writel(0x00000006,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x40008C0F,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x44000000,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x45080C04,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x46800408,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
|
||||
writel(dwVQStartEndH,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(dwVQStartL,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(dwVQEndL,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(dwVQLen,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Disable VQ */
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M900:
|
||||
writel(0x00100000,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSET);
|
||||
writel(0x74301000,
|
||||
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
|
||||
break;
|
||||
default:
|
||||
writel(0x00FE0000,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSET);
|
||||
writel(0x00000004,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x40008C0F,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x44000000,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x45080C04,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
writel(0x46800408,
|
||||
viaparinfo->io_virt + VIA_REG_TRANSPACE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
viafb_set_2d_color_depth(viaparinfo->bpp);
|
||||
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
|
||||
|
||||
writel(VIA_PITCH_ENABLE |
|
||||
(((viaparinfo->hres *
|
||||
viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
|
||||
viaparinfo->
|
||||
bpp >> 3) >> 3) << 16)),
|
||||
viaparinfo->io_virt + VIA_REG_PITCH);
|
||||
}
|
||||
|
||||
void viafb_set_2d_color_depth(int bpp)
|
||||
{
|
||||
u32 dwGEMode;
|
||||
|
||||
dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;
|
||||
|
||||
switch (bpp) {
|
||||
case 16:
|
||||
dwGEMode |= VIA_GEM_16bpp;
|
||||
break;
|
||||
case 32:
|
||||
dwGEMode |= VIA_GEM_32bpp;
|
||||
break;
|
||||
default:
|
||||
dwGEMode |= VIA_GEM_8bpp;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set BPP and Pitch */
|
||||
writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
|
||||
}
|
||||
|
||||
void viafb_hw_cursor_init(void)
|
||||
{
|
||||
/* Set Cursor Image Base Address */
|
||||
writel(viaparinfo->cursor_start,
|
||||
viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
|
||||
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
|
||||
}
|
||||
|
||||
void viafb_show_hw_cursor(struct fb_info *info, int Status)
|
||||
{
|
||||
u32 temp;
|
||||
u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
|
||||
|
||||
temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
|
||||
switch (Status) {
|
||||
case HW_Cursor_ON:
|
||||
temp |= 0x1;
|
||||
break;
|
||||
case HW_Cursor_OFF:
|
||||
temp &= 0xFFFFFFFE;
|
||||
break;
|
||||
}
|
||||
switch (iga_path) {
|
||||
case IGA2:
|
||||
temp |= 0x80000000;
|
||||
break;
|
||||
case IGA1:
|
||||
default:
|
||||
temp &= 0x7FFFFFFF;
|
||||
}
|
||||
writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
|
||||
}
|
||||
|
||||
int viafb_wait_engine_idle(void)
|
||||
{
|
||||
int loop = 0;
|
||||
|
||||
while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
|
||||
VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
|
||||
cpu_relax();
|
||||
|
||||
while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
|
||||
(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
|
||||
(loop++ < MAXLOOP))
|
||||
cpu_relax();
|
||||
|
||||
return loop >= MAXLOOP;
|
||||
}
|
||||
169
drivers/video/via/accel.h
Normal file
169
drivers/video/via/accel.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ACCEL_H__
|
||||
#define __ACCEL_H__
|
||||
|
||||
#define FB_ACCEL_VIA_UNICHROME 50
|
||||
|
||||
/* MMIO Base Address Definition */
|
||||
#define MMIO_VGABASE 0x8000
|
||||
#define MMIO_CR_READ (MMIO_VGABASE + 0x3D4)
|
||||
#define MMIO_CR_WRITE (MMIO_VGABASE + 0x3D5)
|
||||
#define MMIO_SR_READ (MMIO_VGABASE + 0x3C4)
|
||||
#define MMIO_SR_WRITE (MMIO_VGABASE + 0x3C5)
|
||||
|
||||
/* HW Cursor Status Define */
|
||||
#define HW_Cursor_ON 0
|
||||
#define HW_Cursor_OFF 1
|
||||
|
||||
#define CURSOR_SIZE (8 * 1024)
|
||||
#define VQ_SIZE (256 * 1024)
|
||||
|
||||
#define VIA_MMIO_BLTBASE 0x200000
|
||||
#define VIA_MMIO_BLTSIZE 0x200000
|
||||
|
||||
/* Defines for 2D registers */
|
||||
#define VIA_REG_GECMD 0x000
|
||||
#define VIA_REG_GEMODE 0x004
|
||||
#define VIA_REG_SRCPOS 0x008
|
||||
#define VIA_REG_DSTPOS 0x00C
|
||||
/* width and height */
|
||||
#define VIA_REG_DIMENSION 0x010
|
||||
#define VIA_REG_PATADDR 0x014
|
||||
#define VIA_REG_FGCOLOR 0x018
|
||||
#define VIA_REG_BGCOLOR 0x01C
|
||||
/* top and left of clipping */
|
||||
#define VIA_REG_CLIPTL 0x020
|
||||
/* bottom and right of clipping */
|
||||
#define VIA_REG_CLIPBR 0x024
|
||||
#define VIA_REG_OFFSET 0x028
|
||||
/* color key control */
|
||||
#define VIA_REG_KEYCONTROL 0x02C
|
||||
#define VIA_REG_SRCBASE 0x030
|
||||
#define VIA_REG_DSTBASE 0x034
|
||||
/* pitch of src and dst */
|
||||
#define VIA_REG_PITCH 0x038
|
||||
#define VIA_REG_MONOPAT0 0x03C
|
||||
#define VIA_REG_MONOPAT1 0x040
|
||||
/* from 0x100 to 0x1ff */
|
||||
#define VIA_REG_COLORPAT 0x100
|
||||
|
||||
/* VIA_REG_PITCH(0x38): Pitch Setting */
|
||||
#define VIA_PITCH_ENABLE 0x80000000
|
||||
|
||||
/* defines for VIA HW cursor registers */
|
||||
#define VIA_REG_CURSOR_MODE 0x2D0
|
||||
#define VIA_REG_CURSOR_POS 0x2D4
|
||||
#define VIA_REG_CURSOR_ORG 0x2D8
|
||||
#define VIA_REG_CURSOR_BG 0x2DC
|
||||
#define VIA_REG_CURSOR_FG 0x2E0
|
||||
|
||||
/* VIA_REG_GEMODE(0x04): GE mode */
|
||||
#define VIA_GEM_8bpp 0x00000000
|
||||
#define VIA_GEM_16bpp 0x00000100
|
||||
#define VIA_GEM_32bpp 0x00000300
|
||||
|
||||
/* VIA_REG_GECMD(0x00): 2D Engine Command */
|
||||
#define VIA_GEC_NOOP 0x00000000
|
||||
#define VIA_GEC_BLT 0x00000001
|
||||
#define VIA_GEC_LINE 0x00000005
|
||||
|
||||
/* Rotate Command */
|
||||
#define VIA_GEC_ROT 0x00000008
|
||||
|
||||
#define VIA_GEC_SRC_XY 0x00000000
|
||||
#define VIA_GEC_SRC_LINEAR 0x00000010
|
||||
#define VIA_GEC_DST_XY 0x00000000
|
||||
#define VIA_GEC_DST_LINRAT 0x00000020
|
||||
|
||||
#define VIA_GEC_SRC_FB 0x00000000
|
||||
#define VIA_GEC_SRC_SYS 0x00000040
|
||||
#define VIA_GEC_DST_FB 0x00000000
|
||||
#define VIA_GEC_DST_SYS 0x00000080
|
||||
|
||||
/* source is mono */
|
||||
#define VIA_GEC_SRC_MONO 0x00000100
|
||||
/* pattern is mono */
|
||||
#define VIA_GEC_PAT_MONO 0x00000200
|
||||
/* mono src is opaque */
|
||||
#define VIA_GEC_MSRC_OPAQUE 0x00000000
|
||||
/* mono src is transparent */
|
||||
#define VIA_GEC_MSRC_TRANS 0x00000400
|
||||
/* pattern is in frame buffer */
|
||||
#define VIA_GEC_PAT_FB 0x00000000
|
||||
/* pattern is from reg setting */
|
||||
#define VIA_GEC_PAT_REG 0x00000800
|
||||
|
||||
#define VIA_GEC_CLIP_DISABLE 0x00000000
|
||||
#define VIA_GEC_CLIP_ENABLE 0x00001000
|
||||
|
||||
#define VIA_GEC_FIXCOLOR_PAT 0x00002000
|
||||
|
||||
#define VIA_GEC_INCX 0x00000000
|
||||
#define VIA_GEC_DECY 0x00004000
|
||||
#define VIA_GEC_INCY 0x00000000
|
||||
#define VIA_GEC_DECX 0x00008000
|
||||
/* mono pattern is opaque */
|
||||
#define VIA_GEC_MPAT_OPAQUE 0x00000000
|
||||
/* mono pattern is transparent */
|
||||
#define VIA_GEC_MPAT_TRANS 0x00010000
|
||||
|
||||
#define VIA_GEC_MONO_UNPACK 0x00000000
|
||||
#define VIA_GEC_MONO_PACK 0x00020000
|
||||
#define VIA_GEC_MONO_DWORD 0x00000000
|
||||
#define VIA_GEC_MONO_WORD 0x00040000
|
||||
#define VIA_GEC_MONO_BYTE 0x00080000
|
||||
|
||||
#define VIA_GEC_LASTPIXEL_ON 0x00000000
|
||||
#define VIA_GEC_LASTPIXEL_OFF 0x00100000
|
||||
#define VIA_GEC_X_MAJOR 0x00000000
|
||||
#define VIA_GEC_Y_MAJOR 0x00200000
|
||||
#define VIA_GEC_QUICK_START 0x00800000
|
||||
|
||||
/* defines for VIA 3D registers */
|
||||
#define VIA_REG_STATUS 0x400
|
||||
#define VIA_REG_CR_TRANSET 0x41C
|
||||
#define VIA_REG_CR_TRANSPACE 0x420
|
||||
#define VIA_REG_TRANSET 0x43C
|
||||
#define VIA_REG_TRANSPACE 0x440
|
||||
|
||||
/* VIA_REG_STATUS(0x400): Engine Status */
|
||||
|
||||
/* Command Regulator is busy */
|
||||
#define VIA_CMD_RGTR_BUSY 0x00000080
|
||||
/* 2D Engine is busy */
|
||||
#define VIA_2D_ENG_BUSY 0x00000002
|
||||
/* 3D Engine is busy */
|
||||
#define VIA_3D_ENG_BUSY 0x00000001
|
||||
/* Virtual Queue is busy */
|
||||
#define VIA_VR_QUEUE_BUSY 0x00020000
|
||||
|
||||
#define MAXLOOP 0xFFFFFF
|
||||
|
||||
void viafb_init_accel(void);
|
||||
void viafb_init_2d_engine(void);
|
||||
void set_2d_color_depth(int);
|
||||
void viafb_hw_cursor_init(void);
|
||||
void viafb_show_hw_cursor(struct fb_info *info, int Status); int
|
||||
viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
|
||||
|
||||
#endif /* __ACCEL_H__ */
|
||||
190
drivers/video/via/chip.h
Normal file
190
drivers/video/via/chip.h
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __CHIP_H__
|
||||
#define __CHIP_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/***************************************/
|
||||
/* Definition Graphic Chip Information */
|
||||
/***************************************/
|
||||
|
||||
#define PCI_VIA_VENDOR_ID 0x1106
|
||||
|
||||
/* Define VIA Graphic Chip Name */
|
||||
#define UNICHROME_CLE266 1
|
||||
#define UNICHROME_CLE266_DID 0x3122
|
||||
#define CLE266_REVISION_AX 0x0A
|
||||
#define CLE266_REVISION_CX 0x0C
|
||||
|
||||
#define UNICHROME_K400 2
|
||||
#define UNICHROME_K400_DID 0x7205
|
||||
|
||||
#define UNICHROME_K800 3
|
||||
#define UNICHROME_K800_DID 0x3108
|
||||
|
||||
#define UNICHROME_PM800 4
|
||||
#define UNICHROME_PM800_DID 0x3118
|
||||
|
||||
#define UNICHROME_CN700 5
|
||||
#define UNICHROME_CN700_DID 0x3344
|
||||
|
||||
#define UNICHROME_CX700 6
|
||||
#define UNICHROME_CX700_DID 0x3157
|
||||
#define CX700_REVISION_700 0x0
|
||||
#define CX700_REVISION_700M 0x1
|
||||
#define CX700_REVISION_700M2 0x2
|
||||
|
||||
#define UNICHROME_CN750 7
|
||||
#define UNICHROME_CN750_DID 0x3225
|
||||
|
||||
#define UNICHROME_K8M890 8
|
||||
#define UNICHROME_K8M890_DID 0x3230
|
||||
|
||||
#define UNICHROME_P4M890 9
|
||||
#define UNICHROME_P4M890_DID 0x3343
|
||||
|
||||
#define UNICHROME_P4M900 10
|
||||
#define UNICHROME_P4M900_DID 0x3371
|
||||
|
||||
#define UNICHROME_VX800 11
|
||||
#define UNICHROME_VX800_DID 0x1122
|
||||
|
||||
/**************************************************/
|
||||
/* Definition TMDS Trasmitter Information */
|
||||
/**************************************************/
|
||||
|
||||
/* Definition TMDS Trasmitter Index */
|
||||
#define NON_TMDS_TRANSMITTER 0x00
|
||||
#define VT1632_TMDS 0x01
|
||||
#define INTEGRATED_TMDS 0x42
|
||||
|
||||
/* Definition TMDS Trasmitter I2C Slave Address */
|
||||
#define VT1632_TMDS_I2C_ADDR 0x10
|
||||
|
||||
/**************************************************/
|
||||
/* Definition LVDS Trasmitter Information */
|
||||
/**************************************************/
|
||||
|
||||
/* Definition LVDS Trasmitter Index */
|
||||
#define NON_LVDS_TRANSMITTER 0x00
|
||||
#define VT1631_LVDS 0x01
|
||||
#define VT1636_LVDS 0x0E
|
||||
#define INTEGRATED_LVDS 0x41
|
||||
|
||||
/* Definition Digital Transmitter Mode */
|
||||
#define TX_DATA_12_BITS 0x01
|
||||
#define TX_DATA_24_BITS 0x02
|
||||
#define TX_DATA_DDR_MODE 0x04
|
||||
#define TX_DATA_SDR_MODE 0x08
|
||||
|
||||
/* Definition LVDS Trasmitter I2C Slave Address */
|
||||
#define VT1631_LVDS_I2C_ADDR 0x70
|
||||
#define VT3271_LVDS_I2C_ADDR 0x80
|
||||
#define VT1636_LVDS_I2C_ADDR 0x80
|
||||
|
||||
struct tmds_chip_information {
|
||||
int tmds_chip_name;
|
||||
int tmds_chip_slave_addr;
|
||||
int dvi_panel_id;
|
||||
int data_mode;
|
||||
int output_interface;
|
||||
int i2c_port;
|
||||
int device_type;
|
||||
};
|
||||
|
||||
struct lvds_chip_information {
|
||||
int lvds_chip_name;
|
||||
int lvds_chip_slave_addr;
|
||||
int data_mode;
|
||||
int output_interface;
|
||||
int i2c_port;
|
||||
};
|
||||
|
||||
struct chip_information {
|
||||
int gfx_chip_name;
|
||||
int gfx_chip_revision;
|
||||
int chip_on_slot;
|
||||
struct tmds_chip_information tmds_chip_info;
|
||||
struct lvds_chip_information lvds_chip_info;
|
||||
struct lvds_chip_information lvds_chip_info2;
|
||||
};
|
||||
|
||||
struct crt_setting_information {
|
||||
int iga_path;
|
||||
int h_active;
|
||||
int v_active;
|
||||
int bpp;
|
||||
int refresh_rate;
|
||||
};
|
||||
|
||||
struct tmds_setting_information {
|
||||
int iga_path;
|
||||
int h_active;
|
||||
int v_active;
|
||||
int bpp;
|
||||
int refresh_rate;
|
||||
int get_dvi_size_method;
|
||||
int max_pixel_clock;
|
||||
int dvi_panel_size;
|
||||
int dvi_panel_hres;
|
||||
int dvi_panel_vres;
|
||||
int native_size;
|
||||
};
|
||||
|
||||
struct lvds_setting_information {
|
||||
int iga_path;
|
||||
int h_active;
|
||||
int v_active;
|
||||
int bpp;
|
||||
int refresh_rate;
|
||||
int get_lcd_size_method;
|
||||
int lcd_panel_id;
|
||||
int lcd_panel_size;
|
||||
int lcd_panel_hres;
|
||||
int lcd_panel_vres;
|
||||
int display_method;
|
||||
int device_lcd_dualedge;
|
||||
int LCDDithering;
|
||||
int lcd_mode;
|
||||
u32 vclk; /*panel mode clock value */
|
||||
};
|
||||
|
||||
struct GFX_DPA_SETTING {
|
||||
int ClkRangeIndex;
|
||||
u8 DVP0; /* CR96[3:0] */
|
||||
u8 DVP0DataDri_S1; /* SR2A[5] */
|
||||
u8 DVP0DataDri_S; /* SR1B[1] */
|
||||
u8 DVP0ClockDri_S1; /* SR2A[4] */
|
||||
u8 DVP0ClockDri_S; /* SR1E[2] */
|
||||
u8 DVP1; /* CR9B[3:0] */
|
||||
u8 DVP1Driving; /* SR65[3:0], Data and Clock driving */
|
||||
u8 DFPHigh; /* CR97[3:0] */
|
||||
u8 DFPLow; /* CR99[3:0] */
|
||||
|
||||
};
|
||||
|
||||
struct VT1636_DPA_SETTING {
|
||||
int PanelSizeID;
|
||||
u8 CLK_SEL_ST1;
|
||||
u8 CLK_SEL_ST2;
|
||||
};
|
||||
#endif /* __CHIP_H__ */
|
||||
41
drivers/video/via/debug.h
Normal file
41
drivers/video/via/debug.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
#ifndef VIAFB_DEBUG
|
||||
#define VIAFB_DEBUG 0
|
||||
#endif
|
||||
|
||||
#if VIAFB_DEBUG
|
||||
#define DEBUG_MSG(f, a...) printk(f, ## a)
|
||||
#else
|
||||
#define DEBUG_MSG(f, a...)
|
||||
#endif
|
||||
|
||||
#define VIAFB_WARN 0
|
||||
#if VIAFB_WARN
|
||||
#define WARN_MSG(f, a...) printk(f, ## a)
|
||||
#else
|
||||
#define WARN_MSG(f, a...)
|
||||
#endif
|
||||
|
||||
#endif /* __DEBUG_H__ */
|
||||
682
drivers/video/via/dvi.c
Normal file
682
drivers/video/via/dvi.c
Normal file
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "global.h"
|
||||
|
||||
static void tmds_register_write(int index, u8 data);
|
||||
static int tmds_register_read(int index);
|
||||
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
|
||||
static int check_reduce_blanking_mode(int mode_index,
|
||||
int refresh_rate);
|
||||
static int dvi_get_panel_size_from_DDCv1(void);
|
||||
static int dvi_get_panel_size_from_DDCv2(void);
|
||||
static unsigned char dvi_get_panel_info(void);
|
||||
static int viafb_dvi_query_EDID(void);
|
||||
|
||||
static int check_tmds_chip(int device_id_subaddr, int device_id)
|
||||
{
|
||||
if (tmds_register_read(device_id_subaddr) == device_id)
|
||||
return OK;
|
||||
else
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
void viafb_init_dvi_size(void)
|
||||
{
|
||||
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
|
||||
DEBUG_MSG(KERN_INFO
|
||||
"viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
|
||||
viaparinfo->tmds_setting_info->get_dvi_size_method);
|
||||
|
||||
switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
|
||||
case GET_DVI_SIZE_BY_SYSTEM_BIOS:
|
||||
break;
|
||||
case GET_DVI_SZIE_BY_HW_STRAPPING:
|
||||
break;
|
||||
case GET_DVI_SIZE_BY_VGA_BIOS:
|
||||
default:
|
||||
dvi_get_panel_info();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int viafb_tmds_trasmitter_identify(void)
|
||||
{
|
||||
unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
|
||||
|
||||
/* Turn on ouputting pad */
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
/*=* DFP Low Pad on *=*/
|
||||
sr2a = viafb_read_reg(VIASR, SR2A);
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
|
||||
break;
|
||||
|
||||
case UNICHROME_P4M900:
|
||||
case UNICHROME_P4M890:
|
||||
/* DFP Low Pad on */
|
||||
sr2a = viafb_read_reg(VIASR, SR2A);
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
|
||||
/* DVP0 Pad on */
|
||||
sr1e = viafb_read_reg(VIASR, SR1E);
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* DVP0/DVP1 Pad on */
|
||||
sr1e = viafb_read_reg(VIASR, SR1E);
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
|
||||
BIT5 + BIT6 + BIT7);
|
||||
/* SR3E[1]Multi-function selection:
|
||||
0 = Emulate I2C and DDC bus by GPIO2/3/4. */
|
||||
sr3e = viafb_read_reg(VIASR, SR3E);
|
||||
viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for VT1632: */
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
|
||||
viaparinfo->chip_info->
|
||||
tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
|
||||
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
|
||||
/*
|
||||
* Currently only support 12bits,dual edge,add 24bits mode later
|
||||
*/
|
||||
tmds_register_write(0x08, 0x3b);
|
||||
|
||||
DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
|
||||
DEBUG_MSG(KERN_INFO "\n %2d",
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
|
||||
DEBUG_MSG(KERN_INFO "\n %2d",
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port);
|
||||
return OK;
|
||||
} else {
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
|
||||
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
|
||||
!= FAIL) {
|
||||
tmds_register_write(0x08, 0x3b);
|
||||
DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
|
||||
DEBUG_MSG(KERN_INFO "\n %2d",
|
||||
viaparinfo->chip_info->
|
||||
tmds_chip_info.tmds_chip_name);
|
||||
DEBUG_MSG(KERN_INFO "\n %2d",
|
||||
viaparinfo->chip_info->
|
||||
tmds_chip_info.i2c_port);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
|
||||
|
||||
if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
|
||||
((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
|
||||
(viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
|
||||
DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_K8M890:
|
||||
viafb_write_reg(SR2A, VIASR, sr2a);
|
||||
break;
|
||||
|
||||
case UNICHROME_P4M900:
|
||||
case UNICHROME_P4M890:
|
||||
viafb_write_reg(SR2A, VIASR, sr2a);
|
||||
viafb_write_reg(SR1E, VIASR, sr1e);
|
||||
break;
|
||||
|
||||
default:
|
||||
viafb_write_reg(SR1E, VIASR, sr1e);
|
||||
viafb_write_reg(SR3E, VIASR, sr3e);
|
||||
break;
|
||||
}
|
||||
|
||||
viaparinfo->chip_info->
|
||||
tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
|
||||
viaparinfo->chip_info->tmds_chip_info.
|
||||
tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
static void tmds_register_write(int index, u8 data)
|
||||
{
|
||||
viaparinfo->i2c_stuff.i2c_port =
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
||||
|
||||
viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
|
||||
tmds_chip_slave_addr, index,
|
||||
data);
|
||||
}
|
||||
|
||||
static int tmds_register_read(int index)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
viaparinfo->i2c_stuff.i2c_port =
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
||||
viafb_i2c_readbyte((u8) viaparinfo->chip_info->
|
||||
tmds_chip_info.tmds_chip_slave_addr,
|
||||
(u8) index, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
|
||||
{
|
||||
viaparinfo->i2c_stuff.i2c_port =
|
||||
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
||||
viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
|
||||
tmds_chip_slave_addr, (u8) index, buff, buff_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_reduce_blanking_mode(int mode_index,
|
||||
int refresh_rate)
|
||||
{
|
||||
if (refresh_rate != 60)
|
||||
return false;
|
||||
|
||||
switch (mode_index) {
|
||||
/* Following modes have reduce blanking mode. */
|
||||
case VIA_RES_1360X768:
|
||||
case VIA_RES_1400X1050:
|
||||
case VIA_RES_1440X900:
|
||||
case VIA_RES_1600X900:
|
||||
case VIA_RES_1680X1050:
|
||||
case VIA_RES_1920X1080:
|
||||
case VIA_RES_1920X1200:
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MSG(KERN_INFO
|
||||
"This dvi mode %d have no reduce blanking mode!\n",
|
||||
mode_index);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* DVI Set Mode */
|
||||
void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
|
||||
{
|
||||
struct VideoModeTable *videoMode = NULL;
|
||||
struct crt_mode_table *pDviTiming;
|
||||
unsigned long desirePixelClock, maxPixelClock;
|
||||
int status = 0;
|
||||
videoMode = viafb_get_modetbl_pointer(video_index);
|
||||
pDviTiming = videoMode->crtc;
|
||||
desirePixelClock = pDviTiming->clk / 1000000;
|
||||
maxPixelClock = (unsigned long)viaparinfo->
|
||||
tmds_setting_info->max_pixel_clock;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
|
||||
|
||||
if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
|
||||
/*Check if reduce-blanking mode is exist */
|
||||
status =
|
||||
check_reduce_blanking_mode(video_index,
|
||||
pDviTiming->refresh_rate);
|
||||
if (status) {
|
||||
video_index += 100; /*Use reduce-blanking mode */
|
||||
videoMode = viafb_get_modetbl_pointer(video_index);
|
||||
pDviTiming = videoMode->crtc;
|
||||
DEBUG_MSG(KERN_INFO
|
||||
"DVI use reduce blanking mode %d!!\n",
|
||||
video_index);
|
||||
}
|
||||
}
|
||||
viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
|
||||
viafb_set_output_path(DEVICE_DVI, set_iga,
|
||||
viaparinfo->chip_info->tmds_chip_info.output_interface);
|
||||
}
|
||||
|
||||
/* Sense DVI Connector */
|
||||
int viafb_dvi_sense(void)
|
||||
{
|
||||
u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
|
||||
RegCR93 = 0, RegCR9B = 0, data;
|
||||
int ret = false;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
|
||||
|
||||
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
||||
/* DI1 Pad on */
|
||||
RegSR1E = viafb_read_reg(VIASR, SR1E);
|
||||
viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
|
||||
|
||||
/* CR6B[0]VCK Input Selection: 1 = External clock. */
|
||||
RegCR6B = viafb_read_reg(VIACR, CR6B);
|
||||
viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
|
||||
|
||||
/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
|
||||
[0] Software Control Power Sequence */
|
||||
RegCR91 = viafb_read_reg(VIACR, CR91);
|
||||
viafb_write_reg(CR91, VIACR, 0x1D);
|
||||
|
||||
/* CR93[7] DI1 Data Source Selection: 1 = DSP2.
|
||||
CR93[5] DI1 Clock Source: 1 = internal.
|
||||
CR93[4] DI1 Clock Polarity.
|
||||
CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
|
||||
RegCR93 = viafb_read_reg(VIACR, CR93);
|
||||
viafb_write_reg(CR93, VIACR, 0x01);
|
||||
} else {
|
||||
/* DVP0/DVP1 Pad on */
|
||||
RegSR1E = viafb_read_reg(VIASR, SR1E);
|
||||
viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
|
||||
|
||||
/* SR3E[1]Multi-function selection:
|
||||
0 = Emulate I2C and DDC bus by GPIO2/3/4. */
|
||||
RegSR3E = viafb_read_reg(VIASR, SR3E);
|
||||
viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
|
||||
|
||||
/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
|
||||
[0] Software Control Power Sequence */
|
||||
RegCR91 = viafb_read_reg(VIACR, CR91);
|
||||
viafb_write_reg(CR91, VIACR, 0x1D);
|
||||
|
||||
/*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
|
||||
display.CR9B[2:0] DVP1 Clock Adjust */
|
||||
RegCR9B = viafb_read_reg(VIACR, CR9B);
|
||||
viafb_write_reg(CR9B, VIACR, 0x01);
|
||||
}
|
||||
|
||||
data = (u8) tmds_register_read(0x09);
|
||||
if (data & 0x04)
|
||||
ret = true;
|
||||
|
||||
if (ret == false) {
|
||||
if (viafb_dvi_query_EDID())
|
||||
ret = true;
|
||||
}
|
||||
|
||||
/* Restore status */
|
||||
viafb_write_reg(SR1E, VIASR, RegSR1E);
|
||||
viafb_write_reg(CR91, VIACR, RegCR91);
|
||||
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
||||
viafb_write_reg(CR6B, VIACR, RegCR6B);
|
||||
viafb_write_reg(CR93, VIACR, RegCR93);
|
||||
} else {
|
||||
viafb_write_reg(SR3E, VIASR, RegSR3E);
|
||||
viafb_write_reg(CR9B, VIACR, RegCR9B);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Query Flat Panel's EDID Table Version Through DVI Connector */
|
||||
static int viafb_dvi_query_EDID(void)
|
||||
{
|
||||
u8 data0, data1;
|
||||
int restore;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
|
||||
|
||||
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
|
||||
|
||||
data0 = (u8) tmds_register_read(0x00);
|
||||
data1 = (u8) tmds_register_read(0x01);
|
||||
if ((data0 == 0) && (data1 == 0xFF)) {
|
||||
viaparinfo->chip_info->
|
||||
tmds_chip_info.tmds_chip_slave_addr = restore;
|
||||
return EDID_VERSION_1; /* Found EDID1 Table */
|
||||
}
|
||||
|
||||
data0 = (u8) tmds_register_read(0x00);
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
||||
if (data0 == 0x20)
|
||||
return EDID_VERSION_2; /* Found EDID2 Table */
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* int dvi_get_panel_size_from_DDCv1(void)
|
||||
*
|
||||
* - Get Panel Size Using EDID1 Table
|
||||
*
|
||||
* Return Type: int
|
||||
*
|
||||
*/
|
||||
static int dvi_get_panel_size_from_DDCv1(void)
|
||||
{
|
||||
int i, max_h = 0, max_v = 0, tmp, restore;
|
||||
unsigned char rData;
|
||||
unsigned char EDID_DATA[18];
|
||||
|
||||
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
|
||||
|
||||
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
|
||||
|
||||
rData = tmds_register_read(0x23);
|
||||
if (rData & 0x3C)
|
||||
max_h = 640;
|
||||
if (rData & 0xC0)
|
||||
max_h = 720;
|
||||
if (rData & 0x03)
|
||||
max_h = 800;
|
||||
|
||||
rData = tmds_register_read(0x24);
|
||||
if (rData & 0xC0)
|
||||
max_h = 800;
|
||||
if (rData & 0x1E)
|
||||
max_h = 1024;
|
||||
if (rData & 0x01)
|
||||
max_h = 1280;
|
||||
|
||||
for (i = 0x25; i < 0x6D; i++) {
|
||||
switch (i) {
|
||||
case 0x26:
|
||||
case 0x28:
|
||||
case 0x2A:
|
||||
case 0x2C:
|
||||
case 0x2E:
|
||||
case 0x30:
|
||||
case 0x32:
|
||||
case 0x34:
|
||||
rData = tmds_register_read(i);
|
||||
if (rData == 1)
|
||||
break;
|
||||
/* data = (data + 31) * 8 */
|
||||
tmp = (rData + 31) << 3;
|
||||
if (tmp > max_h)
|
||||
max_h = tmp;
|
||||
break;
|
||||
|
||||
case 0x36:
|
||||
case 0x48:
|
||||
case 0x5A:
|
||||
case 0x6C:
|
||||
tmds_register_read_bytes(i, EDID_DATA, 10);
|
||||
if (!(EDID_DATA[0] || EDID_DATA[1])) {
|
||||
/* The first two byte must be zero. */
|
||||
if (EDID_DATA[3] == 0xFD) {
|
||||
/* To get max pixel clock. */
|
||||
viaparinfo->tmds_setting_info->
|
||||
max_pixel_clock = EDID_DATA[9] * 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (max_h) {
|
||||
case 640:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_640X480;
|
||||
break;
|
||||
case 800:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_800X600;
|
||||
break;
|
||||
case 1024:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1024X768;
|
||||
break;
|
||||
case 1280:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1280X1024;
|
||||
break;
|
||||
case 1400:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1400X1050;
|
||||
break;
|
||||
case 1440:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1440X1050;
|
||||
break;
|
||||
case 1600:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1600X1200;
|
||||
break;
|
||||
case 1920:
|
||||
if (max_v == 1200) {
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1920X1200;
|
||||
} else {
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1920X1080;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1024X768;
|
||||
DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
|
||||
set default panel size.\n", max_h);
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
|
||||
viaparinfo->tmds_setting_info->max_pixel_clock);
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
||||
return viaparinfo->tmds_setting_info->dvi_panel_size;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* int dvi_get_panel_size_from_DDCv2(void)
|
||||
*
|
||||
* - Get Panel Size Using EDID2 Table
|
||||
*
|
||||
* Return Type: int
|
||||
*
|
||||
*/
|
||||
static int dvi_get_panel_size_from_DDCv2(void)
|
||||
{
|
||||
int HSize = 0, restore;
|
||||
unsigned char R_Buffer[2];
|
||||
|
||||
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
|
||||
|
||||
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
|
||||
|
||||
/* Horizontal: 0x76, 0x77 */
|
||||
tmds_register_read_bytes(0x76, R_Buffer, 2);
|
||||
HSize = R_Buffer[0];
|
||||
HSize += R_Buffer[1] << 8;
|
||||
|
||||
switch (HSize) {
|
||||
case 640:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_640X480;
|
||||
break;
|
||||
case 800:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_800X600;
|
||||
break;
|
||||
case 1024:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1024X768;
|
||||
break;
|
||||
case 1280:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1280X1024;
|
||||
break;
|
||||
case 1400:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1400X1050;
|
||||
break;
|
||||
case 1440:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1440X1050;
|
||||
break;
|
||||
case 1600:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1600X1200;
|
||||
break;
|
||||
default:
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size =
|
||||
VIA_RES_1024X768;
|
||||
DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
|
||||
set default panel size.\n", HSize);
|
||||
break;
|
||||
}
|
||||
|
||||
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
||||
return viaparinfo->tmds_setting_info->dvi_panel_size;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* unsigned char dvi_get_panel_info(void)
|
||||
*
|
||||
* - Get Panel Size
|
||||
*
|
||||
* Return Type: unsigned char
|
||||
*/
|
||||
static unsigned char dvi_get_panel_info(void)
|
||||
{
|
||||
unsigned char dvipanelsize;
|
||||
DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
|
||||
|
||||
viafb_dvi_sense();
|
||||
switch (viafb_dvi_query_EDID()) {
|
||||
case 1:
|
||||
dvi_get_panel_size_from_DDCv1();
|
||||
break;
|
||||
case 2:
|
||||
dvi_get_panel_size_from_DDCv2();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
|
||||
viaparinfo->tmds_setting_info->dvi_panel_size);
|
||||
dvipanelsize = (unsigned char)(viaparinfo->
|
||||
tmds_setting_info->dvi_panel_size);
|
||||
return dvipanelsize;
|
||||
}
|
||||
|
||||
/* If Disable DVI, turn off pad */
|
||||
void viafb_dvi_disable(void)
|
||||
{
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DVP0)
|
||||
viafb_write_reg(SR1E, VIASR,
|
||||
viafb_read_reg(VIASR, SR1E) & (~0xC0));
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DVP1)
|
||||
viafb_write_reg(SR1E, VIASR,
|
||||
viafb_read_reg(VIASR, SR1E) & (~0x30));
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
|
||||
viafb_write_reg(SR2A, VIASR,
|
||||
viafb_read_reg(VIASR, SR2A) & (~0x0C));
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
|
||||
viafb_write_reg(SR2A, VIASR,
|
||||
viafb_read_reg(VIASR, SR2A) & (~0x03));
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_TMDS)
|
||||
/* Turn off TMDS power. */
|
||||
viafb_write_reg(CRD2, VIACR,
|
||||
viafb_read_reg(VIACR, CRD2) | 0x08);
|
||||
}
|
||||
|
||||
/* If Enable DVI, turn off pad */
|
||||
void viafb_dvi_enable(void)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DVP0) {
|
||||
viafb_write_reg(SR1E, VIASR,
|
||||
viafb_read_reg(VIASR, SR1E) | 0xC0);
|
||||
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
|
||||
tmds_register_write(0x88, 0x3b);
|
||||
else
|
||||
/*clear CR91[5] to direct on display period
|
||||
in the secondary diplay path */
|
||||
viafb_write_reg(CR91, VIACR,
|
||||
viafb_read_reg(VIACR, CR91) & 0xDF);
|
||||
}
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DVP1) {
|
||||
viafb_write_reg(SR1E, VIASR,
|
||||
viafb_read_reg(VIASR, SR1E) | 0x30);
|
||||
|
||||
/*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
|
||||
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
||||
tmds_register_write(0x88, 0x3b);
|
||||
} else {
|
||||
/*clear CR91[5] to direct on display period
|
||||
in the secondary diplay path */
|
||||
viafb_write_reg(CR91, VIACR,
|
||||
viafb_read_reg(VIACR, CR91) & 0xDF);
|
||||
}
|
||||
|
||||
/*fix DVI cannot enable on EPIA-M board */
|
||||
if (viafb_platform_epia_dvi == 1) {
|
||||
viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
|
||||
viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
|
||||
if (viafb_bus_width == 24) {
|
||||
if (viafb_device_lcd_dualedge == 1)
|
||||
data = 0x3F;
|
||||
else
|
||||
data = 0x37;
|
||||
viafb_i2c_writebyte(viaparinfo->chip_info->
|
||||
tmds_chip_info.
|
||||
tmds_chip_slave_addr,
|
||||
0x08, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
|
||||
viafb_write_reg(SR2A, VIASR,
|
||||
viafb_read_reg(VIASR, SR2A) | 0x0C);
|
||||
viafb_write_reg(CR91, VIACR,
|
||||
viafb_read_reg(VIACR, CR91) & 0xDF);
|
||||
}
|
||||
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
|
||||
viafb_write_reg(SR2A, VIASR,
|
||||
viafb_read_reg(VIASR, SR2A) | 0x03);
|
||||
viafb_write_reg(CR91, VIACR,
|
||||
viafb_read_reg(VIACR, CR91) & 0xDF);
|
||||
}
|
||||
if (viaparinfo->chip_info->
|
||||
tmds_chip_info.output_interface == INTERFACE_TMDS) {
|
||||
/* Turn on Display period in the panel path. */
|
||||
viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
|
||||
|
||||
/* Turn on TMDS power. */
|
||||
viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
|
||||
}
|
||||
}
|
||||
|
||||
64
drivers/video/via/dvi.h
Normal file
64
drivers/video/via/dvi.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DVI_H__
|
||||
#define __DVI_H__
|
||||
|
||||
/*Definition TMDS Device ID register*/
|
||||
#define VT1632_DEVICE_ID_REG 0x02
|
||||
#define VT1632_DEVICE_ID 0x92
|
||||
|
||||
#define GET_DVI_SIZE_BY_SYSTEM_BIOS 0x01
|
||||
#define GET_DVI_SIZE_BY_VGA_BIOS 0x02
|
||||
#define GET_DVI_SZIE_BY_HW_STRAPPING 0x03
|
||||
|
||||
/* Definition DVI Panel ID*/
|
||||
/* Resolution: 640x480, Channel: single, Dithering: Enable */
|
||||
#define DVI_PANEL_ID0_640X480 0x00
|
||||
/* Resolution: 800x600, Channel: single, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_800x600 0x01
|
||||
/* Resolution: 1024x768, Channel: single, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_1024x768 0x02
|
||||
/* Resolution: 1280x768, Channel: single, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_1280x768 0x03
|
||||
/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_1280x1024 0x04
|
||||
/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_1400x1050 0x05
|
||||
/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
|
||||
#define DVI_PANEL_ID1_1600x1200 0x06
|
||||
|
||||
/* Define the version of EDID*/
|
||||
#define EDID_VERSION_1 1
|
||||
#define EDID_VERSION_2 2
|
||||
|
||||
#define DEV_CONNECT_DVI 0x01
|
||||
#define DEV_CONNECT_HDMI 0x02
|
||||
|
||||
struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
|
||||
int viafb_dvi_sense(void);
|
||||
void viafb_dvi_disable(void);
|
||||
void viafb_dvi_enable(void);
|
||||
int viafb_tmds_trasmitter_identify(void);
|
||||
void viafb_init_dvi_size(void);
|
||||
void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
|
||||
|
||||
#endif /* __DVI_H__ */
|
||||
60
drivers/video/via/global.c
Normal file
60
drivers/video/via/global.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "global.h"
|
||||
int viafb_platform_epia_dvi = STATE_OFF;
|
||||
int viafb_device_lcd_dualedge = STATE_OFF;
|
||||
int viafb_bus_width = 12;
|
||||
int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
|
||||
int viafb_memsize;
|
||||
int viafb_DeviceStatus = CRT_Device;
|
||||
int viafb_hotplug;
|
||||
int viafb_refresh = 60;
|
||||
int viafb_refresh1 = 60;
|
||||
int viafb_lcd_dsp_method = LCD_EXPANDSION;
|
||||
int viafb_lcd_mode = LCD_OPENLDI;
|
||||
int viafb_bpp = 32;
|
||||
int viafb_bpp1 = 32;
|
||||
int viafb_accel = 1;
|
||||
int viafb_CRT_ON = 1;
|
||||
int viafb_DVI_ON;
|
||||
int viafb_LCD_ON ;
|
||||
int viafb_LCD2_ON;
|
||||
int viafb_SAMM_ON;
|
||||
int viafb_dual_fb;
|
||||
int viafb_hotplug_Xres = 640;
|
||||
int viafb_hotplug_Yres = 480;
|
||||
int viafb_hotplug_bpp = 32;
|
||||
int viafb_hotplug_refresh = 60;
|
||||
unsigned int viafb_second_offset;
|
||||
int viafb_second_size;
|
||||
int viafb_primary_dev = None_Device;
|
||||
void __iomem *viafb_FB_MM;
|
||||
unsigned int viafb_second_xres = 640;
|
||||
unsigned int viafb_second_yres = 480;
|
||||
unsigned int viafb_second_virtual_xres;
|
||||
unsigned int viafb_second_virtual_yres;
|
||||
int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
|
||||
struct fb_cursor viacursor;
|
||||
struct fb_info *viafbinfo;
|
||||
struct fb_info *viafbinfo1;
|
||||
struct viafb_par *viaparinfo;
|
||||
struct viafb_par *viaparinfo1;
|
||||
|
||||
90
drivers/video/via/global.h
Normal file
90
drivers/video/via/global.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GLOBAL_H__
|
||||
#define __GLOBAL_H__
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "iface.h"
|
||||
#include "viafbdev.h"
|
||||
#include "chip.h"
|
||||
#include "debug.h"
|
||||
#include "accel.h"
|
||||
#include "share.h"
|
||||
#include "dvi.h"
|
||||
#include "viamode.h"
|
||||
#include "via_i2c.h"
|
||||
#include "hw.h"
|
||||
|
||||
#include "lcd.h"
|
||||
#include "ioctl.h"
|
||||
#include "viamode.h"
|
||||
#include "via_utility.h"
|
||||
#include "vt1636.h"
|
||||
#include "tblDPASetting.h"
|
||||
#include "tbl1636.h"
|
||||
#include "viafbdev.h"
|
||||
|
||||
/* External struct*/
|
||||
|
||||
extern int viafb_platform_epia_dvi;
|
||||
extern int viafb_device_lcd_dualedge;
|
||||
extern int viafb_bus_width;
|
||||
extern int viafb_display_hardware_layout;
|
||||
extern struct offset offset_reg;
|
||||
extern struct viafb_par *viaparinfo;
|
||||
extern struct viafb_par *viaparinfo1;
|
||||
extern struct fb_info *viafbinfo;
|
||||
extern struct fb_info *viafbinfo1;
|
||||
extern int viafb_DeviceStatus;
|
||||
extern int viafb_refresh;
|
||||
extern int viafb_refresh1;
|
||||
extern int viafb_lcd_dsp_method;
|
||||
extern int viafb_lcd_mode;
|
||||
extern int viafb_bpp;
|
||||
extern int viafb_bpp1;
|
||||
|
||||
extern int viafb_CRT_ON;
|
||||
extern int viafb_hotplug_Xres;
|
||||
extern int viafb_hotplug_Yres;
|
||||
extern int viafb_hotplug_bpp;
|
||||
extern int viafb_hotplug_refresh;
|
||||
extern int viafb_primary_dev;
|
||||
extern void __iomem *viafb_FB_MM;
|
||||
extern struct fb_cursor viacursor;
|
||||
|
||||
extern unsigned int viafb_second_xres;
|
||||
extern unsigned int viafb_second_yres;
|
||||
extern int viafb_lcd_panel_id;
|
||||
|
||||
#endif /* __GLOBAL_H__ */
|
||||
2865
drivers/video/via/hw.c
Normal file
2865
drivers/video/via/hw.c
Normal file
File diff suppressed because it is too large
Load diff
933
drivers/video/via/hw.h
Normal file
933
drivers/video/via/hw.h
Normal file
|
|
@ -0,0 +1,933 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __HW_H__
|
||||
#define __HW_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/***************************************************
|
||||
* Definition IGA1 Design Method of CRTC Registers *
|
||||
****************************************************/
|
||||
#define IGA1_HOR_TOTAL_FORMULA(x) (((x)/8)-5)
|
||||
#define IGA1_HOR_ADDR_FORMULA(x) (((x)/8)-1)
|
||||
#define IGA1_HOR_BLANK_START_FORMULA(x) (((x)/8)-1)
|
||||
#define IGA1_HOR_BLANK_END_FORMULA(x, y) (((x+y)/8)-1)
|
||||
#define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8)
|
||||
#define IGA1_HOR_SYNC_END_FORMULA(x, y) ((x+y)/8)
|
||||
|
||||
#define IGA1_VER_TOTAL_FORMULA(x) ((x)-2)
|
||||
#define IGA1_VER_ADDR_FORMULA(x) ((x)-1)
|
||||
#define IGA1_VER_BLANK_START_FORMULA(x) ((x)-1)
|
||||
#define IGA1_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
|
||||
#define IGA1_VER_SYNC_START_FORMULA(x) ((x)-1)
|
||||
#define IGA1_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
|
||||
|
||||
/***************************************************
|
||||
** Definition IGA2 Design Method of CRTC Registers *
|
||||
****************************************************/
|
||||
#define IGA2_HOR_TOTAL_FORMULA(x) ((x)-1)
|
||||
#define IGA2_HOR_ADDR_FORMULA(x) ((x)-1)
|
||||
#define IGA2_HOR_BLANK_START_FORMULA(x) ((x)-1)
|
||||
#define IGA2_HOR_BLANK_END_FORMULA(x, y) ((x+y)-1)
|
||||
#define IGA2_HOR_SYNC_START_FORMULA(x) ((x)-1)
|
||||
#define IGA2_HOR_SYNC_END_FORMULA(x, y) ((x+y)-1)
|
||||
|
||||
#define IGA2_VER_TOTAL_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_ADDR_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_BLANK_START_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
|
||||
#define IGA2_VER_SYNC_START_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
|
||||
|
||||
/**********************************************************/
|
||||
/* Definition IGA2 Design Method of CRTC Shadow Registers */
|
||||
/**********************************************************/
|
||||
#define IGA2_HOR_TOTAL_SHADOW_FORMULA(x) ((x/8)-5)
|
||||
#define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x, y) (((x+y)/8)-1)
|
||||
#define IGA2_VER_TOTAL_SHADOW_FORMULA(x) ((x)-2)
|
||||
#define IGA2_VER_ADDR_SHADOW_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_BLANK_START_SHADOW_FORMULA(x) ((x)-1)
|
||||
#define IGA2_VER_BLANK_END_SHADOW_FORMULA(x, y) ((x+y)-1)
|
||||
#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x)
|
||||
#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y)
|
||||
|
||||
/* Define Register Number for IGA1 CRTC Timing */
|
||||
|
||||
/* location: {CR00,0,7},{CR36,3,3} */
|
||||
#define IGA1_HOR_TOTAL_REG_NUM 2
|
||||
/* location: {CR01,0,7} */
|
||||
#define IGA1_HOR_ADDR_REG_NUM 1
|
||||
/* location: {CR02,0,7} */
|
||||
#define IGA1_HOR_BLANK_START_REG_NUM 1
|
||||
/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
|
||||
#define IGA1_HOR_BLANK_END_REG_NUM 3
|
||||
/* location: {CR04,0,7},{CR33,4,4} */
|
||||
#define IGA1_HOR_SYNC_START_REG_NUM 2
|
||||
/* location: {CR05,0,4} */
|
||||
#define IGA1_HOR_SYNC_END_REG_NUM 1
|
||||
/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
|
||||
#define IGA1_VER_TOTAL_REG_NUM 4
|
||||
/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
|
||||
#define IGA1_VER_ADDR_REG_NUM 4
|
||||
/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
|
||||
#define IGA1_VER_BLANK_START_REG_NUM 4
|
||||
/* location: {CR16,0,7} */
|
||||
#define IGA1_VER_BLANK_END_REG_NUM 1
|
||||
/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
|
||||
#define IGA1_VER_SYNC_START_REG_NUM 4
|
||||
/* location: {CR11,0,3} */
|
||||
#define IGA1_VER_SYNC_END_REG_NUM 1
|
||||
|
||||
/* Define Register Number for IGA2 Shadow CRTC Timing */
|
||||
|
||||
/* location: {CR6D,0,7},{CR71,3,3} */
|
||||
#define IGA2_SHADOW_HOR_TOTAL_REG_NUM 2
|
||||
/* location: {CR6E,0,7} */
|
||||
#define IGA2_SHADOW_HOR_BLANK_END_REG_NUM 1
|
||||
/* location: {CR6F,0,7},{CR71,0,2} */
|
||||
#define IGA2_SHADOW_VER_TOTAL_REG_NUM 2
|
||||
/* location: {CR70,0,7},{CR71,4,6} */
|
||||
#define IGA2_SHADOW_VER_ADDR_REG_NUM 2
|
||||
/* location: {CR72,0,7},{CR74,4,6} */
|
||||
#define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2
|
||||
/* location: {CR73,0,7},{CR74,0,2} */
|
||||
#define IGA2_SHADOW_VER_BLANK_END_REG_NUM 2
|
||||
/* location: {CR75,0,7},{CR76,4,6} */
|
||||
#define IGA2_SHADOW_VER_SYNC_START_REG_NUM 2
|
||||
/* location: {CR76,0,3} */
|
||||
#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1
|
||||
|
||||
/* Define Register Number for IGA2 CRTC Timing */
|
||||
|
||||
/* location: {CR50,0,7},{CR55,0,3} */
|
||||
#define IGA2_HOR_TOTAL_REG_NUM 2
|
||||
/* location: {CR51,0,7},{CR55,4,6} */
|
||||
#define IGA2_HOR_ADDR_REG_NUM 2
|
||||
/* location: {CR52,0,7},{CR54,0,2} */
|
||||
#define IGA2_HOR_BLANK_START_REG_NUM 2
|
||||
/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
|
||||
is reserved, so it may have problem to set 1600x1200 on IGA2. */
|
||||
/* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
|
||||
#define IGA2_HOR_BLANK_END_REG_NUM 3
|
||||
/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
|
||||
/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
|
||||
#define IGA2_HOR_SYNC_START_REG_NUM 4
|
||||
|
||||
/* location: {CR57,0,7},{CR5C,6,6} */
|
||||
#define IGA2_HOR_SYNC_END_REG_NUM 2
|
||||
/* location: {CR58,0,7},{CR5D,0,2} */
|
||||
#define IGA2_VER_TOTAL_REG_NUM 2
|
||||
/* location: {CR59,0,7},{CR5D,3,5} */
|
||||
#define IGA2_VER_ADDR_REG_NUM 2
|
||||
/* location: {CR5A,0,7},{CR5C,0,2} */
|
||||
#define IGA2_VER_BLANK_START_REG_NUM 2
|
||||
/* location: {CR5E,0,7},{CR5C,3,5} */
|
||||
#define IGA2_VER_BLANK_END_REG_NUM 2
|
||||
/* location: {CR5E,0,7},{CR5F,5,7} */
|
||||
#define IGA2_VER_SYNC_START_REG_NUM 2
|
||||
/* location: {CR5F,0,4} */
|
||||
#define IGA2_VER_SYNC_END_REG_NUM 1
|
||||
|
||||
/* Define Offset and Fetch Count Register*/
|
||||
|
||||
/* location: {CR13,0,7},{CR35,5,7} */
|
||||
#define IGA1_OFFSET_REG_NUM 2
|
||||
/* 8 bytes alignment. */
|
||||
#define IGA1_OFFSER_ALIGN_BYTE 8
|
||||
/* x: H resolution, y: color depth */
|
||||
#define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE)
|
||||
/* location: {SR1C,0,7},{SR1D,0,1} */
|
||||
#define IGA1_FETCH_COUNT_REG_NUM 2
|
||||
/* 16 bytes alignment. */
|
||||
#define IGA1_FETCH_COUNT_ALIGN_BYTE 16
|
||||
/* x: H resolution, y: color depth */
|
||||
#define IGA1_FETCH_COUNT_PATCH_VALUE 4
|
||||
#define IGA1_FETCH_COUNT_FORMULA(x, y) \
|
||||
(((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE)
|
||||
|
||||
/* location: {CR66,0,7},{CR67,0,1} */
|
||||
#define IGA2_OFFSET_REG_NUM 2
|
||||
#define IGA2_OFFSET_ALIGN_BYTE 8
|
||||
/* x: H resolution, y: color depth */
|
||||
#define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE)
|
||||
/* location: {CR65,0,7},{CR67,2,3} */
|
||||
#define IGA2_FETCH_COUNT_REG_NUM 2
|
||||
#define IGA2_FETCH_COUNT_ALIGN_BYTE 16
|
||||
#define IGA2_FETCH_COUNT_PATCH_VALUE 0
|
||||
#define IGA2_FETCH_COUNT_FORMULA(x, y) \
|
||||
(((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE) + IGA2_FETCH_COUNT_PATCH_VALUE)
|
||||
|
||||
/* Staring Address*/
|
||||
|
||||
/* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */
|
||||
#define IGA1_STARTING_ADDR_REG_NUM 4
|
||||
/* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */
|
||||
#define IGA2_STARTING_ADDR_REG_NUM 3
|
||||
|
||||
/* Define Display OFFSET*/
|
||||
/* These value are by HW suggested value*/
|
||||
/* location: {SR17,0,7} */
|
||||
#define K800_IGA1_FIFO_MAX_DEPTH 384
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define K800_IGA1_FIFO_THRESHOLD 328
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define K800_IGA1_FIFO_HIGH_THRESHOLD 296
|
||||
/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
|
||||
/* because HW only 5 bits */
|
||||
#define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
|
||||
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define K800_IGA2_FIFO_MAX_DEPTH 384
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define K800_IGA2_FIFO_THRESHOLD 328
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define K800_IGA2_FIFO_HIGH_THRESHOLD 296
|
||||
/* location: {CR94,0,6} */
|
||||
#define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
|
||||
|
||||
/* location: {SR17,0,7} */
|
||||
#define P880_IGA1_FIFO_MAX_DEPTH 192
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define P880_IGA1_FIFO_THRESHOLD 128
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define P880_IGA1_FIFO_HIGH_THRESHOLD 64
|
||||
/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
|
||||
/* because HW only 5 bits */
|
||||
#define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
|
||||
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define P880_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define P880_IGA2_FIFO_THRESHOLD 64
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define P880_IGA2_FIFO_HIGH_THRESHOLD 32
|
||||
/* location: {CR94,0,6} */
|
||||
#define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
|
||||
|
||||
/* VT3314 chipset*/
|
||||
|
||||
/* location: {SR17,0,7} */
|
||||
#define CN700_IGA1_FIFO_MAX_DEPTH 96
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define CN700_IGA1_FIFO_THRESHOLD 80
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define CN700_IGA1_FIFO_HIGH_THRESHOLD 64
|
||||
/* location: {SR22,0,4}. (128/4) =64, P800 must be set zero,
|
||||
because HW only 5 bits */
|
||||
#define CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define CN700_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define CN700_IGA2_FIFO_THRESHOLD 80
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define CN700_IGA2_FIFO_HIGH_THRESHOLD 32
|
||||
/* location: {CR94,0,6} */
|
||||
#define CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
|
||||
|
||||
/* For VT3324, these values are suggested by HW */
|
||||
/* location: {SR17,0,7} */
|
||||
#define CX700_IGA1_FIFO_MAX_DEPTH 192
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define CX700_IGA1_FIFO_THRESHOLD 128
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define CX700_IGA1_FIFO_HIGH_THRESHOLD 128
|
||||
/* location: {SR22,0,4} */
|
||||
#define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
|
||||
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define CX700_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define CX700_IGA2_FIFO_THRESHOLD 64
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define CX700_IGA2_FIFO_HIGH_THRESHOLD 32
|
||||
/* location: {CR94,0,6} */
|
||||
#define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
|
||||
|
||||
/* VT3336 chipset*/
|
||||
/* location: {SR17,0,7} */
|
||||
#define K8M890_IGA1_FIFO_MAX_DEPTH 360
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define K8M890_IGA1_FIFO_THRESHOLD 328
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define K8M890_IGA1_FIFO_HIGH_THRESHOLD 296
|
||||
/* location: {SR22,0,4}. */
|
||||
#define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
|
||||
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define K8M890_IGA2_FIFO_MAX_DEPTH 360
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define K8M890_IGA2_FIFO_THRESHOLD 328
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define K8M890_IGA2_FIFO_HIGH_THRESHOLD 296
|
||||
/* location: {CR94,0,6} */
|
||||
#define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 124
|
||||
|
||||
/* VT3327 chipset*/
|
||||
/* location: {SR17,0,7} */
|
||||
#define P4M890_IGA1_FIFO_MAX_DEPTH 96
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define P4M890_IGA1_FIFO_THRESHOLD 76
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define P4M890_IGA1_FIFO_HIGH_THRESHOLD 64
|
||||
/* location: {SR22,0,4}. (32/4) =8 */
|
||||
#define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define P4M890_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define P4M890_IGA2_FIFO_THRESHOLD 76
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define P4M890_IGA2_FIFO_HIGH_THRESHOLD 64
|
||||
/* location: {CR94,0,6} */
|
||||
#define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
|
||||
|
||||
/* VT3364 chipset*/
|
||||
/* location: {SR17,0,7} */
|
||||
#define P4M900_IGA1_FIFO_MAX_DEPTH 96
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define P4M900_IGA1_FIFO_THRESHOLD 76
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define P4M900_IGA1_FIFO_HIGH_THRESHOLD 76
|
||||
/* location: {SR22,0,4}. */
|
||||
#define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define P4M900_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define P4M900_IGA2_FIFO_THRESHOLD 76
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define P4M900_IGA2_FIFO_HIGH_THRESHOLD 76
|
||||
/* location: {CR94,0,6} */
|
||||
#define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
|
||||
|
||||
/* For VT3353, these values are suggested by HW */
|
||||
/* location: {SR17,0,7} */
|
||||
#define VX800_IGA1_FIFO_MAX_DEPTH 192
|
||||
/* location: {SR16,0,5},{SR16,7,7} */
|
||||
#define VX800_IGA1_FIFO_THRESHOLD 152
|
||||
/* location: {SR18,0,5},{SR18,7,7} */
|
||||
#define VX800_IGA1_FIFO_HIGH_THRESHOLD 152
|
||||
/* location: {SR22,0,4} */
|
||||
#define VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 64
|
||||
/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
|
||||
#define VX800_IGA2_FIFO_MAX_DEPTH 96
|
||||
/* location: {CR68,0,3},{CR95,4,6} */
|
||||
#define VX800_IGA2_FIFO_THRESHOLD 64
|
||||
/* location: {CR92,0,3},{CR95,0,2} */
|
||||
#define VX800_IGA2_FIFO_HIGH_THRESHOLD 32
|
||||
/* location: {CR94,0,6} */
|
||||
#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
|
||||
|
||||
#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1
|
||||
#define IGA1_FIFO_THRESHOLD_REG_NUM 2
|
||||
#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2
|
||||
#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
|
||||
|
||||
#define IGA2_FIFO_DEPTH_SELECT_REG_NUM 3
|
||||
#define IGA2_FIFO_THRESHOLD_REG_NUM 2
|
||||
#define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM 2
|
||||
#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
|
||||
|
||||
#define IGA1_FIFO_DEPTH_SELECT_FORMULA(x) ((x/2)-1)
|
||||
#define IGA1_FIFO_THRESHOLD_FORMULA(x) (x/4)
|
||||
#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
|
||||
#define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
|
||||
#define IGA2_FIFO_DEPTH_SELECT_FORMULA(x) (((x/2)/4)-1)
|
||||
#define IGA2_FIFO_THRESHOLD_FORMULA(x) (x/4)
|
||||
#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
|
||||
#define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
|
||||
|
||||
/************************************************************************/
|
||||
/* LCD Timing */
|
||||
/************************************************************************/
|
||||
|
||||
/* 500 ms = 500000 us */
|
||||
#define LCD_POWER_SEQ_TD0 500000
|
||||
/* 50 ms = 50000 us */
|
||||
#define LCD_POWER_SEQ_TD1 50000
|
||||
/* 0 us */
|
||||
#define LCD_POWER_SEQ_TD2 0
|
||||
/* 210 ms = 210000 us */
|
||||
#define LCD_POWER_SEQ_TD3 210000
|
||||
/* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */
|
||||
#define CLE266_POWER_SEQ_UNIT 71
|
||||
/* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */
|
||||
#define K800_POWER_SEQ_UNIT 142
|
||||
/* 2^13 * (1/14.31818M) = 572.1 us */
|
||||
#define P880_POWER_SEQ_UNIT 572
|
||||
|
||||
#define CLE266_POWER_SEQ_FORMULA(x) ((x)/CLE266_POWER_SEQ_UNIT)
|
||||
#define K800_POWER_SEQ_FORMULA(x) ((x)/K800_POWER_SEQ_UNIT)
|
||||
#define P880_POWER_SEQ_FORMULA(x) ((x)/P880_POWER_SEQ_UNIT)
|
||||
|
||||
/* location: {CR8B,0,7},{CR8F,0,3} */
|
||||
#define LCD_POWER_SEQ_TD0_REG_NUM 2
|
||||
/* location: {CR8C,0,7},{CR8F,4,7} */
|
||||
#define LCD_POWER_SEQ_TD1_REG_NUM 2
|
||||
/* location: {CR8D,0,7},{CR90,0,3} */
|
||||
#define LCD_POWER_SEQ_TD2_REG_NUM 2
|
||||
/* location: {CR8E,0,7},{CR90,4,7} */
|
||||
#define LCD_POWER_SEQ_TD3_REG_NUM 2
|
||||
|
||||
/* LCD Scaling factor*/
|
||||
/* x: indicate setting horizontal size*/
|
||||
/* y: indicate panel horizontal size*/
|
||||
|
||||
/* Horizontal scaling factor 10 bits (2^10) */
|
||||
#define CLE266_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
|
||||
/* Vertical scaling factor 10 bits (2^10) */
|
||||
#define CLE266_LCD_VER_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
|
||||
/* Horizontal scaling factor 10 bits (2^12) */
|
||||
#define K800_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*4096)/(y-1))
|
||||
/* Vertical scaling factor 10 bits (2^11) */
|
||||
#define K800_LCD_VER_SCF_FORMULA(x, y) (((x-1)*2048)/(y-1))
|
||||
|
||||
/* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */
|
||||
#define LCD_HOR_SCALING_FACTOR_REG_NUM 3
|
||||
/* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */
|
||||
#define LCD_VER_SCALING_FACTOR_REG_NUM 3
|
||||
/* location: {CR77,0,7},{CR79,4,5} */
|
||||
#define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE 2
|
||||
/* location: {CR78,0,7},{CR79,6,7} */
|
||||
#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2
|
||||
|
||||
/************************************************
|
||||
***** Define IGA1 Display Timing *****
|
||||
************************************************/
|
||||
struct io_register {
|
||||
u8 io_addr;
|
||||
u8 start_bit;
|
||||
u8 end_bit;
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Total */
|
||||
struct iga1_hor_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Addressable Video */
|
||||
struct iga1_hor_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Blank Start */
|
||||
struct iga1_hor_blank_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Blank End */
|
||||
struct iga1_hor_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Sync Start */
|
||||
struct iga1_hor_sync_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Horizontal Sync End */
|
||||
struct iga1_hor_sync_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Total */
|
||||
struct iga1_ver_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Addressable Video */
|
||||
struct iga1_ver_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Blank Start */
|
||||
struct iga1_ver_blank_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Blank End */
|
||||
struct iga1_ver_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Sync Start */
|
||||
struct iga1_ver_sync_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Vertical Sync End */
|
||||
struct iga1_ver_sync_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
** Define IGA2 Shadow Display Timing ****
|
||||
*****************************************************/
|
||||
|
||||
/* IGA2 Shadow Horizontal Total */
|
||||
struct iga2_shadow_hor_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Horizontal Blank End */
|
||||
struct iga2_shadow_hor_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Total */
|
||||
struct iga2_shadow_ver_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Addressable Video */
|
||||
struct iga2_shadow_ver_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Blank Start */
|
||||
struct iga2_shadow_ver_blank_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Blank End */
|
||||
struct iga2_shadow_ver_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Sync Start */
|
||||
struct iga2_shadow_ver_sync_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Shadow Vertical Sync End */
|
||||
struct iga2_shadow_ver_sync_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
** Define IGA2 Display Timing ****
|
||||
******************************************************/
|
||||
|
||||
/* IGA2 Horizontal Total */
|
||||
struct iga2_hor_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Horizontal Addressable Video */
|
||||
struct iga2_hor_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Horizontal Blank Start */
|
||||
struct iga2_hor_blank_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Horizontal Blank End */
|
||||
struct iga2_hor_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Horizontal Sync Start */
|
||||
struct iga2_hor_sync_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Horizontal Sync End */
|
||||
struct iga2_hor_sync_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Total */
|
||||
struct iga2_ver_total {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Addressable Video */
|
||||
struct iga2_ver_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Blank Start */
|
||||
struct iga2_ver_blank_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Blank End */
|
||||
struct iga2_ver_blank_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Sync Start */
|
||||
struct iga2_ver_sync_start {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Vertical Sync End */
|
||||
struct iga2_ver_sync_end {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA1 Offset Register */
|
||||
struct iga1_offset {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_OFFSET_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Offset Register */
|
||||
struct iga2_offset {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_OFFSET_REG_NUM];
|
||||
};
|
||||
|
||||
struct offset {
|
||||
struct iga1_offset iga1_offset_reg;
|
||||
struct iga2_offset iga2_offset_reg;
|
||||
};
|
||||
|
||||
/* IGA1 Fetch Count Register */
|
||||
struct iga1_fetch_count {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_FETCH_COUNT_REG_NUM];
|
||||
};
|
||||
|
||||
/* IGA2 Fetch Count Register */
|
||||
struct iga2_fetch_count {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_FETCH_COUNT_REG_NUM];
|
||||
};
|
||||
|
||||
struct fetch_count {
|
||||
struct iga1_fetch_count iga1_fetch_count_reg;
|
||||
struct iga2_fetch_count iga2_fetch_count_reg;
|
||||
};
|
||||
|
||||
/* Starting Address Register */
|
||||
struct iga1_starting_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_STARTING_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga2_starting_addr {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_STARTING_ADDR_REG_NUM];
|
||||
};
|
||||
|
||||
struct starting_addr {
|
||||
struct iga1_starting_addr iga1_starting_addr_reg;
|
||||
struct iga2_starting_addr iga2_starting_addr_reg;
|
||||
};
|
||||
|
||||
/* LCD Power Sequence Timer */
|
||||
struct lcd_pwd_seq_td0 {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM];
|
||||
};
|
||||
|
||||
struct lcd_pwd_seq_td1 {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM];
|
||||
};
|
||||
|
||||
struct lcd_pwd_seq_td2 {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM];
|
||||
};
|
||||
|
||||
struct lcd_pwd_seq_td3 {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM];
|
||||
};
|
||||
|
||||
struct _lcd_pwd_seq_timer {
|
||||
struct lcd_pwd_seq_td0 td0;
|
||||
struct lcd_pwd_seq_td1 td1;
|
||||
struct lcd_pwd_seq_td2 td2;
|
||||
struct lcd_pwd_seq_td3 td3;
|
||||
};
|
||||
|
||||
/* LCD Scaling Factor */
|
||||
struct _lcd_hor_scaling_factor {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM];
|
||||
};
|
||||
|
||||
struct _lcd_ver_scaling_factor {
|
||||
int reg_num;
|
||||
struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM];
|
||||
};
|
||||
|
||||
struct _lcd_scaling_factor {
|
||||
struct _lcd_hor_scaling_factor lcd_hor_scaling_factor;
|
||||
struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
|
||||
};
|
||||
|
||||
struct pll_map {
|
||||
u32 clk;
|
||||
u32 cle266_pll;
|
||||
u32 k800_pll;
|
||||
u32 cx700_pll;
|
||||
};
|
||||
|
||||
struct rgbLUT {
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
};
|
||||
|
||||
struct lcd_pwd_seq_timer {
|
||||
u16 td0;
|
||||
u16 td1;
|
||||
u16 td2;
|
||||
u16 td3;
|
||||
};
|
||||
|
||||
/* Display FIFO Relation Registers*/
|
||||
struct iga1_fifo_depth_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga1_fifo_threshold_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga1_fifo_high_threshold_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga1_display_queue_expire_num {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga2_fifo_depth_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga2_fifo_threshold_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga2_fifo_high_threshold_select {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM];
|
||||
};
|
||||
|
||||
struct iga2_display_queue_expire_num {
|
||||
int reg_num;
|
||||
struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
|
||||
};
|
||||
|
||||
struct fifo_depth_select {
|
||||
struct iga1_fifo_depth_select iga1_fifo_depth_select_reg;
|
||||
struct iga2_fifo_depth_select iga2_fifo_depth_select_reg;
|
||||
};
|
||||
|
||||
struct fifo_threshold_select {
|
||||
struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg;
|
||||
struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg;
|
||||
};
|
||||
|
||||
struct fifo_high_threshold_select {
|
||||
struct iga1_fifo_high_threshold_select
|
||||
iga1_fifo_high_threshold_select_reg;
|
||||
struct iga2_fifo_high_threshold_select
|
||||
iga2_fifo_high_threshold_select_reg;
|
||||
};
|
||||
|
||||
struct display_queue_expire_num {
|
||||
struct iga1_display_queue_expire_num
|
||||
iga1_display_queue_expire_num_reg;
|
||||
struct iga2_display_queue_expire_num
|
||||
iga2_display_queue_expire_num_reg;
|
||||
};
|
||||
|
||||
struct iga1_crtc_timing {
|
||||
struct iga1_hor_total hor_total;
|
||||
struct iga1_hor_addr hor_addr;
|
||||
struct iga1_hor_blank_start hor_blank_start;
|
||||
struct iga1_hor_blank_end hor_blank_end;
|
||||
struct iga1_hor_sync_start hor_sync_start;
|
||||
struct iga1_hor_sync_end hor_sync_end;
|
||||
struct iga1_ver_total ver_total;
|
||||
struct iga1_ver_addr ver_addr;
|
||||
struct iga1_ver_blank_start ver_blank_start;
|
||||
struct iga1_ver_blank_end ver_blank_end;
|
||||
struct iga1_ver_sync_start ver_sync_start;
|
||||
struct iga1_ver_sync_end ver_sync_end;
|
||||
};
|
||||
|
||||
struct iga2_shadow_crtc_timing {
|
||||
struct iga2_shadow_hor_total hor_total_shadow;
|
||||
struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
|
||||
struct iga2_shadow_ver_total ver_total_shadow;
|
||||
struct iga2_shadow_ver_addr ver_addr_shadow;
|
||||
struct iga2_shadow_ver_blank_start ver_blank_start_shadow;
|
||||
struct iga2_shadow_ver_blank_end ver_blank_end_shadow;
|
||||
struct iga2_shadow_ver_sync_start ver_sync_start_shadow;
|
||||
struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
|
||||
};
|
||||
|
||||
struct iga2_crtc_timing {
|
||||
struct iga2_hor_total hor_total;
|
||||
struct iga2_hor_addr hor_addr;
|
||||
struct iga2_hor_blank_start hor_blank_start;
|
||||
struct iga2_hor_blank_end hor_blank_end;
|
||||
struct iga2_hor_sync_start hor_sync_start;
|
||||
struct iga2_hor_sync_end hor_sync_end;
|
||||
struct iga2_ver_total ver_total;
|
||||
struct iga2_ver_addr ver_addr;
|
||||
struct iga2_ver_blank_start ver_blank_start;
|
||||
struct iga2_ver_blank_end ver_blank_end;
|
||||
struct iga2_ver_sync_start ver_sync_start;
|
||||
struct iga2_ver_sync_end ver_sync_end;
|
||||
};
|
||||
|
||||
/* device ID */
|
||||
#define CLE266 0x3123
|
||||
#define KM400 0x3205
|
||||
#define CN400_FUNCTION2 0x2259
|
||||
#define CN400_FUNCTION3 0x3259
|
||||
/* support VT3314 chipset */
|
||||
#define CN700_FUNCTION2 0x2314
|
||||
#define CN700_FUNCTION3 0x3208
|
||||
/* VT3324 chipset */
|
||||
#define CX700_FUNCTION2 0x2324
|
||||
#define CX700_FUNCTION3 0x3324
|
||||
/* VT3204 chipset*/
|
||||
#define KM800_FUNCTION3 0x3204
|
||||
/* VT3336 chipset*/
|
||||
#define KM890_FUNCTION3 0x3336
|
||||
/* VT3327 chipset*/
|
||||
#define P4M890_FUNCTION3 0x3327
|
||||
/* VT3293 chipset*/
|
||||
#define CN750_FUNCTION3 0x3208
|
||||
/* VT3364 chipset*/
|
||||
#define P4M900_FUNCTION3 0x3364
|
||||
/* VT3353 chipset*/
|
||||
#define VX800_FUNCTION3 0x3353
|
||||
|
||||
#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
|
||||
|
||||
struct IODATA {
|
||||
u8 Index;
|
||||
u8 Mask;
|
||||
u8 Data;
|
||||
};
|
||||
|
||||
struct pci_device_id_info {
|
||||
u32 vendor;
|
||||
u32 device;
|
||||
u32 chip_index;
|
||||
};
|
||||
|
||||
extern unsigned int viafb_second_virtual_xres;
|
||||
extern unsigned int viafb_second_offset;
|
||||
extern int viafb_second_size;
|
||||
extern int viafb_SAMM_ON;
|
||||
extern int viafb_dual_fb;
|
||||
extern int viafb_LCD2_ON;
|
||||
extern int viafb_LCD_ON;
|
||||
extern int viafb_DVI_ON;
|
||||
extern int viafb_accel;
|
||||
extern int viafb_hotplug;
|
||||
|
||||
void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
|
||||
void viafb_set_output_path(int device, int set_iga,
|
||||
int output_interface);
|
||||
void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
|
||||
int mode_index, int bpp_byte, int set_iga);
|
||||
|
||||
void viafb_set_vclock(u32 CLK, int set_iga);
|
||||
void viafb_load_reg(int timing_value, int viafb_load_reg_num,
|
||||
struct io_register *reg,
|
||||
int io_type);
|
||||
void viafb_crt_disable(void);
|
||||
void viafb_crt_enable(void);
|
||||
void init_ad9389(void);
|
||||
/* Access I/O Function */
|
||||
void viafb_write_reg(u8 index, u16 io_port, u8 data);
|
||||
u8 viafb_read_reg(int io_port, u8 index);
|
||||
void viafb_lock_crt(void);
|
||||
void viafb_unlock_crt(void);
|
||||
void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
|
||||
void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
|
||||
void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
|
||||
struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
|
||||
u32 viafb_get_clk_value(int clk);
|
||||
void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
|
||||
void viafb_set_color_depth(int bpp_byte, int set_iga);
|
||||
void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
|
||||
*p_gfx_dpa_setting);
|
||||
|
||||
int viafb_setmode(int vmode_index, int hor_res, int ver_res,
|
||||
int video_bpp, int vmode_index1, int hor_res1,
|
||||
int ver_res1, int video_bpp1);
|
||||
void viafb_init_chip_info(void);
|
||||
void viafb_init_dac(int set_iga);
|
||||
int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
|
||||
int viafb_get_refresh(int hres, int vres, u32 float_refresh);
|
||||
void viafb_update_device_setting(int hres, int vres, int bpp,
|
||||
int vmode_refresh, int flag);
|
||||
void viafb_get_mmio_info(unsigned long *mmio_base,
|
||||
unsigned long *mmio_len);
|
||||
|
||||
void viafb_set_iga_path(void);
|
||||
void viafb_set_start_addr(void);
|
||||
void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
|
||||
|
||||
#endif /* __HW_H__ */
|
||||
78
drivers/video/via/iface.c
Normal file
78
drivers/video/via/iface.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/* Get frame buffer size from VGA BIOS */
|
||||
|
||||
unsigned int viafb_get_memsize(void)
|
||||
{
|
||||
unsigned int m;
|
||||
|
||||
/* If memory size provided by user */
|
||||
if (viafb_memsize)
|
||||
m = viafb_memsize * Mb;
|
||||
else {
|
||||
m = (unsigned int)viafb_read_reg(VIASR, SR39);
|
||||
m = m * (4 * Mb);
|
||||
|
||||
if ((m < (16 * Mb)) || (m > (64 * Mb)))
|
||||
m = 16 * Mb;
|
||||
}
|
||||
DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
|
||||
return m;
|
||||
}
|
||||
|
||||
/* Get Video Buffer Starting Physical Address(back door)*/
|
||||
|
||||
unsigned long viafb_get_videobuf_addr(void)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
unsigned char sys_mem;
|
||||
unsigned char video_mem;
|
||||
unsigned long sys_mem_size;
|
||||
unsigned long video_mem_size;
|
||||
/*system memory = 256 MB, video memory 64 MB */
|
||||
unsigned long vmem_starting_adr = 0x0C000000;
|
||||
|
||||
pdev =
|
||||
(struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
|
||||
VIA_K800_BRIDGE_DID, NULL);
|
||||
if (pdev != NULL) {
|
||||
pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
|
||||
&sys_mem);
|
||||
pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
|
||||
&video_mem);
|
||||
video_mem = (video_mem & 0x70) >> 4;
|
||||
sys_mem_size = ((unsigned long)sys_mem) << 24;
|
||||
if (video_mem != 0)
|
||||
video_mem_size = (1 << (video_mem)) * 1024 * 1024;
|
||||
else
|
||||
video_mem_size = 0;
|
||||
|
||||
vmem_starting_adr = sys_mem_size - video_mem_size;
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
|
||||
vmem_starting_adr);
|
||||
return vmem_starting_adr;
|
||||
}
|
||||
38
drivers/video/via/iface.h
Normal file
38
drivers/video/via/iface.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __IFACE_H__
|
||||
#define __IFACE_H__
|
||||
|
||||
#define Kb (1024)
|
||||
#define Mb (Kb*Kb)
|
||||
|
||||
#define VIA_K800_BRIDGE_VID 0x1106
|
||||
#define VIA_K800_BRIDGE_DID 0x3204
|
||||
|
||||
#define VIA_K800_SYSTEM_MEMORY_REG 0x47
|
||||
#define VIA_K800_VIDEO_MEMORY_REG 0xA1
|
||||
|
||||
extern int viafb_memsize;
|
||||
unsigned int viafb_get_memsize(void);
|
||||
unsigned long viafb_get_videobuf_addr(void);
|
||||
|
||||
#endif /* __IFACE_H__ */
|
||||
112
drivers/video/via/ioctl.c
Normal file
112
drivers/video/via/ioctl.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
int viafb_ioctl_get_viafb_info(u_long arg)
|
||||
{
|
||||
struct viafb_ioctl_info viainfo;
|
||||
|
||||
viainfo.viafb_id = VIAID;
|
||||
viainfo.vendor_id = PCI_VIA_VENDOR_ID;
|
||||
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_CLE266:
|
||||
viainfo.device_id = UNICHROME_CLE266_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_K400:
|
||||
viainfo.device_id = UNICHROME_K400_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_K800:
|
||||
viainfo.device_id = UNICHROME_K800_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_PM800:
|
||||
viainfo.device_id = UNICHROME_PM800_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_CN700:
|
||||
viainfo.device_id = UNICHROME_CN700_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_CX700:
|
||||
viainfo.device_id = UNICHROME_CX700_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_K8M890:
|
||||
viainfo.device_id = UNICHROME_K8M890_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_P4M890:
|
||||
viainfo.device_id = UNICHROME_P4M890_DID;
|
||||
break;
|
||||
|
||||
case UNICHROME_P4M900:
|
||||
viainfo.device_id = UNICHROME_P4M900_DID;
|
||||
break;
|
||||
}
|
||||
|
||||
viainfo.version = VERSION_MAJOR;
|
||||
viainfo.revision = VERSION_MINOR;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hot-Plug Priority: DVI > CRT*/
|
||||
int viafb_ioctl_hotplug(int hres, int vres, int bpp)
|
||||
{
|
||||
int DVIsense, status = 0;
|
||||
DEBUG_MSG(KERN_INFO "viafb_ioctl_hotplug!!\n");
|
||||
|
||||
if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name !=
|
||||
NON_TMDS_TRANSMITTER) {
|
||||
DVIsense = viafb_dvi_sense();
|
||||
|
||||
if (DVIsense) {
|
||||
DEBUG_MSG(KERN_INFO "DVI Attached...\n");
|
||||
if (viafb_DeviceStatus != DVI_Device) {
|
||||
viafb_DVI_ON = 1;
|
||||
viafb_CRT_ON = 0;
|
||||
viafb_LCD_ON = 0;
|
||||
viafb_DeviceStatus = DVI_Device;
|
||||
return viafb_DeviceStatus;
|
||||
}
|
||||
status = 1;
|
||||
} else
|
||||
DEBUG_MSG(KERN_INFO "DVI De-attached...\n");
|
||||
}
|
||||
|
||||
if ((viafb_DeviceStatus != CRT_Device) && (status == 0)) {
|
||||
viafb_CRT_ON = 1;
|
||||
viafb_DVI_ON = 0;
|
||||
viafb_LCD_ON = 0;
|
||||
|
||||
viafb_DeviceStatus = CRT_Device;
|
||||
return viafb_DeviceStatus;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
210
drivers/video/via/ioctl.h
Normal file
210
drivers/video/via/ioctl.h
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __IOCTL_H__
|
||||
#define __IOCTL_H__
|
||||
|
||||
#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
|
||||
/* VIAFB IOCTL definition */
|
||||
#define VIAFB_GET_INFO_SIZE 0x56494101 /* 'VIA\01' */
|
||||
#define VIAFB_GET_INFO 0x56494102 /* 'VIA\02' */
|
||||
#define VIAFB_HOTPLUG 0x56494103 /* 'VIA\03' */
|
||||
#define VIAFB_SET_HOTPLUG_FLAG 0x56494104 /* 'VIA\04' */
|
||||
#define VIAFB_GET_RESOLUTION 0x56494105 /* 'VIA\05' */
|
||||
#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */
|
||||
#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */
|
||||
#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */
|
||||
#define VIAFB_SET_DEVICE 0x5649410A
|
||||
#define VIAFB_GET_DEVICE 0x5649410B
|
||||
#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */
|
||||
#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */
|
||||
#define VIAFB_SET_DEVICE_INFO 0x56494114
|
||||
#define VIAFB_GET_DEVICE_INFO 0x56494115
|
||||
|
||||
#define VIAFB_GET_DEVICE_SUPPORT 0x56494118
|
||||
#define VIAFB_GET_DEVICE_CONNECT 0x56494119
|
||||
#define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A
|
||||
#define VIAFB_GET_DRIVER_NAME 0x56494122
|
||||
#define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123
|
||||
#define VIAFB_GET_GAMMA_LUT 0x56494124
|
||||
#define VIAFB_SET_GAMMA_LUT 0x56494125
|
||||
#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
|
||||
#define VIAFB_SET_VIDEO_DEVICE 0x56494127
|
||||
#define VIAFB_GET_VIDEO_DEVICE 0x56494128
|
||||
#define VIAFB_SET_SECOND_MODE 0x56494129
|
||||
#define VIAFB_SYNC_SURFACE 0x56494130
|
||||
#define VIAFB_GET_DRIVER_CAPS 0x56494131
|
||||
#define VIAFB_GET_IGA_SCALING_INFO 0x56494132
|
||||
#define VIAFB_GET_PANEL_MAX_SIZE 0x56494133
|
||||
#define VIAFB_GET_PANEL_MAX_POSITION 0x56494134
|
||||
#define VIAFB_SET_PANEL_SIZE 0x56494135
|
||||
#define VIAFB_SET_PANEL_POSITION 0x56494136
|
||||
#define VIAFB_GET_PANEL_POSITION 0x56494137
|
||||
#define VIAFB_GET_PANEL_SIZE 0x56494138
|
||||
|
||||
#define None_Device 0x00
|
||||
#define CRT_Device 0x01
|
||||
#define LCD_Device 0x02
|
||||
#define DVI_Device 0x08
|
||||
#define CRT2_Device 0x10
|
||||
#define LCD2_Device 0x40
|
||||
|
||||
#define OP_LCD_CENTERING 0x01
|
||||
#define OP_LCD_PANEL_ID 0x02
|
||||
#define OP_LCD_MODE 0x03
|
||||
|
||||
/*SAMM operation flag*/
|
||||
#define OP_SAMM 0x80
|
||||
|
||||
#define LCD_PANEL_ID_MAXIMUM 22
|
||||
|
||||
#define STATE_ON 0x1
|
||||
#define STATE_OFF 0x0
|
||||
#define STATE_DEFAULT 0xFFFF
|
||||
|
||||
#define MAX_ACTIVE_DEV_NUM 2
|
||||
|
||||
struct device_t {
|
||||
unsigned short crt:1;
|
||||
unsigned short dvi:1;
|
||||
unsigned short lcd:1;
|
||||
unsigned short samm:1;
|
||||
unsigned short lcd_dsp_cent:1;
|
||||
unsigned char lcd_mode:1;
|
||||
unsigned short epia_dvi:1;
|
||||
unsigned short lcd_dual_edge:1;
|
||||
unsigned short lcd2:1;
|
||||
|
||||
unsigned short primary_dev;
|
||||
unsigned char lcd_panel_id;
|
||||
unsigned short xres, yres;
|
||||
unsigned short xres1, yres1;
|
||||
unsigned short refresh;
|
||||
unsigned short bpp;
|
||||
unsigned short refresh1;
|
||||
unsigned short bpp1;
|
||||
unsigned short sequence;
|
||||
unsigned short bus_width;
|
||||
};
|
||||
|
||||
struct viafb_ioctl_info {
|
||||
u32 viafb_id; /* for identifying viafb */
|
||||
#define VIAID 0x56494146 /* Identify myself with 'VIAF' */
|
||||
u16 vendor_id;
|
||||
u16 device_id;
|
||||
u8 version;
|
||||
u8 revision;
|
||||
u8 reserved[246]; /* for future use */
|
||||
};
|
||||
|
||||
struct viafb_ioctl_mode {
|
||||
u32 xres;
|
||||
u32 yres;
|
||||
u32 refresh;
|
||||
u32 bpp;
|
||||
u32 xres_sec;
|
||||
u32 yres_sec;
|
||||
u32 virtual_xres_sec;
|
||||
u32 virtual_yres_sec;
|
||||
u32 refresh_sec;
|
||||
u32 bpp_sec;
|
||||
};
|
||||
struct viafb_ioctl_samm {
|
||||
u32 samm_status;
|
||||
u32 size_prim;
|
||||
u32 size_sec;
|
||||
u32 mem_base;
|
||||
u32 offset_sec;
|
||||
};
|
||||
|
||||
struct viafb_driver_version {
|
||||
int iMajorNum;
|
||||
int iKernelNum;
|
||||
int iOSNum;
|
||||
int iMinorNum;
|
||||
};
|
||||
|
||||
struct viafb_ioctl_lcd_attribute {
|
||||
unsigned int panel_id;
|
||||
unsigned int display_center;
|
||||
unsigned int lcd_mode;
|
||||
};
|
||||
|
||||
struct viafb_ioctl_setting {
|
||||
/* Enable or disable active devices */
|
||||
unsigned short device_flag;
|
||||
/* Indicate which device should be turn on or turn off. */
|
||||
unsigned short device_status;
|
||||
unsigned int reserved;
|
||||
/* Indicate which LCD's attribute can be changed. */
|
||||
unsigned short lcd_operation_flag;
|
||||
/* 1: SAMM ON 0: SAMM OFF */
|
||||
unsigned short samm_status;
|
||||
/* horizontal resolution of first device */
|
||||
unsigned short first_dev_hor_res;
|
||||
/* vertical resolution of first device */
|
||||
unsigned short first_dev_ver_res;
|
||||
/* horizontal resolution of second device */
|
||||
unsigned short second_dev_hor_res;
|
||||
/* vertical resolution of second device */
|
||||
unsigned short second_dev_ver_res;
|
||||
/* refresh rate of first device */
|
||||
unsigned short first_dev_refresh;
|
||||
/* bpp of first device */
|
||||
unsigned short first_dev_bpp;
|
||||
/* refresh rate of second device */
|
||||
unsigned short second_dev_refresh;
|
||||
/* bpp of second device */
|
||||
unsigned short second_dev_bpp;
|
||||
/* Indicate which device are primary display device. */
|
||||
unsigned int primary_device;
|
||||
/* Indicate which device will show video. only valid in duoview mode */
|
||||
unsigned int video_device_status;
|
||||
unsigned int struct_reserved[34];
|
||||
struct viafb_ioctl_lcd_attribute lcd_attributes;
|
||||
};
|
||||
|
||||
struct _UTFunctionCaps {
|
||||
unsigned int dw3DScalingState;
|
||||
unsigned int reserved[31];
|
||||
};
|
||||
|
||||
struct _POSITIONVALUE {
|
||||
unsigned int dwX;
|
||||
unsigned int dwY;
|
||||
};
|
||||
|
||||
struct _panel_size_pos_info {
|
||||
unsigned int device_type;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
extern int viafb_LCD_ON;
|
||||
extern int viafb_DVI_ON;
|
||||
|
||||
int viafb_ioctl_get_viafb_info(u_long arg);
|
||||
int viafb_ioctl_hotplug(int hres, int vres, int bpp);
|
||||
|
||||
#endif /* __IOCTL_H__ */
|
||||
1821
drivers/video/via/lcd.c
Normal file
1821
drivers/video/via/lcd.c
Normal file
File diff suppressed because it is too large
Load diff
94
drivers/video/via/lcd.h
Normal file
94
drivers/video/via/lcd.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __LCD_H__
|
||||
#define __LCD_H__
|
||||
|
||||
/*Definition TMDS Device ID register*/
|
||||
#define VT1631_DEVICE_ID_REG 0x02
|
||||
#define VT1631_DEVICE_ID 0x92
|
||||
|
||||
#define VT3271_DEVICE_ID_REG 0x02
|
||||
#define VT3271_DEVICE_ID 0x71
|
||||
|
||||
#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01
|
||||
#define GET_LCD_SIZE_BY_VGA_BIOS 0x02
|
||||
#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03
|
||||
#define GET_LCD_SIZE_BY_USER_SETTING 0x04
|
||||
|
||||
/* Definition DVI Panel ID*/
|
||||
/* Resolution: 640x480, Channel: single, Dithering: Enable */
|
||||
#define LCD_PANEL_ID0_640X480 0x00
|
||||
/* Resolution: 800x600, Channel: single, Dithering: Enable */
|
||||
#define LCD_PANEL_ID1_800X600 0x01
|
||||
/* Resolution: 1024x768, Channel: single, Dithering: Enable */
|
||||
#define LCD_PANEL_ID2_1024X768 0x02
|
||||
/* Resolution: 1280x768, Channel: single, Dithering: Enable */
|
||||
#define LCD_PANEL_ID3_1280X768 0x03
|
||||
/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
|
||||
#define LCD_PANEL_ID4_1280X1024 0x04
|
||||
/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
|
||||
#define LCD_PANEL_ID5_1400X1050 0x05
|
||||
/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
|
||||
#define LCD_PANEL_ID6_1600X1200 0x06
|
||||
/* Resolution: 1366x768, Channel: single, Dithering: Disable */
|
||||
#define LCD_PANEL_ID7_1366X768 0x07
|
||||
/* Resolution: 1024x600, Channel: single, Dithering: Enable*/
|
||||
#define LCD_PANEL_ID8_1024X600 0x08
|
||||
/* Resolution: 1280x800, Channel: single, Dithering: Enable*/
|
||||
#define LCD_PANEL_ID9_1280X800 0x09
|
||||
/* Resolution: 800x480, Channel: single, Dithering: Enable*/
|
||||
#define LCD_PANEL_IDA_800X480 0x0A
|
||||
/* Resolution: 1360x768, Channel: single, Dithering: Disable*/
|
||||
#define LCD_PANEL_IDB_1360X768 0x0B
|
||||
/* Resolution: 480x640, Channel: single, Dithering: Enable */
|
||||
#define LCD_PANEL_IDC_480X640 0x0C
|
||||
|
||||
|
||||
extern int viafb_LCD2_ON;
|
||||
extern int viafb_LCD_ON;
|
||||
extern int viafb_DVI_ON;
|
||||
|
||||
void viafb_disable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_enable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_lcd_disable(void);
|
||||
void viafb_lcd_enable(void);
|
||||
void viafb_init_lcd_size(void);
|
||||
void viafb_init_lvds_output_interface(struct lvds_chip_information
|
||||
*plvds_chip_info,
|
||||
struct lvds_setting_information
|
||||
*plvds_setting_info);
|
||||
void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
int viafb_lvds_trasmitter_identify(void);
|
||||
void viafb_init_lvds_output_interface(struct lvds_chip_information
|
||||
*plvds_chip_info,
|
||||
struct lvds_setting_information
|
||||
*plvds_setting_info);
|
||||
bool viafb_lcd_get_mobile_state(bool *mobile);
|
||||
void viafb_load_crtc_timing(struct display_timing device_timing,
|
||||
int set_iga);
|
||||
|
||||
#endif /* __LCD_H__ */
|
||||
591
drivers/video/via/lcdtbl.h
Normal file
591
drivers/video/via/lcdtbl.h
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __LCDTBL_H__
|
||||
#define __LCDTBL_H__
|
||||
|
||||
#include "share.h"
|
||||
|
||||
/* CLE266 Software Power Sequence */
|
||||
/* {Mask}, {Data}, {Delay} */
|
||||
int PowerSequenceOn[3][3] =
|
||||
{ {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} };
|
||||
int PowerSequenceOff[3][3] =
|
||||
{ {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} };
|
||||
|
||||
/* ++++++ P880 ++++++ */
|
||||
/* Panel 1600x1200 */
|
||||
struct io_reg P880_LCD_RES_6X4_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x5E},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C},
|
||||
{VIASR, SR46, 0xFF, 0x02}
|
||||
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12)
|
||||
|
||||
struct io_reg P880_LCD_RES_7X4_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x78},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C},
|
||||
{VIASR, SR46, 0xFF, 0x01}
|
||||
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12)
|
||||
|
||||
struct io_reg P880_LCD_RES_8X6_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88},
|
||||
{VIASR, SR46, 0xFF, 0x03}
|
||||
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12)
|
||||
|
||||
struct io_reg P880_LCD_RES_10X7_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xAF},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88},
|
||||
{VIASR, SR46, 0xFF, 0x03}
|
||||
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12)
|
||||
|
||||
struct io_reg P880_LCD_RES_12X10_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xD4},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88},
|
||||
{VIASR, SR46, 0xFF, 0x05}
|
||||
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12)
|
||||
|
||||
/* Panel 1400x1050 */
|
||||
struct io_reg P880_LCD_RES_6X4_14X10[] = {
|
||||
/* 640x480 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x63},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C},
|
||||
{VIASR, SR46, 0xFF, 0x05}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10)
|
||||
|
||||
struct io_reg P880_LCD_RES_8X6_14X10[] = {
|
||||
/* 800x600 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D},
|
||||
{VIASR, SR46, 0xFF, 0x05}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10)
|
||||
|
||||
/* ++++++ K400 ++++++ */
|
||||
/* Panel 1600x1200 */
|
||||
struct io_reg K400_LCD_RES_6X4_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x5E},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12)
|
||||
|
||||
struct io_reg K400_LCD_RES_7X4_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x78},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12)
|
||||
|
||||
struct io_reg K400_LCD_RES_8X6_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12)
|
||||
|
||||
struct io_reg K400_LCD_RES_10X7_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xAF},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12)
|
||||
|
||||
struct io_reg K400_LCD_RES_12X10_16X12[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
|
||||
{VIACR, CR5D, 0x40, 0x40},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xD4},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12)
|
||||
|
||||
/* Panel 1400x1050 */
|
||||
struct io_reg K400_LCD_RES_6X4_14X10[] = {
|
||||
/* 640x400 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x63},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_8X6_14X10[] = {
|
||||
/* 800x600 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_10X7_14X10[] = {
|
||||
/* 1024x768 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xA7},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_12X10_14X10[] = {
|
||||
/* 1280x768, 1280x960, 1280x1024 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xD2},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10)
|
||||
|
||||
/* ++++++ K400 ++++++ */
|
||||
/* Panel 1366x768 */
|
||||
struct io_reg K400_LCD_RES_6X4_1366X7[] = {
|
||||
/* 640x400 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x64},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_7X4_1366X7[] = {
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x75},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_8X6_1366X7[] = {
|
||||
/* 800x600 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x82},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_10X7_1366X7[] = {
|
||||
/* 1024x768 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xA7},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_12X10_1366X7[] = {
|
||||
/* 1280x768, 1280x960, 1280x1024 */
|
||||
/* IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
|
||||
/* IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
|
||||
{VIACR, CR5D, 0x40, 0x24},
|
||||
/* IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
|
||||
/* IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xD2},
|
||||
/* IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
|
||||
/* VCLK */
|
||||
{VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\
|
||||
ARRAY_SIZE(K400_LCD_RES_12X10_1366X7)
|
||||
|
||||
/* ++++++ K400 ++++++ */
|
||||
/* Panel 1280x1024 */
|
||||
struct io_reg K400_LCD_RES_6X4_12X10[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
|
||||
{VIACR, CR5D, 0x40, 0x1C},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x63},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_7X4_12X10[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
|
||||
{VIACR, CR5D, 0x40, 0x1C},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x6C},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_8X6_12X10[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
|
||||
{VIACR, CR5D, 0x40, 0x1C},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10)
|
||||
|
||||
struct io_reg K400_LCD_RES_10X7_12X10[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
|
||||
{VIACR, CR5D, 0x40, 0x1C},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0xA7},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10)
|
||||
|
||||
/* ++++++ K400 ++++++ */
|
||||
/* Panel 1024x768 */
|
||||
struct io_reg K400_LCD_RES_6X4_10X7[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x64},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_7X4_10X7[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x75},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7)
|
||||
|
||||
struct io_reg K400_LCD_RES_8X6_10X7[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
|
||||
{VIACR, CR5D, 0x40, 0x13},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x82},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7)
|
||||
|
||||
/* ++++++ K400 ++++++ */
|
||||
/* Panel 800x600 */
|
||||
struct io_reg K400_LCD_RES_6X4_8X6[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3},
|
||||
{VIACR, CR5D, 0x40, 0x12},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x63},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6)
|
||||
|
||||
struct io_reg K400_LCD_RES_7X4_8X6[] = {
|
||||
/*IGA2 Horizontal Total */
|
||||
{VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34},
|
||||
/*IGA2 Horizontal Blank End */
|
||||
{VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3},
|
||||
{VIACR, CR5D, 0x40, 0x12},
|
||||
/*IGA2 Horizontal Total Shadow */
|
||||
{VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22},
|
||||
/*IGA2 Horizontal Blank End Shadow */
|
||||
{VIACR, CR6E, 0xFF, 0x83},
|
||||
/*IGA2 Offset */
|
||||
{VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00},
|
||||
/*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59}
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6)
|
||||
|
||||
#endif /* __LCDTBL_H__ */
|
||||
1105
drivers/video/via/share.h
Normal file
1105
drivers/video/via/share.h
Normal file
File diff suppressed because it is too large
Load diff
71
drivers/video/via/tbl1636.c
Normal file
71
drivers/video/via/tbl1636.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
struct IODATA COMMON_INIT_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
/* Set panel power sequence timing */
|
||||
{0x10, 0xC0, 0x00},
|
||||
/* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
|
||||
{0x0B, 0xFF, 0x40},
|
||||
/* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
|
||||
{0x0C, 0xFF, 0x31},
|
||||
/* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
|
||||
{0x0D, 0xFF, 0x31},
|
||||
/* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
|
||||
{0x0E, 0xFF, 0x68},
|
||||
/* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
|
||||
{0x0F, 0xFF, 0x68},
|
||||
/* LVDS output power up */
|
||||
{0x09, 0xA0, 0xA0},
|
||||
/* turn on back light */
|
||||
{0x10, 0x33, 0x13}
|
||||
};
|
||||
|
||||
struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x08, 0xF0, 0xE0} /* Input Data Mode Select */
|
||||
};
|
||||
|
||||
struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x08, 0xF0, 0x00} /* Input Data Mode Select */
|
||||
};
|
||||
|
||||
struct IODATA DITHERING_ENABLE_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x0A, 0x70, 0x50}
|
||||
};
|
||||
|
||||
struct IODATA DITHERING_DISABLE_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x0A, 0x70, 0x00}
|
||||
};
|
||||
|
||||
struct IODATA VDD_ON_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x10, 0x20, 0x20}
|
||||
};
|
||||
|
||||
struct IODATA VDD_OFF_TBL_VT1636[] = {
|
||||
/* Index, Mask, Value */
|
||||
{0x10, 0x20, 0x00}
|
||||
};
|
||||
34
drivers/video/via/tbl1636.h
Normal file
34
drivers/video/via/tbl1636.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _TBL1636_H_
|
||||
#define _TBL1636_H_
|
||||
#include "hw.h"
|
||||
|
||||
extern struct IODATA COMMON_INIT_TBL_VT1636[8];
|
||||
extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1];
|
||||
extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1];
|
||||
extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1];
|
||||
extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1];
|
||||
extern struct IODATA VDD_ON_TBL_VT1636[1];
|
||||
extern struct IODATA VDD_OFF_TBL_VT1636[1];
|
||||
|
||||
#endif /* _VIA_TBL1636_H_ */
|
||||
109
drivers/video/via/tblDPASetting.c
Normal file
109
drivers/video/via/tblDPASetting.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
/* For VT3324: */
|
||||
struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = {
|
||||
/* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
|
||||
{LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
|
||||
{LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
|
||||
{LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
|
||||
{LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
|
||||
{LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
|
||||
{LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
|
||||
{LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */
|
||||
};
|
||||
|
||||
struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
|
||||
/* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
|
||||
DVP1Driving, DFPHigh, DFPLow */
|
||||
/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
|
||||
SR65, CR97, CR99 */
|
||||
/* LCK/VCK < 30000000 will use this value */
|
||||
{DPA_CLK_RANGE_30M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00},
|
||||
/* 30000000 < LCK/VCK < 50000000 will use this value */
|
||||
{DPA_CLK_RANGE_30_50M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00},
|
||||
/* 50000000 < LCK/VCK < 70000000 will use this value */
|
||||
{DPA_CLK_RANGE_50_70M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00},
|
||||
/* 70000000 < LCK/VCK < 100000000 will use this value */
|
||||
{DPA_CLK_RANGE_70_100M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00},
|
||||
/* 100000000 < LCK/VCK < 15000000 will use this value */
|
||||
{DPA_CLK_RANGE_100_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00},
|
||||
/* 15000000 < LCK/VCK will use this value */
|
||||
{DPA_CLK_RANGE_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x00,
|
||||
0x00},
|
||||
};
|
||||
|
||||
/* For VT3327: */
|
||||
struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = {
|
||||
/* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
|
||||
{LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
|
||||
{LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
|
||||
{LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
|
||||
{LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
|
||||
{LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
|
||||
{LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
|
||||
{LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */
|
||||
};
|
||||
|
||||
struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = {
|
||||
/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
|
||||
DVP1Driving, DFPHigh, DFPLow */
|
||||
/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
|
||||
SR65, CR97, CR99 */
|
||||
/* LCK/VCK < 30000000 will use this value */
|
||||
{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
|
||||
/* 30000000 < LCK/VCK < 50000000 will use this value */
|
||||
{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
|
||||
/* 50000000 < LCK/VCK < 70000000 will use this value */
|
||||
{DPA_CLK_RANGE_50_70M, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
|
||||
/* 70000000 < LCK/VCK < 100000000 will use this value */
|
||||
{DPA_CLK_RANGE_70_100M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x03},
|
||||
/* 100000000 < LCK/VCK < 15000000 will use this value */
|
||||
{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02},
|
||||
/* 15000000 < LCK/VCK will use this value */
|
||||
{DPA_CLK_RANGE_150M, 0x00, 0x20, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0D, 0x03},
|
||||
};
|
||||
|
||||
/* For VT3364: */
|
||||
struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[] = {
|
||||
/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
|
||||
DVP1Driving, DFPHigh, DFPLow */
|
||||
/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
|
||||
SR65, CR97, CR99 */
|
||||
/* LCK/VCK < 30000000 will use this value */
|
||||
{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
/* 30000000 < LCK/VCK < 50000000 will use this value */
|
||||
{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
/* 50000000 < LCK/VCK < 70000000 will use this value */
|
||||
{DPA_CLK_RANGE_50_70M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
/* 70000000 < LCK/VCK < 100000000 will use this value */
|
||||
{DPA_CLK_RANGE_70_100M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
/* 100000000 < LCK/VCK < 15000000 will use this value */
|
||||
{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
/* 15000000 < LCK/VCK will use this value */
|
||||
{DPA_CLK_RANGE_150M, 0x01, 0x00, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x08},
|
||||
};
|
||||
47
drivers/video/via/tblDPASetting.h
Normal file
47
drivers/video/via/tblDPASetting.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _TBLDPASETTING_H_
|
||||
#define _TBLDPASETTING_H_
|
||||
#include "global.h"
|
||||
|
||||
#define DPA_CLK_30M 30000000
|
||||
#define DPA_CLK_50M 50000000
|
||||
#define DPA_CLK_70M 70000000
|
||||
#define DPA_CLK_100M 100000000
|
||||
#define DPA_CLK_150M 150000000
|
||||
|
||||
enum DPA_RANGE {
|
||||
DPA_CLK_RANGE_30M,
|
||||
DPA_CLK_RANGE_30_50M,
|
||||
DPA_CLK_RANGE_50_70M,
|
||||
DPA_CLK_RANGE_70_100M,
|
||||
DPA_CLK_RANGE_100_150M,
|
||||
DPA_CLK_RANGE_150M
|
||||
};
|
||||
|
||||
extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7];
|
||||
extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6];
|
||||
extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7];
|
||||
extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[];
|
||||
extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6];
|
||||
|
||||
#endif
|
||||
177
drivers/video/via/via_i2c.c
Normal file
177
drivers/video/via/via_i2c.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
static void via_i2c_setscl(void *data, int state)
|
||||
{
|
||||
u8 val;
|
||||
struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
|
||||
|
||||
val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
|
||||
if (state)
|
||||
val |= 0x20;
|
||||
else
|
||||
val &= ~0x20;
|
||||
switch (via_i2c_chan->i2c_port) {
|
||||
case I2CPORTINDEX:
|
||||
val |= 0x01;
|
||||
break;
|
||||
case GPIOPORTINDEX:
|
||||
val |= 0x80;
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
|
||||
}
|
||||
viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
|
||||
}
|
||||
|
||||
static int via_i2c_getscl(void *data)
|
||||
{
|
||||
struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
|
||||
|
||||
if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int via_i2c_getsda(void *data)
|
||||
{
|
||||
struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
|
||||
|
||||
if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void via_i2c_setsda(void *data, int state)
|
||||
{
|
||||
u8 val;
|
||||
struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
|
||||
|
||||
val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
|
||||
if (state)
|
||||
val |= 0x10;
|
||||
else
|
||||
val &= ~0x10;
|
||||
switch (via_i2c_chan->i2c_port) {
|
||||
case I2CPORTINDEX:
|
||||
val |= 0x01;
|
||||
break;
|
||||
case GPIOPORTINDEX:
|
||||
val |= 0x40;
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
|
||||
}
|
||||
viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
|
||||
}
|
||||
|
||||
int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
|
||||
{
|
||||
u8 mm1[] = {0x00};
|
||||
struct i2c_msg msgs[2];
|
||||
|
||||
*pdata = 0;
|
||||
msgs[0].flags = 0;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[0].addr = msgs[1].addr = slave_addr / 2;
|
||||
mm1[0] = index;
|
||||
msgs[0].len = 1; msgs[1].len = 1;
|
||||
msgs[0].buf = mm1; msgs[1].buf = pdata;
|
||||
i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
|
||||
{
|
||||
u8 msg[2] = { index, data };
|
||||
struct i2c_msg msgs;
|
||||
|
||||
msgs.flags = 0;
|
||||
msgs.addr = slave_addr / 2;
|
||||
msgs.len = 2;
|
||||
msgs.buf = msg;
|
||||
return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1);
|
||||
}
|
||||
|
||||
int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
|
||||
{
|
||||
u8 mm1[] = {0x00};
|
||||
struct i2c_msg msgs[2];
|
||||
|
||||
msgs[0].flags = 0;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[0].addr = msgs[1].addr = slave_addr / 2;
|
||||
mm1[0] = index;
|
||||
msgs[0].len = 1; msgs[1].len = buff_len;
|
||||
msgs[0].buf = mm1; msgs[1].buf = buff;
|
||||
i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int viafb_create_i2c_bus(void *viapar)
|
||||
{
|
||||
int ret;
|
||||
struct viafb_par *par = (struct viafb_par *)viapar;
|
||||
|
||||
strcpy(par->i2c_stuff.adapter.name, "via_i2c");
|
||||
par->i2c_stuff.i2c_port = 0x0;
|
||||
par->i2c_stuff.adapter.owner = THIS_MODULE;
|
||||
par->i2c_stuff.adapter.id = 0x01FFFF;
|
||||
par->i2c_stuff.adapter.class = 0;
|
||||
par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo;
|
||||
par->i2c_stuff.adapter.dev.parent = NULL;
|
||||
par->i2c_stuff.algo.setsda = via_i2c_setsda;
|
||||
par->i2c_stuff.algo.setscl = via_i2c_setscl;
|
||||
par->i2c_stuff.algo.getsda = via_i2c_getsda;
|
||||
par->i2c_stuff.algo.getscl = via_i2c_getscl;
|
||||
par->i2c_stuff.algo.udelay = 40;
|
||||
par->i2c_stuff.algo.timeout = 20;
|
||||
par->i2c_stuff.algo.data = &par->i2c_stuff;
|
||||
|
||||
i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff);
|
||||
|
||||
/* Raise SCL and SDA */
|
||||
par->i2c_stuff.i2c_port = I2CPORTINDEX;
|
||||
via_i2c_setsda(&par->i2c_stuff, 1);
|
||||
via_i2c_setscl(&par->i2c_stuff, 1);
|
||||
|
||||
par->i2c_stuff.i2c_port = GPIOPORTINDEX;
|
||||
via_i2c_setsda(&par->i2c_stuff, 1);
|
||||
via_i2c_setscl(&par->i2c_stuff, 1);
|
||||
udelay(20);
|
||||
|
||||
ret = i2c_bit_add_bus(&par->i2c_stuff.adapter);
|
||||
if (ret == 0)
|
||||
DEBUG_MSG("I2C bus %s registered.\n",
|
||||
par->i2c_stuff.adapter.name);
|
||||
else
|
||||
DEBUG_MSG("Failed to register I2C bus %s.\n",
|
||||
par->i2c_stuff.adapter.name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void viafb_delete_i2c_buss(void *par)
|
||||
{
|
||||
i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter);
|
||||
}
|
||||
46
drivers/video/via/via_i2c.h
Normal file
46
drivers/video/via/via_i2c.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __VIA_I2C_H__
|
||||
#define __VIA_I2C_H__
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
struct via_i2c_stuff {
|
||||
u16 i2c_port; /* GPIO or I2C port */
|
||||
struct i2c_adapter adapter;
|
||||
struct i2c_algo_bit_data algo;
|
||||
};
|
||||
|
||||
#define I2CPORT 0x3c4
|
||||
#define I2CPORTINDEX 0x31
|
||||
#define GPIOPORT 0x3C4
|
||||
#define GPIOPORTINDEX 0x2C
|
||||
#define I2C_BUS 1
|
||||
#define GPIO_BUS 2
|
||||
#define DELAYPORT 0x3C3
|
||||
|
||||
int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata);
|
||||
int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data);
|
||||
int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len);
|
||||
int viafb_create_i2c_bus(void *par);
|
||||
void viafb_delete_i2c_buss(void *par);
|
||||
#endif /* __VIA_I2C_H__ */
|
||||
253
drivers/video/via/via_utility.c
Normal file
253
drivers/video/via/via_utility.c
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
void viafb_get_device_support_state(u32 *support_state)
|
||||
{
|
||||
*support_state = CRT_Device;
|
||||
|
||||
if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
|
||||
*support_state |= DVI_Device;
|
||||
|
||||
if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
|
||||
*support_state |= LCD_Device;
|
||||
}
|
||||
|
||||
void viafb_get_device_connect_state(u32 *connect_state)
|
||||
{
|
||||
bool mobile = false;
|
||||
|
||||
*connect_state = CRT_Device;
|
||||
|
||||
if (viafb_dvi_sense())
|
||||
*connect_state |= DVI_Device;
|
||||
|
||||
viafb_lcd_get_mobile_state(&mobile);
|
||||
if (mobile)
|
||||
*connect_state |= LCD_Device;
|
||||
}
|
||||
|
||||
bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
|
||||
{
|
||||
unsigned int support_state = 0;
|
||||
|
||||
switch (viafb_lcd_panel_id) {
|
||||
case LCD_PANEL_ID0_640X480:
|
||||
if ((xres < 640) && (yres < 480))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID1_800X600:
|
||||
if ((xres < 800) && (yres < 600))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID2_1024X768:
|
||||
if ((xres < 1024) && (yres < 768))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID3_1280X768:
|
||||
if ((xres < 1280) && (yres < 768))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID4_1280X1024:
|
||||
if ((xres < 1280) && (yres < 1024))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID5_1400X1050:
|
||||
if ((xres < 1400) && (yres < 1050))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID6_1600X1200:
|
||||
if ((xres < 1600) && (yres < 1200))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID7_1366X768:
|
||||
if ((xres < 1366) && (yres < 768))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID8_1024X600:
|
||||
if ((xres < 1024) && (yres < 600))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_ID9_1280X800:
|
||||
if ((xres < 1280) && (yres < 800))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_IDA_800X480:
|
||||
if ((xres < 800) && (yres < 480))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_IDB_1360X768:
|
||||
if ((xres < 1360) && (yres < 768))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
case LCD_PANEL_IDC_480X640:
|
||||
if ((xres < 480) && (yres < 640))
|
||||
support_state = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
support_state = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return support_state;
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
/* Gamma Function Implementation*/
|
||||
/*====================================================================*/
|
||||
|
||||
void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
|
||||
{
|
||||
int i, sr1a;
|
||||
int active_device_amount = 0;
|
||||
int device_status = viafb_DeviceStatus;
|
||||
|
||||
for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
|
||||
if (device_status & 1)
|
||||
active_device_amount++;
|
||||
device_status >>= 1;
|
||||
}
|
||||
|
||||
/* 8 bpp mode can't adjust gamma */
|
||||
if (bpp == 8)
|
||||
return ;
|
||||
|
||||
/* Enable Gamma */
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_CLE266:
|
||||
case UNICHROME_K400:
|
||||
viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
|
||||
break;
|
||||
|
||||
case UNICHROME_K800:
|
||||
case UNICHROME_PM800:
|
||||
case UNICHROME_CN700:
|
||||
case UNICHROME_CX700:
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M890:
|
||||
case UNICHROME_P4M900:
|
||||
viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
|
||||
break;
|
||||
}
|
||||
sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
|
||||
viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
|
||||
|
||||
/* Fill IGA1 Gamma Table */
|
||||
outb(0, LUT_INDEX_WRITE);
|
||||
for (i = 0; i < 256; i++) {
|
||||
outb(gamma_table[i] >> 16, LUT_DATA);
|
||||
outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
|
||||
outb(gamma_table[i] & 0xFF, LUT_DATA);
|
||||
}
|
||||
|
||||
/* If adjust Gamma value in SAMM, fill IGA1,
|
||||
IGA2 Gamma table simultanous. */
|
||||
/* Switch to IGA2 Gamma Table */
|
||||
if ((active_device_amount > 1) &&
|
||||
!((viaparinfo->chip_info->gfx_chip_name ==
|
||||
UNICHROME_CLE266) &&
|
||||
(viaparinfo->chip_info->gfx_chip_revision < 15))) {
|
||||
viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
|
||||
viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
|
||||
|
||||
/* Fill IGA2 Gamma Table */
|
||||
outb(0, LUT_INDEX_WRITE);
|
||||
for (i = 0; i < 256; i++) {
|
||||
outb(gamma_table[i] >> 16, LUT_DATA);
|
||||
outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
|
||||
outb(gamma_table[i] & 0xFF, LUT_DATA);
|
||||
}
|
||||
}
|
||||
viafb_write_reg(SR1A, VIASR, sr1a);
|
||||
}
|
||||
|
||||
void viafb_get_gamma_table(unsigned int *gamma_table)
|
||||
{
|
||||
unsigned char color_r, color_g, color_b;
|
||||
unsigned char sr1a = 0;
|
||||
int i;
|
||||
|
||||
/* Enable Gamma */
|
||||
switch (viaparinfo->chip_info->gfx_chip_name) {
|
||||
case UNICHROME_CLE266:
|
||||
case UNICHROME_K400:
|
||||
viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
|
||||
break;
|
||||
|
||||
case UNICHROME_K800:
|
||||
case UNICHROME_PM800:
|
||||
case UNICHROME_CN700:
|
||||
case UNICHROME_CX700:
|
||||
case UNICHROME_K8M890:
|
||||
case UNICHROME_P4M890:
|
||||
case UNICHROME_P4M900:
|
||||
viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
|
||||
break;
|
||||
}
|
||||
sr1a = viafb_read_reg(VIASR, SR1A);
|
||||
viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
|
||||
|
||||
/* Reading gamma table to get color value */
|
||||
outb(0, LUT_INDEX_READ);
|
||||
for (i = 0; i < 256; i++) {
|
||||
color_r = inb(LUT_DATA);
|
||||
color_g = inb(LUT_DATA);
|
||||
color_b = inb(LUT_DATA);
|
||||
gamma_table[i] =
|
||||
((((u32) color_r) << 16) |
|
||||
(((u16) color_g) << 8)) | color_b;
|
||||
}
|
||||
viafb_write_reg(SR1A, VIASR, sr1a);
|
||||
}
|
||||
|
||||
void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
|
||||
{
|
||||
if (bpp == 8)
|
||||
*support_state = None_Device;
|
||||
else
|
||||
*support_state = CRT_Device | DVI_Device | LCD_Device;
|
||||
}
|
||||
|
||||
int viafb_input_parameter_converter(int parameter_value)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (parameter_value >= 1 && parameter_value <= 9)
|
||||
result = 1 << (parameter_value - 1);
|
||||
else
|
||||
result = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
35
drivers/video/via/via_utility.h
Normal file
35
drivers/video/via/via_utility.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __VIAUTILITY_H__
|
||||
#define __VIAUTILITY_H__
|
||||
|
||||
/* These functions are used to get infomation about device's state */
|
||||
void viafb_get_device_support_state(u32 *support_state);
|
||||
void viafb_get_device_connect_state(u32 *connect_state);
|
||||
bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
|
||||
|
||||
/* These function are used to access gamma table */
|
||||
void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
|
||||
void viafb_get_gamma_table(unsigned int *gamma_table);
|
||||
void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
|
||||
int viafb_input_parameter_converter(int parameter_value);
|
||||
|
||||
#endif /* __VIAUTILITY_H__ */
|
||||
2571
drivers/video/via/viafbdev.c
Normal file
2571
drivers/video/via/viafbdev.c
Normal file
File diff suppressed because it is too large
Load diff
112
drivers/video/via/viafbdev.h
Normal file
112
drivers/video/via/viafbdev.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __VIAFBDEV_H__
|
||||
#define __VIAFBDEV_H__
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include "ioctl.h"
|
||||
#include "share.h"
|
||||
#include "chip.h"
|
||||
#include "hw.h"
|
||||
#include "via_i2c.h"
|
||||
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_KERNEL 6 /* For kernel 2.6 */
|
||||
|
||||
#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
|
||||
#define VERSION_MINOR 4
|
||||
|
||||
struct viafb_par {
|
||||
int bpp;
|
||||
int hres;
|
||||
int vres;
|
||||
int linelength;
|
||||
u32 xoffset;
|
||||
u32 yoffset;
|
||||
|
||||
void __iomem *fbmem_virt; /*framebuffer virtual memory address */
|
||||
void __iomem *io_virt; /*iospace virtual memory address */
|
||||
unsigned int fbmem; /*framebuffer physical memory address */
|
||||
unsigned int memsize; /*size of fbmem */
|
||||
unsigned int io; /*io space address */
|
||||
unsigned long mmio_base; /*mmio base address */
|
||||
unsigned long mmio_len; /*mmio base length */
|
||||
u32 fbmem_free; /* Free FB memory */
|
||||
u32 fbmem_used; /* Use FB memory size */
|
||||
u32 cursor_start; /* Cursor Start Address */
|
||||
u32 VQ_start; /* Virtual Queue Start Address */
|
||||
u32 VQ_end; /* Virtual Queue End Address */
|
||||
u32 iga_path;
|
||||
struct proc_dir_entry *proc_entry; /*viafb proc entry */
|
||||
u8 duoview; /*Is working in duoview mode? */
|
||||
|
||||
/* I2C stuff */
|
||||
struct via_i2c_stuff i2c_stuff;
|
||||
|
||||
/* All the information will be needed to set engine */
|
||||
struct tmds_setting_information *tmds_setting_info;
|
||||
struct crt_setting_information *crt_setting_info;
|
||||
struct lvds_setting_information *lvds_setting_info;
|
||||
struct lvds_setting_information *lvds_setting_info2;
|
||||
struct chip_information *chip_info;
|
||||
|
||||
/* some information related to video playing */
|
||||
int video_on_crt;
|
||||
int video_on_dvi;
|
||||
int video_on_lcd;
|
||||
|
||||
};
|
||||
struct viafb_modeinfo {
|
||||
u32 xres;
|
||||
u32 yres;
|
||||
int mode_index;
|
||||
char *mode_res;
|
||||
};
|
||||
extern unsigned int viafb_second_virtual_yres;
|
||||
extern unsigned int viafb_second_virtual_xres;
|
||||
extern unsigned int viafb_second_offset;
|
||||
extern int viafb_second_size;
|
||||
extern int viafb_SAMM_ON;
|
||||
extern int viafb_dual_fb;
|
||||
extern int viafb_LCD2_ON;
|
||||
extern int viafb_LCD_ON;
|
||||
extern int viafb_DVI_ON;
|
||||
extern int viafb_accel;
|
||||
extern int viafb_hotplug;
|
||||
extern int viafb_memsize;
|
||||
|
||||
extern int strict_strtoul(const char *cp, unsigned int base,
|
||||
unsigned long *res);
|
||||
|
||||
void viafb_memory_pitch_patch(struct fb_info *info);
|
||||
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
|
||||
int mode_index);
|
||||
int viafb_get_mode_index(int hres, int vres, int flag);
|
||||
u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information
|
||||
*plvds_chip_info, u8 index);
|
||||
void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information
|
||||
*plvds_chip_info, struct IODATA io_data);
|
||||
#endif /* __VIAFBDEV_H__ */
|
||||
1086
drivers/video/via/viamode.c
Normal file
1086
drivers/video/via/viamode.c
Normal file
File diff suppressed because it is too large
Load diff
177
drivers/video/via/viamode.h
Normal file
177
drivers/video/via/viamode.h
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __VIAMODE_H__
|
||||
#define __VIAMODE_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
struct VPITTable {
|
||||
unsigned char Misc;
|
||||
unsigned char SR[StdSR];
|
||||
unsigned char GR[StdGR];
|
||||
unsigned char AR[StdAR];
|
||||
};
|
||||
|
||||
struct VideoModeTable {
|
||||
int ModeIndex;
|
||||
struct crt_mode_table *crtc;
|
||||
int mode_array;
|
||||
};
|
||||
|
||||
struct patch_table {
|
||||
int mode_index;
|
||||
int table_length;
|
||||
struct io_reg *io_reg_table;
|
||||
};
|
||||
|
||||
struct res_map_refresh {
|
||||
int hres;
|
||||
int vres;
|
||||
int pixclock;
|
||||
int vmode_refresh;
|
||||
};
|
||||
|
||||
#define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl)
|
||||
#define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes)
|
||||
#define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs)
|
||||
#define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs)
|
||||
#define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs)
|
||||
#define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs)
|
||||
#define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs)
|
||||
#define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs)
|
||||
#define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table)
|
||||
#define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes)
|
||||
|
||||
/********************/
|
||||
/* Mode Table */
|
||||
/********************/
|
||||
|
||||
/* 480x640 */
|
||||
extern struct crt_mode_table CRTM480x640[1];
|
||||
/* 640x480*/
|
||||
extern struct crt_mode_table CRTM640x480[5];
|
||||
/*720x480 (GTF)*/
|
||||
extern struct crt_mode_table CRTM720x480[1];
|
||||
/*720x576 (GTF)*/
|
||||
extern struct crt_mode_table CRTM720x576[1];
|
||||
/* 800x480 (CVT) */
|
||||
extern struct crt_mode_table CRTM800x480[1];
|
||||
/* 800x600*/
|
||||
extern struct crt_mode_table CRTM800x600[5];
|
||||
/* 848x480 (CVT) */
|
||||
extern struct crt_mode_table CRTM848x480[1];
|
||||
/*856x480 (GTF) convert to 852x480*/
|
||||
extern struct crt_mode_table CRTM852x480[1];
|
||||
/*1024x512 (GTF)*/
|
||||
extern struct crt_mode_table CRTM1024x512[1];
|
||||
/* 1024x600*/
|
||||
extern struct crt_mode_table CRTM1024x600[1];
|
||||
/* 1024x768*/
|
||||
extern struct crt_mode_table CRTM1024x768[4];
|
||||
/* 1152x864*/
|
||||
extern struct crt_mode_table CRTM1152x864[1];
|
||||
/* 1280x720 (HDMI 720P)*/
|
||||
extern struct crt_mode_table CRTM1280x720[2];
|
||||
/*1280x768 (GTF)*/
|
||||
extern struct crt_mode_table CRTM1280x768[2];
|
||||
/* 1280x800 (CVT) */
|
||||
extern struct crt_mode_table CRTM1280x800[1];
|
||||
/*1280x960*/
|
||||
extern struct crt_mode_table CRTM1280x960[1];
|
||||
/* 1280x1024*/
|
||||
extern struct crt_mode_table CRTM1280x1024[3];
|
||||
/* 1368x768 (GTF) */
|
||||
extern struct crt_mode_table CRTM1368x768[1];
|
||||
/*1440x1050 (GTF)*/
|
||||
extern struct crt_mode_table CRTM1440x1050[1];
|
||||
/* 1600x1200*/
|
||||
extern struct crt_mode_table CRTM1600x1200[2];
|
||||
/* 1680x1050 (CVT) */
|
||||
extern struct crt_mode_table CRTM1680x1050[2];
|
||||
/* 1680x1050 (CVT Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1680x1050_RB[1];
|
||||
/* 1920x1080 (CVT)*/
|
||||
extern struct crt_mode_table CRTM1920x1080[1];
|
||||
/* 1920x1080 (CVT with Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1920x1080_RB[1];
|
||||
/* 1920x1440*/
|
||||
extern struct crt_mode_table CRTM1920x1440[2];
|
||||
/* 1400x1050 (CVT) */
|
||||
extern struct crt_mode_table CRTM1400x1050[2];
|
||||
/* 1400x1050 (CVT Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1400x1050_RB[1];
|
||||
/* 960x600 (CVT) */
|
||||
extern struct crt_mode_table CRTM960x600[1];
|
||||
/* 1000x600 (GTF) */
|
||||
extern struct crt_mode_table CRTM1000x600[1];
|
||||
/* 1024x576 (GTF) */
|
||||
extern struct crt_mode_table CRTM1024x576[1];
|
||||
/* 1088x612 (CVT) */
|
||||
extern struct crt_mode_table CRTM1088x612[1];
|
||||
/* 1152x720 (CVT) */
|
||||
extern struct crt_mode_table CRTM1152x720[1];
|
||||
/* 1200x720 (GTF) */
|
||||
extern struct crt_mode_table CRTM1200x720[1];
|
||||
/* 1280x600 (GTF) */
|
||||
extern struct crt_mode_table CRTM1280x600[1];
|
||||
/* 1360x768 (CVT) */
|
||||
extern struct crt_mode_table CRTM1360x768[1];
|
||||
/* 1360x768 (CVT Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1360x768_RB[1];
|
||||
/* 1366x768 (GTF) */
|
||||
extern struct crt_mode_table CRTM1366x768[2];
|
||||
/* 1440x900 (CVT) */
|
||||
extern struct crt_mode_table CRTM1440x900[2];
|
||||
/* 1440x900 (CVT Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1440x900_RB[1];
|
||||
/* 1600x900 (CVT) */
|
||||
extern struct crt_mode_table CRTM1600x900[1];
|
||||
/* 1600x900 (CVT Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1600x900_RB[1];
|
||||
/* 1600x1024 (GTF) */
|
||||
extern struct crt_mode_table CRTM1600x1024[1];
|
||||
/* 1792x1344 (DMT) */
|
||||
extern struct crt_mode_table CRTM1792x1344[1];
|
||||
/* 1856x1392 (DMT) */
|
||||
extern struct crt_mode_table CRTM1856x1392[1];
|
||||
/* 1920x1200 (CVT) */
|
||||
extern struct crt_mode_table CRTM1920x1200[1];
|
||||
/* 1920x1200 (CVT with Reduce Blanking) */
|
||||
extern struct crt_mode_table CRTM1920x1200_RB[1];
|
||||
/* 2048x1536 (CVT) */
|
||||
extern struct crt_mode_table CRTM2048x1536[1];
|
||||
extern struct VideoModeTable CLE266Modes[47];
|
||||
extern struct crt_mode_table CEAM1280x720[1];
|
||||
extern struct crt_mode_table CEAM1920x1080[1];
|
||||
extern struct VideoModeTable CEA_HDMI_Modes[2];
|
||||
|
||||
extern struct res_map_refresh res_map_refresh_tbl[61];
|
||||
extern struct io_reg CN400_ModeXregs[52];
|
||||
extern struct io_reg CN700_ModeXregs[66];
|
||||
extern struct io_reg KM400_ModeXregs[55];
|
||||
extern struct io_reg CX700_ModeXregs[58];
|
||||
extern struct io_reg VX800_ModeXregs[58];
|
||||
extern struct io_reg CLE266_ModeXregs[32];
|
||||
extern struct io_reg PM1024x768[2];
|
||||
extern struct patch_table res_patch_table[1];
|
||||
extern struct VPITTable VPIT;
|
||||
#endif /* __VIAMODE_H__ */
|
||||
306
drivers/video/via/vt1636.c
Normal file
306
drivers/video/via/vt1636.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
|
||||
u8 index)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
|
||||
viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information
|
||||
*plvds_chip_info, struct IODATA io_data)
|
||||
{
|
||||
int index, data;
|
||||
|
||||
viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
|
||||
|
||||
index = io_data.Index;
|
||||
data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
|
||||
index);
|
||||
data = (data & (~io_data.Mask)) | io_data.Data;
|
||||
|
||||
viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data);
|
||||
}
|
||||
|
||||
void viafb_init_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
int reg_num, i;
|
||||
|
||||
/* Common settings: */
|
||||
reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
|
||||
|
||||
for (i = 0; i < reg_num; i++) {
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info,
|
||||
COMMON_INIT_TBL_VT1636[i]);
|
||||
}
|
||||
|
||||
/* Input Data Mode Select */
|
||||
if (plvds_setting_info->device_lcd_dualedge) {
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info,
|
||||
DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
|
||||
} else {
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info,
|
||||
SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
|
||||
}
|
||||
|
||||
if (plvds_setting_info->LCDDithering) {
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info,
|
||||
DITHERING_ENABLE_TBL_VT1636[0]);
|
||||
} else {
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info,
|
||||
DITHERING_DISABLE_TBL_VT1636[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void viafb_enable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
|
||||
VDD_ON_TBL_VT1636[0]);
|
||||
|
||||
/* Pad on: */
|
||||
switch (plvds_chip_info->output_interface) {
|
||||
case INTERFACE_DVP0:
|
||||
{
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DVP1:
|
||||
{
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DFP_LOW:
|
||||
{
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DFP_HIGH:
|
||||
{
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void viafb_disable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
|
||||
VDD_OFF_TBL_VT1636[0]);
|
||||
|
||||
/* Pad off: */
|
||||
switch (plvds_chip_info->output_interface) {
|
||||
case INTERFACE_DVP0:
|
||||
{
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DVP1:
|
||||
{
|
||||
viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DFP_LOW:
|
||||
{
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERFACE_DFP_HIGH:
|
||||
{
|
||||
viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool viafb_lvds_identify_vt1636(void)
|
||||
{
|
||||
u8 Buffer[2];
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
|
||||
|
||||
/* Sense VT1636 LVDS Transmiter */
|
||||
viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
|
||||
VT1636_LVDS_I2C_ADDR;
|
||||
|
||||
/* Check vendor ID first: */
|
||||
viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
|
||||
lvds_chip_slave_addr,
|
||||
0x00, &Buffer[0]);
|
||||
viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
|
||||
lvds_chip_slave_addr,
|
||||
0x01, &Buffer[1]);
|
||||
|
||||
if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
|
||||
return false;
|
||||
|
||||
/* Check Chip ID: */
|
||||
viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
|
||||
lvds_chip_slave_addr,
|
||||
0x02, &Buffer[0]);
|
||||
viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
|
||||
lvds_chip_slave_addr,
|
||||
0x03, &Buffer[1]);
|
||||
if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
|
||||
viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
|
||||
VT1636_LVDS;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int get_clk_range_index(u32 Clk)
|
||||
{
|
||||
if (Clk < DPA_CLK_30M)
|
||||
return DPA_CLK_RANGE_30M;
|
||||
else if (Clk < DPA_CLK_50M)
|
||||
return DPA_CLK_RANGE_30_50M;
|
||||
else if (Clk < DPA_CLK_70M)
|
||||
return DPA_CLK_RANGE_50_70M;
|
||||
else if (Clk < DPA_CLK_100M)
|
||||
return DPA_CLK_RANGE_70_100M;
|
||||
else if (Clk < DPA_CLK_150M)
|
||||
return DPA_CLK_RANGE_100_150M;
|
||||
else
|
||||
return DPA_CLK_RANGE_150M;
|
||||
}
|
||||
|
||||
static int get_lvds_dpa_setting_index(int panel_size_id,
|
||||
struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
|
||||
int tbl_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tbl_size; i++) {
|
||||
if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
|
||||
return i;
|
||||
|
||||
p_vt1636_dpasetting_tbl++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_dpa_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
|
||||
struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
|
||||
{
|
||||
struct IODATA io_data;
|
||||
|
||||
io_data.Index = 0x09;
|
||||
io_data.Mask = 0x1F;
|
||||
io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
|
||||
plvds_chip_info, io_data);
|
||||
|
||||
io_data.Index = 0x08;
|
||||
io_data.Mask = 0x0F;
|
||||
io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
|
||||
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
|
||||
io_data);
|
||||
}
|
||||
|
||||
void viafb_vt1636_patch_skew_on_vt3324(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
int index, size;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
|
||||
|
||||
/* Graphics DPA settings: */
|
||||
index = get_clk_range_index(plvds_setting_info->vclk);
|
||||
viafb_set_dpa_gfx(plvds_chip_info->output_interface,
|
||||
&GFX_DPA_SETTING_TBL_VT3324[index]);
|
||||
|
||||
/* LVDS Transmitter DPA settings: */
|
||||
size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
|
||||
index =
|
||||
get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
|
||||
VT1636_DPA_SETTING_TBL_VT3324, size);
|
||||
set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
|
||||
&VT1636_DPA_SETTING_TBL_VT3324[index]);
|
||||
}
|
||||
|
||||
void viafb_vt1636_patch_skew_on_vt3327(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
int index, size;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
|
||||
|
||||
/* Graphics DPA settings: */
|
||||
index = get_clk_range_index(plvds_setting_info->vclk);
|
||||
viafb_set_dpa_gfx(plvds_chip_info->output_interface,
|
||||
&GFX_DPA_SETTING_TBL_VT3327[index]);
|
||||
|
||||
/* LVDS Transmitter DPA settings: */
|
||||
size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
|
||||
index =
|
||||
get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
|
||||
VT1636_DPA_SETTING_TBL_VT3327, size);
|
||||
set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
|
||||
&VT1636_DPA_SETTING_TBL_VT3327[index]);
|
||||
}
|
||||
|
||||
void viafb_vt1636_patch_skew_on_vt3364(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info)
|
||||
{
|
||||
int index;
|
||||
|
||||
DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
|
||||
|
||||
/* Graphics DPA settings: */
|
||||
index = get_clk_range_index(plvds_setting_info->vclk);
|
||||
viafb_set_dpa_gfx(plvds_chip_info->output_interface,
|
||||
&GFX_DPA_SETTING_TBL_VT3364[index]);
|
||||
}
|
||||
44
drivers/video/via/vt1636.h
Normal file
44
drivers/video/via/vt1636.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.See the GNU General Public License
|
||||
* for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _VT1636_H_
|
||||
#define _VT1636_H_
|
||||
#include "chip.h"
|
||||
bool viafb_lvds_identify_vt1636(void);
|
||||
void viafb_init_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_enable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_disable_lvds_vt1636(struct lvds_setting_information
|
||||
*plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_vt1636_patch_skew_on_vt3324(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_vt1636_patch_skew_on_vt3327(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
void viafb_vt1636_patch_skew_on_vt3364(
|
||||
struct lvds_setting_information *plvds_setting_info,
|
||||
struct lvds_chip_information *plvds_chip_info);
|
||||
|
||||
#endif
|
||||
|
|
@ -680,11 +680,11 @@ static struct xenbus_driver xenfb = {
|
|||
|
||||
static int __init xenfb_init(void)
|
||||
{
|
||||
if (!is_running_on_xen())
|
||||
if (!xen_domain())
|
||||
return -ENODEV;
|
||||
|
||||
/* Nothing to do if running in dom0. */
|
||||
if (is_initial_xendomain())
|
||||
if (xen_initial_domain())
|
||||
return -ENODEV;
|
||||
|
||||
return xenbus_register_frontend(&xenfb);
|
||||
|
|
|
|||
Loading…
Reference in a new issue