aboutsummaryrefslogtreecommitdiffstats
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.c284
1 files changed, 6 insertions, 278 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 1082541358f0..bdd0e4130f4e 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -49,11 +49,6 @@ char *viafb_active_dev;
49char *viafb_lcd_port = ""; 49char *viafb_lcd_port = "";
50char *viafb_dvi_port = ""; 50char *viafb_dvi_port = "";
51 51
52static void viafb_set_device(struct device_t active_dev);
53static int apply_device_setting(struct viafb_ioctl_setting setting_info,
54 struct fb_info *info);
55static void apply_second_mode_setting(struct fb_var_screeninfo
56 *sec_var);
57static void retrieve_device_setting(struct viafb_ioctl_setting 52static void retrieve_device_setting(struct viafb_ioctl_setting
58 *setting_info); 53 *setting_info);
59static int viafb_pan_display(struct fb_var_screeninfo *var, 54static int viafb_pan_display(struct fb_var_screeninfo *var,
@@ -221,9 +216,9 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
221 216
222 /* Adjust var according to our driver's own table */ 217 /* Adjust var according to our driver's own table */
223 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 218 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
224 if (info->var.accel_flags & FB_ACCELF_TEXT && 219 if (var->accel_flags & FB_ACCELF_TEXT &&
225 !ppar->shared->vdev->engine_mmio) 220 !ppar->shared->vdev->engine_mmio)
226 info->var.accel_flags = 0; 221 var->accel_flags = 0;
227 222
228 return 0; 223 return 0;
229} 224}
@@ -234,6 +229,7 @@ static int viafb_set_par(struct fb_info *info)
234 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; 229 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
235 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 230 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
236 231
232 viafb_update_fix(info);
237 viapar->depth = fb_get_color_depth(&info->var, &info->fix); 233 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
238 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 234 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
239 viafbinfo->var.bits_per_pixel, viafb_refresh, 0); 235 viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
@@ -257,7 +253,6 @@ static int viafb_set_par(struct fb_info *info)
257 } 253 }
258 254
259 if (vmode_entry) { 255 if (vmode_entry) {
260 viafb_update_fix(info);
261 if (viafb_dual_fb && viapar->iga_path == IGA2) 256 if (viafb_dual_fb && viapar->iga_path == IGA2)
262 viafb_bpp1 = info->var.bits_per_pixel; 257 viafb_bpp1 = info->var.bits_per_pixel;
263 else 258 else
@@ -478,13 +473,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
478 if (gpu32 & LCD_Device) 473 if (gpu32 & LCD_Device)
479 viafb_lcd_disable(); 474 viafb_lcd_disable();
480 break; 475 break;
481 case VIAFB_SET_DEVICE:
482 if (copy_from_user(&u.active_dev, (void *)argp,
483 sizeof(u.active_dev)))
484 return -EFAULT;
485 viafb_set_device(u.active_dev);
486 viafb_set_par(info);
487 break;
488 case VIAFB_GET_DEVICE: 476 case VIAFB_GET_DEVICE:
489 u.active_dev.crt = viafb_CRT_ON; 477 u.active_dev.crt = viafb_CRT_ON;
490 u.active_dev.dvi = viafb_DVI_ON; 478 u.active_dev.dvi = viafb_DVI_ON;
@@ -527,21 +515,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
527 515
528 break; 516 break;
529 517
530 case VIAFB_SET_DEVICE_INFO:
531 if (copy_from_user(&u.viafb_setting,
532 argp, sizeof(u.viafb_setting)))
533 return -EFAULT;
534 if (apply_device_setting(u.viafb_setting, info) < 0)
535 return -EINVAL;
536
537 break;
538
539 case VIAFB_SET_SECOND_MODE:
540 if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))
541 return -EFAULT;
542 apply_second_mode_setting(&u.sec_var);
543 break;
544
545 case VIAFB_GET_DEVICE_INFO: 518 case VIAFB_GET_DEVICE_INFO:
546 519
547 retrieve_device_setting(&u.viafb_setting); 520 retrieve_device_setting(&u.viafb_setting);
@@ -913,112 +886,6 @@ static int viafb_sync(struct fb_info *info)
913 return 0; 886 return 0;
914} 887}
915 888
916static void check_available_device_to_enable(int device_id)
917{
918 int device_num = 0;
919
920 /* Initialize: */
921 viafb_CRT_ON = STATE_OFF;
922 viafb_DVI_ON = STATE_OFF;
923 viafb_LCD_ON = STATE_OFF;
924 viafb_LCD2_ON = STATE_OFF;
925 viafb_DeviceStatus = None_Device;
926
927 if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
928 viafb_CRT_ON = STATE_ON;
929 device_num++;
930 viafb_DeviceStatus |= CRT_Device;
931 }
932
933 if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
934 viafb_DVI_ON = STATE_ON;
935 device_num++;
936 viafb_DeviceStatus |= DVI_Device;
937 }
938
939 if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
940 viafb_LCD_ON = STATE_ON;
941 device_num++;
942 viafb_DeviceStatus |= LCD_Device;
943 }
944
945 if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
946 viafb_LCD2_ON = STATE_ON;
947 device_num++;
948 viafb_DeviceStatus |= LCD2_Device;
949 }
950
951 if (viafb_DeviceStatus == None_Device) {
952 /* Use CRT as default active device: */
953 viafb_CRT_ON = STATE_ON;
954 viafb_DeviceStatus = CRT_Device;
955 }
956 DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
957}
958
959static void viafb_set_device(struct device_t active_dev)
960{
961 /* Check available device to enable: */
962 int device_id = None_Device;
963 if (active_dev.crt)
964 device_id |= CRT_Device;
965 if (active_dev.dvi)
966 device_id |= DVI_Device;
967 if (active_dev.lcd)
968 device_id |= LCD_Device;
969
970 check_available_device_to_enable(device_id);
971
972 /* Check property of LCD: */
973 if (viafb_LCD_ON) {
974 if (active_dev.lcd_dsp_cent) {
975 viaparinfo->lvds_setting_info->display_method =
976 viafb_lcd_dsp_method = LCD_CENTERING;
977 } else {
978 viaparinfo->lvds_setting_info->display_method =
979 viafb_lcd_dsp_method = LCD_EXPANDSION;
980 }
981
982 if (active_dev.lcd_mode == LCD_SPWG) {
983 viaparinfo->lvds_setting_info->lcd_mode =
984 viafb_lcd_mode = LCD_SPWG;
985 } else {
986 viaparinfo->lvds_setting_info->lcd_mode =
987 viafb_lcd_mode = LCD_OPENLDI;
988 }
989
990 if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
991 viafb_lcd_panel_id = active_dev.lcd_panel_id;
992 viafb_init_lcd_size();
993 }
994 }
995
996 /* Check property of mode: */
997 if (!active_dev.xres1)
998 viafb_second_xres = 640;
999 else
1000 viafb_second_xres = active_dev.xres1;
1001 if (!active_dev.yres1)
1002 viafb_second_yres = 480;
1003 else
1004 viafb_second_yres = active_dev.yres1;
1005 if (active_dev.bpp != 0)
1006 viafb_bpp = active_dev.bpp;
1007 if (active_dev.bpp1 != 0)
1008 viafb_bpp1 = active_dev.bpp1;
1009 if (active_dev.refresh != 0)
1010 viafb_refresh = active_dev.refresh;
1011 if (active_dev.refresh1 != 0)
1012 viafb_refresh1 = active_dev.refresh1;
1013 if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
1014 viafb_SAMM_ON = active_dev.samm;
1015 viafb_primary_dev = active_dev.primary_dev;
1016
1017 via_set_primary_address(0);
1018 via_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1019 viafb_set_iga_path();
1020}
1021
1022static int get_primary_device(void) 889static int get_primary_device(void)
1023{ 890{
1024 int primary_device = 0; 891 int primary_device = 0;
@@ -1060,124 +927,6 @@ static int get_primary_device(void)
1060 return primary_device; 927 return primary_device;
1061} 928}
1062 929
1063static void apply_second_mode_setting(struct fb_var_screeninfo
1064 *sec_var)
1065{
1066 u32 htotal, vtotal, long_refresh;
1067
1068 htotal = sec_var->xres + sec_var->left_margin +
1069 sec_var->right_margin + sec_var->hsync_len;
1070 vtotal = sec_var->yres + sec_var->upper_margin +
1071 sec_var->lower_margin + sec_var->vsync_len;
1072 if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
1073 /*Is 32 bytes alignment? */
1074 /*32 pixel alignment */
1075 sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
1076 }
1077
1078 htotal = sec_var->xres + sec_var->left_margin +
1079 sec_var->right_margin + sec_var->hsync_len;
1080 vtotal = sec_var->yres + sec_var->upper_margin +
1081 sec_var->lower_margin + sec_var->vsync_len;
1082 long_refresh = 1000000000UL / sec_var->pixclock * 1000;
1083 long_refresh /= (htotal * vtotal);
1084
1085 viafb_second_xres = sec_var->xres;
1086 viafb_second_yres = sec_var->yres;
1087 viafb_second_virtual_xres = sec_var->xres_virtual;
1088 viafb_second_virtual_yres = sec_var->yres_virtual;
1089 viafb_bpp1 = sec_var->bits_per_pixel;
1090 viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
1091 long_refresh);
1092}
1093
1094static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1095 struct fb_info *info)
1096{
1097 int need_set_mode = 0;
1098 DEBUG_MSG(KERN_INFO "apply_device_setting\n");
1099
1100 if (setting_info.device_flag) {
1101 need_set_mode = 1;
1102 check_available_device_to_enable(setting_info.device_status);
1103 }
1104
1105 /* Unlock LCD's operation according to LCD flag
1106 and check if the setting value is valid. */
1107 /* If the value is valid, apply the new setting value to the device. */
1108 if (viafb_LCD_ON) {
1109 if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
1110 need_set_mode = 1;
1111 if (setting_info.lcd_attributes.display_center) {
1112 /* Centering */
1113 viaparinfo->lvds_setting_info->display_method =
1114 LCD_CENTERING;
1115 viafb_lcd_dsp_method = LCD_CENTERING;
1116 viaparinfo->lvds_setting_info2->display_method =
1117 viafb_lcd_dsp_method = LCD_CENTERING;
1118 } else {
1119 /* expandsion */
1120 viaparinfo->lvds_setting_info->display_method =
1121 LCD_EXPANDSION;
1122 viafb_lcd_dsp_method = LCD_EXPANDSION;
1123 viaparinfo->lvds_setting_info2->display_method =
1124 LCD_EXPANDSION;
1125 viafb_lcd_dsp_method = LCD_EXPANDSION;
1126 }
1127 }
1128
1129 if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
1130 need_set_mode = 1;
1131 if (setting_info.lcd_attributes.lcd_mode ==
1132 LCD_SPWG) {
1133 viaparinfo->lvds_setting_info->lcd_mode =
1134 viafb_lcd_mode = LCD_SPWG;
1135 } else {
1136 viaparinfo->lvds_setting_info->lcd_mode =
1137 viafb_lcd_mode = LCD_OPENLDI;
1138 }
1139 viaparinfo->lvds_setting_info2->lcd_mode =
1140 viaparinfo->lvds_setting_info->lcd_mode;
1141 }
1142
1143 if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
1144 need_set_mode = 1;
1145 if (setting_info.lcd_attributes.panel_id <=
1146 LCD_PANEL_ID_MAXIMUM) {
1147 viafb_lcd_panel_id =
1148 setting_info.lcd_attributes.panel_id;
1149 viafb_init_lcd_size();
1150 }
1151 }
1152 }
1153
1154 if (0 != (setting_info.samm_status & OP_SAMM)) {
1155 setting_info.samm_status =
1156 setting_info.samm_status & (~OP_SAMM);
1157 if (setting_info.samm_status == 0
1158 || setting_info.samm_status == 1) {
1159 viafb_SAMM_ON = setting_info.samm_status;
1160
1161 if (viafb_SAMM_ON)
1162 viafb_primary_dev = setting_info.primary_device;
1163
1164 via_set_primary_address(0);
1165 via_set_secondary_address(viafb_SAMM_ON ?
1166 viafb_second_offset : 0);
1167 viafb_set_iga_path();
1168 }
1169 need_set_mode = 1;
1170 }
1171
1172 if (!need_set_mode) {
1173 ;
1174 } else {
1175 viafb_set_iga_path();
1176 viafb_set_par(info);
1177 }
1178 return true;
1179}
1180
1181static void retrieve_device_setting(struct viafb_ioctl_setting 930static void retrieve_device_setting(struct viafb_ioctl_setting
1182 *setting_info) 931 *setting_info)
1183{ 932{
@@ -1776,10 +1525,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1776 parse_lcd_port(); 1525 parse_lcd_port();
1777 parse_dvi_port(); 1526 parse_dvi_port();
1778 1527
1779 /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
1780 if (!viafb_SAMM_ON)
1781 viafb_dual_fb = 0;
1782
1783 viafb_init_chip_info(vdev->chip_type); 1528 viafb_init_chip_info(vdev->chip_type);
1784 /* 1529 /*
1785 * The framebuffer will have been successfully mapped by 1530 * The framebuffer will have been successfully mapped by
@@ -1823,30 +1568,13 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1823 parse_mode(viafb_mode1, &viafb_second_xres, 1568 parse_mode(viafb_mode1, &viafb_second_xres,
1824 &viafb_second_yres); 1569 &viafb_second_yres);
1825 1570
1826 if (0 == viafb_second_virtual_xres) { 1571 viafb_second_virtual_xres = viafb_second_xres;
1827 switch (viafb_second_xres) { 1572 viafb_second_virtual_yres = viafb_second_yres;
1828 case 1400:
1829 viafb_second_virtual_xres = 1408;
1830 break;
1831 default:
1832 viafb_second_virtual_xres = viafb_second_xres;
1833 break;
1834 }
1835 }
1836 if (0 == viafb_second_virtual_yres)
1837 viafb_second_virtual_yres = viafb_second_yres;
1838 } 1573 }
1839 1574
1840 default_var.xres = default_xres; 1575 default_var.xres = default_xres;
1841 default_var.yres = default_yres; 1576 default_var.yres = default_yres;
1842 switch (default_xres) { 1577 default_var.xres_virtual = default_xres;
1843 case 1400:
1844 default_var.xres_virtual = 1408;
1845 break;
1846 default:
1847 default_var.xres_virtual = default_xres;
1848 break;
1849 }
1850 default_var.yres_virtual = default_yres; 1578 default_var.yres_virtual = default_yres;
1851 default_var.bits_per_pixel = viafb_bpp; 1579 default_var.bits_per_pixel = viafb_bpp;
1852 default_var.pixclock = 1580 default_var.pixclock =