Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6

* 'viafb-next' of git://github.com/schandinat/linux-2.6: (29 commits)
  viafb: add initial VX900 support
  viafb: fix hardware acceleration for suspend & resume
  viafb: make suspend and resume work (on all machines?)
  viafb: restore display on resume
  Minimal support for viafb suspend/resume
  viafb: use proper register for colour when doing fill ops
  viafb: add documentation for proc interface
  viafb: rename output devices
  viafb: add a mapping of supported output devices
  viafb: set sync polarity for all output devices
  viafb: add function to change sync polarity per device
  viafb: reduce I2C timeout and delay
  viafb: enable I2C for CRT
  viafb: fix i2c_transfer error handling
  viafb: vt1636 cleanup
  viafb: introduce per output device power management
  viafb: limit LCD code impact
  viafb: add interface for output device configuration
  viafb: merge the remaining output path with enable functions
  viafb: use new device routing
  ...
This commit is contained in:
Linus Torvalds 2010-10-27 19:02:41 -07:00
Родитель bdab225015 51f4332bb5
Коммит 9ae6d03922
21 изменённых файлов: 1061 добавлений и 1284 удалений

Просмотреть файл

@ -197,6 +197,54 @@ Notes:
example, example,
# fbset -depth 16 # fbset -depth 16
[Configure viafb via /proc]
---------------------------
The following files exist in /proc/viafb
supported_output_devices
This read-only file contains a full ',' seperated list containing all
output devices that could be available on your platform. It is likely
that not all of those have a connector on your hardware but it should
provide a good starting point to figure out which of those names match
a real connector.
Example:
# cat /proc/viafb/supported_output_devices
iga1/output_devices
iga2/output_devices
These two files are readable and writable. iga1 and iga2 are the two
independent units that produce the screen image. Those images can be
forwarded to one or more output devices. Reading those files is a way
to query which output devices are currently used by an iga.
Example:
# cat /proc/viafb/iga1/output_devices
If there are no output devices printed the output of this iga is lost.
This can happen for example if only one (the other) iga is used.
Writing to these files allows adjusting the output devices during
runtime. One can add new devices, remove existing ones or switch
between igas. Essentially you can write a ',' seperated list of device
names (or a single one) in the same format as the output to those
files. You can add a '+' or '-' as a prefix allowing simple addition
and removal of devices. So a prefix '+' adds the devices from your list
to the already existing ones, '-' removes the listed devices from the
existing ones and if no prefix is given it replaces all existing ones
with the listed ones. If you remove devices they are expected to turn
off. If you add devices that are already part of the other iga they are
removed there and added to the new one.
Examples:
Add CRT as output device to iga1
# echo +CRT > /proc/viafb/iga1/output_devices
Remove (turn off) DVP1 and LVDS1 as output devices of iga2
# echo -DVP1,LVDS1 > /proc/viafb/iga2/output_devices
Replace all iga1 output devices by CRT
# echo CRT > /proc/viafb/iga1/output_devices
[Bootup with viafb]: [Bootup with viafb]:
-------------------- --------------------
Add the following line to your grub.conf: Add the following line to your grub.conf:

Просмотреть файл

@ -5,5 +5,5 @@
obj-$(CONFIG_FB_VIA) += viafb.o obj-$(CONFIG_FB_VIA) += viafb.o
viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ viafb-y :=viafbdev.o hw.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 \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
via-core.o via-gpio.o via_modesetting.o via-core.o via-gpio.o via_modesetting.o

Просмотреть файл

