aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r--drivers/video/via/hw.c648
1 files changed, 377 insertions, 271 deletions
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;
}