summaryrefslogtreecommitdiffstats
path: root/drivers/video/via/viafbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/viafbdev.c')
-rw-r--r--drivers/video/via/viafbdev.c578
1 files changed, 264 insertions, 314 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 1082541358f0..d298cfccd6fc 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -49,11 +49,6 @@ char *viafb_active_dev;
char *viafb_lcd_port = "";
char *viafb_dvi_port = "";
-static void viafb_set_device(struct device_t active_dev);
-static int apply_device_setting(struct viafb_ioctl_setting setting_info,
- struct fb_info *info);
-static void apply_second_mode_setting(struct fb_var_screeninfo
- *sec_var);
static void retrieve_device_setting(struct viafb_ioctl_setting
*setting_info);
static int viafb_pan_display(struct fb_var_screeninfo *var,
@@ -61,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)
{
@@ -221,9 +242,9 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
/* Adjust var according to our driver's own table */
viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
- if (info->var.accel_flags & FB_ACCELF_TEXT &&
+ if (var->accel_flags & FB_ACCELF_TEXT &&
!ppar->shared->vdev->engine_mmio)
- info->var.accel_flags = 0;
+ var->accel_flags = 0;
return 0;
}
@@ -234,6 +255,7 @@ static int viafb_set_par(struct fb_info *info)
struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
+ viafb_update_fix(info);
viapar->depth = fb_get_color_depth(&info->var, &info->fix);
viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
@@ -257,7 +279,6 @@ static int viafb_set_par(struct fb_info *info)
}
if (vmode_entry) {
- viafb_update_fix(info);
if (viafb_dual_fb && viapar->iga_path == IGA2)
viafb_bpp1 = info->var.bits_per_pixel;
else
@@ -337,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;
}
@@ -462,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)
@@ -472,19 +493,12 @@ 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)
viafb_lcd_disable();
break;
- case VIAFB_SET_DEVICE:
- if (copy_from_user(&u.active_dev, (void *)argp,
- sizeof(u.active_dev)))
- return -EFAULT;
- viafb_set_device(u.active_dev);
- viafb_set_par(info);
- break;
case VIAFB_GET_DEVICE:
u.active_dev.crt = viafb_CRT_ON;
u.active_dev.dvi = viafb_DVI_ON;
@@ -527,21 +541,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
break;
- case VIAFB_SET_DEVICE_INFO:
- if (copy_from_user(&u.viafb_setting,
- argp, sizeof(u.viafb_setting)))
- return -EFAULT;
- if (apply_device_setting(u.viafb_setting, info) < 0)
- return -EINVAL;
-
- break;
-
- case VIAFB_SET_SECOND_MODE:
- if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))
- return -EFAULT;
- apply_second_mode_setting(&u.sec_var);
- break;
-
case VIAFB_GET_DEVICE_INFO:
retrieve_device_setting(&u.viafb_setting);
@@ -814,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) |
@@ -913,112 +913,6 @@ static int viafb_sync(struct fb_info *info)
return 0;
}
-static void check_available_device_to_enable(int device_id)
-{
- int device_num = 0;
-
- /* Initialize: */
- viafb_CRT_ON = STATE_OFF;
- viafb_DVI_ON = STATE_OFF;
- viafb_LCD_ON = STATE_OFF;
- viafb_LCD2_ON = STATE_OFF;
- viafb_DeviceStatus = None_Device;
-
- if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
- viafb_CRT_ON = STATE_ON;
- device_num++;
- viafb_DeviceStatus |= CRT_Device;
- }
-
- if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
- viafb_DVI_ON = STATE_ON;
- device_num++;
- viafb_DeviceStatus |= DVI_Device;
- }
-
- if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
- viafb_LCD_ON = STATE_ON;
- device_num++;
- viafb_DeviceStatus |= LCD_Device;
- }
-
- if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
- viafb_LCD2_ON = STATE_ON;
- device_num++;
- viafb_DeviceStatus |= LCD2_Device;
- }
-
- if (viafb_DeviceStatus == None_Device) {
- /* Use CRT as default active device: */
- viafb_CRT_ON = STATE_ON;
- viafb_DeviceStatus = CRT_Device;
- }
- DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
-}
-
-static void viafb_set_device(struct device_t active_dev)
-{
- /* Check available device to enable: */
- int device_id = None_Device;
- if (active_dev.crt)
- device_id |= CRT_Device;
- if (active_dev.dvi)
- device_id |= DVI_Device;
- if (active_dev.lcd)
- device_id |= LCD_Device;
-
- check_available_device_to_enable(device_id);
-
- /* Check property of LCD: */
- if (viafb_LCD_ON) {
- if (active_dev.lcd_dsp_cent) {
- viaparinfo->lvds_setting_info->display_method =
- viafb_lcd_dsp_method = LCD_CENTERING;
- } else {
- viaparinfo->lvds_setting_info->display_method =
- viafb_lcd_dsp_method = LCD_EXPANDSION;
- }
-
- if (active_dev.lcd_mode == LCD_SPWG) {
- viaparinfo->lvds_setting_info->lcd_mode =
- viafb_lcd_mode = LCD_SPWG;
- } else {
- viaparinfo->lvds_setting_info->lcd_mode =
- viafb_lcd_mode = LCD_OPENLDI;
- }
-
- if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
- viafb_lcd_panel_id = active_dev.lcd_panel_id;
- viafb_init_lcd_size();
- }
- }
-
- /* Check property of mode: */
- if (!active_dev.xres1)
- viafb_second_xres = 640;
- else
- viafb_second_xres = active_dev.xres1;
- if (!active_dev.yres1)
- viafb_second_yres = 480;
- else
- viafb_second_yres = active_dev.yres1;
- if (active_dev.bpp != 0)
- viafb_bpp = active_dev.bpp;
- if (active_dev.bpp1 != 0)
- viafb_bpp1 = active_dev.bpp1;
- if (active_dev.refresh != 0)
- viafb_refresh = active_dev.refresh;
- if (active_dev.refresh1 != 0)
- viafb_refresh1 = active_dev.refresh1;
- if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
- viafb_SAMM_ON = active_dev.samm;
- viafb_primary_dev = active_dev.primary_dev;
-
- via_set_primary_address(0);
- via_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
- viafb_set_iga_path();
-}
-
static int get_primary_device(void)
{
int primary_device = 0;
@@ -1060,124 +954,6 @@ static int get_primary_device(void)
return primary_device;
}
-static void apply_second_mode_setting(struct fb_var_screeninfo
- *sec_var)
-{
- u32 htotal, vtotal, long_refresh;
-
- htotal = sec_var->xres + sec_var->left_margin +
- sec_var->right_margin + sec_var->hsync_len;
- vtotal = sec_var->yres + sec_var->upper_margin +
- sec_var->lower_margin + sec_var->vsync_len;
- if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
- /*Is 32 bytes alignment? */
- /*32 pixel alignment */
- sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
- }
-
- htotal = sec_var->xres + sec_var->left_margin +
- sec_var->right_margin + sec_var->hsync_len;
- vtotal = sec_var->yres + sec_var->upper_margin +
- sec_var->lower_margin + sec_var->vsync_len;
- long_refresh = 1000000000UL / sec_var->pixclock * 1000;
- long_refresh /= (htotal * vtotal);
-
- viafb_second_xres = sec_var->xres;
- viafb_second_yres = sec_var->yres;
- viafb_second_virtual_xres = sec_var->xres_virtual;
- viafb_second_virtual_yres = sec_var->yres_virtual;
- viafb_bpp1 = sec_var->bits_per_pixel;
- viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
- long_refresh);
-}
-
-static int apply_device_setting(struct viafb_ioctl_setting setting_info,
- struct fb_info *info)
-{
- int need_set_mode = 0;
- DEBUG_MSG(KERN_INFO "apply_device_setting\n");
-
- if (setting_info.device_flag) {
- need_set_mode = 1;
- check_available_device_to_enable(setting_info.device_status);
- }
-
- /* Unlock LCD's operation according to LCD flag
- and check if the setting value is valid. */
- /* If the value is valid, apply the new setting value to the device. */
- if (viafb_LCD_ON) {
- if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
- need_set_mode = 1;
- if (setting_info.lcd_attributes.display_center) {
- /* Centering */
- viaparinfo->lvds_setting_info->display_method =
- LCD_CENTERING;
- viafb_lcd_dsp_method = LCD_CENTERING;
- viaparinfo->lvds_setting_info2->display_method =
- viafb_lcd_dsp_method = LCD_CENTERING;
- } else {
- /* expandsion */
- viaparinfo->lvds_setting_info->display_method =
- LCD_EXPANDSION;
- viafb_lcd_dsp_method = LCD_EXPANDSION;
- viaparinfo->lvds_setting_info2->display_method =
- LCD_EXPANDSION;
- viafb_lcd_dsp_method = LCD_EXPANDSION;
- }
- }
-
- if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
- need_set_mode = 1;
- if (setting_info.lcd_attributes.lcd_mode ==
- LCD_SPWG) {
- viaparinfo->lvds_setting_info->lcd_mode =
- viafb_lcd_mode = LCD_SPWG;
- } else {
- viaparinfo->lvds_setting_info->lcd_mode =
- viafb_lcd_mode = LCD_OPENLDI;
- }
- viaparinfo->lvds_setting_info2->lcd_mode =
- viaparinfo->lvds_setting_info->lcd_mode;
- }
-
- if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
- need_set_mode = 1;
- if (setting_info.lcd_attributes.panel_id <=
- LCD_PANEL_ID_MAXIMUM) {
- viafb_lcd_panel_id =
- setting_info.lcd_attributes.panel_id;
- viafb_init_lcd_size();
- }
- }
- }
-
- if (0 != (setting_info.samm_status & OP_SAMM)) {
- setting_info.samm_status =
- setting_info.samm_status & (~OP_SAMM);
- if (setting_info.samm_status == 0
- || setting_info.samm_status == 1) {
- viafb_SAMM_ON = setting_info.samm_status;
-
- if (viafb_SAMM_ON)
- viafb_primary_dev = setting_info.primary_device;
-
- via_set_primary_address(0);
- via_set_secondary_address(viafb_SAMM_ON ?
- viafb_second_offset : 0);
- viafb_set_iga_path();
- }
- need_set_mode = 1;
- }
-
- if (!need_set_mode) {
- ;
- } else {
- viafb_set_iga_path();
- viafb_set_par(info);
- }
- return true;
-}
-
static void retrieve_device_setting(struct viafb_ioctl_setting
*setting_info)
{
@@ -1212,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;
@@ -1282,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;
@@ -1299,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);
@@ -1312,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);
@@ -1682,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)
{
@@ -1737,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;
@@ -1776,10 +1751,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
parse_lcd_port();
parse_dvi_port();
- /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
- if (!viafb_SAMM_ON)
- viafb_dual_fb = 0;
-
viafb_init_chip_info(vdev->chip_type);
/*
* The framebuffer will have been successfully mapped by
@@ -1799,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;
@@ -1823,30 +1794,13 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
parse_mode(viafb_mode1, &viafb_second_xres,
&viafb_second_yres);
- if (0 == viafb_second_virtual_xres) {
- switch (viafb_second_xres) {
- case 1400:
- viafb_second_virtual_xres = 1408;
- break;
- default:
- viafb_second_virtual_xres = viafb_second_xres;
- break;
- }
- }
- if (0 == viafb_second_virtual_yres)
- viafb_second_virtual_yres = viafb_second_yres;
+ viafb_second_virtual_xres = viafb_second_xres;
+ viafb_second_virtual_yres = viafb_second_yres;
}
default_var.xres = default_xres;
default_var.yres = default_yres;
- switch (default_xres) {
- case 1400:
- default_var.xres_virtual = 1408;
- break;
- default:
- default_var.xres_virtual = default_xres;
- break;
- }
+ default_var.xres_virtual = default_xres;
default_var.yres_virtual = default_yres;
default_var.bits_per_pixel = viafb_bpp;
default_var.pixclock =
@@ -1943,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;
@@ -1972,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);