@ -283,11 +283,12 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
writel(tmp, engine + 0x1C); writel(tmp, engine + 0x1C);
} }
if (op != VIA_BITBLT_COLOR) if (op == VIA_BITBLT_FILL) {
writel(fg_color, engine + 0x58);
} else if (op == VIA_BITBLT_MONO) {
writel(fg_color, engine + 0x4C); writel(fg_color, engine + 0x4C);
if (op == VIA_BITBLT_MONO)
writel(bg_color, engine + 0x50); writel(bg_color, engine + 0x50);
}
if (op == VIA_BITBLT_FILL) if (op == VIA_BITBLT_FILL)
ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
@ -314,13 +315,11 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
return 0; return 0;
} }
int viafb_init_engine(struct fb_info *info) int viafb_setup_engine(struct fb_info *info)
{ {
struct viafb_par *viapar = info->par; struct viafb_par *viapar = info->par;
void __iomem *engine; void __iomem *engine;
int highest_reg, i; u32 chip_name = viapar->shared->chip_info.gfx_chip_name;
u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
engine = viapar->shared->vdev->engine_mmio; engine = viapar->shared->vdev->engine_mmio;
if (!engine) { if (!engine) {
@ -329,18 +328,6 @@ int viafb_init_engine(struct fb_info *info)
return -ENOMEM; return -ENOMEM;
} }
/* Initialize registers to reset the 2D engine */
switch (viapar->shared->chip_info.twod_engine) {
case VIA_2D_ENG_M1:
highest_reg = 0x5c;
break;
default:
highest_reg = 0x40;
break;
}
for (i = 0; i <= highest_reg; i += 4)
writel(0x0, engine + i);
switch (chip_name) { switch (chip_name) {
case UNICHROME_CLE266: case UNICHROME_CLE266:
case UNICHROME_K400: case UNICHROME_K400:
@ -356,6 +343,7 @@ int viafb_init_engine(struct fb_info *info)
break; break;
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
viapar->shared->hw_bitblt = hw_bitblt_2; viapar->shared->hw_bitblt = hw_bitblt_2;
break; break;
default: default:
@ -386,12 +374,36 @@ int viafb_init_engine(struct fb_info *info)
viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free;
#endif #endif
viafb_reset_engine(viapar);
return 0;
}
void viafb_reset_engine(struct viafb_par *viapar)
{
void __iomem *engine = viapar->shared->vdev->engine_mmio;
int highest_reg, i;
u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
/* Initialize registers to reset the 2D engine */
switch (viapar->shared->chip_info.twod_engine) {
case VIA_2D_ENG_M1:
highest_reg = 0x5c;
break;
default:
highest_reg = 0x40;
break;
}
for (i = 0; i <= highest_reg; i += 4)
writel(0x0, engine + i);
/* Init AGP and VQ regs */ /* Init AGP and VQ regs */
switch (chip_name) { switch (chip_name) {
case UNICHROME_K8M890: case UNICHROME_K8M890:
case UNICHROME_P4M900: case UNICHROME_P4M900:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
writel(0x00100000, engine + VIA_REG_CR_TRANSET); writel(0x00100000, engine + VIA_REG_CR_TRANSET);
writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
@ -428,6 +440,7 @@ int viafb_init_engine(struct fb_info *info)
case UNICHROME_P4M900: case UNICHROME_P4M900:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
vq_start_low |= 0x20000000; vq_start_low |= 0x20000000;
vq_end_low |= 0x20000000; vq_end_low |= 0x20000000;
vq_high |= 0x20000000; vq_high |= 0x20000000;
@ -473,7 +486,7 @@ int viafb_init_engine(struct fb_info *info)
writel(0x0, engine + VIA_REG_CURSOR_ORG); writel(0x0, engine + VIA_REG_CURSOR_ORG);
writel(0x0, engine + VIA_REG_CURSOR_BG); writel(0x0, engine + VIA_REG_CURSOR_BG);
writel(0x0, engine + VIA_REG_CURSOR_FG); writel(0x0, engine + VIA_REG_CURSOR_FG);
return 0; return;
} }
void viafb_show_hw_cursor(struct fb_info *info, int Status) void viafb_show_hw_cursor(struct fb_info *info, int Status)

Просмотреть файл

@ -203,7 +203,8 @@
#define VIA_BITBLT_MONO 2 #define VIA_BITBLT_MONO 2
#define VIA_BITBLT_FILL 3 #define VIA_BITBLT_FILL 3
int viafb_init_engine(struct fb_info *info); int viafb_setup_engine(struct fb_info *info);
void viafb_reset_engine(struct viafb_par *viapar);
void viafb_show_hw_cursor(struct fb_info *info, int Status); void viafb_show_hw_cursor(struct fb_info *info, int Status);
void viafb_wait_engine_idle(struct fb_info *info); void viafb_wait_engine_idle(struct fb_info *info);

Просмотреть файл

@ -71,6 +71,9 @@
#define UNICHROME_VX855 12 #define UNICHROME_VX855 12
#define UNICHROME_VX855_DID 0x5122 #define UNICHROME_VX855_DID 0x5122
#define UNICHROME_VX900 13
#define UNICHROME_VX900_DID 0x7122
/**************************************************/ /**************************************************/
/* Definition TMDS Trasmitter Information */ /* Definition TMDS Trasmitter Information */
/**************************************************/ /**************************************************/

Просмотреть файл

@ -25,10 +25,12 @@
static void tmds_register_write(int index, u8 data); static void tmds_register_write(int index, u8 data);
static int tmds_register_read(int index); static int tmds_register_read(int index);
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information static void __devinit dvi_get_panel_size_from_DDCv1(
*tmds_chip, struct tmds_setting_information *tmds_setting); struct tmds_chip_information *tmds_chip,
static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information struct tmds_setting_information *tmds_setting);
*tmds_chip, struct tmds_setting_information *tmds_setting); static void __devinit dvi_get_panel_size_from_DDCv2(
struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting);
static int viafb_dvi_query_EDID(void); static int viafb_dvi_query_EDID(void);
static int check_tmds_chip(int device_id_subaddr, int device_id) static int check_tmds_chip(int device_id_subaddr, int device_id)
@ -39,7 +41,7 @@ static int check_tmds_chip(int device_id_subaddr, int device_id)
return FAIL; return FAIL;
} }
void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting) struct tmds_setting_information *tmds_setting)
{ {
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
@ -60,7 +62,7 @@ void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
return; return;
} }
int viafb_tmds_trasmitter_identify(void) int __devinit viafb_tmds_trasmitter_identify(void)
{ {
unsigned char sr2a = 0, sr1e = 0, sr3e = 0; unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
@ -208,8 +210,6 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
} }
} }
viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
viafb_set_output_path(DEVICE_DVI, set_iga,
viaparinfo->chip_info->tmds_chip_info.output_interface);
} }
/* Sense DVI Connector */ /* Sense DVI Connector */
@ -313,8 +313,9 @@ static int viafb_dvi_query_EDID(void)
} }
/* Get Panel Size Using EDID1 Table */ /* Get Panel Size Using EDID1 Table */
static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information static void __devinit dvi_get_panel_size_from_DDCv1(
*tmds_chip, struct tmds_setting_information *tmds_setting) struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting)
{ {
int i, max_h = 0, tmp, restore; int i, max_h = 0, tmp, restore;
unsigned char rData; unsigned char rData;
@ -418,8 +419,9 @@ static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
} }
/* Get Panel Size Using EDID2 Table */ /* Get Panel Size Using EDID2 Table */
static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information static void __devinit dvi_get_panel_size_from_DDCv2(
*tmds_chip, struct tmds_setting_information *tmds_setting) struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting)
{ {
int restore; int restore;
unsigned char R_Buffer[2]; unsigned char R_Buffer[2];
@ -467,26 +469,6 @@ static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
/* If Disable DVI, turn off pad */ /* If Disable DVI, turn off pad */
void viafb_dvi_disable(void) 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-> if (viaparinfo->chip_info->
tmds_chip_info.output_interface == INTERFACE_TMDS) tmds_chip_info.output_interface == INTERFACE_TMDS)
/* Turn off TMDS power. */ /* Turn off TMDS power. */
@ -494,38 +476,101 @@ void viafb_dvi_disable(void)
viafb_read_reg(VIACR, CRD2) | 0x08); viafb_read_reg(VIACR, CRD2) | 0x08);
} }
static void dvi_patch_skew_dvp0(void)
{
/* Reset data driving first: */
viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_P4M890:
{
if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
(viaparinfo->tmds_setting_info->v_active ==
1200))
viafb_write_reg_mask(CR96, VIACR, 0x03,
BIT0 + BIT1 + BIT2);
else
viafb_write_reg_mask(CR96, VIACR, 0x07,
BIT0 + BIT1 + BIT2);
break;
}
case UNICHROME_P4M900:
{
viafb_write_reg_mask(CR96, VIACR, 0x07,
BIT0 + BIT1 + BIT2 + BIT3);
viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
break;
}
default:
{
break;
}
}
}
static void dvi_patch_skew_dvp_low(void)
{
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
{
viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
break;
}
case UNICHROME_P4M900:
{
viafb_write_reg_mask(CR99, VIACR, 0x08,
BIT0 + BIT1 + BIT2 + BIT3);
break;
}
case UNICHROME_P4M890:
{
viafb_write_reg_mask(CR99, VIACR, 0x0F,
BIT0 + BIT1 + BIT2 + BIT3);
break;
}
default:
{
break;
}
}
}
/* If Enable DVI, turn off pad */ /* If Enable DVI, turn off pad */
void viafb_dvi_enable(void) void viafb_dvi_enable(void)
{ {
u8 data; u8 data;
if (viaparinfo->chip_info-> switch (viaparinfo->chip_info->tmds_chip_info.output_interface) {
tmds_chip_info.output_interface == INTERFACE_DVP0) { case INTERFACE_DVP0:
viafb_write_reg(SR1E, VIASR, viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
viafb_read_reg(VIASR, SR1E) | 0xC0); viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5);
dvi_patch_skew_dvp0();
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
tmds_register_write(0x88, 0x3b); tmds_register_write(0x88, 0x3b);
else else
/*clear CR91[5] to direct on display period /*clear CR91[5] to direct on display period
in the secondary diplay path */ in the secondary diplay path */
viafb_write_reg(CR91, VIACR, via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
viafb_read_reg(VIACR, CR91) & 0xDF); break;
}
if (viaparinfo->chip_info-> case INTERFACE_DVP1:
tmds_chip_info.output_interface == INTERFACE_DVP1) { if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
viafb_write_reg(SR1E, VIASR, viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5);
viafb_read_reg(VIASR, SR1E) | 0x30);
/*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
tmds_register_write(0x88, 0x3b); tmds_register_write(0x88, 0x3b);
} else { else
/*clear CR91[5] to direct on display period /*clear CR91[5] to direct on display period
in the secondary diplay path */ in the secondary diplay path */
viafb_write_reg(CR91, VIACR, via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
viafb_read_reg(VIACR, CR91) & 0xDF);
}
/*fix DVI cannot enable on EPIA-M board */ /*fix DVI cannot enable on EPIA-M board */
if (viafb_platform_epia_dvi == 1) { if (viafb_platform_epia_dvi == 1) {
@ -537,36 +582,40 @@ void viafb_dvi_enable(void)
else else
data = 0x37; data = 0x37;
viafb_i2c_writebyte(viaparinfo->chip_info-> viafb_i2c_writebyte(viaparinfo->chip_info->
tmds_chip_info.i2c_port, tmds_chip_info.i2c_port,
viaparinfo->chip_info-> viaparinfo->chip_info->
tmds_chip_info.tmds_chip_slave_addr, tmds_chip_info.tmds_chip_slave_addr,
0x08, data); 0x08, data);
} }
} }
} break;
if (viaparinfo->chip_info-> case INTERFACE_DFP_HIGH:
tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
viafb_write_reg(SR2A, VIASR, via_write_reg_mask(VIACR, CR97, 0x03, 0x03);
viafb_read_reg(VIASR, SR2A) | 0x0C);
viafb_write_reg(CR91, VIACR,
viafb_read_reg(VIACR, CR91) & 0xDF);
}
if (viaparinfo->chip_info-> via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { break;
viafb_write_reg(SR2A, VIASR,
viafb_read_reg(VIASR, SR2A) | 0x03); case INTERFACE_DFP_LOW:
viafb_write_reg(CR91, VIACR, if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
viafb_read_reg(VIACR, CR91) & 0xDF); break;
}
if (viaparinfo->chip_info-> dvi_patch_skew_dvp_low();
tmds_chip_info.output_interface == INTERFACE_TMDS) { via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
break;
case INTERFACE_TMDS:
/* Turn on Display period in the panel path. */ /* Turn on Display period in the panel path. */
viafb_write_reg_mask(CR91, VIACR, 0, BIT7); viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
/* Turn on TMDS power. */ /* Turn on TMDS power. */
viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
break;
}
if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
/* Disable LCD Scaling */
viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
} }
} }

Просмотреть файл

@ -56,8 +56,8 @@
int viafb_dvi_sense(void); int viafb_dvi_sense(void);
void viafb_dvi_disable(void); void viafb_dvi_disable(void);
void viafb_dvi_enable(void); void viafb_dvi_enable(void);
int viafb_tmds_trasmitter_identify(void); int __devinit viafb_tmds_trasmitter_identify(void);
void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting); struct tmds_setting_information *tmds_setting);
void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
int set_iga); int set_iga);

Просмотреть файл

@ -48,7 +48,6 @@
#include "via_utility.h" #include "via_utility.h"
#include "vt1636.h" #include "vt1636.h"
#include "tblDPASetting.h" #include "tblDPASetting.h"
#include "tbl1636.h"
/* External struct*/ /* External struct*/

Просмотреть файл

