diff options
Diffstat (limited to 'drivers/video/via/viafbdev.c')
| -rw-r--r-- | drivers/video/via/viafbdev.c | 518 |
1 files changed, 196 insertions, 322 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 3028e7ddc3b5..ce7783b63f6a 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
| @@ -26,18 +26,22 @@ | |||
| 26 | 26 | ||
| 27 | #include "global.h" | 27 | #include "global.h" |
| 28 | 28 | ||
| 29 | static struct fb_var_screeninfo default_var; | ||
| 30 | static char *viafb_name = "Via"; | 29 | static char *viafb_name = "Via"; |
| 31 | static u32 pseudo_pal[17]; | 30 | static u32 pseudo_pal[17]; |
| 32 | 31 | ||
| 33 | /* video mode */ | 32 | /* video mode */ |
| 34 | static char *viafb_mode = "640x480"; | 33 | static char *viafb_mode; |
| 35 | static char *viafb_mode1 = "640x480"; | 34 | static char *viafb_mode1; |
| 35 | static int viafb_bpp = 32; | ||
| 36 | static int viafb_bpp1 = 32; | ||
| 37 | |||
| 38 | static unsigned int viafb_second_offset; | ||
| 39 | static int viafb_second_size; | ||
| 36 | 40 | ||
| 37 | static int viafb_accel = 1; | 41 | static int viafb_accel = 1; |
| 38 | 42 | ||
| 39 | /* Added for specifying active devices.*/ | 43 | /* Added for specifying active devices.*/ |
| 40 | char *viafb_active_dev = ""; | 44 | char *viafb_active_dev; |
| 41 | 45 | ||
| 42 | /*Added for specify lcd output port*/ | 46 | /*Added for specify lcd output port*/ |
| 43 | char *viafb_lcd_port = ""; | 47 | char *viafb_lcd_port = ""; |
| @@ -50,18 +54,78 @@ static void apply_second_mode_setting(struct fb_var_screeninfo | |||
| 50 | *sec_var); | 54 | *sec_var); |
| 51 | static void retrieve_device_setting(struct viafb_ioctl_setting | 55 | static void retrieve_device_setting(struct viafb_ioctl_setting |
| 52 | *setting_info); | 56 | *setting_info); |
| 57 | static int viafb_pan_display(struct fb_var_screeninfo *var, | ||
| 58 | struct fb_info *info); | ||
| 53 | 59 | ||
| 54 | static struct fb_ops viafb_ops; | 60 | static struct fb_ops viafb_ops; |
| 55 | 61 | ||
| 56 | 62 | ||
| 63 | static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) | ||
| 64 | { | ||
| 65 | var->grayscale = 0; | ||
| 66 | var->red.msb_right = 0; | ||
| 67 | var->green.msb_right = 0; | ||
| 68 | var->blue.msb_right = 0; | ||
| 69 | var->transp.offset = 0; | ||
| 70 | var->transp.length = 0; | ||
| 71 | var->transp.msb_right = 0; | ||
| 72 | var->nonstd = 0; | ||
| 73 | switch (depth) { | ||
| 74 | case 8: | ||
| 75 | var->bits_per_pixel = 8; | ||
| 76 | var->red.offset = 0; | ||
| 77 | var->green.offset = 0; | ||
| 78 | var->blue.offset = 0; | ||
| 79 | var->red.length = 8; | ||
| 80 | var->green.length = 8; | ||
| 81 | var->blue.length = 8; | ||
| 82 | break; | ||
| 83 | case 15: | ||
| 84 | var->bits_per_pixel = 16; | ||
| 85 | var->red.offset = 10; | ||
| 86 | var->green.offset = 5; | ||
| 87 | var->blue.offset = 0; | ||
| 88 | var->red.length = 5; | ||
| 89 | var->green.length = 5; | ||
| 90 | var->blue.length = 5; | ||
| 91 | break; | ||
| 92 | case 16: | ||
| 93 | var->bits_per_pixel = 16; | ||
| 94 | var->red.offset = 11; | ||
| 95 | var->green.offset = 5; | ||
| 96 | var->blue.offset = 0; | ||
| 97 | var->red.length = 5; | ||
| 98 | var->green.length = 6; | ||
| 99 | var->blue.length = 5; | ||
| 100 | break; | ||
| 101 | case 24: | ||
| 102 | var->bits_per_pixel = 32; | ||
| 103 | var->red.offset = 16; | ||
| 104 | var->green.offset = 8; | ||
| 105 | var->blue.offset = 0; | ||
| 106 | var->red.length = 8; | ||
| 107 | var->green.length = 8; | ||
| 108 | var->blue.length = 8; | ||
| 109 | break; | ||
| 110 | case 30: | ||
| 111 | var->bits_per_pixel = 32; | ||
| 112 | var->red.offset = 20; | ||
| 113 | var->green.offset = 10; | ||
| 114 | var->blue.offset = 0; | ||
| 115 | var->red.length = 10; | ||
| 116 | var->green.length = 10; | ||
| 117 | var->blue.length = 10; | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 57 | static void viafb_update_fix(struct fb_info *info) | 122 | static void viafb_update_fix(struct fb_info *info) |
| 58 | { | 123 | { |
| 59 | u32 bpp = info->var.bits_per_pixel; | 124 | u32 bpp = info->var.bits_per_pixel; |
| 60 | 125 | ||
| 61 | info->fix.visual = | 126 | info->fix.visual = |
| 62 | bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 127 | bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; |
| 63 | info->fix.line_length = | 128 | info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7; |
| 64 | ((info->var.xres_virtual + 7) & ~7) * bpp / 8; | ||
| 65 | } | 129 | } |
| 66 | 130 | ||
| 67 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | 131 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, |
| @@ -75,6 +139,7 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | |||
| 75 | 139 | ||
| 76 | fix->type = FB_TYPE_PACKED_PIXELS; | 140 | fix->type = FB_TYPE_PACKED_PIXELS; |
| 77 | fix->type_aux = 0; | 141 | fix->type_aux = 0; |
| 142 | fix->visual = FB_VISUAL_TRUECOLOR; | ||
| 78 | 143 | ||
| 79 | fix->xpanstep = fix->ywrapstep = 0; | 144 | fix->xpanstep = fix->ywrapstep = 0; |
| 80 | fix->ypanstep = 1; | 145 | fix->ypanstep = 1; |
| @@ -97,9 +162,10 @@ static int viafb_release(struct fb_info *info, int user) | |||
| 97 | static int viafb_check_var(struct fb_var_screeninfo *var, | 162 | static int viafb_check_var(struct fb_var_screeninfo *var, |
| 98 | struct fb_info *info) | 163 | struct fb_info *info) |
| 99 | { | 164 | { |
| 100 | int vmode_index, htotal, vtotal; | 165 | int htotal, vtotal, depth; |
| 166 | struct VideoModeTable *vmode_entry; | ||
| 101 | struct viafb_par *ppar = info->par; | 167 | struct viafb_par *ppar = info->par; |
| 102 | u32 long_refresh; | 168 | u32 long_refresh, line; |
| 103 | 169 | ||
| 104 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); | 170 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); |
| 105 | /* Sanity check */ | 171 | /* Sanity check */ |
| @@ -107,26 +173,36 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
| 107 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) | 173 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) |
| 108 | return -EINVAL; | 174 | return -EINVAL; |
| 109 | 175 | ||
| 110 | vmode_index = viafb_get_mode_index(var->xres, var->yres); | 176 | vmode_entry = viafb_get_mode(var->xres, var->yres); |
| 111 | if (vmode_index == VIA_RES_INVALID) { | 177 | if (!vmode_entry) { |
| 112 | DEBUG_MSG(KERN_INFO | 178 | DEBUG_MSG(KERN_INFO |
| 113 | "viafb: Mode %dx%dx%d not supported!!\n", | 179 | "viafb: Mode %dx%dx%d not supported!!\n", |
| 114 | var->xres, var->yres, var->bits_per_pixel); | 180 | var->xres, var->yres, var->bits_per_pixel); |
| 115 | return -EINVAL; | 181 | return -EINVAL; |
| 116 | } | 182 | } |
| 117 | 183 | ||
| 118 | if (24 == var->bits_per_pixel) | 184 | depth = fb_get_color_depth(var, &info->fix); |
| 119 | var->bits_per_pixel = 32; | 185 | if (!depth) |
| 186 | depth = var->bits_per_pixel; | ||
| 120 | 187 | ||
| 121 | if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && | 188 | if (depth < 0 || depth > 32) |
| 122 | var->bits_per_pixel != 32) | ||
| 123 | return -EINVAL; | 189 | return -EINVAL; |
| 190 | else if (!depth) | ||
| 191 | depth = 24; | ||
| 192 | else if (depth == 15 && viafb_dual_fb && ppar->iga_path == IGA1) | ||
| 193 | depth = 15; | ||
| 194 | else if (depth == 30) | ||
| 195 | depth = 30; | ||
| 196 | else if (depth <= 8) | ||
| 197 | depth = 8; | ||
| 198 | else if (depth <= 16) | ||
| 199 | depth = 16; | ||
| 200 | else | ||
| 201 | depth = 24; | ||
| 124 | 202 | ||
| 125 | if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F) | 203 | viafb_fill_var_color_info(var, depth); |
| 126 | /*32 pixel alignment */ | 204 | line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7; |
| 127 | var->xres_virtual = (var->xres_virtual + 31) & ~31; | 205 | if (line * var->yres_virtual > ppar->memsize) |
| 128 | if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > | ||
| 129 | ppar->memsize) | ||
| 130 | return -EINVAL; | 206 | return -EINVAL; |
| 131 | 207 | ||
| 132 | /* Based on var passed in to calculate the refresh, | 208 | /* Based on var passed in to calculate the refresh, |
| @@ -142,7 +218,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
| 142 | viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh); | 218 | viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh); |
| 143 | 219 | ||
| 144 | /* Adjust var according to our driver's own table */ | 220 | /* Adjust var according to our driver's own table */ |
| 145 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); | 221 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); |
| 146 | if (info->var.accel_flags & FB_ACCELF_TEXT && | 222 | if (info->var.accel_flags & FB_ACCELF_TEXT && |
| 147 | !ppar->shared->engine_mmio) | 223 | !ppar->shared->engine_mmio) |
| 148 | info->var.accel_flags = 0; | 224 | info->var.accel_flags = 0; |
| @@ -153,39 +229,45 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
| 153 | static int viafb_set_par(struct fb_info *info) | 229 | static int viafb_set_par(struct fb_info *info) |
| 154 | { | 230 | { |
| 155 | struct viafb_par *viapar = info->par; | 231 | struct viafb_par *viapar = info->par; |
| 156 | int vmode_index; | 232 | struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; |
| 157 | int vmode_index1 = 0; | ||
| 158 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); | 233 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); |
| 159 | 234 | ||
| 160 | viapar->depth = fb_get_color_depth(&info->var, &info->fix); | 235 | viapar->depth = fb_get_color_depth(&info->var, &info->fix); |
| 161 | viafb_update_device_setting(info->var.xres, info->var.yres, | 236 | viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, |
| 162 | info->var.bits_per_pixel, viafb_refresh, 0); | 237 | viafbinfo->var.bits_per_pixel, viafb_refresh, 0); |
| 163 | 238 | ||
| 164 | vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres); | 239 | vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres); |
| 165 | 240 | if (viafb_dual_fb) { | |
| 166 | if (viafb_SAMM_ON == 1) { | 241 | vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres, |
| 242 | viafbinfo1->var.yres); | ||
| 243 | viafb_update_device_setting(viafbinfo1->var.xres, | ||
| 244 | viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, | ||
| 245 | viafb_refresh1, 1); | ||
| 246 | } else if (viafb_SAMM_ON == 1) { | ||
| 167 | DEBUG_MSG(KERN_INFO | 247 | DEBUG_MSG(KERN_INFO |
| 168 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", | 248 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", |
| 169 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 249 | viafb_second_xres, viafb_second_yres, viafb_bpp1); |
| 170 | vmode_index1 = viafb_get_mode_index(viafb_second_xres, | 250 | vmode_entry1 = viafb_get_mode(viafb_second_xres, |
| 171 | viafb_second_yres); | 251 | viafb_second_yres); |
| 172 | DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n", | ||
| 173 | vmode_index1); | ||
| 174 | 252 | ||
| 175 | viafb_update_device_setting(viafb_second_xres, | 253 | viafb_update_device_setting(viafb_second_xres, |
| 176 | viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); | 254 | viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); |
| 177 | } | 255 | } |
| 178 | 256 | ||
| 179 | if (vmode_index != VIA_RES_INVALID) { | 257 | if (vmode_entry) { |
| 180 | viafb_update_fix(info); | 258 | viafb_update_fix(info); |
| 181 | viafb_bpp = info->var.bits_per_pixel; | 259 | if (viafb_dual_fb && viapar->iga_path == IGA2) |
| 260 | viafb_bpp1 = info->var.bits_per_pixel; | ||
| 261 | else | ||
| 262 | viafb_bpp = info->var.bits_per_pixel; | ||
| 263 | |||
| 182 | if (info->var.accel_flags & FB_ACCELF_TEXT) | 264 | if (info->var.accel_flags & FB_ACCELF_TEXT) |
| 183 | info->flags &= ~FBINFO_HWACCEL_DISABLED; | 265 | info->flags &= ~FBINFO_HWACCEL_DISABLED; |
| 184 | else | 266 | else |
| 185 | info->flags |= FBINFO_HWACCEL_DISABLED; | 267 | info->flags |= FBINFO_HWACCEL_DISABLED; |
| 186 | viafb_setmode(vmode_index, info->var.xres, info->var.yres, | 268 | viafb_setmode(vmode_entry, info->var.bits_per_pixel, |
| 187 | info->var.bits_per_pixel, vmode_index1, | 269 | vmode_entry1, viafb_bpp1); |
| 188 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 270 | viafb_pan_display(&info->var, info); |
| 189 | } | 271 | } |
| 190 | 272 | ||
| 191 | return 0; | 273 | return 0; |
| @@ -195,234 +277,52 @@ static int viafb_set_par(struct fb_info *info) | |||
| 195 | static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, | 277 | static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, |
| 196 | unsigned blue, unsigned transp, struct fb_info *info) | 278 | unsigned blue, unsigned transp, struct fb_info *info) |
| 197 | { | 279 | { |
| 198 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | 280 | struct viafb_par *viapar = info->par; |
| 199 | unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16; | 281 | u32 r, g, b; |
| 200 | DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n"); | ||
| 201 | if (regno >= cmap_entries) | ||
| 202 | return 1; | ||
| 203 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
| 204 | /* | ||
| 205 | * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev. | ||
| 206 | */ | ||
| 207 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
| 208 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
| 209 | } | ||
| 210 | switch (info->var.bits_per_pixel) { | ||
| 211 | case 8: | ||
| 212 | outb(0x1A, 0x3C4); | ||
| 213 | sr1a = inb(0x3C5); | ||
| 214 | outb(0x1B, 0x3C4); | ||
| 215 | sr1b = inb(0x3C5); | ||
| 216 | outb(0x67, 0x3D4); | ||
| 217 | cr67 = inb(0x3D5); | ||
| 218 | outb(0x6A, 0x3D4); | ||
| 219 | cr6a = inb(0x3D5); | ||
| 220 | |||
| 221 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
| 222 | outb(0x1A, 0x3C4); | ||
| 223 | outb(sr1a | 0x01, 0x3C5); | ||
| 224 | /* Second Display Engine colck always on */ | ||
| 225 | outb(0x1B, 0x3C4); | ||
| 226 | outb(sr1b | 0x80, 0x3C5); | ||
| 227 | /* Second Display Color Depth 8 */ | ||
| 228 | outb(0x67, 0x3D4); | ||
| 229 | outb(cr67 & 0x3F, 0x3D5); | ||
| 230 | outb(0x6A, 0x3D4); | ||
| 231 | /* Second Display Channel Reset CR6A[6]) */ | ||
| 232 | outb(cr6a & 0xBF, 0x3D5); | ||
| 233 | /* Second Display Channel Enable CR6A[7] */ | ||
| 234 | outb(cr6a | 0x80, 0x3D5); | ||
| 235 | /* Second Display Channel stop reset) */ | ||
| 236 | outb(cr6a | 0x40, 0x3D5); | ||
| 237 | |||
| 238 | /* Bit mask of palette */ | ||
| 239 | outb(0xFF, 0x3c6); | ||
| 240 | /* Write one register of IGA2 */ | ||
| 241 | outb(regno, 0x3C8); | ||
| 242 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
| 243 | rev >= 15) { | ||
| 244 | shift = 8; | ||
| 245 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
| 246 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
| 247 | } else { | ||
| 248 | shift = 10; | ||
| 249 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
| 250 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
| 251 | } | ||
| 252 | outb(red >> shift, 0x3C9); | ||
| 253 | outb(green >> shift, 0x3C9); | ||
| 254 | outb(blue >> shift, 0x3C9); | ||
| 255 | |||
| 256 | /* Map the 3C6/7/8/9 to the IGA1 */ | ||
| 257 | outb(0x1A, 0x3C4); | ||
| 258 | outb(sr1a & 0xFE, 0x3C5); | ||
| 259 | /* Bit mask of palette */ | ||
| 260 | outb(0xFF, 0x3c6); | ||
| 261 | /* Write one register of IGA1 */ | ||
| 262 | outb(regno, 0x3C8); | ||
| 263 | outb(red >> shift, 0x3C9); | ||
| 264 | outb(green >> shift, 0x3C9); | ||
| 265 | outb(blue >> shift, 0x3C9); | ||
| 266 | |||
| 267 | outb(0x1A, 0x3C4); | ||
| 268 | outb(sr1a, 0x3C5); | ||
| 269 | outb(0x1B, 0x3C4); | ||
| 270 | outb(sr1b, 0x3C5); | ||
| 271 | outb(0x67, 0x3D4); | ||
| 272 | outb(cr67, 0x3D5); | ||
| 273 | outb(0x6A, 0x3D4); | ||
| 274 | outb(cr6a, 0x3D5); | ||
| 275 | break; | ||
| 276 | case 16: | ||
| 277 | ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) | | ||
| 278 | ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); | ||
| 279 | break; | ||
| 280 | case 32: | ||
| 281 | ((u32 *) info->pseudo_palette)[regno] = | ||
| 282 | ((transp & 0xFF00) << 16) | | ||
| 283 | ((red & 0xFF00) << 8) | | ||
| 284 | ((green & 0xFF00)) | ((blue & 0xFF00) >> 8); | ||
| 285 | break; | ||
| 286 | } | ||
| 287 | |||
| 288 | return 0; | ||
| 289 | 282 | ||
| 290 | } | 283 | if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { |
| 284 | if (regno > 255) | ||
| 285 | return -EINVAL; | ||
| 291 | 286 | ||
| 292 | /*CALLED BY: fb_set_cmap */ | 287 | if (!viafb_dual_fb || viapar->iga_path == IGA1) |
| 293 | /* fb_set_var, pass 256 colors */ | 288 | viafb_set_primary_color_register(regno, red >> 8, |
| 294 | /*CALLED BY: fb_set_cmap */ | 289 | green >> 8, blue >> 8); |
| 295 | /* fbcon_set_palette, pass 16 colors */ | ||
| 296 | static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
| 297 | { | ||
| 298 | u32 len = cmap->len; | ||
| 299 | u32 i; | ||
| 300 | u16 *pred = cmap->red; | ||
| 301 | u16 *pgreen = cmap->green; | ||
| 302 | u16 *pblue = cmap->blue; | ||
| 303 | u16 *ptransp = cmap->transp; | ||
| 304 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | ||
| 305 | if (len > 256) | ||
| 306 | return 1; | ||
| 307 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
| 308 | /* | ||
| 309 | * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip | ||
| 310 | * rev. | ||
| 311 | */ | ||
| 312 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
| 313 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
| 314 | } | ||
| 315 | switch (info->var.bits_per_pixel) { | ||
| 316 | case 8: | ||
| 317 | outb(0x1A, 0x3C4); | ||
| 318 | sr1a = inb(0x3C5); | ||
| 319 | outb(0x1B, 0x3C4); | ||
| 320 | sr1b = inb(0x3C5); | ||
| 321 | outb(0x67, 0x3D4); | ||
| 322 | cr67 = inb(0x3D5); | ||
| 323 | outb(0x6A, 0x3D4); | ||
| 324 | cr6a = inb(0x3D5); | ||
| 325 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
| 326 | outb(0x1A, 0x3C4); | ||
| 327 | outb(sr1a | 0x01, 0x3C5); | ||
| 328 | outb(0x1B, 0x3C4); | ||
| 329 | /* Second Display Engine colck always on */ | ||
| 330 | outb(sr1b | 0x80, 0x3C5); | ||
| 331 | outb(0x67, 0x3D4); | ||
| 332 | /* Second Display Color Depth 8 */ | ||
| 333 | outb(cr67 & 0x3F, 0x3D5); | ||
| 334 | outb(0x6A, 0x3D4); | ||
| 335 | /* Second Display Channel Reset CR6A[6]) */ | ||
| 336 | outb(cr6a & 0xBF, 0x3D5); | ||
| 337 | /* Second Display Channel Enable CR6A[7] */ | ||
| 338 | outb(cr6a | 0x80, 0x3D5); | ||
| 339 | /* Second Display Channel stop reset) */ | ||
| 340 | outb(cr6a | 0xC0, 0x3D5); | ||
| 341 | |||
| 342 | /* Bit mask of palette */ | ||
| 343 | outb(0xFF, 0x3c6); | ||
| 344 | outb(0x00, 0x3C8); | ||
| 345 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
| 346 | rev >= 15) { | ||
| 347 | shift = 8; | ||
| 348 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
| 349 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
| 350 | } else { | ||
| 351 | shift = 10; | ||
| 352 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
| 353 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
| 354 | } | ||
| 355 | for (i = 0; i < len; i++) { | ||
| 356 | outb((*(pred + i)) >> shift, 0x3C9); | ||
| 357 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
| 358 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
| 359 | } | ||
| 360 | 290 | ||
| 361 | outb(0x1A, 0x3C4); | 291 | if (!viafb_dual_fb || viapar->iga_path == IGA2) |
| 362 | /* Map the 3C6/7/8/9 to the IGA1 */ | 292 | viafb_set_secondary_color_register(regno, red >> 8, |
| 363 | outb(sr1a & 0xFE, 0x3C5); | 293 | green >> 8, blue >> 8); |
| 364 | /* Bit mask of palette */ | 294 | } else { |
| 365 | outb(0xFF, 0x3c6); | 295 | if (regno > 15) |
| 366 | outb(0x00, 0x3C8); | 296 | return -EINVAL; |
| 367 | for (i = 0; i < len; i++) { | ||
| 368 | outb((*(pred + i)) >> shift, 0x3C9); | ||
| 369 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
| 370 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
| 371 | } | ||
| 372 | 297 | ||
| 373 | outb(0x1A, 0x3C4); | 298 | r = (red >> (16 - info->var.red.length)) |
| 374 | outb(sr1a, 0x3C5); | 299 | << info->var.red.offset; |
| 375 | outb(0x1B, 0x3C4); | 300 | b = (blue >> (16 - info->var.blue.length)) |
| 376 | outb(sr1b, 0x3C5); | 301 | << info->var.blue.offset; |
| 377 | outb(0x67, 0x3D4); | 302 | g = (green >> (16 - info->var.green.length)) |
| 378 | outb(cr67, 0x3D5); | 303 | << info->var.green.offset; |
| 379 | outb(0x6A, 0x3D4); | 304 | ((u32 *) info->pseudo_palette)[regno] = r | g | b; |
| 380 | outb(cr6a, 0x3D5); | ||
| 381 | break; | ||
| 382 | case 16: | ||
| 383 | if (len > 17) | ||
| 384 | return 0; /* Because static u32 pseudo_pal[17]; */ | ||
| 385 | for (i = 0; i < len; i++) | ||
| 386 | ((u32 *) info->pseudo_palette)[i] = | ||
| 387 | (*(pred + i) & 0xF800) | | ||
| 388 | ((*(pgreen + i) & 0xFC00) >> 5) | | ||
| 389 | ((*(pblue + i) & 0xF800) >> 11); | ||
| 390 | break; | ||
| 391 | case 32: | ||
| 392 | if (len > 17) | ||
| 393 | return 0; | ||
| 394 | if (ptransp) { | ||
| 395 | for (i = 0; i < len; i++) | ||
| 396 | ((u32 *) info->pseudo_palette)[i] = | ||
| 397 | ((*(ptransp + i) & 0xFF00) << 16) | | ||
| 398 | ((*(pred + i) & 0xFF00) << 8) | | ||
| 399 | ((*(pgreen + i) & 0xFF00)) | | ||
| 400 | ((*(pblue + i) & 0xFF00) >> 8); | ||
| 401 | } else { | ||
| 402 | for (i = 0; i < len; i++) | ||
| 403 | ((u32 *) info->pseudo_palette)[i] = | ||
| 404 | 0x00000000 | | ||
| 405 | ((*(pred + i) & 0xFF00) << 8) | | ||
| 406 | ((*(pgreen + i) & 0xFF00)) | | ||
| 407 | ((*(pblue + i) & 0xFF00) >> 8); | ||
| 408 | } | ||
| 409 | break; | ||
| 410 | } | 305 | } |
| 306 | |||
| 411 | return 0; | 307 | return 0; |
| 412 | } | 308 | } |
| 413 | 309 | ||
| 414 | static int viafb_pan_display(struct fb_var_screeninfo *var, | 310 | static int viafb_pan_display(struct fb_var_screeninfo *var, |
| 415 | struct fb_info *info) | 311 | struct fb_info *info) |
| 416 | { | 312 | { |
| 417 | unsigned int offset; | 313 | struct viafb_par *viapar = info->par; |
| 418 | 314 | u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset) | |
| 419 | DEBUG_MSG(KERN_INFO "viafb_pan_display!\n"); | 315 | * (var->bits_per_pixel / 8) + viapar->vram_addr; |
| 420 | 316 | ||
| 421 | offset = (var->xoffset + (var->yoffset * var->xres_virtual)) * | 317 | DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr); |
| 422 | var->bits_per_pixel / 16; | 318 | if (!viafb_dual_fb) { |
| 319 | viafb_set_primary_address(vram_addr); | ||
| 320 | viafb_set_secondary_address(vram_addr); | ||
| 321 | } else if (viapar->iga_path == IGA1) | ||
| 322 | viafb_set_primary_address(vram_addr); | ||
| 323 | else | ||
| 324 | viafb_set_secondary_address(vram_addr); | ||
| 423 | 325 | ||
| 424 | DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); | ||
| 425 | viafb_set_primary_address(offset); | ||
| 426 | return 0; | 326 | return 0; |
| 427 | } | 327 | } |
| 428 | 328 | ||
| @@ -476,6 +376,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
| 476 | u32 gpu32; | 376 | u32 gpu32; |
| 477 | 377 | ||
| 478 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); | 378 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); |
| 379 | printk(KERN_WARNING "viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n"); | ||
| 479 | memset(&u, 0, sizeof(u)); | 380 | memset(&u, 0, sizeof(u)); |
| 480 | 381 | ||
| 481 | switch (cmd) { | 382 | switch (cmd) { |
| @@ -1015,23 +916,6 @@ static int viafb_sync(struct fb_info *info) | |||
| 1015 | return 0; | 916 | return 0; |
| 1016 | } | 917 | } |
| 1017 | 918 | ||
| 1018 | int viafb_get_mode_index(int hres, int vres) | ||
| 1019 | { | ||
| 1020 | u32 i; | ||
| 1021 | DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); | ||
| 1022 | |||
| 1023 | for (i = 0; i < NUM_TOTAL_MODETABLE; i++) | ||
| 1024 | if (CLE266Modes[i].mode_array && | ||
| 1025 | CLE266Modes[i].crtc[0].crtc.hor_addr == hres && | ||
| 1026 | CLE266Modes[i].crtc[0].crtc.ver_addr == vres) | ||
| 1027 | break; | ||
| 1028 | |||
| 1029 | if (i == NUM_TOTAL_MODETABLE) | ||
| 1030 | return VIA_RES_INVALID; | ||
| 1031 | |||
| 1032 | return CLE266Modes[i].ModeIndex; | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | static void check_available_device_to_enable(int device_id) | 919 | static void check_available_device_to_enable(int device_id) |
| 1036 | { | 920 | { |
| 1037 | int device_num = 0; | 921 | int device_num = 0; |
| @@ -1330,7 +1214,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting | |||
| 1330 | setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; | 1214 | setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; |
| 1331 | } | 1215 | } |
| 1332 | 1216 | ||
| 1333 | static void parse_active_dev(void) | 1217 | static int parse_active_dev(void) |
| 1334 | { | 1218 | { |
| 1335 | viafb_CRT_ON = STATE_OFF; | 1219 | viafb_CRT_ON = STATE_OFF; |
| 1336 | viafb_DVI_ON = STATE_OFF; | 1220 | viafb_DVI_ON = STATE_OFF; |
| @@ -1341,60 +1225,63 @@ static void parse_active_dev(void) | |||
| 1341 | IGA path to devices in SAMM case. */ | 1225 | IGA path to devices in SAMM case. */ |
| 1342 | /* Note: The previous of active_dev is primary device, | 1226 | /* Note: The previous of active_dev is primary device, |
| 1343 | and the following is secondary device. */ | 1227 | and the following is secondary device. */ |
| 1344 | if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) { | 1228 | if (!viafb_active_dev) { |
| 1229 | viafb_CRT_ON = STATE_ON; | ||
| 1230 | viafb_SAMM_ON = STATE_OFF; | ||
| 1231 | } else if (!strcmp(viafb_active_dev, "CRT+DVI")) { | ||
| 1345 | /* CRT+DVI */ | 1232 | /* CRT+DVI */ |
| 1346 | viafb_CRT_ON = STATE_ON; | 1233 | viafb_CRT_ON = STATE_ON; |
| 1347 | viafb_DVI_ON = STATE_ON; | 1234 | viafb_DVI_ON = STATE_ON; |
| 1348 | viafb_primary_dev = CRT_Device; | 1235 | viafb_primary_dev = CRT_Device; |
| 1349 | } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) { | 1236 | } else if (!strcmp(viafb_active_dev, "DVI+CRT")) { |
| 1350 | /* DVI+CRT */ | 1237 | /* DVI+CRT */ |
| 1351 | viafb_CRT_ON = STATE_ON; | 1238 | viafb_CRT_ON = STATE_ON; |
| 1352 | viafb_DVI_ON = STATE_ON; | 1239 | viafb_DVI_ON = STATE_ON; |
| 1353 | viafb_primary_dev = DVI_Device; | 1240 | viafb_primary_dev = DVI_Device; |
| 1354 | } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) { | 1241 | } else if (!strcmp(viafb_active_dev, "CRT+LCD")) { |
| 1355 | /* CRT+LCD */ | 1242 | /* CRT+LCD */ |
| 1356 | viafb_CRT_ON = STATE_ON; | 1243 | viafb_CRT_ON = STATE_ON; |
| 1357 | viafb_LCD_ON = STATE_ON; | 1244 | viafb_LCD_ON = STATE_ON; |
| 1358 | viafb_primary_dev = CRT_Device; | 1245 | viafb_primary_dev = CRT_Device; |
| 1359 | } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) { | 1246 | } else if (!strcmp(viafb_active_dev, "LCD+CRT")) { |
| 1360 | /* LCD+CRT */ | 1247 | /* LCD+CRT */ |
| 1361 | viafb_CRT_ON = STATE_ON; | 1248 | viafb_CRT_ON = STATE_ON; |
| 1362 | viafb_LCD_ON = STATE_ON; | 1249 | viafb_LCD_ON = STATE_ON; |
| 1363 | viafb_primary_dev = LCD_Device; | 1250 | viafb_primary_dev = LCD_Device; |
| 1364 | } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) { | 1251 | } else if (!strcmp(viafb_active_dev, "DVI+LCD")) { |
| 1365 | /* DVI+LCD */ | 1252 | /* DVI+LCD */ |
| 1366 | viafb_DVI_ON = STATE_ON; | 1253 | viafb_DVI_ON = STATE_ON; |
| 1367 | viafb_LCD_ON = STATE_ON; | 1254 | viafb_LCD_ON = STATE_ON; |
| 1368 | viafb_primary_dev = DVI_Device; | 1255 | viafb_primary_dev = DVI_Device; |
| 1369 | } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) { | 1256 | } else if (!strcmp(viafb_active_dev, "LCD+DVI")) { |
| 1370 | /* LCD+DVI */ | 1257 | /* LCD+DVI */ |
| 1371 | viafb_DVI_ON = STATE_ON; | 1258 | viafb_DVI_ON = STATE_ON; |
| 1372 | viafb_LCD_ON = STATE_ON; | 1259 | viafb_LCD_ON = STATE_ON; |
| 1373 | viafb_primary_dev = LCD_Device; | 1260 | viafb_primary_dev = LCD_Device; |
| 1374 | } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) { | 1261 | } else if (!strcmp(viafb_active_dev, "LCD+LCD2")) { |
| 1375 | viafb_LCD_ON = STATE_ON; | 1262 | viafb_LCD_ON = STATE_ON; |
| 1376 | viafb_LCD2_ON = STATE_ON; | 1263 | viafb_LCD2_ON = STATE_ON; |
| 1377 | viafb_primary_dev = LCD_Device; | 1264 | viafb_primary_dev = LCD_Device; |
| 1378 | } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) { | 1265 | } else if (!strcmp(viafb_active_dev, "LCD2+LCD")) { |
| 1379 | viafb_LCD_ON = STATE_ON; | 1266 | viafb_LCD_ON = STATE_ON; |
| 1380 | viafb_LCD2_ON = STATE_ON; | 1267 | viafb_LCD2_ON = STATE_ON; |
| 1381 | viafb_primary_dev = LCD2_Device; | 1268 | viafb_primary_dev = LCD2_Device; |
| 1382 | } else if (!strncmp(viafb_active_dev, "CRT", 3)) { | 1269 | } else if (!strcmp(viafb_active_dev, "CRT")) { |
| 1383 | /* CRT only */ | 1270 | /* CRT only */ |
| 1384 | viafb_CRT_ON = STATE_ON; | 1271 | viafb_CRT_ON = STATE_ON; |
| 1385 | viafb_SAMM_ON = STATE_OFF; | 1272 | viafb_SAMM_ON = STATE_OFF; |
| 1386 | } else if (!strncmp(viafb_active_dev, "DVI", 3)) { | 1273 | } else if (!strcmp(viafb_active_dev, "DVI")) { |
| 1387 | /* DVI only */ | 1274 | /* DVI only */ |
| 1388 | viafb_DVI_ON = STATE_ON; | 1275 | viafb_DVI_ON = STATE_ON; |
| 1389 | viafb_SAMM_ON = STATE_OFF; | 1276 | viafb_SAMM_ON = STATE_OFF; |
| 1390 | } else if (!strncmp(viafb_active_dev, "LCD", 3)) { | 1277 | } else if (!strcmp(viafb_active_dev, "LCD")) { |
| 1391 | /* LCD only */ | 1278 | /* LCD only */ |
| 1392 | viafb_LCD_ON = STATE_ON; | 1279 | viafb_LCD_ON = STATE_ON; |
| 1393 | viafb_SAMM_ON = STATE_OFF; | 1280 | viafb_SAMM_ON = STATE_OFF; |
| 1394 | } else { | 1281 | } else |
| 1395 | viafb_CRT_ON = STATE_ON; | 1282 | return -EINVAL; |
| 1396 | viafb_SAMM_ON = STATE_OFF; | 1283 | |
| 1397 | } | 1284 | return 0; |
| 1398 | } | 1285 | } |
| 1399 | 1286 | ||
| 1400 | static int parse_port(char *opt_str, int *output_interface) | 1287 | static int parse_port(char *opt_str, int *output_interface) |
| @@ -1823,35 +1710,37 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | |||
| 1823 | remove_proc_entry("viafb", NULL); | 1710 | remove_proc_entry("viafb", NULL); |
| 1824 | } | 1711 | } |
| 1825 | 1712 | ||
| 1826 | static void parse_mode(const char *str, u32 *xres, u32 *yres) | 1713 | static int parse_mode(const char *str, u32 *xres, u32 *yres) |
| 1827 | { | 1714 | { |
| 1828 | char *ptr; | 1715 | char *ptr; |
| 1829 | 1716 | ||
| 1717 | if (!str) { | ||
| 1718 | *xres = 640; | ||
| 1719 | *yres = 480; | ||
| 1720 | return 0; | ||
| 1721 | } | ||
| 1722 | |||
| 1830 | *xres = simple_strtoul(str, &ptr, 10); | 1723 | *xres = simple_strtoul(str, &ptr, 10); |
| 1831 | if (ptr[0] != 'x') | 1724 | if (ptr[0] != 'x') |
| 1832 | goto out_default; | 1725 | return -EINVAL; |
| 1833 | 1726 | ||
| 1834 | *yres = simple_strtoul(&ptr[1], &ptr, 10); | 1727 | *yres = simple_strtoul(&ptr[1], &ptr, 10); |
| 1835 | if (ptr[0]) | 1728 | if (ptr[0]) |
| 1836 | goto out_default; | 1729 | return -EINVAL; |
| 1837 | |||
| 1838 | return; | ||
| 1839 | 1730 | ||
| 1840 | out_default: | 1731 | return 0; |
| 1841 | printk(KERN_WARNING "viafb received invalid mode string: %s\n", str); | ||
| 1842 | *xres = 640; | ||
| 1843 | *yres = 480; | ||
| 1844 | } | 1732 | } |
| 1845 | 1733 | ||
| 1846 | static int __devinit via_pci_probe(struct pci_dev *pdev, | 1734 | static int __devinit via_pci_probe(struct pci_dev *pdev, |
| 1847 | const struct pci_device_id *ent) | 1735 | const struct pci_device_id *ent) |
| 1848 | { | 1736 | { |
| 1849 | u32 default_xres, default_yres; | 1737 | u32 default_xres, default_yres; |
| 1850 | int vmode_index; | 1738 | struct VideoModeTable *vmode_entry; |
| 1739 | struct fb_var_screeninfo default_var; | ||
| 1851 | u32 viafb_par_length; | 1740 | u32 viafb_par_length; |
| 1852 | 1741 | ||
| 1853 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); | 1742 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); |
| 1854 | 1743 | memset(&default_var, 0, sizeof(default_var)); | |
| 1855 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); | 1744 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); |
| 1856 | 1745 | ||
| 1857 | /* Allocate fb_info and ***_par here, also including some other needed | 1746 | /* Allocate fb_info and ***_par here, also including some other needed |
| @@ -1877,7 +1766,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 1877 | 1766 | ||
| 1878 | if (viafb_dual_fb) | 1767 | if (viafb_dual_fb) |
| 1879 | viafb_SAMM_ON = 1; | 1768 | viafb_SAMM_ON = 1; |
| 1880 | parse_active_dev(); | ||
| 1881 | parse_lcd_port(); | 1769 | parse_lcd_port(); |
| 1882 | parse_dvi_port(); | 1770 | parse_dvi_port(); |
| 1883 | 1771 | ||
| @@ -1926,9 +1814,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 1926 | } | 1814 | } |
| 1927 | 1815 | ||
| 1928 | parse_mode(viafb_mode, &default_xres, &default_yres); | 1816 | parse_mode(viafb_mode, &default_xres, &default_yres); |
| 1929 | vmode_index = viafb_get_mode_index(default_xres, default_yres); | 1817 | vmode_entry = viafb_get_mode(default_xres, default_yres); |
| 1930 | DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); | ||
| 1931 | |||
| 1932 | if (viafb_SAMM_ON == 1) { | 1818 | if (viafb_SAMM_ON == 1) { |
| 1933 | parse_mode(viafb_mode1, &viafb_second_xres, | 1819 | parse_mode(viafb_mode1, &viafb_second_xres, |
| 1934 | &viafb_second_yres); | 1820 | &viafb_second_yres); |
| @@ -1947,19 +1833,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 1947 | viafb_second_virtual_yres = viafb_second_yres; | 1833 | viafb_second_virtual_yres = viafb_second_yres; |
| 1948 | } | 1834 | } |
| 1949 | 1835 | ||
| 1950 | switch (viafb_bpp) { | ||
| 1951 | case 0 ... 8: | ||
| 1952 | viafb_bpp = 8; | ||
| 1953 | break; | ||
| 1954 | case 9 ... 16: | ||
| 1955 | viafb_bpp = 16; | ||
| 1956 | break; | ||
| 1957 | case 17 ... 32: | ||
| 1958 | viafb_bpp = 32; | ||
| 1959 | break; | ||
| 1960 | default: | ||
| 1961 | viafb_bpp = 8; | ||
| 1962 | } | ||
| 1963 | default_var.xres = default_xres; | 1836 | default_var.xres = default_xres; |
| 1964 | default_var.yres = default_yres; | 1837 | default_var.yres = default_yres; |
| 1965 | switch (default_xres) { | 1838 | switch (default_xres) { |
| @@ -1972,8 +1845,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 1972 | } | 1845 | } |
| 1973 | default_var.yres_virtual = default_yres; | 1846 | default_var.yres_virtual = default_yres; |
| 1974 | default_var.bits_per_pixel = viafb_bpp; | 1847 | default_var.bits_per_pixel = viafb_bpp; |
| 1975 | if (default_var.bits_per_pixel == 15) | ||
| 1976 | default_var.bits_per_pixel = 16; | ||
| 1977 | default_var.pixclock = | 1848 | default_var.pixclock = |
| 1978 | viafb_get_pixclock(default_xres, default_yres, viafb_refresh); | 1849 | viafb_get_pixclock(default_xres, default_yres, viafb_refresh); |
| 1979 | default_var.left_margin = (default_xres >> 3) & 0xf8; | 1850 | default_var.left_margin = (default_xres >> 3) & 0xf8; |
| @@ -1982,6 +1853,8 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 1982 | default_var.lower_margin = 4; | 1853 | default_var.lower_margin = 4; |
| 1983 | default_var.hsync_len = default_var.left_margin; | 1854 | default_var.hsync_len = default_var.left_margin; |
| 1984 | default_var.vsync_len = 4; | 1855 | default_var.vsync_len = 4; |
| 1856 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | ||
| 1857 | viafbinfo->var = default_var; | ||
| 1985 | 1858 | ||
| 1986 | if (viafb_dual_fb) { | 1859 | if (viafb_dual_fb) { |
| 1987 | viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); | 1860 | viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); |
| @@ -2016,8 +1889,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 2016 | default_var.yres = viafb_second_yres; | 1889 | default_var.yres = viafb_second_yres; |
| 2017 | default_var.xres_virtual = viafb_second_virtual_xres; | 1890 | default_var.xres_virtual = viafb_second_virtual_xres; |
| 2018 | default_var.yres_virtual = viafb_second_virtual_yres; | 1891 | default_var.yres_virtual = viafb_second_virtual_yres; |
| 2019 | if (viafb_bpp1 != viafb_bpp) | ||
| 2020 | viafb_bpp1 = viafb_bpp; | ||
| 2021 | default_var.bits_per_pixel = viafb_bpp1; | 1892 | default_var.bits_per_pixel = viafb_bpp1; |
| 2022 | default_var.pixclock = | 1893 | default_var.pixclock = |
| 2023 | viafb_get_pixclock(viafb_second_xres, viafb_second_yres, | 1894 | viafb_get_pixclock(viafb_second_xres, viafb_second_yres, |
| @@ -2037,9 +1908,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 2037 | &viafbinfo1->fix); | 1908 | &viafbinfo1->fix); |
| 2038 | } | 1909 | } |
| 2039 | 1910 | ||
| 2040 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | 1911 | viafb_check_var(&viafbinfo->var, viafbinfo); |
| 2041 | viafb_check_var(&default_var, viafbinfo); | ||
| 2042 | viafbinfo->var = default_var; | ||
| 2043 | viafb_update_fix(viafbinfo); | 1912 | viafb_update_fix(viafbinfo); |
| 2044 | viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, | 1913 | viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, |
| 2045 | &viafbinfo->fix); | 1914 | &viafbinfo->fix); |
| @@ -2197,12 +2066,20 @@ static struct pci_driver viafb_driver = { | |||
| 2197 | 2066 | ||
| 2198 | static int __init viafb_init(void) | 2067 | static int __init viafb_init(void) |
| 2199 | { | 2068 | { |
| 2069 | u32 dummy; | ||
| 2200 | #ifndef MODULE | 2070 | #ifndef MODULE |
| 2201 | char *option = NULL; | 2071 | char *option = NULL; |
| 2202 | if (fb_get_options("viafb", &option)) | 2072 | if (fb_get_options("viafb", &option)) |
| 2203 | return -ENODEV; | 2073 | return -ENODEV; |
| 2204 | viafb_setup(option); | 2074 | viafb_setup(option); |
| 2205 | #endif | 2075 | #endif |
| 2076 | if (parse_mode(viafb_mode, &dummy, &dummy) | ||
| 2077 | || parse_mode(viafb_mode1, &dummy, &dummy) | ||
| 2078 | || viafb_bpp < 0 || viafb_bpp > 32 | ||
| 2079 | || viafb_bpp1 < 0 || viafb_bpp1 > 32 | ||
| 2080 | || parse_active_dev()) | ||
| 2081 | return -EINVAL; | ||
| 2082 | |||
| 2206 | printk(KERN_INFO | 2083 | printk(KERN_INFO |
| 2207 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", | 2084 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", |
| 2208 | VERSION_MAJOR, VERSION_MINOR); | 2085 | VERSION_MAJOR, VERSION_MINOR); |
| @@ -2230,15 +2107,12 @@ static struct fb_ops viafb_ops = { | |||
| 2230 | .fb_cursor = viafb_cursor, | 2107 | .fb_cursor = viafb_cursor, |
| 2231 | .fb_ioctl = viafb_ioctl, | 2108 | .fb_ioctl = viafb_ioctl, |
| 2232 | .fb_sync = viafb_sync, | 2109 | .fb_sync = viafb_sync, |
| 2233 | .fb_setcmap = viafb_setcmap, | ||
| 2234 | }; | 2110 | }; |
| 2235 | 2111 | ||
| 2236 | module_init(viafb_init); | 2112 | module_init(viafb_init); |
| 2237 | module_exit(viafb_exit); | 2113 | module_exit(viafb_exit); |
| 2238 | 2114 | ||
| 2239 | #ifdef MODULE | 2115 | #ifdef MODULE |
| 2240 | module_param(viafb_memsize, int, S_IRUSR); | ||
| 2241 | |||
| 2242 | module_param(viafb_mode, charp, S_IRUSR); | 2116 | module_param(viafb_mode, charp, S_IRUSR); |
| 2243 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); | 2117 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); |
| 2244 | 2118 | ||
