diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 19:02:41 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 19:02:41 -0700 |
commit | 9ae6d039224def926656206725ae6e89d1331417 (patch) | |
tree | 8ebee863f61da7d095575ca7ef17812d3952389c | |
parent | bdab225015fbbb45ccd8913f5d7c01b2bf67d8b2 (diff) | |
parent | 51f4332bb5fef869e8a89895a7bac6b4c03b4946 (diff) |
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
...
-rw-r--r-- | Documentation/fb/viafb.txt | 48 | ||||
-rw-r--r-- | drivers/video/via/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/via/accel.c | 53 | ||||
-rw-r--r-- | drivers/video/via/accel.h | 3 | ||||
-rw-r--r-- | drivers/video/via/chip.h | 3 | ||||
-rw-r--r-- | drivers/video/via/dvi.c | 189 | ||||
-rw-r--r-- | drivers/video/via/dvi.h | 4 | ||||
-rw-r--r-- | drivers/video/via/global.h | 1 | ||||
-rw-r--r-- | drivers/video/via/hw.c | 648 | ||||
-rw-r--r-- | drivers/video/via/hw.h | 53 | ||||
-rw-r--r-- | drivers/video/via/ioctl.c | 2 | ||||
-rw-r--r-- | drivers/video/via/lcd.c | 90 | ||||
-rw-r--r-- | drivers/video/via/lcd.h | 6 | ||||
-rw-r--r-- | drivers/video/via/lcdtbl.h | 591 | ||||
-rw-r--r-- | drivers/video/via/tbl1636.c | 71 | ||||
-rw-r--r-- | drivers/video/via/tbl1636.h | 34 | ||||
-rw-r--r-- | drivers/video/via/via-core.c | 16 | ||||
-rw-r--r-- | drivers/video/via/via_i2c.c | 31 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.c | 294 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.h | 7 | ||||
-rw-r--r-- | drivers/video/via/vt1636.c | 121 |
21 files changed, 1022 insertions, 1245 deletions
diff --git a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt index f3e046a6a987..1a2e8aa3fbb1 100644 --- a/Documentation/fb/viafb.txt +++ b/Documentation/fb/viafb.txt @@ -197,6 +197,54 @@ Notes: example, # 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]: -------------------- Add the following line to your grub.conf: diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index d496adb0f832..96f01ee2a412 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -5,5 +5,5 @@ obj-$(CONFIG_FB_VIA) += viafb.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 diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index e44893ea590d..3c969cdef0af 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -283,11 +283,12 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, 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); - - if (op == VIA_BITBLT_MONO) writel(bg_color, engine + 0x50); + } if (op == VIA_BITBLT_FILL) 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; } -int viafb_init_engine(struct fb_info *info) +int viafb_setup_engine(struct fb_info *info) { struct viafb_par *viapar = info->par; void __iomem *engine; - 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; + u32 chip_name = viapar->shared->chip_info.gfx_chip_name; engine = viapar->shared->vdev->engine_mmio; if (!engine) { @@ -329,18 +328,6 @@ int viafb_init_engine(struct fb_info *info) 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) { case UNICHROME_CLE266: case UNICHROME_K400: @@ -356,6 +343,7 @@ int viafb_init_engine(struct fb_info *info) break; case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: viapar->shared->hw_bitblt = hw_bitblt_2; break; default: @@ -386,12 +374,36 @@ int viafb_init_engine(struct fb_info *info) viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; #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 */ switch (chip_name) { case UNICHROME_K8M890: case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: writel(0x00100000, engine + VIA_REG_CR_TRANSET); writel(0x680A0000, 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_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: vq_start_low |= 0x20000000; vq_end_low |= 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_BG); writel(0x0, engine + VIA_REG_CURSOR_FG); - return 0; + return; } void viafb_show_hw_cursor(struct fb_info *info, int Status) diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h index 2c122d292365..79d5e10cc835 100644 --- a/drivers/video/via/accel.h +++ b/drivers/video/via/accel.h @@ -203,7 +203,8 @@ #define VIA_BITBLT_MONO 2 #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_wait_engine_idle(struct fb_info *info); diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index ef1f3de2e052..48f1342897bd 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -71,6 +71,9 @@ #define UNICHROME_VX855 12 #define UNICHROME_VX855_DID 0x5122 +#define UNICHROME_VX900 13 +#define UNICHROME_VX900_DID 0x7122 + /**************************************************/ /* Definition TMDS Trasmitter Information */ /**************************************************/ diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 39b040bb3817..84e21b39dd0b 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -25,10 +25,12 @@ static void tmds_register_write(int index, u8 data); static int tmds_register_read(int index); static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); -static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information - *tmds_chip, struct tmds_setting_information *tmds_setting); -static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information - *tmds_chip, struct tmds_setting_information *tmds_setting); +static void __devinit dvi_get_panel_size_from_DDCv1( + struct tmds_chip_information *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 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; } -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) { 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; } -int viafb_tmds_trasmitter_identify(void) +int __devinit viafb_tmds_trasmitter_identify(void) { 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_set_output_path(DEVICE_DVI, set_iga, - viaparinfo->chip_info->tmds_chip_info.output_interface); } /* Sense DVI Connector */ @@ -313,8 +313,9 @@ static int viafb_dvi_query_EDID(void) } /* Get Panel Size Using EDID1 Table */ -static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information - *tmds_chip, struct tmds_setting_information *tmds_setting) +static void __devinit dvi_get_panel_size_from_DDCv1( + struct tmds_chip_information *tmds_chip, + struct tmds_setting_information *tmds_setting) { int i, max_h = 0, tmp, restore; 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 */ -static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information - *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) { int restore; unsigned char R_Buffer[2]; @@ -468,64 +470,107 @@ static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information void viafb_dvi_disable(void) { if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP0) - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) & (~0xC0)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP1) - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) & (~0x30)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) & (~0x0C)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_LOW) - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) & (~0x03)); - - if (viaparinfo->chip_info-> tmds_chip_info.output_interface == INTERFACE_TMDS) /* Turn off TMDS power. */ viafb_write_reg(CRD2, VIACR, viafb_read_reg(VIACR, CRD2) | 0x08); } +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 */ void viafb_dvi_enable(void) { u8 data; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP0) { - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) | 0xC0); + switch (viaparinfo->chip_info->tmds_chip_info.output_interface) { + case INTERFACE_DVP0: + viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); + viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); + dvi_patch_skew_dvp0(); if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) tmds_register_write(0x88, 0x3b); else /*clear CR91[5] to direct on display period in the secondary diplay path */ - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP1) { - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) | 0x30); + case INTERFACE_DVP1: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); /*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); - } else { + else /*clear CR91[5] to direct on display period in the secondary diplay path */ - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); /*fix DVI cannot enable on EPIA-M board */ if (viafb_platform_epia_dvi == 1) { @@ -537,36 +582,40 @@ void viafb_dvi_enable(void) else data = 0x37; viafb_i2c_writebyte(viaparinfo->chip_info-> - tmds_chip_info.i2c_port, - viaparinfo->chip_info-> - tmds_chip_info.tmds_chip_slave_addr, - 0x08, data); + tmds_chip_info.i2c_port, + viaparinfo->chip_info-> + tmds_chip_info.tmds_chip_slave_addr, + 0x08, data); } } - } + break; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) | 0x0C); - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + case INTERFACE_DFP_HIGH: + if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) + via_write_reg_mask(VIACR, CR97, 0x03, 0x03); - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) | 0x03); - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_TMDS) { + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; + + case INTERFACE_DFP_LOW: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + break; + + dvi_patch_skew_dvp_low(); + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; + + case INTERFACE_TMDS: /* Turn on Display period in the panel path. */ viafb_write_reg_mask(CR91, VIACR, 0, BIT7); /* Turn on TMDS power. */ viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); + break; } -} + if (viaparinfo->tmds_setting_info->iga_path == IGA2) { + /* Disable LCD Scaling */ + viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); + } +} diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index 0dffcfd395f3..2c525c0c1adb 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -56,8 +56,8 @@ int viafb_dvi_sense(void); void viafb_dvi_disable(void); void viafb_dvi_enable(void); -int viafb_tmds_trasmitter_identify(void); -void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, +int __devinit viafb_tmds_trasmitter_identify(void); +void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, int set_iga); diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 28221a062dda..38ef5ac66953 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -48,7 +48,6 @@ #include "via_utility.h" #include "vt1636.h" #include "tblDPASetting.h" -#include "tbl1636.h" /* External struct*/ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 7dcb4d5bb9c3..36d73f940d8b 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -718,16 +718,20 @@ static struct rgbLUT palLUT_table[] = { 0x00} }; -static void set_crt_output_path(int set_iga); -static void dvi_patch_skew_dvp0(void); -static void dvi_patch_skew_dvp1(void); -static void dvi_patch_skew_dvp_low(void); -static void set_dvi_output_path(int set_iga, int output_interface); -static void set_lcd_output_path(int set_iga, int output_interface); +static struct via_device_mapping device_mapping[] = { + {VIA_LDVP0, "LDVP0"}, + {VIA_LDVP1, "LDVP1"}, + {VIA_DVP0, "DVP0"}, + {VIA_CRT, "CRT"}, + {VIA_DVP1, "DVP1"}, + {VIA_LVDS1, "LVDS1"}, + {VIA_LVDS2, "LVDS2"} +}; + static void load_fix_bit_crtc_reg(void); -static void init_gfx_chip_info(int chip_type); -static void init_tmds_chip_info(void); -static void init_lvds_chip_info(void); +static void __devinit init_gfx_chip_info(int chip_type); +static void __devinit init_tmds_chip_info(void); +static void __devinit init_lvds_chip_info(void); static void device_screen_off(void); static void device_screen_on(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); } +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*/ void viafb_set_iga_path(void) { @@ -821,6 +885,48 @@ void viafb_set_iga_path(void) 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) @@ -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); } -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) { - case DEVICE_CRT: - set_crt_output_path(set_iga); - break; - case DEVICE_DVI: - set_dvi_output_path(set_iga, output_interface); + u8 value, mask = 1 << offset; + + switch (iga) { + case IGA1: + value = 0x00; break; - case DEVICE_LCD: - set_lcd_output_path(set_iga, output_interface); + case IGA2: + value = mask; break; + default: + printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); + return; } + + via_write_reg_mask(VIACR, index, value, mask); } -static void set_crt_output_path(int set_iga) +static void set_crt_source(u8 iga) { - viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); + u8 value; - switch (set_iga) { + switch (iga) { case IGA1: - viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); + value = 0x00; break; case IGA2: - viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); - viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); + value = 0x40; break; + default: + printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); + return; } + + via_write_reg_mask(VIASR, 0x16, value, 0x40); } -static void dvi_patch_skew_dvp0(void) +static inline void set_ldvp0_source(u8 iga) { - /* 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; - } + set_source_common(0x6C, 7, iga); +} - 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; - } +static inline void set_ldvp1_source(u8 iga) +{ + set_source_common(0x93, 7, iga); +} - default: - { - break; - } - } +static inline void set_dvp0_source(u8 iga) +{ + set_source_common(0x96, 4, iga); } -static void dvi_patch_skew_dvp1(void) +static inline void set_dvp1_source(u8 iga) { - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CX700: - { - break; - } + set_source_common(0x9B, 4, iga); +} - default: - { - break; - } - } +static inline void set_lvds1_source(u8 iga) +{ + set_source_common(0x99, 4, iga); } -static void dvi_patch_skew_dvp_low(void) +static inline void set_lvds2_source(u8 iga) { - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_K8M890: - { - viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); - break; - } + set_source_common(0x97, 4, iga); +} - case UNICHROME_P4M900: - { - viafb_write_reg_mask(CR99, VIACR, 0x08, - BIT0 + BIT1 + BIT2 + BIT3); - break; - } +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); +} - case UNICHROME_P4M890: - { - viafb_write_reg_mask(CR99, VIACR, 0x0F, - BIT0 + BIT1 + BIT2 + BIT3); - break; - } +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: - { - break; - } + return; } + + via_write_reg_mask(VIACR, 0x36, value, 0x30); } -static void set_dvi_output_path(int set_iga, int output_interface) +static void set_dvp0_state(u8 state) { - 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); + u8 value; - dvi_patch_skew_dvp0(); + switch (state) { + case VIA_STATE_ON: + value = 0xC0; break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } - case INTERFACE_DVP1: - 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); - } + via_write_reg_mask(VIASR, 0x1E, value, 0xC0); +} + +static void set_dvp1_state(u8 state) +{ + u8 value; - viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); - dvi_patch_skew_dvp1(); + switch (state) { + case VIA_STATE_ON: + value = 0x30; break; - case INTERFACE_DFP_HIGH: - if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { - if (set_iga == IGA1) { - viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); - viafb_write_reg_mask(CR97, VIACR, 0x03, - BIT0 + BIT1 + BIT4); - } else { - viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR97, VIACR, 0x13, - BIT0 + BIT1 + BIT4); - } - } - viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); + case VIA_STATE_OFF: + value = 0x00; break; + default: + return; + } - case INTERFACE_DFP_LOW: - if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) - break; + via_write_reg_mask(VIASR, 0x1E, value, 0x30); +} - 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); - } +static void set_lvds1_state(u8 state) +{ + u8 value; - viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); - dvi_patch_skew_dvp_low(); + switch (state) { + case VIA_STATE_ON: + value = 0x03; 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); + case VIA_STATE_OFF: + value = 0x00; break; + default: + return; } - if (set_iga == IGA2) { - enable_second_display_channel(); - /* Disable LCD Scaling */ - viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); - } + via_write_reg_mask(VIASR, 0x2A, value, 0x03); } -static void set_lcd_output_path(int set_iga, int output_interface) +static void set_lvds2_state(u8 state) { - DEBUG_MSG(KERN_INFO - "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); + u8 value; - disable_second_display_channel(); + switch (state) { + case VIA_STATE_ON: + value = 0x0C; break; - - case IGA2: - viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); - viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); - - enable_second_display_channel(); + case VIA_STATE_OFF: + value = 0x00; break; + default: + return; } - switch (output_interface) { - 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; + via_write_reg_mask(VIASR, 0x2A, value, 0x0C); +} - 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; +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); +} - 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); - } +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; + } - break; + 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); +} - 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); +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; + } + } } - 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); + *end = ptr; + return odev; +} - break; +void via_odev_to_seq(struct seq_file *m, u32 odev) +{ + int i, count = 0; - 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; + for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { + if (odev & device_mapping[i].device) { + if (count > 0) + seq_putc(m, ','); + + seq_puts(m, device_mapping[i].name); + count++; + } } + + seq_putc(m, '\n'); } 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; } + 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 */ reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); 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; } + 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) { /* Set Display FIFO Depath Select */ reg_value = @@ -1612,6 +1707,7 @@ u32 viafb_get_clk_value(int clk) break; case UNICHROME_VX855: + case UNICHROME_VX900: value = vx855_encode_pll(pll_value[i].vx855_pll); break; } @@ -1645,6 +1741,7 @@ void viafb_set_vclock(u32 clk, int set_iga) case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: via_write_reg(VIASR, SR44, (clk & 0x0000FF)); via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); 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_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); 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) { - viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); + viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); + viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); } /* Fire! */ @@ -1937,7 +2035,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int index = 0; int h_addr, v_addr; u32 pll_D_N; - u8 polarity = 0; for (i = 0; i < video_mode->mode_array; i++) { index = i; @@ -1964,14 +2061,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, h_addr = crt_reg.hor_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) { viafb_unlock_crt(); 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_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; @@ -2111,6 +2200,7 @@ static void init_gfx_chip_info(int chip_type) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1; break; 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(); @@ -2168,7 +2258,7 @@ static void init_tmds_chip_info(void) &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_init_lcd_size(); @@ -2202,7 +2292,7 @@ static void init_lvds_chip_info(void) 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; 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, struct VideoModeTable *vmode_tbl1, int video_bpp1) { int i, j; int port; + u32 devices = viaparinfo->shared->iga1_devices + | viaparinfo->shared->iga2_devices; u8 value, index, mask; struct crt_mode_table *crt_timing; struct crt_mode_table *crt_timing1 = NULL; @@ -2322,11 +2425,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, break; case UNICHROME_VX855: + case UNICHROME_VX900: viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); break; } device_off(); + via_set_state(devices, VIA_STATE_OFF); /* Fill VPIT Parameters */ /* 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]); viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); - viafb_set_iga_path(); /* Write CRTC */ 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_secondary_color_depth(viafb_dual_fb ? viaparinfo1->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 */ /* Clear On Screen */ @@ -2394,8 +2505,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, 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 to 8 alignment (1368),there is several pixels (2 pixels) on right side of screen. */ @@ -2482,10 +2591,16 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_DeviceStatus = CRT_Device; } 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) - viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); - + via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; } @@ -2526,31 +2641,18 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh) static void device_off(void) { - viafb_crt_disable(); viafb_dvi_disable(); viafb_lcd_disable(); } static void device_on(void) { - if (viafb_CRT_ON == 1) - viafb_crt_enable(); if (viafb_DVI_ON == 1) viafb_dvi_enable(); if (viafb_LCD_ON == 1) 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) { /* to enable second display channel. */ @@ -2567,7 +2669,6 @@ static void disable_second_display_channel(void) viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); } - void viafb_set_dpa_gfx(int output_interface, struct 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); var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; 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; } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index c44399895294..668d534542ef 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -22,6 +22,8 @@ #ifndef __HW_H__ #define __HW_H__ +#include <linux/seq_file.h> + #include "viamode.h" #include "global.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_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 * ****************************************************/ @@ -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_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_THRESHOLD_REG_NUM 2 #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 @@ -858,6 +890,8 @@ struct iga2_crtc_timing { #define VX800_FUNCTION3 0x3353 /* VT3409 chipset*/ #define VX855_FUNCTION3 0x3409 +/* VT3410 chipset*/ +#define VX900_FUNCTION3 0x3410 #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) @@ -873,6 +907,11 @@ struct pci_device_id_info { u32 chip_index; }; +struct via_device_mapping { + u32 device; + const char *name; +}; + extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; @@ -881,9 +920,6 @@ extern int viafb_LCD_ON; extern int viafb_DVI_ON; 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, 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, struct io_register *reg, int io_type); -void viafb_crt_disable(void); -void viafb_crt_enable(void); +void via_set_source(u32 devices, u8 iga); +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); /* Access I/O Function */ 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); void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, struct VideoModeTable *vmode_tbl); -void viafb_init_chip_info(int chip_type); -void viafb_init_dac(int set_iga); +void __devinit viafb_init_chip_info(int chip_type); +void __devinit viafb_init_dac(int set_iga); int viafb_get_pixclock(int hres, int vres, int vmode_refresh); int viafb_get_refresh(int hres, int vres, u32 float_refresh); void viafb_update_device_setting(int hres, int vres, int bpp, diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c index 4d553d0b8d7a..ea1c51428823 100644 --- a/drivers/video/via/ioctl.c +++ b/drivers/video/via/ioctl.c @@ -94,6 +94,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp) viafb_CRT_ON = 0; viafb_LCD_ON = 0; viafb_DeviceStatus = DVI_Device; + viafb_set_iga_path(); return viafb_DeviceStatus; } status = 1; @@ -107,6 +108,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp) viafb_LCD_ON = 0; viafb_DeviceStatus = CRT_Device; + viafb_set_iga_path(); return viafb_DeviceStatus; } diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index fc25ae30c5f6..3425c3969806 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -21,10 +21,16 @@ #include <linux/via-core.h> #include <linux/via_i2c.h> #include "global.h" -#include "lcdtbl.h" #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 = { /* LCD Horizontal Scaling Factor Register */ {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 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 void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres); @@ -84,7 +90,7 @@ static int check_lvds_chip(int device_id_subaddr, int device_id) return FAIL; } -void viafb_init_lcd_size(void) +void __devinit viafb_init_lcd_size(void) { DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); @@ -144,7 +150,7 @@ static bool lvds_identify_integratedlvds(void) return true; } -int viafb_lvds_trasmitter_identify(void) +int __devinit viafb_lvds_trasmitter_identify(void) { if (viafb_lvds_identify_vt1636(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; } -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"); @@ -436,6 +442,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, case UNICHROME_CN750: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: reg_value = K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); /* 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_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: reg_value = K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); /* 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); DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); 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); /* 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); } - /* Turn DFP High/Low Pad off. */ - viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3); - /* Power off LVDS channel. */ switch (plvds_chip_info->output_interface) { case INTERFACE_LVDS0: @@ -758,9 +760,6 @@ static void integrated_lvds_enable(struct lvds_setting_information break; } - /* Turn DFP High/Low pad on. */ - viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3); - /* Power on LVDS channel. */ switch (plvds_chip_info->output_interface) { case INTERFACE_LVDS0: @@ -809,29 +808,48 @@ void viafb_lcd_disable(void) viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } else { - /* DFP-HL pad off */ - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F); /* Backlight off */ viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); /* 24 bit DI data paht off */ viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); - /* Simultaneout disabled */ - viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); } /* Disable expansion bit */ viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); - /* CRT path set to IGA1 */ - viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40); /* Simultaneout disabled */ 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) { + 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) { /* DI1 pad on */ 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, &viaparinfo->chip_info->lvds_chip_info); } else { - /* DFP-HL pad on */ - viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F); /* Backlight on */ viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); /* 24 bit DI data paht on */ 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 */ 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) @@ -993,7 +985,7 @@ static void check_diport_of_integrated_lvds( 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, struct lvds_setting_information *plvds_setting_info) diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index b348efc360b8..c7909fe29550 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -71,15 +71,15 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information struct lvds_chip_information *plvds_chip_info); void viafb_lcd_disable(void); void viafb_lcd_enable(void); -void viafb_init_lcd_size(void); -void viafb_init_lvds_output_interface(struct lvds_chip_information +void __devinit viafb_init_lcd_size(void); +void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information *plvds_setting_info); void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); -int viafb_lvds_trasmitter_identify(void); +int __devinit viafb_lvds_trasmitter_identify(void); void viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h deleted file mode 100644 index 6f3dd800be59..000000000000 --- a/drivers/video/via/lcdtbl.h +++ /dev/null @@ -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__ */ diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c deleted file mode 100644 index 2d8453429d4a..000000000000 --- a/drivers/video/via/tbl1636.c +++ /dev/null @@ -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} -}; diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h deleted file mode 100644 index d906055f1511..000000000000 --- a/drivers/video/via/tbl1636.h +++ /dev/null @@ -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_ */ diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 66f403033111..31e30338e893 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -20,7 +20,7 @@ * The default port config. */ 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_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, [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[] = { CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_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 @@ -370,6 +370,7 @@ static int viafb_get_fb_size_from_pci(int chip_type) case P4M900_FUNCTION3: case VX800_FUNCTION3: case VX855_FUNCTION3: + case VX900_FUNCTION3: /*case CN750_FUNCTION3: */ offset = 0xA0; 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 * 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); if (ret < 0) goto out_unmap; @@ -635,6 +639,8 @@ static struct pci_device_id via_pci_table[] __devinitdata = { .driver_data = UNICHROME_VX800 }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), .driver_data = UNICHROME_VX855 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX900_DID), + .driver_data = UNICHROME_VX900 }, { } }; MODULE_DEVICE_TABLE(pci, via_pci_table); @@ -644,6 +650,10 @@ static struct pci_driver via_driver = { .id_table = via_pci_table, .probe = via_pci_probe, .remove = __devexit_p(via_pci_remove), +#ifdef CONFIG_PM + .suspend = viafb_suspend, + .resume = viafb_resume, +#endif }; static int __init via_core_init(void) diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index da9e4ca94b17..3844b558b7bd 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -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 ret; u8 mm1[] = {0x00}; 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; msgs[0].len = 1; msgs[1].len = 1; 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 ret; u8 msg[2] = { index, data }; 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.len = 2; 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 ret; u8 mm1[] = {0x00}; 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; msgs[0].len = 1; msgs[1].len = buff_len; 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->getsda = via_i2c_getsda; algo->getscl = via_i2c_getscl; - algo->udelay = 40; - algo->timeout = 20; + algo->udelay = 10; + algo->timeout = 2; algo->data = adap_cfg; sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index bdd0e4130f4e..d298cfccd6fc 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -56,6 +56,32 @@ static int viafb_pan_display(struct fb_var_screeninfo *var, 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) { @@ -332,22 +358,22 @@ static int viafb_blank(int blank_mode, struct fb_info *info) case FB_BLANK_UNBLANK: /* Screen: On, HSync: On, VSync: On */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_ON); break; case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off, HSync: Off, VSync: On */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_STANDBY); break; case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off, HSync: On, VSync: Off */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_SUSPEND); break; case FB_BLANK_POWERDOWN: /* Screen: Off, HSync: Off, VSync: Off */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_OFF); 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))) return -EFAULT; if (gpu32 & CRT_Device) - viafb_crt_enable(); + via_set_state(VIA_CRT, VIA_STATE_ON); if (gpu32 & DVI_Device) viafb_dvi_enable(); 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))) return -EFAULT; if (gpu32 & CRT_Device) - viafb_crt_disable(); + via_set_state(VIA_CRT, VIA_STATE_OFF); if (gpu32 & DVI_Device) viafb_dvi_disable(); 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; if (chip_name == UNICHROME_CX700 || chip_name == UNICHROME_VX800 || - chip_name == UNICHROME_VX855) { + chip_name == UNICHROME_VX855 || + chip_name == UNICHROME_VX900) { fg_color = ((info->cmap.red[fg_color] & 0xFFC0) << 14) | ((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; } -static int parse_active_dev(void) +static int __init parse_active_dev(void) { viafb_CRT_ON = STATE_OFF; viafb_DVI_ON = STATE_OFF; @@ -1031,7 +1058,7 @@ static int parse_active_dev(void) 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)) *output_interface = INTERFACE_DVP0; @@ -1048,7 +1075,7 @@ static int parse_port(char *opt_str, int *output_interface) 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. output_interface); @@ -1061,7 +1088,7 @@ static void parse_lcd_port(void) 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. output_interface); @@ -1431,38 +1458,196 @@ static const struct file_operations viafb_vt1636_proc_fops = { .write = viafb_vt1636_proc_write, }; -static void viafb_init_proc(struct proc_dir_entry **viafb_entry) +#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ + +static int viafb_sup_odev_proc_show(struct seq_file *m, void *v) { - *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); - } + 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("dvp1", viafb_entry); remove_proc_entry("dfph", viafb_entry); remove_proc_entry("dfpl", viafb_entry); - if (chip_info->lvds_chip_info.lvds_chip_name == VT1636_LVDS - || chip_info->lvds_chip_info2.lvds_chip_name == VT1636_LVDS) + if (IS_VT1636(shared->chip_info.lvds_chip_info) + || IS_VT1636(shared->chip_info.lvds_chip_info2)) remove_proc_entry("vt1636", viafb_entry); +#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ remove_proc_entry("viafb", NULL); } - -#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ +#undef IS_VT1636 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) { 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->pseudo_palette = pseudo_pal; - if (viafb_accel && !viafb_init_engine(viafbinfo)) { + if (viafb_accel && !viafb_setup_engine(viafbinfo)) { viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; 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, default_var.yres, default_var.bits_per_pixel); -#ifdef CONFIG_FB_VIA_DIRECT_PROCFS - viafb_init_proc(&viaparinfo->shared->proc_entry); -#endif + viafb_init_proc(viaparinfo->shared); viafb_init_dac(IGA2); return 0; @@ -1700,9 +1924,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) unregister_framebuffer(viafbinfo); if (viafb_dual_fb) unregister_framebuffer(viafbinfo1); -#ifdef CONFIG_FB_VIA_DIRECT_PROCFS - viafb_remove_proc(viaparinfo->shared->proc_entry); -#endif + viafb_remove_proc(viaparinfo->shared); framebuffer_release(viafbinfo); if (viafb_dual_fb) framebuffer_release(viafbinfo1); diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 52a35fabba91..4960e3da6645 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -40,7 +40,12 @@ #define VIAFB_NUM_I2C 5 struct viafb_shared { + u32 iga1_devices; + u32 iga2_devices; + 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 */ /* All the information will be needed to set engine */ @@ -103,4 +108,6 @@ void via_fb_pci_remove(struct pci_dev *pdev); /* Temporary */ int viafb_init(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__ */ diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index d65bf1aee87c..60e4192c2b34 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -23,6 +23,34 @@ #include <linux/via_i2c.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 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, u8 index) @@ -55,108 +83,41 @@ void viafb_init_lvds_vt1636(struct lvds_setting_information int reg_num, i; /* Common settings: */ - reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636); - - for (i = 0; i < reg_num; i++) { + reg_num = ARRAY_SIZE(common_init_data); + for (i = 0; i < reg_num; i++) viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - COMMON_INIT_TBL_VT1636[i]); - } + plvds_chip_info, common_init_data[i]); /* 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, - plvds_chip_info, - DUAL_CHANNEL_ENABLE_TBL_VT1636[0]); - } else { + plvds_chip_info, dual_channel_enable_data); + else viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]); - } + plvds_chip_info, single_channel_enable_data); - if (plvds_setting_info->LCDDithering) { + if (plvds_setting_info->LCDDithering) viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - DITHERING_ENABLE_TBL_VT1636[0]); - } else { + plvds_chip_info, dithering_enable_data); + else viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - DITHERING_DISABLE_TBL_VT1636[0]); - } + plvds_chip_info, dithering_disable_data); } void viafb_enable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) { - viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, - VDD_ON_TBL_VT1636[0]); - - /* Pad on: */ - switch (plvds_chip_info->output_interface) { - case INTERFACE_DVP0: - { - viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0); - break; - } - - case INTERFACE_DVP1: - { - viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); - break; - } - - case INTERFACE_DFP_LOW: - { - viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03); - break; - } - - case INTERFACE_DFP_HIGH: - { - viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C); - break; - } - - } + vdd_on_data); } void viafb_disable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) { - viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, - VDD_OFF_TBL_VT1636[0]); - - /* Pad off: */ - switch (plvds_chip_info->output_interface) { - case INTERFACE_DVP0: - { - viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0); - break; - } - - case INTERFACE_DVP1: - { - viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); - break; - } - - case INTERFACE_DFP_LOW: - { - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03); - break; - } - - case INTERFACE_DFP_HIGH: - { - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C); - break; - } - - } + vdd_off_data); } bool viafb_lvds_identify_vt1636(u8 i2c_adapter) |