@ -718,16 +718,20 @@ static struct rgbLUT palLUT_table[] = {
0x00} 0x00}
}; };
static void set_crt_output_path(int set_iga); static struct via_device_mapping device_mapping[] = {
static void dvi_patch_skew_dvp0(void); {VIA_LDVP0, "LDVP0"},
static void dvi_patch_skew_dvp1(void); {VIA_LDVP1, "LDVP1"},
static void dvi_patch_skew_dvp_low(void); {VIA_DVP0, "DVP0"},
static void set_dvi_output_path(int set_iga, int output_interface); {VIA_CRT, "CRT"},
static void set_lcd_output_path(int set_iga, int output_interface); {VIA_DVP1, "DVP1"},
{VIA_LVDS1, "LVDS1"},
{VIA_LVDS2, "LVDS2"}
};
static void load_fix_bit_crtc_reg(void); static void load_fix_bit_crtc_reg(void);
static void init_gfx_chip_info(int chip_type); static void __devinit init_gfx_chip_info(int chip_type);
static void init_tmds_chip_info(void); static void __devinit init_tmds_chip_info(void);
static void init_lvds_chip_info(void); static void __devinit init_lvds_chip_info(void);
static void device_screen_off(void); static void device_screen_off(void);
static void device_screen_on(void); static void device_screen_on(void);
static void set_display_channel(void); static void set_display_channel(void);
@ -755,6 +759,66 @@ void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
outb(b, LUT_DATA); outb(b, LUT_DATA);
} }
static u32 get_dvi_devices(int output_interface)
{
switch (output_interface) {
case INTERFACE_DVP0:
return VIA_DVP0 | VIA_LDVP0;
case INTERFACE_DVP1:
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
return VIA_LDVP1;
else
return VIA_DVP1;
case INTERFACE_DFP_HIGH:
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
return 0;
else
return VIA_LVDS2 | VIA_DVP0;
case INTERFACE_DFP_LOW:
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
return 0;
else
return VIA_DVP1 | VIA_LVDS1;
case INTERFACE_TMDS:
return VIA_LVDS1;
}
return 0;
}
static u32 get_lcd_devices(int output_interface)
{
switch (output_interface) {
case INTERFACE_DVP0:
return VIA_DVP0;
case INTERFACE_DVP1:
return VIA_DVP1;
case INTERFACE_DFP_HIGH:
return VIA_LVDS2 | VIA_DVP0;
case INTERFACE_DFP_LOW:
return VIA_LVDS1 | VIA_DVP1;
case INTERFACE_DFP:
return VIA_LVDS1 | VIA_LVDS2;
case INTERFACE_LVDS0:
case INTERFACE_LVDS0LVDS1:
return VIA_LVDS1;
case INTERFACE_LVDS1:
return VIA_LVDS2;
}
return 0;
}
/*Set IGA path for each device*/ /*Set IGA path for each device*/
void viafb_set_iga_path(void) void viafb_set_iga_path(void)
{ {
@ -821,6 +885,48 @@ void viafb_set_iga_path(void)
viaparinfo->tmds_setting_info->iga_path = IGA1; viaparinfo->tmds_setting_info->iga_path = IGA1;
} }
} }
viaparinfo->shared->iga1_devices = 0;
viaparinfo->shared->iga2_devices = 0;
if (viafb_CRT_ON) {
if (viaparinfo->crt_setting_info->iga_path == IGA1)
viaparinfo->shared->iga1_devices |= VIA_CRT;
else
viaparinfo->shared->iga2_devices |= VIA_CRT;
}
if (viafb_DVI_ON) {
if (viaparinfo->tmds_setting_info->iga_path == IGA1)
viaparinfo->shared->iga1_devices |= get_dvi_devices(
viaparinfo->chip_info->
tmds_chip_info.output_interface);
else
viaparinfo->shared->iga2_devices |= get_dvi_devices(
viaparinfo->chip_info->
tmds_chip_info.output_interface);
}
if (viafb_LCD_ON) {
if (viaparinfo->lvds_setting_info->iga_path == IGA1)
viaparinfo->shared->iga1_devices |= get_lcd_devices(
viaparinfo->chip_info->
lvds_chip_info.output_interface);
else
viaparinfo->shared->iga2_devices |= get_lcd_devices(
viaparinfo->chip_info->
lvds_chip_info.output_interface);
}
if (viafb_LCD2_ON) {
if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
viaparinfo->shared->iga1_devices |= get_lcd_devices(
viaparinfo->chip_info->
lvds_chip_info2.output_interface);
else
viaparinfo->shared->iga2_devices |= get_lcd_devices(
viaparinfo->chip_info->
lvds_chip_info2.output_interface);
}
} }
static void set_color_register(u8 index, u8 red, u8 green, u8 blue) static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
@ -844,295 +950,266 @@ void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
set_color_register(index, red, green, blue); set_color_register(index, red, green, blue);
} }
void viafb_set_output_path(int device, int set_iga, int output_interface) static void set_source_common(u8 index, u8 offset, u8 iga)
{ {
switch (device) { u8 value, mask = 1 << offset;
case DEVICE_CRT:
set_crt_output_path(set_iga);
break;
case DEVICE_DVI:
set_dvi_output_path(set_iga, output_interface);
break;
case DEVICE_LCD:
set_lcd_output_path(set_iga, output_interface);
break;
}
}
static void set_crt_output_path(int set_iga) switch (iga) {
{
viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
switch (set_iga) {
case IGA1: case IGA1:
viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); value = 0x00;
break; break;
case IGA2: case IGA2:
viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); value = mask;
viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
break; break;
}
}
static void dvi_patch_skew_dvp0(void)
{
/* Reset data driving first: */
viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_P4M890:
{
if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
(viaparinfo->tmds_setting_info->v_active ==
1200))
viafb_write_reg_mask(CR96, VIACR, 0x03,
BIT0 + BIT1 + BIT2);
else
viafb_write_reg_mask(CR96, VIACR, 0x07,
BIT0 + BIT1 + BIT2);
break;
}
case UNICHROME_P4M900:
{
viafb_write_reg_mask(CR96, VIACR, 0x07,
BIT0 + BIT1 + BIT2 + BIT3);
viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
break;
}
default: default:
{ printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
break; return;
}
} }
via_write_reg_mask(VIACR, index, value, mask);
} }
static void dvi_patch_skew_dvp1(void) static void set_crt_source(u8 iga)
{ {
switch (viaparinfo->chip_info->gfx_chip_name) { u8 value;
case UNICHROME_CX700:
{
break;
}
default: switch (iga) {
{ case IGA1:
break; value = 0x00;
}
}
}
static void dvi_patch_skew_dvp_low(void)
{
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
{
viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
break;
}
case UNICHROME_P4M900:
{
viafb_write_reg_mask(CR99, VIACR, 0x08,
BIT0 + BIT1 + BIT2 + BIT3);
break;
}
case UNICHROME_P4M890:
{
viafb_write_reg_mask(CR99, VIACR, 0x0F,
BIT0 + BIT1 + BIT2 + BIT3);
break;
}
default:
{
break;
}
}
}
static void set_dvi_output_path(int set_iga, int output_interface)
{
switch (output_interface) {
case INTERFACE_DVP0:
viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
if (set_iga == IGA1) {
viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
BIT5 + BIT7);
} else {
viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
BIT5 + BIT7);
}
viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
dvi_patch_skew_dvp0();
break; break;
case IGA2:
case INTERFACE_DVP1: value = 0x40;
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
if (set_iga == IGA1)
viafb_write_reg_mask(CR93, VIACR, 0x21,
BIT0 + BIT5 + BIT7);
else
viafb_write_reg_mask(CR93, VIACR, 0xA1,
BIT0 + BIT5 + BIT7);
} else {
if (set_iga == IGA1)
viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
else
viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
}
viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
dvi_patch_skew_dvp1();
break; break;
case INTERFACE_DFP_HIGH: default:
if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
if (set_iga == IGA1) { return;
viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); }
viafb_write_reg_mask(CR97, VIACR, 0x03,
BIT0 + BIT1 + BIT4); via_write_reg_mask(VIASR, 0x16, value, 0x40);
} else { }
viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR97, VIACR, 0x13, static inline void set_ldvp0_source(u8 iga)
BIT0 + BIT1 + BIT4); {
set_source_common(0x6C, 7, iga);
}
static inline void set_ldvp1_source(u8 iga)
{
set_source_common(0x93, 7, iga);
}
static inline void set_dvp0_source(u8 iga)
{
set_source_common(0x96, 4, iga);
}
static inline void set_dvp1_source(u8 iga)
{
set_source_common(0x9B, 4, iga);
}
static inline void set_lvds1_source(u8 iga)
{
set_source_common(0x99, 4, iga);
}
static inline void set_lvds2_source(u8 iga)
{
set_source_common(0x97, 4, iga);
}
void via_set_source(u32 devices, u8 iga)
{
if (devices & VIA_LDVP0)
set_ldvp0_source(iga);
if (devices & VIA_LDVP1)
set_ldvp1_source(iga);
if (devices & VIA_DVP0)
set_dvp0_source(iga);
if (devices & VIA_CRT)
set_crt_source(iga);
if (devices & VIA_DVP1)
set_dvp1_source(iga);
if (devices & VIA_LVDS1)
set_lvds1_source(iga);
if (devices & VIA_LVDS2)
set_lvds2_source(iga);
}
static void set_crt_state(u8 state)
{
u8 value;
switch (state) {
case VIA_STATE_ON:
value = 0x00;
break;
case VIA_STATE_STANDBY:
value = 0x10;
break;
case VIA_STATE_SUSPEND:
value = 0x20;
break;
case VIA_STATE_OFF:
value = 0x30;
break;
default:
return;
}
via_write_reg_mask(VIACR, 0x36, value, 0x30);
}
static void set_dvp0_state(u8 state)
{
u8 value;
switch (state) {
case VIA_STATE_ON:
value = 0xC0;
break;
case VIA_STATE_OFF:
value = 0x00;
break;
default:
return;
}
via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
}
static void set_dvp1_state(u8 state)
{
u8 value;
switch (state) {
case VIA_STATE_ON:
value = 0x30;
break;
case VIA_STATE_OFF:
value = 0x00;
break;
default:
return;
}
via_write_reg_mask(VIASR, 0x1E, value, 0x30);
}
static void set_lvds1_state(u8 state)
{
u8 value;
switch (state) {
case VIA_STATE_ON:
value = 0x03;
break;
case VIA_STATE_OFF:
value = 0x00;
break;
default:
return;
}
via_write_reg_mask(VIASR, 0x2A, value, 0x03);
}
static void set_lvds2_state(u8 state)
{
u8 value;
switch (state) {
case VIA_STATE_ON:
value = 0x0C;
break;
case VIA_STATE_OFF:
value = 0x00;
break;
default:
return;
}
via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
}
void via_set_state(u32 devices, u8 state)
{
/*
TODO: Can we enable/disable these devices? How?
if (devices & VIA_LDVP0)
if (devices & VIA_LDVP1)
*/
if (devices & VIA_DVP0)
set_dvp0_state(state);
if (devices & VIA_CRT)
set_crt_state(state);
if (devices & VIA_DVP1)
set_dvp1_state(state);
if (devices & VIA_LVDS1)
set_lvds1_state(state);
if (devices & VIA_LVDS2)
set_lvds2_state(state);
}
void via_set_sync_polarity(u32 devices, u8 polarity)
{
if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
polarity);
return;
}
if (devices & VIA_CRT)
via_write_misc_reg_mask(polarity << 6, 0xC0);
if (devices & VIA_DVP1)
via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
if (devices & VIA_LVDS1)
via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
if (devices & VIA_LVDS2)
via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
}
u32 via_parse_odev(char *input, char **end)
{
char *ptr = input;
u32 odev = 0;
bool next = true;
int i, len;
while (next) {
next = false;
for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
len = strlen(device_mapping[i].name);
if (!strncmp(ptr, device_mapping[i].name, len)) {
odev |= device_mapping[i].device;
ptr += len;
if (*ptr == ',') {
ptr++;
next = true;
}
} }
} }
viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
break;
case INTERFACE_DFP_LOW:
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
break;
if (set_iga == IGA1) {
viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
} else {
viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
}
viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
dvi_patch_skew_dvp_low();
break;
case INTERFACE_TMDS:
if (set_iga == IGA1)
viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
else
viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
break;
} }
if (set_iga == IGA2) { *end = ptr;
enable_second_display_channel(); return odev;
/* Disable LCD Scaling */
viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
}
} }
static void set_lcd_output_path(int set_iga, int output_interface) void via_odev_to_seq(struct seq_file *m, u32 odev)
{ {
DEBUG_MSG(KERN_INFO int i, count = 0;
"set_lcd_output_path, iga:%d,out_interface:%d\n",
set_iga, output_interface);
switch (set_iga) {
case IGA1:
viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
disable_second_display_channel(); for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
break; if (odev & device_mapping[i].device) {
if (count > 0)
seq_putc(m, ',');
case IGA2: seq_puts(m, device_mapping[i].name);
viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); count++;
viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); }
enable_second_display_channel();
break;
} }
switch (output_interface) { seq_putc(m, '\n');
case INTERFACE_DVP0:
if (set_iga == IGA1) {
viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
} else {
viafb_write_reg(CR91, VIACR, 0x00);
viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
}
break;
case INTERFACE_DVP1:
if (set_iga == IGA1)
viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
else {
viafb_write_reg(CR91, VIACR, 0x00);
viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
}
break;
case INTERFACE_DFP_HIGH:
if (set_iga == IGA1)
viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
else {
viafb_write_reg(CR91, VIACR, 0x00);
viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
}
break;
case INTERFACE_DFP_LOW:
if (set_iga == IGA1)
viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
else {
viafb_write_reg(CR91, VIACR, 0x00);
viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
}
break;
case INTERFACE_DFP:
if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
|| (UNICHROME_P4M890 ==
viaparinfo->chip_info->gfx_chip_name))
viafb_write_reg_mask(CR97, VIACR, 0x84,
BIT7 + BIT2 + BIT1 + BIT0);
if (set_iga == IGA1) {
viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
} else {
viafb_write_reg(CR91, VIACR, 0x00);
viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
}
break;
case INTERFACE_LVDS0:
case INTERFACE_LVDS0LVDS1:
if (set_iga == IGA1)
viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
else
viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
break;
case INTERFACE_LVDS1:
if (set_iga == IGA1)
viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
else
viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
break;
}
} }
static void load_fix_bit_crtc_reg(void) static void load_fix_bit_crtc_reg(void)
@ -1352,6 +1429,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
} }
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
iga1_fifo_high_threshold =
VX900_IGA1_FIFO_HIGH_THRESHOLD;
iga1_display_queue_expire_num =
VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
}
/* Set Display FIFO Depath Select */ /* Set Display FIFO Depath Select */
reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
viafb_load_reg_num = viafb_load_reg_num =
@ -1492,6 +1578,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
} }
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
iga2_fifo_high_threshold =
VX900_IGA2_FIFO_HIGH_THRESHOLD;
iga2_display_queue_expire_num =
VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
}
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
/* Set Display FIFO Depath Select */ /* Set Display FIFO Depath Select */
reg_value = reg_value =
@ -1612,6 +1707,7 @@ u32 viafb_get_clk_value(int clk)
break; break;
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
value = vx855_encode_pll(pll_value[i].vx855_pll); value = vx855_encode_pll(pll_value[i].vx855_pll);
break; break;
} }
@ -1645,6 +1741,7 @@ void viafb_set_vclock(u32 clk, int set_iga)
case UNICHROME_P4M900: case UNICHROME_P4M900:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
via_write_reg(VIASR, SR44, (clk & 0x0000FF)); via_write_reg(VIASR, SR44, (clk & 0x0000FF));
via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
@ -1671,6 +1768,7 @@ void viafb_set_vclock(u32 clk, int set_iga)
case UNICHROME_P4M900: case UNICHROME_P4M900:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
@ -1688,8 +1786,8 @@ void viafb_set_vclock(u32 clk, int set_iga)
} }
if (set_iga == IGA2) { if (set_iga == IGA2) {
viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
} }
/* Fire! */ /* Fire! */
@ -1937,7 +2035,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
int index = 0; int index = 0;
int h_addr, v_addr; int h_addr, v_addr;
u32 pll_D_N; u32 pll_D_N;
u8 polarity = 0;
for (i = 0; i < video_mode->mode_array; i++) { for (i = 0; i < video_mode->mode_array; i++) {
index = i; index = i;
@ -1964,14 +2061,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
h_addr = crt_reg.hor_addr; h_addr = crt_reg.hor_addr;
v_addr = crt_reg.ver_addr; v_addr = crt_reg.ver_addr;
/* update polarity for CRT timing */
if (crt_table[index].h_sync_polarity == NEGATIVE)
polarity |= BIT6;
if (crt_table[index].v_sync_polarity == NEGATIVE)
polarity |= BIT7;
via_write_misc_reg_mask(polarity, BIT6 | BIT7);
if (set_iga == IGA1) { if (set_iga == IGA1) {
viafb_unlock_crt(); viafb_unlock_crt();
viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
@ -2004,7 +2093,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
} }
void viafb_init_chip_info(int chip_type) void __devinit viafb_init_chip_info(int chip_type)
{ {
init_gfx_chip_info(chip_type); init_gfx_chip_info(chip_type);
init_tmds_chip_info(); init_tmds_chip_info();
@ -2071,7 +2160,7 @@ void viafb_update_device_setting(int hres, int vres,
} }
} }
static void init_gfx_chip_info(int chip_type) static void __devinit init_gfx_chip_info(int chip_type)
{ {
u8 tmp; u8 tmp;
@ -2111,6 +2200,7 @@ static void init_gfx_chip_info(int chip_type)
switch (viaparinfo->chip_info->gfx_chip_name) { switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1; viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
break; break;
case UNICHROME_K8M890: case UNICHROME_K8M890:
@ -2123,7 +2213,7 @@ static void init_gfx_chip_info(int chip_type)
} }
} }
static void init_tmds_chip_info(void) static void __devinit init_tmds_chip_info(void)
{ {
viafb_tmds_trasmitter_identify(); viafb_tmds_trasmitter_identify();
@ -2168,7 +2258,7 @@ static void init_tmds_chip_info(void)
&viaparinfo->shared->tmds_setting_info); &viaparinfo->shared->tmds_setting_info);
} }
static void init_lvds_chip_info(void) static void __devinit init_lvds_chip_info(void)
{ {
viafb_lvds_trasmitter_identify(); viafb_lvds_trasmitter_identify();
viafb_init_lcd_size(); viafb_init_lcd_size();
@ -2202,7 +2292,7 @@ static void init_lvds_chip_info(void)
viaparinfo->chip_info->lvds_chip_info.output_interface); viaparinfo->chip_info->lvds_chip_info.output_interface);
} }
void viafb_init_dac(int set_iga) void __devinit viafb_init_dac(int set_iga)
{ {
int i; int i;
u8 tmp; u8 tmp;
@ -2275,11 +2365,24 @@ static void set_display_channel(void)
} }
} }
static u8 get_sync(struct fb_info *info)
{
u8 polarity = 0;
if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
polarity |= VIA_HSYNC_NEGATIVE;
if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
polarity |= VIA_VSYNC_NEGATIVE;
return polarity;
}
int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
struct VideoModeTable *vmode_tbl1, int video_bpp1) struct VideoModeTable *vmode_tbl1, int video_bpp1)
{ {
int i, j; int i, j;
int port; int port;
u32 devices = viaparinfo->shared->iga1_devices
| viaparinfo->shared->iga2_devices;
u8 value, index, mask; u8 value, index, mask;
struct crt_mode_table *crt_timing; struct crt_mode_table *crt_timing;
struct crt_mode_table *crt_timing1 = NULL; struct crt_mode_table *crt_timing1 = NULL;
@ -2322,11 +2425,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
break; break;
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
break; break;
} }
device_off(); device_off();
via_set_state(devices, VIA_STATE_OFF);
/* Fill VPIT Parameters */ /* Fill VPIT Parameters */
/* Write Misc Register */ /* Write Misc Register */
@ -2337,7 +2442,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
via_write_reg(VIASR, i, VPIT.SR[i - 1]); via_write_reg(VIASR, i, VPIT.SR[i - 1]);
viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
viafb_set_iga_path();
/* Write CRTC */ /* Write CRTC */
viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
@ -2377,6 +2481,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
via_set_primary_color_depth(viaparinfo->depth); via_set_primary_color_depth(viaparinfo->depth);
via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
: viaparinfo->depth); : viaparinfo->depth);
via_set_source(viaparinfo->shared->iga1_devices, IGA1);
via_set_source(viaparinfo->shared->iga2_devices, IGA2);
if (viaparinfo->shared->iga2_devices)
enable_second_display_channel();
else
disable_second_display_channel();
/* Update Refresh Rate Setting */ /* Update Refresh Rate Setting */
/* Clear On Screen */ /* Clear On Screen */
@ -2394,8 +2505,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
viaparinfo->crt_setting_info->iga_path); viaparinfo->crt_setting_info->iga_path);
} }
set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
to 8 alignment (1368),there is several pixels (2 pixels) to 8 alignment (1368),there is several pixels (2 pixels)
on right side of screen. */ on right side of screen. */
@ -2482,10 +2591,16 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
viafb_DeviceStatus = CRT_Device; viafb_DeviceStatus = CRT_Device;
} }
device_on(); device_on();
if (!viafb_dual_fb)
via_set_sync_polarity(devices, get_sync(viafbinfo));
else {
via_set_sync_polarity(viaparinfo->shared->iga1_devices,
get_sync(viafbinfo));
via_set_sync_polarity(viaparinfo->shared->iga2_devices,
get_sync(viafbinfo1));
}
if (viafb_SAMM_ON == 1) via_set_state(devices, VIA_STATE_ON);
viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
device_screen_on(); device_screen_on();
return 1; return 1;
} }
@ -2526,31 +2641,18 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh)
static void device_off(void) static void device_off(void)
{ {
viafb_crt_disable();
viafb_dvi_disable(); viafb_dvi_disable();
viafb_lcd_disable(); viafb_lcd_disable();
} }
static void device_on(void) static void device_on(void)
{ {
if (viafb_CRT_ON == 1)
viafb_crt_enable();
if (viafb_DVI_ON == 1) if (viafb_DVI_ON == 1)
viafb_dvi_enable(); viafb_dvi_enable();
if (viafb_LCD_ON == 1) if (viafb_LCD_ON == 1)
viafb_lcd_enable(); viafb_lcd_enable();
} }
void viafb_crt_disable(void)
{
viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
}
void viafb_crt_enable(void)
{
viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
}
static void enable_second_display_channel(void) static void enable_second_display_channel(void)
{ {
/* to enable second display channel. */ /* to enable second display channel. */
@ -2567,7 +2669,6 @@ static void disable_second_display_channel(void)
viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
} }
void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
*p_gfx_dpa_setting) *p_gfx_dpa_setting)
{ {
@ -2652,4 +2753,9 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end); crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
var->vsync_len = crt_reg.ver_sync_end; var->vsync_len = crt_reg.ver_sync_end;
var->sync = 0;
if (crt_timing[index].h_sync_polarity == POSITIVE)
var->sync |= FB_SYNC_HOR_HIGH_ACT;
if (crt_timing[index].v_sync_polarity == POSITIVE)
var->sync |= FB_SYNC_VERT_HIGH_ACT;
} }

Просмотреть файл

@ -22,6 +22,8 @@
#ifndef __HW_H__ #ifndef __HW_H__
#define __HW_H__ #define __HW_H__
#include <linux/seq_file.h>
#include "viamode.h" #include "viamode.h"
#include "global.h" #include "global.h"
#include "via_modesetting.h" #include "via_modesetting.h"
@ -30,6 +32,25 @@
#define viafb_write_reg(i, p, d) via_write_reg(p, i, d) #define viafb_write_reg(i, p, d) via_write_reg(p, i, d)
#define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m) #define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m)
/* VIA output devices */
#define VIA_LDVP0 0x00000001
#define VIA_LDVP1 0x00000002
#define VIA_DVP0 0x00000004
#define VIA_CRT 0x00000010
#define VIA_DVP1 0x00000020
#define VIA_LVDS1 0x00000040
#define VIA_LVDS2 0x00000080
/* VIA output device power states */
#define VIA_STATE_ON 0
#define VIA_STATE_STANDBY 1
#define VIA_STATE_SUSPEND 2
#define VIA_STATE_OFF 3
/* VIA output device sync polarity */
#define VIA_HSYNC_NEGATIVE 0x01
#define VIA_VSYNC_NEGATIVE 0x02
/*************************************************** /***************************************************
* Definition IGA1 Design Method of CRTC Registers * * Definition IGA1 Design Method of CRTC Registers *
****************************************************/ ****************************************************/
@ -341,6 +362,17 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
#define VX855_IGA2_FIFO_HIGH_THRESHOLD 160 #define VX855_IGA2_FIFO_HIGH_THRESHOLD 160
#define VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320 #define VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320
/* For VT3410 */
#define VX900_IGA1_FIFO_MAX_DEPTH 400
#define VX900_IGA1_FIFO_THRESHOLD 320
#define VX900_IGA1_FIFO_HIGH_THRESHOLD 320
#define VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 160
#define VX900_IGA2_FIFO_MAX_DEPTH 192
#define VX900_IGA2_FIFO_THRESHOLD 160
#define VX900_IGA2_FIFO_HIGH_THRESHOLD 160
#define VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320
#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 #define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1
#define IGA1_FIFO_THRESHOLD_REG_NUM 2 #define IGA1_FIFO_THRESHOLD_REG_NUM 2
#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2
@ -858,6 +890,8 @@ struct iga2_crtc_timing {
#define VX800_FUNCTION3 0x3353 #define VX800_FUNCTION3 0x3353
/* VT3409 chipset*/ /* VT3409 chipset*/
#define VX855_FUNCTION3 0x3409 #define VX855_FUNCTION3 0x3409
/* VT3410 chipset*/
#define VX900_FUNCTION3 0x3410
#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
@ -873,6 +907,11 @@ struct pci_device_id_info {
u32 chip_index; u32 chip_index;
}; };
struct via_device_mapping {
u32 device;
const char *name;
};
extern unsigned int viafb_second_virtual_xres; extern unsigned int viafb_second_virtual_xres;
extern int viafb_SAMM_ON; extern int viafb_SAMM_ON;
extern int viafb_dual_fb; extern int viafb_dual_fb;
@ -881,9 +920,6 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON; extern int viafb_DVI_ON;
extern int viafb_hotplug; extern int viafb_hotplug;
void viafb_set_output_path(int device, int set_iga,
int output_interface);
void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
struct VideoModeTable *video_mode, int bpp_byte, int set_iga); struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
@ -891,8 +927,11 @@ void viafb_set_vclock(u32 CLK, int set_iga);
void viafb_load_reg(int timing_value, int viafb_load_reg_num, void viafb_load_reg(int timing_value, int viafb_load_reg_num,
struct io_register *reg, struct io_register *reg,
int io_type); int io_type);
void viafb_crt_disable(void); void via_set_source(u32 devices, u8 iga);
void viafb_crt_enable(void); void via_set_state(u32 devices, u8 state);
void via_set_sync_polarity(u32 devices, u8 polarity);
u32 via_parse_odev(char *input, char **end);
void via_odev_to_seq(struct seq_file *m, u32 odev);
void init_ad9389(void); void init_ad9389(void);
/* Access I/O Function */ /* Access I/O Function */
void viafb_lock_crt(void); void viafb_lock_crt(void);
@ -908,8 +947,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
struct VideoModeTable *vmode_tbl1, int video_bpp1); struct VideoModeTable *vmode_tbl1, int video_bpp1);
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
struct VideoModeTable *vmode_tbl); struct VideoModeTable *vmode_tbl);
void viafb_init_chip_info(int chip_type); void __devinit viafb_init_chip_info(int chip_type);
void viafb_init_dac(int set_iga); void __devinit viafb_init_dac(int set_iga);
int viafb_get_pixclock(int hres, int vres, int vmode_refresh); int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
int viafb_get_refresh(int hres, int vres, u32 float_refresh); int viafb_get_refresh(int hres, int vres, u32 float_refresh);
void viafb_update_device_setting(int hres, int vres, int bpp, void viafb_update_device_setting(int hres, int vres, int bpp,

Просмотреть файл

@ -94,6 +94,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp)
viafb_CRT_ON = 0; viafb_CRT_ON = 0;
viafb_LCD_ON = 0; viafb_LCD_ON = 0;
viafb_DeviceStatus = DVI_Device; viafb_DeviceStatus = DVI_Device;
viafb_set_iga_path();
return viafb_DeviceStatus; return viafb_DeviceStatus;
} }
status = 1; status = 1;
@ -107,6 +108,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp)
viafb_LCD_ON = 0; viafb_LCD_ON = 0;
viafb_DeviceStatus = CRT_Device; viafb_DeviceStatus = CRT_Device;
viafb_set_iga_path();
return viafb_DeviceStatus; return viafb_DeviceStatus;
} }

Просмотреть файл

@ -21,10 +21,16 @@
#include <linux/via-core.h> #include <linux/via-core.h>
#include <linux/via_i2c.h> #include <linux/via_i2c.h>
#include "global.h" #include "global.h"
#include "lcdtbl.h"
#define viafb_compact_res(x, y) (((x)<<16)|(y)) #define viafb_compact_res(x, y) (((x)<<16)|(y))
/* 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} };
static struct _lcd_scaling_factor lcd_scaling_factor = { static struct _lcd_scaling_factor lcd_scaling_factor = {
/* LCD Horizontal Scaling Factor Register */ /* LCD Horizontal Scaling Factor Register */
{LCD_HOR_SCALING_FACTOR_REG_NUM, {LCD_HOR_SCALING_FACTOR_REG_NUM,
@ -42,7 +48,7 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
static int check_lvds_chip(int device_id_subaddr, int device_id); static int check_lvds_chip(int device_id_subaddr, int device_id);
static bool lvds_identify_integratedlvds(void); static bool lvds_identify_integratedlvds(void);
static void fp_id_to_vindex(int panel_id); static void __devinit fp_id_to_vindex(int panel_id);
static int lvds_register_read(int index); static int lvds_register_read(int index);
static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
int panel_vres); int panel_vres);
@ -84,7 +90,7 @@ static int check_lvds_chip(int device_id_subaddr, int device_id)
return FAIL; return FAIL;
} }
void viafb_init_lcd_size(void) void __devinit viafb_init_lcd_size(void)
{ {
DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
@ -144,7 +150,7 @@ static bool lvds_identify_integratedlvds(void)
return true; return true;
} }
int viafb_lvds_trasmitter_identify(void) int __devinit viafb_lvds_trasmitter_identify(void)
{ {
if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
@ -185,7 +191,7 @@ int viafb_lvds_trasmitter_identify(void)
return FAIL; return FAIL;
} }
static void fp_id_to_vindex(int panel_id) static void __devinit fp_id_to_vindex(int panel_id)
{ {
DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
@ -436,6 +442,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
case UNICHROME_CN750: case UNICHROME_CN750:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
reg_value = reg_value =
K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
/* Horizontal scaling enabled */ /* Horizontal scaling enabled */
@ -479,6 +486,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
case UNICHROME_CN750: case UNICHROME_CN750:
case UNICHROME_VX800: case UNICHROME_VX800:
case UNICHROME_VX855: case UNICHROME_VX855:
case UNICHROME_VX900:
reg_value = reg_value =
K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
/* Vertical scaling enabled */ /* Vertical scaling enabled */
@ -655,9 +663,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
viafb_set_vclock(pll_D_N, set_iga); viafb_set_vclock(pll_D_N, set_iga);
viafb_set_output_path(DEVICE_LCD, set_iga,
plvds_chip_info->output_interface);
lcd_patch_skew(plvds_setting_info, plvds_chip_info); lcd_patch_skew(plvds_setting_info, plvds_chip_info);
/* If K8M800, enable LCD Prefetch Mode. */ /* If K8M800, enable LCD Prefetch Mode. */
@ -700,9 +705,6 @@ static void integrated_lvds_disable(struct lvds_setting_information
viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7); viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
} }
/* Turn DFP High/Low Pad off. */
viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
/* Power off LVDS channel. */ /* Power off LVDS channel. */
switch (plvds_chip_info->output_interface) { switch (plvds_chip_info->output_interface) {
case INTERFACE_LVDS0: case INTERFACE_LVDS0:
@ -758,9 +760,6 @@ static void integrated_lvds_enable(struct lvds_setting_information
break; break;
} }
/* Turn DFP High/Low pad on. */
viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
/* Power on LVDS channel. */ /* Power on LVDS channel. */
switch (plvds_chip_info->output_interface) { switch (plvds_chip_info->output_interface) {
case INTERFACE_LVDS0: case INTERFACE_LVDS0:
@ -809,29 +808,48 @@ void viafb_lcd_disable(void)
viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
&viaparinfo->chip_info->lvds_chip_info); &viaparinfo->chip_info->lvds_chip_info);
} else { } else {
/* DFP-HL pad off */
viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
/* Backlight off */ /* Backlight off */
viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
/* 24 bit DI data paht off */ /* 24 bit DI data paht off */
viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
/* Simultaneout disabled */
viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
} }
/* Disable expansion bit */ /* Disable expansion bit */
viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
/* CRT path set to IGA1 */
viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
/* Simultaneout disabled */ /* Simultaneout disabled */
viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
/* IGA2 path disabled */ }
viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
static void set_lcd_output_path(int set_iga, int output_interface)
{
switch (output_interface) {
case INTERFACE_DFP:
if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
|| (UNICHROME_P4M890 ==
viaparinfo->chip_info->gfx_chip_name))
viafb_write_reg_mask(CR97, VIACR, 0x84,
BIT7 + BIT2 + BIT1 + BIT0);
case INTERFACE_DVP0:
case INTERFACE_DVP1:
case INTERFACE_DFP_HIGH:
case INTERFACE_DFP_LOW:
if (set_iga == IGA2)
viafb_write_reg(CR91, VIACR, 0x00);
break;
}
} }
void viafb_lcd_enable(void) void viafb_lcd_enable(void)
{ {
viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
viaparinfo->chip_info->lvds_chip_info.output_interface);
if (viafb_LCD2_ON)
set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
viaparinfo->chip_info->
lvds_chip_info2.output_interface);
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
/* DI1 pad on */ /* DI1 pad on */
viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
@ -855,39 +873,13 @@ void viafb_lcd_enable(void)
viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info, viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
&viaparinfo->chip_info->lvds_chip_info); &viaparinfo->chip_info->lvds_chip_info);
} else { } else {
/* DFP-HL pad on */
viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
/* Backlight on */ /* Backlight on */
viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
/* 24 bit DI data paht on */ /* 24 bit DI data paht on */
viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80); viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
/* Set data source selection bit by iga path */
if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
/* DFP-H set to IGA1 */
viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
/* DFP-L set to IGA1 */
viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
} else {
/* DFP-H set to IGA2 */
viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
/* DFP-L set to IGA2 */
viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
}
/* LCD enabled */ /* LCD enabled */
viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
} }
if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
/* CRT path set to IGA2 */
viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
/* IGA2 path disabled */
viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
/* IGA2 path enabled */
} else { /* IGA2 */
viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
}
} }
static void lcd_powersequence_off(void) static void lcd_powersequence_off(void)
@ -993,7 +985,7 @@ static void check_diport_of_integrated_lvds(
plvds_chip_info->output_interface); plvds_chip_info->output_interface);
} }
void viafb_init_lvds_output_interface(struct lvds_chip_information void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info, *plvds_chip_info,
struct lvds_setting_information struct lvds_setting_information
*plvds_setting_info) *plvds_setting_info)

Просмотреть файл

@ -71,15 +71,15 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information
struct lvds_chip_information *plvds_chip_info); struct lvds_chip_information *plvds_chip_info);
void viafb_lcd_disable(void); void viafb_lcd_disable(void);
void viafb_lcd_enable(void); void viafb_lcd_enable(void);
void viafb_init_lcd_size(void); void __devinit viafb_init_lcd_size(void);
void viafb_init_lvds_output_interface(struct lvds_chip_information void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info, *plvds_chip_info,
struct lvds_setting_information struct lvds_setting_information
*plvds_setting_info); *plvds_setting_info);
void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
struct lvds_setting_information *plvds_setting_info, struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info); struct lvds_chip_information *plvds_chip_info);
int viafb_lvds_trasmitter_identify(void); int __devinit viafb_lvds_trasmitter_identify(void);
void viafb_init_lvds_output_interface(struct lvds_chip_information void viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info, *plvds_chip_info,
struct lvds_setting_information struct lvds_setting_information

Просмотреть файл

@ -1,591 +0,0 @@
/*
* 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__ */

Просмотреть файл

@ -1,71 +0,0 @@
/*
* 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}
};

Просмотреть файл

@ -1,34 +0,0 @@
/*
* 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_ */

Просмотреть файл

@ -20,7 +20,7 @@
* The default port config. * The default port config.
*/ */
static struct via_port_cfg adap_configs[] = { static struct via_port_cfg adap_configs[] = {
[VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 }, [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 },
[VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 },
[VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
[VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c }, [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c },
@ -333,7 +333,7 @@ EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg);
static u16 via_function3[] = { static u16 via_function3[] = {
CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3, CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3, CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3, P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3, VX900_FUNCTION3,
}; };
/* Get the BIOS-configured framebuffer size from PCI configuration space /* Get the BIOS-configured framebuffer size from PCI configuration space
@ -370,6 +370,7 @@ static int viafb_get_fb_size_from_pci(int chip_type)
case P4M900_FUNCTION3: case P4M900_FUNCTION3:
case VX800_FUNCTION3: case VX800_FUNCTION3:
case VX855_FUNCTION3: case VX855_FUNCTION3:
case VX900_FUNCTION3:
/*case CN750_FUNCTION3: */ /*case CN750_FUNCTION3: */
offset = 0xA0; offset = 0xA0;
break; break;
@ -474,7 +475,10 @@ static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
* Eventually we want to move away from mapping this * Eventually we want to move away from mapping this
* entire region. * entire region.
*/ */
vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); if (vdev->chip_type == UNICHROME_VX900)
vdev->fbmem_start = pci_resource_start(vdev->pdev, 2);
else
vdev->fbmem_start = pci_resource_start(vdev->pdev, 0);
ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
if (ret < 0) if (ret < 0)
goto out_unmap; goto out_unmap;
@ -635,6 +639,8 @@ static struct pci_device_id via_pci_table[] __devinitdata = {
.driver_data = UNICHROME_VX800 }, .driver_data = UNICHROME_VX800 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
.driver_data = UNICHROME_VX855 }, .driver_data = UNICHROME_VX855 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX900_DID),
.driver_data = UNICHROME_VX900 },
{ } { }
}; };
MODULE_DEVICE_TABLE(pci, via_pci_table); MODULE_DEVICE_TABLE(pci, via_pci_table);
@ -644,6 +650,10 @@ static struct pci_driver via_driver = {
.id_table = via_pci_table, .id_table = via_pci_table,
.probe = via_pci_probe, .probe = via_pci_probe,
.remove = __devexit_p(via_pci_remove), .remove = __devexit_p(via_pci_remove),
#ifdef CONFIG_PM
.suspend = viafb_suspend,
.resume = viafb_resume,
#endif
}; };
static int __init via_core_init(void) static int __init via_core_init(void)

Просмотреть файл

@ -114,6 +114,7 @@ static void via_i2c_setsda(void *data, int state)
int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
{ {
int ret;
u8 mm1[] = {0x00}; u8 mm1[] = {0x00};
struct i2c_msg msgs[2]; struct i2c_msg msgs[2];
@ -126,11 +127,18 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
mm1[0] = index; mm1[0] = index;
msgs[0].len = 1; msgs[1].len = 1; msgs[0].len = 1; msgs[1].len = 1;
msgs[0].buf = mm1; msgs[1].buf = pdata; msgs[0].buf = mm1; msgs[1].buf = pdata;
return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
if (ret == 2)
ret = 0;
else if (ret >= 0)
ret = -EIO;
return ret;
} }
int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
{ {
int ret;
u8 msg[2] = { index, data }; u8 msg[2] = { index, data };
struct i2c_msg msgs; struct i2c_msg msgs;
@ -140,11 +148,18 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
msgs.addr = slave_addr / 2; msgs.addr = slave_addr / 2;
msgs.len = 2; msgs.len = 2;
msgs.buf = msg; msgs.buf = msg;
return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1);
if (ret == 1)
ret = 0;
else if (ret >= 0)
ret = -EIO;
return ret;
} }
int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
{ {
int ret;
u8 mm1[] = {0x00}; u8 mm1[] = {0x00};
struct i2c_msg msgs[2]; struct i2c_msg msgs[2];
@ -156,7 +171,13 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len
mm1[0] = index; mm1[0] = index;
msgs[0].len = 1; msgs[1].len = buff_len; msgs[0].len = 1; msgs[1].len = buff_len;
msgs[0].buf = mm1; msgs[1].buf = buff; msgs[0].buf = mm1; msgs[1].buf = buff;
return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
if (ret == 2)
ret = 0;
else if (ret >= 0)
ret = -EIO;
return ret;
} }
/* /*
@ -181,8 +202,8 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
algo->setscl = via_i2c_setscl; algo->setscl = via_i2c_setscl;
algo->getsda = via_i2c_getsda; algo->getsda = via_i2c_getsda;
algo->getscl = via_i2c_getscl; algo->getscl = via_i2c_getscl;
algo->udelay = 40; algo->udelay = 10;
algo->timeout = 20; algo->timeout = 2;
algo->data = adap_cfg; algo->data = adap_cfg;
sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",

Просмотреть файл

@ -56,6 +56,32 @@ static int viafb_pan_display(struct fb_var_screeninfo *var,
static struct fb_ops viafb_ops; static struct fb_ops viafb_ops;
/* supported output devices on each IGP
* only CX700, VX800, VX855, VX900 were documented
* VIA_CRT should be everywhere
* VIA_6C can be onle pre-CX700 (probably only on CLE266) as 6C is used for PLL
* source selection on CX700 and later
* K400 seems to support VIA_96, VIA_DVP1, VIA_LVDS{1,2} as in viamode.c
*/
static const u32 supported_odev_map[] = {
[UNICHROME_CLE266] = VIA_CRT | VIA_LDVP0 | VIA_LDVP1,
[UNICHROME_K400] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1
| VIA_LVDS2,
[UNICHROME_K800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1
| VIA_LVDS2,
[UNICHROME_PM800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1
| VIA_LVDS2,
[UNICHROME_CN700] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1
| VIA_LVDS2,
[UNICHROME_CX700] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_CN750] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_K8M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_P4M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_P4M900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_VX800] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_VX855] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
[UNICHROME_VX900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2,
};
static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth)
{ {
@ -332,22 +358,22 @@ static int viafb_blank(int blank_mode, struct fb_info *info)
case FB_BLANK_UNBLANK: case FB_BLANK_UNBLANK:
/* Screen: On, HSync: On, VSync: On */ /* Screen: On, HSync: On, VSync: On */
/* control CRT monitor power management */ /* control CRT monitor power management */
viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); via_set_state(VIA_CRT, VIA_STATE_ON);
break; break;
case FB_BLANK_HSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND:
/* Screen: Off, HSync: Off, VSync: On */ /* Screen: Off, HSync: Off, VSync: On */
/* control CRT monitor power management */ /* control CRT monitor power management */
viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5); via_set_state(VIA_CRT, VIA_STATE_STANDBY);
break; break;
case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_VSYNC_SUSPEND:
/* Screen: Off, HSync: On, VSync: Off */ /* Screen: Off, HSync: On, VSync: Off */
/* control CRT monitor power management */ /* control CRT monitor power management */
viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5); via_set_state(VIA_CRT, VIA_STATE_SUSPEND);
break; break;
case FB_BLANK_POWERDOWN: case FB_BLANK_POWERDOWN:
/* Screen: Off, HSync: Off, VSync: Off */ /* Screen: Off, HSync: Off, VSync: Off */
/* control CRT monitor power management */ /* control CRT monitor power management */
viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5); via_set_state(VIA_CRT, VIA_STATE_OFF);
break; break;
} }
@ -457,7 +483,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
if (copy_from_user(&gpu32, argp, sizeof(gpu32))) if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
return -EFAULT; return -EFAULT;
if (gpu32 & CRT_Device) if (gpu32 & CRT_Device)
viafb_crt_enable(); via_set_state(VIA_CRT, VIA_STATE_ON);
if (gpu32 & DVI_Device) if (gpu32 & DVI_Device)
viafb_dvi_enable(); viafb_dvi_enable();
if (gpu32 & LCD_Device) if (gpu32 & LCD_Device)
@ -467,7 +493,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
if (copy_from_user(&gpu32, argp, sizeof(gpu32))) if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
return -EFAULT; return -EFAULT;
if (gpu32 & CRT_Device) if (gpu32 & CRT_Device)
viafb_crt_disable(); via_set_state(VIA_CRT, VIA_STATE_OFF);
if (gpu32 & DVI_Device) if (gpu32 & DVI_Device)
viafb_dvi_disable(); viafb_dvi_disable();
if (gpu32 & LCD_Device) if (gpu32 & LCD_Device)
@ -787,7 +813,8 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
bg_color = cursor->image.bg_color; bg_color = cursor->image.bg_color;
if (chip_name == UNICHROME_CX700 || if (chip_name == UNICHROME_CX700 ||
chip_name == UNICHROME_VX800 || chip_name == UNICHROME_VX800 ||
chip_name == UNICHROME_VX855) { chip_name == UNICHROME_VX855 ||
chip_name == UNICHROME_VX900) {
fg_color = fg_color =
((info->cmap.red[fg_color] & 0xFFC0) << 14) | ((info->cmap.red[fg_color] & 0xFFC0) << 14) |
((info->cmap.green[fg_color] & 0xFFC0) << 4) | ((info->cmap.green[fg_color] & 0xFFC0) << 4) |
@ -961,7 +988,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting
setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
} }
static int parse_active_dev(void) static int __init parse_active_dev(void)
{ {
viafb_CRT_ON = STATE_OFF; viafb_CRT_ON = STATE_OFF;
viafb_DVI_ON = STATE_OFF; viafb_DVI_ON = STATE_OFF;
@ -1031,7 +1058,7 @@ static int parse_active_dev(void)
return 0; return 0;
} }
static int parse_port(char *opt_str, int *output_interface) static int __devinit parse_port(char *opt_str, int *output_interface)
{ {
if (!strncmp(opt_str, "DVP0", 4)) if (!strncmp(opt_str, "DVP0", 4))
*output_interface = INTERFACE_DVP0; *output_interface = INTERFACE_DVP0;
@ -1048,7 +1075,7 @@ static int parse_port(char *opt_str, int *output_interface)
return 0; return 0;
} }
static void parse_lcd_port(void) static void __devinit parse_lcd_port(void)
{ {
parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info. parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
output_interface); output_interface);
@ -1061,7 +1088,7 @@ static void parse_lcd_port(void)
output_interface); output_interface);
} }
static void parse_dvi_port(void) static void __devinit parse_dvi_port(void)
{ {
parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info. parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
output_interface); output_interface);
@ -1431,38 +1458,196 @@ static const struct file_operations viafb_vt1636_proc_fops = {
.write = viafb_vt1636_proc_write, .write = viafb_vt1636_proc_write,
}; };
static void viafb_init_proc(struct proc_dir_entry **viafb_entry) #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
{
*viafb_entry = proc_mkdir("viafb", NULL);
if (*viafb_entry) {
proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops);
proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops);
proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops);
proc_create("dfpl", 0, *viafb_entry, &viafb_dfpl_proc_fops);
if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info.
lvds_chip_name || VT1636_LVDS ==
viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
proc_create("vt1636", 0, *viafb_entry, &viafb_vt1636_proc_fops);
}
static int viafb_sup_odev_proc_show(struct seq_file *m, void *v)
{
via_odev_to_seq(m, supported_odev_map[
viaparinfo->shared->chip_info.gfx_chip_name]);
return 0;
}
static int viafb_sup_odev_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, viafb_sup_odev_proc_show, NULL);
}
static const struct file_operations viafb_sup_odev_proc_fops = {
.owner = THIS_MODULE,
.open = viafb_sup_odev_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev)
{
char buf[64], *ptr = buf;
u32 devices;
bool add, sub;
if (count < 1 || count > 63)
return -EINVAL;
if (copy_from_user(&buf[0], buffer, count))
return -EFAULT;
buf[count] = '\0';
add = buf[0] == '+';
sub = buf[0] == '-';
if (add || sub)
ptr++;
devices = via_parse_odev(ptr, &ptr);
if (*ptr == '\n')
ptr++;
if (*ptr != 0)
return -EINVAL;
if (add)
*odev |= devices;
else if (sub)
*odev &= ~devices;
else
*odev = devices;
return count;
}
static int viafb_iga1_odev_proc_show(struct seq_file *m, void *v)
{
via_odev_to_seq(m, viaparinfo->shared->iga1_devices);
return 0;
}
static int viafb_iga1_odev_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, viafb_iga1_odev_proc_show, NULL);
}
static ssize_t viafb_iga1_odev_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *pos)
{
u32 dev_on, dev_off, dev_old, dev_new;
ssize_t res;
dev_old = dev_new = viaparinfo->shared->iga1_devices;
res = odev_update(buffer, count, &dev_new);
if (res != count)
return res;
dev_off = dev_old & ~dev_new;
dev_on = dev_new & ~dev_old;
viaparinfo->shared->iga1_devices = dev_new;
viaparinfo->shared->iga2_devices &= ~dev_new;
via_set_state(dev_off, VIA_STATE_OFF);
via_set_source(dev_new, IGA1);
via_set_state(dev_on, VIA_STATE_ON);
return res;
}
static const struct file_operations viafb_iga1_odev_proc_fops = {
.owner = THIS_MODULE,
.open = viafb_iga1_odev_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = viafb_iga1_odev_proc_write,
};
static int viafb_iga2_odev_proc_show(struct seq_file *m, void *v)
{
via_odev_to_seq(m, viaparinfo->shared->iga2_devices);
return 0;
}
static int viafb_iga2_odev_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, viafb_iga2_odev_proc_show, NULL);
}
static ssize_t viafb_iga2_odev_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *pos)
{
u32 dev_on, dev_off, dev_old, dev_new;
ssize_t res;
dev_old = dev_new = viaparinfo->shared->iga2_devices;
res = odev_update(buffer, count, &dev_new);
if (res != count)
return res;
dev_off = dev_old & ~dev_new;
dev_on = dev_new & ~dev_old;
viaparinfo->shared->iga2_devices = dev_new;
viaparinfo->shared->iga1_devices &= ~dev_new;
via_set_state(dev_off, VIA_STATE_OFF);
via_set_source(dev_new, IGA2);
via_set_state(dev_on, VIA_STATE_ON);
return res;
}
static const struct file_operations viafb_iga2_odev_proc_fops = {
.owner = THIS_MODULE,
.open = viafb_iga2_odev_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = viafb_iga2_odev_proc_write,
};
#define IS_VT1636(lvds_chip) ((lvds_chip).lvds_chip_name == VT1636_LVDS)
static void viafb_init_proc(struct viafb_shared *shared)
{
struct proc_dir_entry *iga1_entry, *iga2_entry,
*viafb_entry = proc_mkdir("viafb", NULL);
shared->proc_entry = viafb_entry;
if (viafb_entry) {
#ifdef CONFIG_FB_VIA_DIRECT_PROCFS
proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_fops);
proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_fops);
proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_fops);
proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_fops);
if (IS_VT1636(shared->chip_info.lvds_chip_info)
|| IS_VT1636(shared->chip_info.lvds_chip_info2))
proc_create("vt1636", 0, viafb_entry,
&viafb_vt1636_proc_fops);
#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
proc_create("supported_output_devices", 0, viafb_entry,
&viafb_sup_odev_proc_fops);
iga1_entry = proc_mkdir("iga1", viafb_entry);
shared->iga1_proc_entry = iga1_entry;
proc_create("output_devices", 0, iga1_entry,
&viafb_iga1_odev_proc_fops);
iga2_entry = proc_mkdir("iga2", viafb_entry);
shared->iga2_proc_entry = iga2_entry;
proc_create("output_devices", 0, iga2_entry,
&viafb_iga2_odev_proc_fops);
} }
} }
static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) static void viafb_remove_proc(struct viafb_shared *shared)
{ {
struct chip_information *chip_info = &viaparinfo->shared->chip_info; struct proc_dir_entry *viafb_entry = shared->proc_entry,
*iga1_entry = shared->iga1_proc_entry,
*iga2_entry = shared->iga2_proc_entry;
if (!viafb_entry)
return;
remove_proc_entry("output_devices", iga2_entry);
remove_proc_entry("iga2", viafb_entry);
remove_proc_entry("output_devices", iga1_entry);
remove_proc_entry("iga1", viafb_entry);
remove_proc_entry("supported_output_devices", viafb_entry);
#ifdef CONFIG_FB_VIA_DIRECT_PROCFS
remove_proc_entry("dvp0", viafb_entry);/* parent dir */ remove_proc_entry("dvp0", viafb_entry);/* parent dir */
remove_proc_entry("dvp1", viafb_entry); remove_proc_entry("dvp1", viafb_entry);
remove_proc_entry("dfph", viafb_entry); remove_proc_entry("dfph", viafb_entry);
remove_proc_entry("dfpl", viafb_entry); remove_proc_entry("dfpl", viafb_entry);
if (chip_info->lvds_chip_info.lvds_chip_name == VT1636_LVDS if (IS_VT1636(shared->chip_info.lvds_chip_info)
|| chip_info->lvds_chip_info2.lvds_chip_name == VT1636_LVDS) || IS_VT1636(shared->chip_info.lvds_chip_info2))
remove_proc_entry("vt1636", viafb_entry); remove_proc_entry("vt1636", viafb_entry);
#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
remove_proc_entry("viafb", NULL); remove_proc_entry("viafb", NULL);
} }
#undef IS_VT1636
#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
static int parse_mode(const char *str, u32 *xres, u32 *yres) static int parse_mode(const char *str, u32 *xres, u32 *yres)
{ {
@ -1486,6 +1671,47 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
} }
#ifdef CONFIG_PM
int viafb_suspend(struct pci_dev *pdev, pm_message_t state)
{
if (state.event == PM_EVENT_SUSPEND) {
acquire_console_sem();
fb_set_suspend(viafbinfo, 1);
viafb_sync(viafbinfo);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
release_console_sem();
}
return 0;
}
int viafb_resume(struct pci_dev *pdev)
{
acquire_console_sem();
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
if (pci_enable_device(pdev))
goto fail;
pci_set_master(pdev);
if (viaparinfo->shared->vdev->engine_mmio)
viafb_reset_engine(viaparinfo);
viafb_set_par(viafbinfo);
if (viafb_dual_fb)
viafb_set_par(viafbinfo1);
fb_set_suspend(viafbinfo, 0);
fail:
release_console_sem();
return 0;
}
#endif
int __devinit via_fb_pci_probe(struct viafb_dev *vdev) int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
{ {
u32 default_xres, default_yres; u32 default_xres, default_yres;
@ -1544,7 +1770,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
viafbinfo->pseudo_palette = pseudo_pal; viafbinfo->pseudo_palette = pseudo_pal;
if (viafb_accel && !viafb_init_engine(viafbinfo)) { if (viafb_accel && !viafb_setup_engine(viafbinfo)) {
viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA |
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT;
default_var.accel_flags = FB_ACCELF_TEXT; default_var.accel_flags = FB_ACCELF_TEXT;
@ -1671,9 +1897,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
viafbinfo->node, viafbinfo->fix.id, default_var.xres, viafbinfo->node, viafbinfo->fix.id, default_var.xres,
default_var.yres, default_var.bits_per_pixel); default_var.yres, default_var.bits_per_pixel);
#ifdef CONFIG_FB_VIA_DIRECT_PROCFS viafb_init_proc(viaparinfo->shared);
viafb_init_proc(&viaparinfo->shared->proc_entry);
#endif
viafb_init_dac(IGA2); viafb_init_dac(IGA2);
return 0; return 0;
@ -1700,9 +1924,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
unregister_framebuffer(viafbinfo); unregister_framebuffer(viafbinfo);
if (viafb_dual_fb) if (viafb_dual_fb)
unregister_framebuffer(viafbinfo1); unregister_framebuffer(viafbinfo1);
#ifdef CONFIG_FB_VIA_DIRECT_PROCFS viafb_remove_proc(viaparinfo->shared);
viafb_remove_proc(viaparinfo->shared->proc_entry);
#endif
framebuffer_release(viafbinfo); framebuffer_release(viafbinfo);
if (viafb_dual_fb) if (viafb_dual_fb)
framebuffer_release(viafbinfo1); framebuffer_release(viafbinfo1);

Просмотреть файл

@ -40,7 +40,12 @@
#define VIAFB_NUM_I2C 5 #define VIAFB_NUM_I2C 5
struct viafb_shared { struct viafb_shared {
u32 iga1_devices;
u32 iga2_devices;
struct proc_dir_entry *proc_entry; /*viafb proc entry */ struct proc_dir_entry *proc_entry; /*viafb proc entry */
struct proc_dir_entry *iga1_proc_entry;
struct proc_dir_entry *iga2_proc_entry;
struct viafb_dev *vdev; /* Global dev info */ struct viafb_dev *vdev; /* Global dev info */
/* All the information will be needed to set engine */ /* All the information will be needed to set engine */
@ -103,4 +108,6 @@ void via_fb_pci_remove(struct pci_dev *pdev);
/* Temporary */ /* Temporary */
int viafb_init(void); int viafb_init(void);
void viafb_exit(void); void viafb_exit(void);
int viafb_suspend(struct pci_dev *pdev, pm_message_t state);
int viafb_resume(struct pci_dev *pdev);
#endif /* __VIAFBDEV_H__ */ #endif /* __VIAFBDEV_H__ */

Просмотреть файл

@ -23,6 +23,34 @@
#include <linux/via_i2c.h> #include <linux/via_i2c.h>
#include "global.h" #include "global.h"
static const struct IODATA common_init_data[] = {
/* 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}
};
/* Index, Mask, Value */
static const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0};
static const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00};
static const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50};
static const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00};
static const struct IODATA vdd_on_data = {0x10, 0x20, 0x20};
static const struct IODATA vdd_off_data = {0x10, 0x20, 0x00};
u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
*plvds_setting_info, struct lvds_chip_information *plvds_chip_info, *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
u8 index) u8 index)
@ -55,108 +83,41 @@ void viafb_init_lvds_vt1636(struct lvds_setting_information
int reg_num, i; int reg_num, i;
/* Common settings: */ /* Common settings: */
reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636); reg_num = ARRAY_SIZE(common_init_data);
for (i = 0; i < reg_num; i++)
for (i = 0; i < reg_num; i++) {
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
plvds_chip_info, plvds_chip_info, common_init_data[i]);
COMMON_INIT_TBL_VT1636[i]);
}
/* Input Data Mode Select */ /* Input Data Mode Select */
if (plvds_setting_info->device_lcd_dualedge) { if (plvds_setting_info->device_lcd_dualedge)
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
plvds_chip_info, plvds_chip_info, dual_channel_enable_data);
DUAL_CHANNEL_ENABLE_TBL_VT1636[0]); else
} else {
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
plvds_chip_info, plvds_chip_info, single_channel_enable_data);
SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
}
if (plvds_setting_info->LCDDithering) { if (plvds_setting_info->LCDDithering)
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
plvds_chip_info, plvds_chip_info, dithering_enable_data);
DITHERING_ENABLE_TBL_VT1636[0]); else
} else {
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
plvds_chip_info, plvds_chip_info, dithering_disable_data);
DITHERING_DISABLE_TBL_VT1636[0]);
}
} }
void viafb_enable_lvds_vt1636(struct lvds_setting_information void viafb_enable_lvds_vt1636(struct lvds_setting_information
*plvds_setting_info, *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info) struct lvds_chip_information *plvds_chip_info)
{ {
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
VDD_ON_TBL_VT1636[0]); vdd_on_data);
/* 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 void viafb_disable_lvds_vt1636(struct lvds_setting_information
*plvds_setting_info, *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info) struct lvds_chip_information *plvds_chip_info)
{ {
viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
VDD_OFF_TBL_VT1636[0]); vdd_off_data);
/* 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(u8 i2c_adapter) bool viafb_lvds_identify_vt1636(u8 i2c_adapter)