1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
4 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
8 #include <linux/compiler.h>
9 #include <linux/module.h>
10 #include <linux/seq_file.h>
11 #include <linux/slab.h>
12 #include <linux/stat.h>
13 #include <linux/via-core.h>
14 #include <linux/via_i2c.h>
19 static char *viafb_name
= "Via";
20 static u32 pseudo_pal
[17];
23 static char *viafb_mode
;
24 static char *viafb_mode1
;
25 static int viafb_bpp
= 32;
26 static int viafb_bpp1
= 32;
28 static unsigned int viafb_second_offset
;
29 static int viafb_second_size
;
31 static int viafb_accel
= 1;
33 /* Added for specifying active devices.*/
34 static char *viafb_active_dev
;
36 /*Added for specify lcd output port*/
37 static char *viafb_lcd_port
= "";
38 static char *viafb_dvi_port
= "";
40 static void retrieve_device_setting(struct viafb_ioctl_setting
42 static int viafb_pan_display(struct fb_var_screeninfo
*var
,
43 struct fb_info
*info
);
45 static struct fb_ops viafb_ops
;
47 /* supported output devices on each IGP
48 * only CX700, VX800, VX855, VX900 were documented
49 * VIA_CRT should be everywhere
50 * VIA_6C can be onle pre-CX700 (probably only on CLE266) as 6C is used for PLL
51 * source selection on CX700 and later
52 * K400 seems to support VIA_96, VIA_DVP1, VIA_LVDS{1,2} as in viamode.c
54 static const u32 supported_odev_map
[] = {
55 [UNICHROME_CLE266
] = VIA_CRT
| VIA_LDVP0
| VIA_LDVP1
,
56 [UNICHROME_K400
] = VIA_CRT
| VIA_DVP0
| VIA_DVP1
| VIA_LVDS1
58 [UNICHROME_K800
] = VIA_CRT
| VIA_DVP0
| VIA_DVP1
| VIA_LVDS1
60 [UNICHROME_PM800
] = VIA_CRT
| VIA_DVP0
| VIA_DVP1
| VIA_LVDS1
62 [UNICHROME_CN700
] = VIA_CRT
| VIA_DVP0
| VIA_DVP1
| VIA_LVDS1
64 [UNICHROME_CX700
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
65 [UNICHROME_CN750
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
66 [UNICHROME_K8M890
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
67 [UNICHROME_P4M890
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
68 [UNICHROME_P4M900
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
69 [UNICHROME_VX800
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
70 [UNICHROME_VX855
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
71 [UNICHROME_VX900
] = VIA_CRT
| VIA_DVP1
| VIA_LVDS1
| VIA_LVDS2
,
74 static void viafb_fill_var_color_info(struct fb_var_screeninfo
*var
, u8 depth
)
77 var
->red
.msb_right
= 0;
78 var
->green
.msb_right
= 0;
79 var
->blue
.msb_right
= 0;
80 var
->transp
.offset
= 0;
81 var
->transp
.length
= 0;
82 var
->transp
.msb_right
= 0;
86 var
->bits_per_pixel
= 8;
88 var
->green
.offset
= 0;
91 var
->green
.length
= 8;
95 var
->bits_per_pixel
= 16;
97 var
->green
.offset
= 5;
100 var
->green
.length
= 5;
101 var
->blue
.length
= 5;
104 var
->bits_per_pixel
= 16;
105 var
->red
.offset
= 11;
106 var
->green
.offset
= 5;
107 var
->blue
.offset
= 0;
109 var
->green
.length
= 6;
110 var
->blue
.length
= 5;
113 var
->bits_per_pixel
= 32;
114 var
->red
.offset
= 16;
115 var
->green
.offset
= 8;
116 var
->blue
.offset
= 0;
118 var
->green
.length
= 8;
119 var
->blue
.length
= 8;
122 var
->bits_per_pixel
= 32;
123 var
->red
.offset
= 20;
124 var
->green
.offset
= 10;
125 var
->blue
.offset
= 0;
126 var
->red
.length
= 10;
127 var
->green
.length
= 10;
128 var
->blue
.length
= 10;
133 static void viafb_update_fix(struct fb_info
*info
)
135 u32 bpp
= info
->var
.bits_per_pixel
;
138 bpp
== 8 ? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR
;
139 info
->fix
.line_length
= ALIGN(info
->var
.xres_virtual
* bpp
/ 8,
143 static void viafb_setup_fixinfo(struct fb_fix_screeninfo
*fix
,
144 struct viafb_par
*viaparinfo
)
146 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
147 strcpy(fix
->id
, viafb_name
);
149 fix
->smem_start
= viaparinfo
->fbmem
;
150 fix
->smem_len
= viaparinfo
->fbmem_free
;
152 fix
->type
= FB_TYPE_PACKED_PIXELS
;
154 fix
->visual
= FB_VISUAL_TRUECOLOR
;
156 fix
->xpanstep
= fix
->ywrapstep
= 0;
159 /* Just tell the accel name */
160 viafbinfo
->fix
.accel
= FB_ACCEL_VIA_UNICHROME
;
162 static int viafb_open(struct fb_info
*info
, int user
)
164 DEBUG_MSG(KERN_INFO
"viafb_open!\n");
168 static int viafb_release(struct fb_info
*info
, int user
)
170 DEBUG_MSG(KERN_INFO
"viafb_release!\n");
174 static inline int get_var_refresh(struct fb_var_screeninfo
*var
)
178 htotal
= var
->left_margin
+ var
->xres
+ var
->right_margin
180 vtotal
= var
->upper_margin
+ var
->yres
+ var
->lower_margin
182 return PICOS2KHZ(var
->pixclock
) * 1000 / (htotal
* vtotal
);
185 static int viafb_check_var(struct fb_var_screeninfo
*var
,
186 struct fb_info
*info
)
189 struct viafb_par
*ppar
= info
->par
;
192 DEBUG_MSG(KERN_INFO
"viafb_check_var!\n");
194 /* HW neither support interlacte nor double-scaned mode */
195 if (var
->vmode
& FB_VMODE_INTERLACED
|| var
->vmode
& FB_VMODE_DOUBLE
)
198 /* the refresh rate is not important here, as we only want to know
199 * whether the resolution exists
201 if (!viafb_get_best_mode(var
->xres
, var
->yres
, 60)) {
203 "viafb: Mode %dx%dx%d not supported!!\n",
204 var
->xres
, var
->yres
, var
->bits_per_pixel
);
208 depth
= fb_get_color_depth(var
, &info
->fix
);
210 depth
= var
->bits_per_pixel
;
212 if (depth
< 0 || depth
> 32)
216 else if (depth
== 15 && viafb_dual_fb
&& ppar
->iga_path
== IGA1
)
218 else if (depth
== 30)
222 else if (depth
<= 16)
227 viafb_fill_var_color_info(var
, depth
);
228 if (var
->xres_virtual
< var
->xres
)
229 var
->xres_virtual
= var
->xres
;
231 line
= ALIGN(var
->xres_virtual
* var
->bits_per_pixel
/ 8,
233 if (line
> VIA_PITCH_MAX
|| line
* var
->yres_virtual
> ppar
->memsize
)
236 /* Based on var passed in to calculate the refresh,
237 * because our driver use some modes special.
239 refresh
= viafb_get_refresh(var
->xres
, var
->yres
,
240 get_var_refresh(var
));
242 /* Adjust var according to our driver's own table */
243 viafb_fill_var_timing_info(var
,
244 viafb_get_best_mode(var
->xres
, var
->yres
, refresh
));
245 if (var
->accel_flags
& FB_ACCELF_TEXT
&&
246 !ppar
->shared
->vdev
->engine_mmio
)
247 var
->accel_flags
= 0;
252 static int viafb_set_par(struct fb_info
*info
)
254 struct viafb_par
*viapar
= info
->par
;
256 DEBUG_MSG(KERN_INFO
"viafb_set_par!\n");
258 viafb_update_fix(info
);
259 viapar
->depth
= fb_get_color_depth(&info
->var
, &info
->fix
);
260 viafb_update_device_setting(viafbinfo
->var
.xres
, viafbinfo
->var
.yres
,
261 viafbinfo
->var
.bits_per_pixel
, 0);
264 viafb_update_device_setting(viafbinfo1
->var
.xres
,
265 viafbinfo1
->var
.yres
, viafbinfo1
->var
.bits_per_pixel
,
267 } else if (viafb_SAMM_ON
== 1) {
269 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
270 viafb_second_xres
, viafb_second_yres
, viafb_bpp1
);
272 viafb_update_device_setting(viafb_second_xres
,
273 viafb_second_yres
, viafb_bpp1
, 1);
276 refresh
= get_var_refresh(&info
->var
);
277 if (viafb_dual_fb
&& viapar
->iga_path
== IGA2
) {
278 viafb_bpp1
= info
->var
.bits_per_pixel
;
279 viafb_refresh1
= refresh
;
281 viafb_bpp
= info
->var
.bits_per_pixel
;
282 viafb_refresh
= refresh
;
285 if (info
->var
.accel_flags
& FB_ACCELF_TEXT
)
286 info
->flags
&= ~FBINFO_HWACCEL_DISABLED
;
288 info
->flags
|= FBINFO_HWACCEL_DISABLED
;
290 viafb_pan_display(&info
->var
, info
);
295 /* Set one color register */
296 static int viafb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
297 unsigned blue
, unsigned transp
, struct fb_info
*info
)
299 struct viafb_par
*viapar
= info
->par
;
302 if (info
->fix
.visual
== FB_VISUAL_PSEUDOCOLOR
) {
306 if (!viafb_dual_fb
|| viapar
->iga_path
== IGA1
)
307 viafb_set_primary_color_register(regno
, red
>> 8,
308 green
>> 8, blue
>> 8);
310 if (!viafb_dual_fb
|| viapar
->iga_path
== IGA2
)
311 viafb_set_secondary_color_register(regno
, red
>> 8,
312 green
>> 8, blue
>> 8);
317 r
= (red
>> (16 - info
->var
.red
.length
))
318 << info
->var
.red
.offset
;
319 b
= (blue
>> (16 - info
->var
.blue
.length
))
320 << info
->var
.blue
.offset
;
321 g
= (green
>> (16 - info
->var
.green
.length
))
322 << info
->var
.green
.offset
;
323 ((u32
*) info
->pseudo_palette
)[regno
] = r
| g
| b
;
329 static int viafb_pan_display(struct fb_var_screeninfo
*var
,
330 struct fb_info
*info
)
332 struct viafb_par
*viapar
= info
->par
;
333 u32 vram_addr
= viapar
->vram_addr
334 + var
->yoffset
* info
->fix
.line_length
335 + var
->xoffset
* info
->var
.bits_per_pixel
/ 8;
337 DEBUG_MSG(KERN_DEBUG
"viafb_pan_display, address = %d\n", vram_addr
);
338 if (!viafb_dual_fb
) {
339 via_set_primary_address(vram_addr
);
340 via_set_secondary_address(vram_addr
);
341 } else if (viapar
->iga_path
== IGA1
)
342 via_set_primary_address(vram_addr
);
344 via_set_secondary_address(vram_addr
);
349 static int viafb_blank(int blank_mode
, struct fb_info
*info
)
351 DEBUG_MSG(KERN_INFO
"viafb_blank!\n");
352 /* clear DPMS setting */
354 switch (blank_mode
) {
355 case FB_BLANK_UNBLANK
:
356 /* Screen: On, HSync: On, VSync: On */
357 /* control CRT monitor power management */
358 via_set_state(VIA_CRT
, VIA_STATE_ON
);
360 case FB_BLANK_HSYNC_SUSPEND
:
361 /* Screen: Off, HSync: Off, VSync: On */
362 /* control CRT monitor power management */
363 via_set_state(VIA_CRT
, VIA_STATE_STANDBY
);
365 case FB_BLANK_VSYNC_SUSPEND
:
366 /* Screen: Off, HSync: On, VSync: Off */
367 /* control CRT monitor power management */
368 via_set_state(VIA_CRT
, VIA_STATE_SUSPEND
);
370 case FB_BLANK_POWERDOWN
:
371 /* Screen: Off, HSync: Off, VSync: Off */
372 /* control CRT monitor power management */
373 via_set_state(VIA_CRT
, VIA_STATE_OFF
);
380 static int viafb_ioctl(struct fb_info
*info
, u_int cmd
, u_long arg
)
383 struct viafb_ioctl_mode viamode
;
384 struct viafb_ioctl_samm viasamm
;
385 struct viafb_driver_version driver_version
;
386 struct fb_var_screeninfo sec_var
;
387 struct _panel_size_pos_info panel_pos_size_para
;
388 struct viafb_ioctl_setting viafb_setting
;
389 struct device_t active_dev
;
392 u32
*viafb_gamma_table
;
393 char driver_name
[] = "viafb";
395 u32 __user
*argp
= (u32 __user
*) arg
;
398 DEBUG_MSG(KERN_INFO
"viafb_ioctl: 0x%X !!\n", cmd
);
399 printk(KERN_WARNING
"viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n");
400 memset(&u
, 0, sizeof(u
));
403 case VIAFB_GET_CHIP_INFO
:
404 if (copy_to_user(argp
, viaparinfo
->chip_info
,
405 sizeof(struct chip_information
)))
408 case VIAFB_GET_INFO_SIZE
:
409 return put_user((u32
)sizeof(struct viafb_ioctl_info
), argp
);
411 return viafb_ioctl_get_viafb_info(arg
);
413 return put_user(viafb_ioctl_hotplug(info
->var
.xres
,
415 info
->var
.bits_per_pixel
), argp
);
416 case VIAFB_SET_HOTPLUG_FLAG
:
417 if (copy_from_user(&gpu32
, argp
, sizeof(gpu32
)))
419 viafb_hotplug
= (gpu32
) ? 1 : 0;
421 case VIAFB_GET_RESOLUTION
:
422 u
.viamode
.xres
= (u32
) viafb_hotplug_Xres
;
423 u
.viamode
.yres
= (u32
) viafb_hotplug_Yres
;
424 u
.viamode
.refresh
= (u32
) viafb_hotplug_refresh
;
425 u
.viamode
.bpp
= (u32
) viafb_hotplug_bpp
;
426 if (viafb_SAMM_ON
== 1) {
427 u
.viamode
.xres_sec
= viafb_second_xres
;
428 u
.viamode
.yres_sec
= viafb_second_yres
;
429 u
.viamode
.virtual_xres_sec
= viafb_dual_fb
? viafbinfo1
->var
.xres_virtual
: viafbinfo
->var
.xres_virtual
;
430 u
.viamode
.virtual_yres_sec
= viafb_dual_fb
? viafbinfo1
->var
.yres_virtual
: viafbinfo
->var
.yres_virtual
;
431 u
.viamode
.refresh_sec
= viafb_refresh1
;
432 u
.viamode
.bpp_sec
= viafb_bpp1
;
434 u
.viamode
.xres_sec
= 0;
435 u
.viamode
.yres_sec
= 0;
436 u
.viamode
.virtual_xres_sec
= 0;
437 u
.viamode
.virtual_yres_sec
= 0;
438 u
.viamode
.refresh_sec
= 0;
439 u
.viamode
.bpp_sec
= 0;
441 if (copy_to_user(argp
, &u
.viamode
, sizeof(u
.viamode
)))
444 case VIAFB_GET_SAMM_INFO
:
445 u
.viasamm
.samm_status
= viafb_SAMM_ON
;
447 if (viafb_SAMM_ON
== 1) {
449 u
.viasamm
.size_prim
= viaparinfo
->fbmem_free
;
450 u
.viasamm
.size_sec
= viaparinfo1
->fbmem_free
;
452 if (viafb_second_size
) {
453 u
.viasamm
.size_prim
=
454 viaparinfo
->fbmem_free
-
455 viafb_second_size
* 1024 * 1024;
457 viafb_second_size
* 1024 * 1024;
459 u
.viasamm
.size_prim
=
460 viaparinfo
->fbmem_free
>> 1;
462 (viaparinfo
->fbmem_free
>> 1);
465 u
.viasamm
.mem_base
= viaparinfo
->fbmem
;
466 u
.viasamm
.offset_sec
= viafb_second_offset
;
468 u
.viasamm
.size_prim
=
469 viaparinfo
->memsize
- viaparinfo
->fbmem_used
;
470 u
.viasamm
.size_sec
= 0;
471 u
.viasamm
.mem_base
= viaparinfo
->fbmem
;
472 u
.viasamm
.offset_sec
= 0;
475 if (copy_to_user(argp
, &u
.viasamm
, sizeof(u
.viasamm
)))
479 case VIAFB_TURN_ON_OUTPUT_DEVICE
:
480 if (copy_from_user(&gpu32
, argp
, sizeof(gpu32
)))
482 if (gpu32
& CRT_Device
)
483 via_set_state(VIA_CRT
, VIA_STATE_ON
);
484 if (gpu32
& DVI_Device
)
486 if (gpu32
& LCD_Device
)
489 case VIAFB_TURN_OFF_OUTPUT_DEVICE
:
490 if (copy_from_user(&gpu32
, argp
, sizeof(gpu32
)))
492 if (gpu32
& CRT_Device
)
493 via_set_state(VIA_CRT
, VIA_STATE_OFF
);
494 if (gpu32
& DVI_Device
)
496 if (gpu32
& LCD_Device
)
499 case VIAFB_GET_DEVICE
:
500 u
.active_dev
.crt
= viafb_CRT_ON
;
501 u
.active_dev
.dvi
= viafb_DVI_ON
;
502 u
.active_dev
.lcd
= viafb_LCD_ON
;
503 u
.active_dev
.samm
= viafb_SAMM_ON
;
504 u
.active_dev
.primary_dev
= viafb_primary_dev
;
506 u
.active_dev
.lcd_dsp_cent
= viafb_lcd_dsp_method
;
507 u
.active_dev
.lcd_panel_id
= viafb_lcd_panel_id
;
508 u
.active_dev
.lcd_mode
= viafb_lcd_mode
;
510 u
.active_dev
.xres
= viafb_hotplug_Xres
;
511 u
.active_dev
.yres
= viafb_hotplug_Yres
;
513 u
.active_dev
.xres1
= viafb_second_xres
;
514 u
.active_dev
.yres1
= viafb_second_yres
;
516 u
.active_dev
.bpp
= viafb_bpp
;
517 u
.active_dev
.bpp1
= viafb_bpp1
;
518 u
.active_dev
.refresh
= viafb_refresh
;
519 u
.active_dev
.refresh1
= viafb_refresh1
;
521 u
.active_dev
.epia_dvi
= viafb_platform_epia_dvi
;
522 u
.active_dev
.lcd_dual_edge
= viafb_device_lcd_dualedge
;
523 u
.active_dev
.bus_width
= viafb_bus_width
;
525 if (copy_to_user(argp
, &u
.active_dev
, sizeof(u
.active_dev
)))
529 case VIAFB_GET_DRIVER_VERSION
:
530 u
.driver_version
.iMajorNum
= VERSION_MAJOR
;
531 u
.driver_version
.iKernelNum
= VERSION_KERNEL
;
532 u
.driver_version
.iOSNum
= VERSION_OS
;
533 u
.driver_version
.iMinorNum
= VERSION_MINOR
;
535 if (copy_to_user(argp
, &u
.driver_version
,
536 sizeof(u
.driver_version
)))
541 case VIAFB_GET_DEVICE_INFO
:
543 retrieve_device_setting(&u
.viafb_setting
);
545 if (copy_to_user(argp
, &u
.viafb_setting
,
546 sizeof(u
.viafb_setting
)))
551 case VIAFB_GET_DEVICE_SUPPORT
:
552 viafb_get_device_support_state(&state_info
);
553 if (put_user(state_info
, argp
))
557 case VIAFB_GET_DEVICE_CONNECT
:
558 viafb_get_device_connect_state(&state_info
);
559 if (put_user(state_info
, argp
))
563 case VIAFB_GET_PANEL_SUPPORT_EXPAND
:
565 viafb_lcd_get_support_expand_state(info
->var
.xres
,
567 if (put_user(state_info
, argp
))
571 case VIAFB_GET_DRIVER_NAME
:
572 if (copy_to_user(argp
, driver_name
, sizeof(driver_name
)))
576 case VIAFB_SET_GAMMA_LUT
:
577 viafb_gamma_table
= memdup_user(argp
, 256 * sizeof(u32
));
578 if (IS_ERR(viafb_gamma_table
))
579 return PTR_ERR(viafb_gamma_table
);
580 viafb_set_gamma_table(viafb_bpp
, viafb_gamma_table
);
581 kfree(viafb_gamma_table
);
584 case VIAFB_GET_GAMMA_LUT
:
585 viafb_gamma_table
= kmalloc_array(256, sizeof(u32
),
587 if (!viafb_gamma_table
)
589 viafb_get_gamma_table(viafb_gamma_table
);
590 if (copy_to_user(argp
, viafb_gamma_table
,
591 256 * sizeof(u32
))) {
592 kfree(viafb_gamma_table
);
595 kfree(viafb_gamma_table
);
598 case VIAFB_GET_GAMMA_SUPPORT_STATE
:
599 viafb_get_gamma_support_state(viafb_bpp
, &state_info
);
600 if (put_user(state_info
, argp
))
603 case VIAFB_SYNC_SURFACE
:
604 DEBUG_MSG(KERN_INFO
"lobo VIAFB_SYNC_SURFACE\n");
606 case VIAFB_GET_DRIVER_CAPS
:
609 case VIAFB_GET_PANEL_MAX_SIZE
:
610 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
611 sizeof(u
.panel_pos_size_para
)))
613 u
.panel_pos_size_para
.x
= u
.panel_pos_size_para
.y
= 0;
614 if (copy_to_user(argp
, &u
.panel_pos_size_para
,
615 sizeof(u
.panel_pos_size_para
)))
618 case VIAFB_GET_PANEL_MAX_POSITION
:
619 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
620 sizeof(u
.panel_pos_size_para
)))
622 u
.panel_pos_size_para
.x
= u
.panel_pos_size_para
.y
= 0;
623 if (copy_to_user(argp
, &u
.panel_pos_size_para
,
624 sizeof(u
.panel_pos_size_para
)))
628 case VIAFB_GET_PANEL_POSITION
:
629 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
630 sizeof(u
.panel_pos_size_para
)))
632 u
.panel_pos_size_para
.x
= u
.panel_pos_size_para
.y
= 0;
633 if (copy_to_user(argp
, &u
.panel_pos_size_para
,
634 sizeof(u
.panel_pos_size_para
)))
637 case VIAFB_GET_PANEL_SIZE
:
638 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
639 sizeof(u
.panel_pos_size_para
)))
641 u
.panel_pos_size_para
.x
= u
.panel_pos_size_para
.y
= 0;
642 if (copy_to_user(argp
, &u
.panel_pos_size_para
,
643 sizeof(u
.panel_pos_size_para
)))
647 case VIAFB_SET_PANEL_POSITION
:
648 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
649 sizeof(u
.panel_pos_size_para
)))
652 case VIAFB_SET_PANEL_SIZE
:
653 if (copy_from_user(&u
.panel_pos_size_para
, argp
,
654 sizeof(u
.panel_pos_size_para
)))
665 static void viafb_fillrect(struct fb_info
*info
,
666 const struct fb_fillrect
*rect
)
668 struct viafb_par
*viapar
= info
->par
;
669 struct viafb_shared
*shared
= viapar
->shared
;
673 if (info
->flags
& FBINFO_HWACCEL_DISABLED
|| !shared
->hw_bitblt
) {
674 cfb_fillrect(info
, rect
);
678 if (!rect
->width
|| !rect
->height
)
681 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
)
682 fg_color
= ((u32
*)info
->pseudo_palette
)[rect
->color
];
684 fg_color
= rect
->color
;
686 if (rect
->rop
== ROP_XOR
)
691 DEBUG_MSG(KERN_DEBUG
"viafb 2D engine: fillrect\n");
692 if (shared
->hw_bitblt(shared
->vdev
->engine_mmio
, VIA_BITBLT_FILL
,
693 rect
->width
, rect
->height
, info
->var
.bits_per_pixel
,
694 viapar
->vram_addr
, info
->fix
.line_length
, rect
->dx
, rect
->dy
,
695 NULL
, 0, 0, 0, 0, fg_color
, 0, rop
))
696 cfb_fillrect(info
, rect
);
699 static void viafb_copyarea(struct fb_info
*info
,
700 const struct fb_copyarea
*area
)
702 struct viafb_par
*viapar
= info
->par
;
703 struct viafb_shared
*shared
= viapar
->shared
;
705 if (info
->flags
& FBINFO_HWACCEL_DISABLED
|| !shared
->hw_bitblt
) {
706 cfb_copyarea(info
, area
);
710 if (!area
->width
|| !area
->height
)
713 DEBUG_MSG(KERN_DEBUG
"viafb 2D engine: copyarea\n");
714 if (shared
->hw_bitblt(shared
->vdev
->engine_mmio
, VIA_BITBLT_COLOR
,
715 area
->width
, area
->height
, info
->var
.bits_per_pixel
,
716 viapar
->vram_addr
, info
->fix
.line_length
, area
->dx
, area
->dy
,
717 NULL
, viapar
->vram_addr
, info
->fix
.line_length
,
718 area
->sx
, area
->sy
, 0, 0, 0))
719 cfb_copyarea(info
, area
);
722 static void viafb_imageblit(struct fb_info
*info
,
723 const struct fb_image
*image
)
725 struct viafb_par
*viapar
= info
->par
;
726 struct viafb_shared
*shared
= viapar
->shared
;
727 u32 fg_color
= 0, bg_color
= 0;
730 if (info
->flags
& FBINFO_HWACCEL_DISABLED
|| !shared
->hw_bitblt
||
731 (image
->depth
!= 1 && image
->depth
!= viapar
->depth
)) {
732 cfb_imageblit(info
, image
);
736 if (image
->depth
== 1) {
737 op
= VIA_BITBLT_MONO
;
738 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
) {
740 ((u32
*)info
->pseudo_palette
)[image
->fg_color
];
742 ((u32
*)info
->pseudo_palette
)[image
->bg_color
];
744 fg_color
= image
->fg_color
;
745 bg_color
= image
->bg_color
;
748 op
= VIA_BITBLT_COLOR
;
750 DEBUG_MSG(KERN_DEBUG
"viafb 2D engine: imageblit\n");
751 if (shared
->hw_bitblt(shared
->vdev
->engine_mmio
, op
,
752 image
->width
, image
->height
, info
->var
.bits_per_pixel
,
753 viapar
->vram_addr
, info
->fix
.line_length
, image
->dx
, image
->dy
,
754 (u32
*)image
->data
, 0, 0, 0, 0, fg_color
, bg_color
, 0))
755 cfb_imageblit(info
, image
);
758 static int viafb_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
)
760 struct viafb_par
*viapar
= info
->par
;
761 void __iomem
*engine
= viapar
->shared
->vdev
->engine_mmio
;
762 u32 temp
, xx
, yy
, bg_color
= 0, fg_color
= 0,
763 chip_name
= viapar
->shared
->chip_info
.gfx_chip_name
;
764 int i
, j
= 0, cur_size
= 64;
766 if (info
->flags
& FBINFO_HWACCEL_DISABLED
|| info
!= viafbinfo
)
769 /* LCD ouput does not support hw cursors (at least on VN896) */
770 if ((chip_name
== UNICHROME_CLE266
&& viapar
->iga_path
== IGA2
) ||
774 viafb_show_hw_cursor(info
, HW_Cursor_OFF
);
776 if (cursor
->set
& FB_CUR_SETHOT
) {
777 temp
= (cursor
->hot
.x
<< 16) + cursor
->hot
.y
;
778 writel(temp
, engine
+ VIA_REG_CURSOR_ORG
);
781 if (cursor
->set
& FB_CUR_SETPOS
) {
782 yy
= cursor
->image
.dy
- info
->var
.yoffset
;
783 xx
= cursor
->image
.dx
- info
->var
.xoffset
;
786 writel(temp
, engine
+ VIA_REG_CURSOR_POS
);
789 if (cursor
->image
.width
<= 32 && cursor
->image
.height
<= 32)
791 else if (cursor
->image
.width
<= 64 && cursor
->image
.height
<= 64)
794 printk(KERN_WARNING
"viafb_cursor: The cursor is too large "
795 "%dx%d", cursor
->image
.width
, cursor
->image
.height
);
799 if (cursor
->set
& FB_CUR_SETSIZE
) {
800 temp
= readl(engine
+ VIA_REG_CURSOR_MODE
);
806 writel(temp
, engine
+ VIA_REG_CURSOR_MODE
);
809 if (cursor
->set
& FB_CUR_SETCMAP
) {
810 fg_color
= cursor
->image
.fg_color
;
811 bg_color
= cursor
->image
.bg_color
;
812 if (chip_name
== UNICHROME_CX700
||
813 chip_name
== UNICHROME_VX800
||
814 chip_name
== UNICHROME_VX855
||
815 chip_name
== UNICHROME_VX900
) {
817 ((info
->cmap
.red
[fg_color
] & 0xFFC0) << 14) |
818 ((info
->cmap
.green
[fg_color
] & 0xFFC0) << 4) |
819 ((info
->cmap
.blue
[fg_color
] & 0xFFC0) >> 6);
821 ((info
->cmap
.red
[bg_color
] & 0xFFC0) << 14) |
822 ((info
->cmap
.green
[bg_color
] & 0xFFC0) << 4) |
823 ((info
->cmap
.blue
[bg_color
] & 0xFFC0) >> 6);
826 ((info
->cmap
.red
[fg_color
] & 0xFF00) << 8) |
827 (info
->cmap
.green
[fg_color
] & 0xFF00) |
828 ((info
->cmap
.blue
[fg_color
] & 0xFF00) >> 8);
830 ((info
->cmap
.red
[bg_color
] & 0xFF00) << 8) |
831 (info
->cmap
.green
[bg_color
] & 0xFF00) |
832 ((info
->cmap
.blue
[bg_color
] & 0xFF00) >> 8);
835 writel(bg_color
, engine
+ VIA_REG_CURSOR_BG
);
836 writel(fg_color
, engine
+ VIA_REG_CURSOR_FG
);
839 if (cursor
->set
& FB_CUR_SETSHAPE
) {
841 u8 data
[CURSOR_SIZE
];
842 u32 bak
[CURSOR_SIZE
/ 4];
843 } *cr_data
= kzalloc(sizeof(*cr_data
), GFP_ATOMIC
);
844 int size
= ((cursor
->image
.width
+ 7) >> 3) *
845 cursor
->image
.height
;
850 if (cur_size
== 32) {
851 for (i
= 0; i
< (CURSOR_SIZE
/ 4); i
++) {
852 cr_data
->bak
[i
] = 0x0;
853 cr_data
->bak
[i
+ 1] = 0xFFFFFFFF;
857 for (i
= 0; i
< (CURSOR_SIZE
/ 4); i
++) {
858 cr_data
->bak
[i
] = 0x0;
859 cr_data
->bak
[i
+ 1] = 0x0;
860 cr_data
->bak
[i
+ 2] = 0xFFFFFFFF;
861 cr_data
->bak
[i
+ 3] = 0xFFFFFFFF;
866 switch (cursor
->rop
) {
868 for (i
= 0; i
< size
; i
++)
869 cr_data
->data
[i
] = cursor
->mask
[i
];
873 for (i
= 0; i
< size
; i
++)
874 cr_data
->data
[i
] = cursor
->mask
[i
];
880 if (cur_size
== 32) {
881 for (i
= 0; i
< size
; i
++) {
882 cr_data
->bak
[j
] = (u32
) cr_data
->data
[i
];
883 cr_data
->bak
[j
+ 1] = ~cr_data
->bak
[j
];
887 for (i
= 0; i
< size
; i
++) {
888 cr_data
->bak
[j
] = (u32
) cr_data
->data
[i
];
889 cr_data
->bak
[j
+ 1] = 0x0;
890 cr_data
->bak
[j
+ 2] = ~cr_data
->bak
[j
];
891 cr_data
->bak
[j
+ 3] = ~cr_data
->bak
[j
+ 1];
896 memcpy_toio(viafbinfo
->screen_base
+ viapar
->shared
->
897 cursor_vram_addr
, cr_data
->bak
, CURSOR_SIZE
);
902 viafb_show_hw_cursor(info
, HW_Cursor_ON
);
907 static int viafb_sync(struct fb_info
*info
)
909 if (!(info
->flags
& FBINFO_HWACCEL_DISABLED
))
910 viafb_wait_engine_idle(info
);
914 static int get_primary_device(void)
916 int primary_device
= 0;
917 /* Rule: device on iga1 path are the primary device. */
920 if (viaparinfo
->shared
->iga1_devices
& VIA_CRT
) {
921 DEBUG_MSG(KERN_INFO
"CRT IGA Path:%d\n", IGA1
);
922 primary_device
= CRT_Device
;
926 if (viaparinfo
->tmds_setting_info
->iga_path
== IGA1
) {
927 DEBUG_MSG(KERN_INFO
"DVI IGA Path:%d\n",
929 tmds_setting_info
->iga_path
);
930 primary_device
= DVI_Device
;
934 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
935 DEBUG_MSG(KERN_INFO
"LCD IGA Path:%d\n",
937 lvds_setting_info
->iga_path
);
938 primary_device
= LCD_Device
;
942 if (viaparinfo
->lvds_setting_info2
->iga_path
== IGA1
) {
943 DEBUG_MSG(KERN_INFO
"LCD2 IGA Path:%d\n",
945 lvds_setting_info2
->iga_path
);
946 primary_device
= LCD2_Device
;
950 return primary_device
;
953 static void retrieve_device_setting(struct viafb_ioctl_setting
957 /* get device status */
958 if (viafb_CRT_ON
== 1)
959 setting_info
->device_status
= CRT_Device
;
960 if (viafb_DVI_ON
== 1)
961 setting_info
->device_status
|= DVI_Device
;
962 if (viafb_LCD_ON
== 1)
963 setting_info
->device_status
|= LCD_Device
;
964 if (viafb_LCD2_ON
== 1)
965 setting_info
->device_status
|= LCD2_Device
;
967 setting_info
->samm_status
= viafb_SAMM_ON
;
968 setting_info
->primary_device
= get_primary_device();
970 setting_info
->first_dev_bpp
= viafb_bpp
;
971 setting_info
->second_dev_bpp
= viafb_bpp1
;
973 setting_info
->first_dev_refresh
= viafb_refresh
;
974 setting_info
->second_dev_refresh
= viafb_refresh1
;
976 setting_info
->first_dev_hor_res
= viafb_hotplug_Xres
;
977 setting_info
->first_dev_ver_res
= viafb_hotplug_Yres
;
978 setting_info
->second_dev_hor_res
= viafb_second_xres
;
979 setting_info
->second_dev_ver_res
= viafb_second_yres
;
981 /* Get lcd attributes */
982 setting_info
->lcd_attributes
.display_center
= viafb_lcd_dsp_method
;
983 setting_info
->lcd_attributes
.panel_id
= viafb_lcd_panel_id
;
984 setting_info
->lcd_attributes
.lcd_mode
= viafb_lcd_mode
;
987 static int __init
parse_active_dev(void)
989 viafb_CRT_ON
= STATE_OFF
;
990 viafb_DVI_ON
= STATE_OFF
;
991 viafb_LCD_ON
= STATE_OFF
;
992 viafb_LCD2_ON
= STATE_OFF
;
993 /* 1. Modify the active status of devices. */
994 /* 2. Keep the order of devices, so we can set corresponding
995 IGA path to devices in SAMM case. */
996 /* Note: The previous of active_dev is primary device,
997 and the following is secondary device. */
998 if (!viafb_active_dev
) {
999 if (machine_is_olpc()) { /* LCD only */
1000 viafb_LCD_ON
= STATE_ON
;
1001 viafb_SAMM_ON
= STATE_OFF
;
1003 viafb_CRT_ON
= STATE_ON
;
1004 viafb_SAMM_ON
= STATE_OFF
;
1006 } else if (!strcmp(viafb_active_dev
, "CRT+DVI")) {
1008 viafb_CRT_ON
= STATE_ON
;
1009 viafb_DVI_ON
= STATE_ON
;
1010 viafb_primary_dev
= CRT_Device
;
1011 } else if (!strcmp(viafb_active_dev
, "DVI+CRT")) {
1013 viafb_CRT_ON
= STATE_ON
;
1014 viafb_DVI_ON
= STATE_ON
;
1015 viafb_primary_dev
= DVI_Device
;
1016 } else if (!strcmp(viafb_active_dev
, "CRT+LCD")) {
1018 viafb_CRT_ON
= STATE_ON
;
1019 viafb_LCD_ON
= STATE_ON
;
1020 viafb_primary_dev
= CRT_Device
;
1021 } else if (!strcmp(viafb_active_dev
, "LCD+CRT")) {
1023 viafb_CRT_ON
= STATE_ON
;
1024 viafb_LCD_ON
= STATE_ON
;
1025 viafb_primary_dev
= LCD_Device
;
1026 } else if (!strcmp(viafb_active_dev
, "DVI+LCD")) {
1028 viafb_DVI_ON
= STATE_ON
;
1029 viafb_LCD_ON
= STATE_ON
;
1030 viafb_primary_dev
= DVI_Device
;
1031 } else if (!strcmp(viafb_active_dev
, "LCD+DVI")) {
1033 viafb_DVI_ON
= STATE_ON
;
1034 viafb_LCD_ON
= STATE_ON
;
1035 viafb_primary_dev
= LCD_Device
;
1036 } else if (!strcmp(viafb_active_dev
, "LCD+LCD2")) {
1037 viafb_LCD_ON
= STATE_ON
;
1038 viafb_LCD2_ON
= STATE_ON
;
1039 viafb_primary_dev
= LCD_Device
;
1040 } else if (!strcmp(viafb_active_dev
, "LCD2+LCD")) {
1041 viafb_LCD_ON
= STATE_ON
;
1042 viafb_LCD2_ON
= STATE_ON
;
1043 viafb_primary_dev
= LCD2_Device
;
1044 } else if (!strcmp(viafb_active_dev
, "CRT")) {
1046 viafb_CRT_ON
= STATE_ON
;
1047 viafb_SAMM_ON
= STATE_OFF
;
1048 } else if (!strcmp(viafb_active_dev
, "DVI")) {
1050 viafb_DVI_ON
= STATE_ON
;
1051 viafb_SAMM_ON
= STATE_OFF
;
1052 } else if (!strcmp(viafb_active_dev
, "LCD")) {
1054 viafb_LCD_ON
= STATE_ON
;
1055 viafb_SAMM_ON
= STATE_OFF
;
1062 static int parse_port(char *opt_str
, int *output_interface
)
1064 if (!strncmp(opt_str
, "DVP0", 4))
1065 *output_interface
= INTERFACE_DVP0
;
1066 else if (!strncmp(opt_str
, "DVP1", 4))
1067 *output_interface
= INTERFACE_DVP1
;
1068 else if (!strncmp(opt_str
, "DFP_HIGHLOW", 11))
1069 *output_interface
= INTERFACE_DFP
;
1070 else if (!strncmp(opt_str
, "DFP_HIGH", 8))
1071 *output_interface
= INTERFACE_DFP_HIGH
;
1072 else if (!strncmp(opt_str
, "DFP_LOW", 7))
1073 *output_interface
= INTERFACE_DFP_LOW
;
1075 *output_interface
= INTERFACE_NONE
;
1079 static void parse_lcd_port(void)
1081 parse_port(viafb_lcd_port
, &viaparinfo
->chip_info
->lvds_chip_info
.
1083 /*Initialize to avoid unexpected behavior */
1084 viaparinfo
->chip_info
->lvds_chip_info2
.output_interface
=
1087 DEBUG_MSG(KERN_INFO
"parse_lcd_port: viafb_lcd_port:%s,interface:%d\n",
1088 viafb_lcd_port
, viaparinfo
->chip_info
->lvds_chip_info
.
1092 static void parse_dvi_port(void)
1094 parse_port(viafb_dvi_port
, &viaparinfo
->chip_info
->tmds_chip_info
.
1097 DEBUG_MSG(KERN_INFO
"parse_dvi_port: viafb_dvi_port:%s,interface:%d\n",
1098 viafb_dvi_port
, viaparinfo
->chip_info
->tmds_chip_info
.
1102 #ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1105 * The proc filesystem read/write function, a simple proc implement to
1106 * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
1107 * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2],
1108 * CR9B, SR65, CR97, CR99
1110 static int viafb_dvp0_proc_show(struct seq_file
*m
, void *v
)
1112 u8 dvp0_data_dri
= 0, dvp0_clk_dri
= 0, dvp0
= 0;
1114 (viafb_read_reg(VIASR
, SR2A
) & BIT5
) >> 4 |
1115 (viafb_read_reg(VIASR
, SR1B
) & BIT1
) >> 1;
1117 (viafb_read_reg(VIASR
, SR2A
) & BIT4
) >> 3 |
1118 (viafb_read_reg(VIASR
, SR1E
) & BIT2
) >> 2;
1119 dvp0
= viafb_read_reg(VIACR
, CR96
) & 0x0f;
1120 seq_printf(m
, "%x %x %x\n", dvp0
, dvp0_data_dri
, dvp0_clk_dri
);
1124 static int viafb_dvp0_proc_open(struct inode
*inode
, struct file
*file
)
1126 return single_open(file
, viafb_dvp0_proc_show
, NULL
);
1129 static ssize_t
viafb_dvp0_proc_write(struct file
*file
,
1130 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1132 char buf
[20], *value
, *pbuf
;
1134 unsigned long length
, i
;
1137 length
= count
> 20 ? 20 : count
;
1138 if (copy_from_user(&buf
[0], buffer
, length
))
1140 buf
[length
- 1] = '\0'; /*Ensure end string */
1142 for (i
= 0; i
< 3; i
++) {
1143 value
= strsep(&pbuf
, " ");
1144 if (value
!= NULL
) {
1145 if (kstrtou8(value
, 0, ®_val
) < 0)
1147 DEBUG_MSG(KERN_INFO
"DVP0:reg_val[%lu]=:%x\n", i
,
1151 viafb_write_reg_mask(CR96
, VIACR
,
1155 viafb_write_reg_mask(SR2A
, VIASR
,
1156 reg_val
<< 4, BIT5
);
1157 viafb_write_reg_mask(SR1B
, VIASR
,
1158 reg_val
<< 1, BIT1
);
1161 viafb_write_reg_mask(SR2A
, VIASR
,
1162 reg_val
<< 3, BIT4
);
1163 viafb_write_reg_mask(SR1E
, VIASR
,
1164 reg_val
<< 2, BIT2
);
1176 static const struct proc_ops viafb_dvp0_proc_ops
= {
1177 .proc_open
= viafb_dvp0_proc_open
,
1178 .proc_read
= seq_read
,
1179 .proc_lseek
= seq_lseek
,
1180 .proc_release
= single_release
,
1181 .proc_write
= viafb_dvp0_proc_write
,
1184 static int viafb_dvp1_proc_show(struct seq_file
*m
, void *v
)
1186 u8 dvp1
= 0, dvp1_data_dri
= 0, dvp1_clk_dri
= 0;
1187 dvp1
= viafb_read_reg(VIACR
, CR9B
) & 0x0f;
1188 dvp1_data_dri
= (viafb_read_reg(VIASR
, SR65
) & 0x0c) >> 2;
1189 dvp1_clk_dri
= viafb_read_reg(VIASR
, SR65
) & 0x03;
1190 seq_printf(m
, "%x %x %x\n", dvp1
, dvp1_data_dri
, dvp1_clk_dri
);
1194 static int viafb_dvp1_proc_open(struct inode
*inode
, struct file
*file
)
1196 return single_open(file
, viafb_dvp1_proc_show
, NULL
);
1199 static ssize_t
viafb_dvp1_proc_write(struct file
*file
,
1200 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1202 char buf
[20], *value
, *pbuf
;
1204 unsigned long length
, i
;
1207 length
= count
> 20 ? 20 : count
;
1208 if (copy_from_user(&buf
[0], buffer
, length
))
1210 buf
[length
- 1] = '\0'; /*Ensure end string */
1212 for (i
= 0; i
< 3; i
++) {
1213 value
= strsep(&pbuf
, " ");
1214 if (value
!= NULL
) {
1215 if (kstrtou8(value
, 0, ®_val
) < 0)
1219 viafb_write_reg_mask(CR9B
, VIACR
,
1223 viafb_write_reg_mask(SR65
, VIASR
,
1224 reg_val
<< 2, 0x0c);
1227 viafb_write_reg_mask(SR65
, VIASR
,
1240 static const struct proc_ops viafb_dvp1_proc_ops
= {
1241 .proc_open
= viafb_dvp1_proc_open
,
1242 .proc_read
= seq_read
,
1243 .proc_lseek
= seq_lseek
,
1244 .proc_release
= single_release
,
1245 .proc_write
= viafb_dvp1_proc_write
,
1248 static int viafb_dfph_proc_show(struct seq_file
*m
, void *v
)
1251 dfp_high
= viafb_read_reg(VIACR
, CR97
) & 0x0f;
1252 seq_printf(m
, "%x\n", dfp_high
);
1256 static int viafb_dfph_proc_open(struct inode
*inode
, struct file
*file
)
1258 return single_open(file
, viafb_dfph_proc_show
, NULL
);
1261 static ssize_t
viafb_dfph_proc_write(struct file
*file
,
1262 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1266 err
= kstrtou8_from_user(buffer
, count
, 0, ®_val
);
1270 viafb_write_reg_mask(CR97
, VIACR
, reg_val
, 0x0f);
1274 static const struct proc_ops viafb_dfph_proc_ops
= {
1275 .proc_open
= viafb_dfph_proc_open
,
1276 .proc_read
= seq_read
,
1277 .proc_lseek
= seq_lseek
,
1278 .proc_release
= single_release
,
1279 .proc_write
= viafb_dfph_proc_write
,
1282 static int viafb_dfpl_proc_show(struct seq_file
*m
, void *v
)
1285 dfp_low
= viafb_read_reg(VIACR
, CR99
) & 0x0f;
1286 seq_printf(m
, "%x\n", dfp_low
);
1290 static int viafb_dfpl_proc_open(struct inode
*inode
, struct file
*file
)
1292 return single_open(file
, viafb_dfpl_proc_show
, NULL
);
1295 static ssize_t
viafb_dfpl_proc_write(struct file
*file
,
1296 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1300 err
= kstrtou8_from_user(buffer
, count
, 0, ®_val
);
1304 viafb_write_reg_mask(CR99
, VIACR
, reg_val
, 0x0f);
1308 static const struct proc_ops viafb_dfpl_proc_ops
= {
1309 .proc_open
= viafb_dfpl_proc_open
,
1310 .proc_read
= seq_read
,
1311 .proc_lseek
= seq_lseek
,
1312 .proc_release
= single_release
,
1313 .proc_write
= viafb_dfpl_proc_write
,
1316 static int viafb_vt1636_proc_show(struct seq_file
*m
, void *v
)
1318 u8 vt1636_08
= 0, vt1636_09
= 0;
1319 switch (viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
1322 viafb_gpio_i2c_read_lvds(viaparinfo
->lvds_setting_info
,
1323 &viaparinfo
->chip_info
->lvds_chip_info
, 0x08) & 0x0f;
1325 viafb_gpio_i2c_read_lvds(viaparinfo
->lvds_setting_info
,
1326 &viaparinfo
->chip_info
->lvds_chip_info
, 0x09) & 0x1f;
1327 seq_printf(m
, "%x %x\n", vt1636_08
, vt1636_09
);
1332 switch (viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
) {
1335 viafb_gpio_i2c_read_lvds(viaparinfo
->lvds_setting_info2
,
1336 &viaparinfo
->chip_info
->lvds_chip_info2
, 0x08) & 0x0f;
1338 viafb_gpio_i2c_read_lvds(viaparinfo
->lvds_setting_info2
,
1339 &viaparinfo
->chip_info
->lvds_chip_info2
, 0x09) & 0x1f;
1340 seq_printf(m
, " %x %x\n", vt1636_08
, vt1636_09
);
1348 static int viafb_vt1636_proc_open(struct inode
*inode
, struct file
*file
)
1350 return single_open(file
, viafb_vt1636_proc_show
, NULL
);
1353 static ssize_t
viafb_vt1636_proc_write(struct file
*file
,
1354 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1356 char buf
[30], *value
, *pbuf
;
1357 struct IODATA reg_val
;
1358 unsigned long length
, i
;
1361 length
= count
> 30 ? 30 : count
;
1362 if (copy_from_user(&buf
[0], buffer
, length
))
1364 buf
[length
- 1] = '\0'; /*Ensure end string */
1366 switch (viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
1368 for (i
= 0; i
< 2; i
++) {
1369 value
= strsep(&pbuf
, " ");
1370 if (value
!= NULL
) {
1371 if (kstrtou8(value
, 0, ®_val
.Data
) < 0)
1375 reg_val
.Index
= 0x08;
1376 reg_val
.Mask
= 0x0f;
1377 viafb_gpio_i2c_write_mask_lvds
1378 (viaparinfo
->lvds_setting_info
,
1380 chip_info
->lvds_chip_info
,
1384 reg_val
.Index
= 0x09;
1385 reg_val
.Mask
= 0x1f;
1386 viafb_gpio_i2c_write_mask_lvds
1387 (viaparinfo
->lvds_setting_info
,
1389 chip_info
->lvds_chip_info
,
1403 switch (viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
) {
1405 for (i
= 0; i
< 2; i
++) {
1406 value
= strsep(&pbuf
, " ");
1407 if (value
!= NULL
) {
1408 if (kstrtou8(value
, 0, ®_val
.Data
) < 0)
1412 reg_val
.Index
= 0x08;
1413 reg_val
.Mask
= 0x0f;
1414 viafb_gpio_i2c_write_mask_lvds
1415 (viaparinfo
->lvds_setting_info2
,
1417 chip_info
->lvds_chip_info2
,
1421 reg_val
.Index
= 0x09;
1422 reg_val
.Mask
= 0x1f;
1423 viafb_gpio_i2c_write_mask_lvds
1424 (viaparinfo
->lvds_setting_info2
,
1426 chip_info
->lvds_chip_info2
,
1443 static const struct proc_ops viafb_vt1636_proc_ops
= {
1444 .proc_open
= viafb_vt1636_proc_open
,
1445 .proc_read
= seq_read
,
1446 .proc_lseek
= seq_lseek
,
1447 .proc_release
= single_release
,
1448 .proc_write
= viafb_vt1636_proc_write
,
1451 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
1453 static int __maybe_unused
viafb_sup_odev_proc_show(struct seq_file
*m
, void *v
)
1455 via_odev_to_seq(m
, supported_odev_map
[
1456 viaparinfo
->shared
->chip_info
.gfx_chip_name
]);
1460 static ssize_t
odev_update(const char __user
*buffer
, size_t count
, u32
*odev
)
1462 char buf
[64], *ptr
= buf
;
1466 if (count
< 1 || count
> 63)
1468 if (copy_from_user(&buf
[0], buffer
, count
))
1471 add
= buf
[0] == '+';
1472 sub
= buf
[0] == '-';
1475 devices
= via_parse_odev(ptr
, &ptr
);
1489 static int viafb_iga1_odev_proc_show(struct seq_file
*m
, void *v
)
1491 via_odev_to_seq(m
, viaparinfo
->shared
->iga1_devices
);
1495 static int viafb_iga1_odev_proc_open(struct inode
*inode
, struct file
*file
)
1497 return single_open(file
, viafb_iga1_odev_proc_show
, NULL
);
1500 static ssize_t
viafb_iga1_odev_proc_write(struct file
*file
,
1501 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1503 u32 dev_on
, dev_off
, dev_old
, dev_new
;
1506 dev_old
= dev_new
= viaparinfo
->shared
->iga1_devices
;
1507 res
= odev_update(buffer
, count
, &dev_new
);
1510 dev_off
= dev_old
& ~dev_new
;
1511 dev_on
= dev_new
& ~dev_old
;
1512 viaparinfo
->shared
->iga1_devices
= dev_new
;
1513 viaparinfo
->shared
->iga2_devices
&= ~dev_new
;
1514 via_set_state(dev_off
, VIA_STATE_OFF
);
1515 via_set_source(dev_new
, IGA1
);
1516 via_set_state(dev_on
, VIA_STATE_ON
);
1520 static const struct proc_ops viafb_iga1_odev_proc_ops
= {
1521 .proc_open
= viafb_iga1_odev_proc_open
,
1522 .proc_read
= seq_read
,
1523 .proc_lseek
= seq_lseek
,
1524 .proc_release
= single_release
,
1525 .proc_write
= viafb_iga1_odev_proc_write
,
1528 static int viafb_iga2_odev_proc_show(struct seq_file
*m
, void *v
)
1530 via_odev_to_seq(m
, viaparinfo
->shared
->iga2_devices
);
1534 static int viafb_iga2_odev_proc_open(struct inode
*inode
, struct file
*file
)
1536 return single_open(file
, viafb_iga2_odev_proc_show
, NULL
);
1539 static ssize_t
viafb_iga2_odev_proc_write(struct file
*file
,
1540 const char __user
*buffer
, size_t count
, loff_t
*pos
)
1542 u32 dev_on
, dev_off
, dev_old
, dev_new
;
1545 dev_old
= dev_new
= viaparinfo
->shared
->iga2_devices
;
1546 res
= odev_update(buffer
, count
, &dev_new
);
1549 dev_off
= dev_old
& ~dev_new
;
1550 dev_on
= dev_new
& ~dev_old
;
1551 viaparinfo
->shared
->iga2_devices
= dev_new
;
1552 viaparinfo
->shared
->iga1_devices
&= ~dev_new
;
1553 via_set_state(dev_off
, VIA_STATE_OFF
);
1554 via_set_source(dev_new
, IGA2
);
1555 via_set_state(dev_on
, VIA_STATE_ON
);
1559 static const struct proc_ops viafb_iga2_odev_proc_ops
= {
1560 .proc_open
= viafb_iga2_odev_proc_open
,
1561 .proc_read
= seq_read
,
1562 .proc_lseek
= seq_lseek
,
1563 .proc_release
= single_release
,
1564 .proc_write
= viafb_iga2_odev_proc_write
,
1567 #define IS_VT1636(lvds_chip) ((lvds_chip).lvds_chip_name == VT1636_LVDS)
1568 static void viafb_init_proc(struct viafb_shared
*shared
)
1570 struct proc_dir_entry
*iga1_entry
, *iga2_entry
,
1571 *viafb_entry
= proc_mkdir("viafb", NULL
);
1573 shared
->proc_entry
= viafb_entry
;
1575 #ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1576 proc_create("dvp0", 0, viafb_entry
, &viafb_dvp0_proc_ops
);
1577 proc_create("dvp1", 0, viafb_entry
, &viafb_dvp1_proc_ops
);
1578 proc_create("dfph", 0, viafb_entry
, &viafb_dfph_proc_ops
);
1579 proc_create("dfpl", 0, viafb_entry
, &viafb_dfpl_proc_ops
);
1580 if (IS_VT1636(shared
->chip_info
.lvds_chip_info
)
1581 || IS_VT1636(shared
->chip_info
.lvds_chip_info2
))
1582 proc_create("vt1636", 0, viafb_entry
,
1583 &viafb_vt1636_proc_ops
);
1584 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
1586 proc_create_single("supported_output_devices", 0, viafb_entry
,
1587 viafb_sup_odev_proc_show
);
1588 iga1_entry
= proc_mkdir("iga1", viafb_entry
);
1589 shared
->iga1_proc_entry
= iga1_entry
;
1590 proc_create("output_devices", 0, iga1_entry
,
1591 &viafb_iga1_odev_proc_ops
);
1592 iga2_entry
= proc_mkdir("iga2", viafb_entry
);
1593 shared
->iga2_proc_entry
= iga2_entry
;
1594 proc_create("output_devices", 0, iga2_entry
,
1595 &viafb_iga2_odev_proc_ops
);
1598 static void viafb_remove_proc(struct viafb_shared
*shared
)
1600 struct proc_dir_entry
*viafb_entry
= shared
->proc_entry
;
1605 remove_proc_entry("output_devices", shared
->iga2_proc_entry
);
1606 remove_proc_entry("iga2", viafb_entry
);
1607 remove_proc_entry("output_devices", shared
->iga1_proc_entry
);
1608 remove_proc_entry("iga1", viafb_entry
);
1609 remove_proc_entry("supported_output_devices", viafb_entry
);
1611 #ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1612 remove_proc_entry("dvp0", viafb_entry
);/* parent dir */
1613 remove_proc_entry("dvp1", viafb_entry
);
1614 remove_proc_entry("dfph", viafb_entry
);
1615 remove_proc_entry("dfpl", viafb_entry
);
1616 if (IS_VT1636(shared
->chip_info
.lvds_chip_info
)
1617 || IS_VT1636(shared
->chip_info
.lvds_chip_info2
))
1618 remove_proc_entry("vt1636", viafb_entry
);
1619 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
1621 remove_proc_entry("viafb", NULL
);
1625 static int parse_mode(const char *str
, u32 devices
, u32
*xres
, u32
*yres
)
1627 const struct fb_videomode
*mode
= NULL
;
1631 if (devices
== VIA_CRT
)
1632 mode
= via_aux_get_preferred_mode(
1633 viaparinfo
->shared
->i2c_26
);
1634 else if (devices
== VIA_DVP1
)
1635 mode
= via_aux_get_preferred_mode(
1636 viaparinfo
->shared
->i2c_31
);
1641 } else if (machine_is_olpc()) {
1651 *xres
= simple_strtoul(str
, &ptr
, 10);
1655 *yres
= simple_strtoul(&ptr
[1], &ptr
, 10);
1664 static int viafb_suspend(void *unused
)
1667 fb_set_suspend(viafbinfo
, 1);
1668 viafb_sync(viafbinfo
);
1674 static int viafb_resume(void *unused
)
1677 if (viaparinfo
->shared
->vdev
->engine_mmio
)
1678 viafb_reset_engine(viaparinfo
);
1679 viafb_set_par(viafbinfo
);
1681 viafb_set_par(viafbinfo1
);
1682 fb_set_suspend(viafbinfo
, 0);
1688 static struct viafb_pm_hooks viafb_fb_pm_hooks
= {
1689 .suspend
= viafb_suspend
,
1690 .resume
= viafb_resume
1695 static void i2c_bus_probe(struct viafb_shared
*shared
)
1697 /* should be always CRT */
1698 printk(KERN_INFO
"viafb: Probing I2C bus 0x26\n");
1699 shared
->i2c_26
= via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26
));
1701 /* seems to be usually DVP1 */
1702 printk(KERN_INFO
"viafb: Probing I2C bus 0x31\n");
1703 shared
->i2c_31
= via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31
));
1705 /* FIXME: what is this? */
1706 if (!machine_is_olpc()) {
1707 printk(KERN_INFO
"viafb: Probing I2C bus 0x2C\n");
1708 shared
->i2c_2C
= via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C
));
1711 printk(KERN_INFO
"viafb: Finished I2C bus probing");
1714 static void i2c_bus_free(struct viafb_shared
*shared
)
1716 via_aux_free(shared
->i2c_26
);
1717 via_aux_free(shared
->i2c_31
);
1718 via_aux_free(shared
->i2c_2C
);
1721 int via_fb_pci_probe(struct viafb_dev
*vdev
)
1723 u32 default_xres
, default_yres
;
1724 struct fb_var_screeninfo default_var
;
1726 u32 viafb_par_length
;
1728 DEBUG_MSG(KERN_INFO
"VIAFB PCI Probe!!\n");
1729 memset(&default_var
, 0, sizeof(default_var
));
1730 viafb_par_length
= ALIGN(sizeof(struct viafb_par
), BITS_PER_LONG
/8);
1732 /* Allocate fb_info and ***_par here, also including some other needed
1735 viafbinfo
= framebuffer_alloc(viafb_par_length
+
1736 ALIGN(sizeof(struct viafb_shared
), BITS_PER_LONG
/8),
1741 viaparinfo
= (struct viafb_par
*)viafbinfo
->par
;
1742 viaparinfo
->shared
= viafbinfo
->par
+ viafb_par_length
;
1743 viaparinfo
->shared
->vdev
= vdev
;
1744 viaparinfo
->vram_addr
= 0;
1745 viaparinfo
->tmds_setting_info
= &viaparinfo
->shared
->tmds_setting_info
;
1746 viaparinfo
->lvds_setting_info
= &viaparinfo
->shared
->lvds_setting_info
;
1747 viaparinfo
->lvds_setting_info2
=
1748 &viaparinfo
->shared
->lvds_setting_info2
;
1749 viaparinfo
->chip_info
= &viaparinfo
->shared
->chip_info
;
1751 i2c_bus_probe(viaparinfo
->shared
);
1757 viafb_init_chip_info(vdev
->chip_type
);
1759 * The framebuffer will have been successfully mapped by
1760 * the core (or we'd not be here), but we still need to
1761 * set up our own accounting.
1763 viaparinfo
->fbmem
= vdev
->fbmem_start
;
1764 viaparinfo
->memsize
= vdev
->fbmem_len
;
1765 viaparinfo
->fbmem_free
= viaparinfo
->memsize
;
1766 viaparinfo
->fbmem_used
= 0;
1767 viafbinfo
->screen_base
= vdev
->fbmem
;
1769 viafbinfo
->fix
.mmio_start
= vdev
->engine_start
;
1770 viafbinfo
->fix
.mmio_len
= vdev
->engine_len
;
1771 viafbinfo
->node
= 0;
1772 viafbinfo
->fbops
= &viafb_ops
;
1773 viafbinfo
->flags
= FBINFO_DEFAULT
| FBINFO_HWACCEL_YPAN
;
1775 viafbinfo
->pseudo_palette
= pseudo_pal
;
1776 if (viafb_accel
&& !viafb_setup_engine(viafbinfo
)) {
1777 viafbinfo
->flags
|= FBINFO_HWACCEL_COPYAREA
|
1778 FBINFO_HWACCEL_FILLRECT
| FBINFO_HWACCEL_IMAGEBLIT
;
1779 default_var
.accel_flags
= FB_ACCELF_TEXT
;
1781 viafbinfo
->flags
|= FBINFO_HWACCEL_DISABLED
;
1782 default_var
.accel_flags
= 0;
1785 if (viafb_second_size
&& (viafb_second_size
< 8)) {
1786 viafb_second_offset
= viaparinfo
->fbmem_free
-
1787 viafb_second_size
* 1024 * 1024;
1789 viafb_second_size
= 8;
1790 viafb_second_offset
= viaparinfo
->fbmem_free
-
1791 viafb_second_size
* 1024 * 1024;
1794 parse_mode(viafb_mode
, viaparinfo
->shared
->iga1_devices
,
1795 &default_xres
, &default_yres
);
1796 if (viafb_SAMM_ON
== 1)
1797 parse_mode(viafb_mode1
, viaparinfo
->shared
->iga2_devices
,
1798 &viafb_second_xres
, &viafb_second_yres
);
1800 default_var
.xres
= default_xres
;
1801 default_var
.yres
= default_yres
;
1802 default_var
.xres_virtual
= default_xres
;
1803 default_var
.yres_virtual
= default_yres
;
1804 default_var
.bits_per_pixel
= viafb_bpp
;
1805 viafb_fill_var_timing_info(&default_var
, viafb_get_best_mode(
1806 default_var
.xres
, default_var
.yres
, viafb_refresh
));
1807 viafb_setup_fixinfo(&viafbinfo
->fix
, viaparinfo
);
1808 viafbinfo
->var
= default_var
;
1810 if (viafb_dual_fb
) {
1811 viafbinfo1
= framebuffer_alloc(viafb_par_length
,
1815 goto out_fb_release
;
1817 viaparinfo1
= viafbinfo1
->par
;
1818 memcpy(viaparinfo1
, viaparinfo
, viafb_par_length
);
1819 viaparinfo1
->vram_addr
= viafb_second_offset
;
1820 viaparinfo1
->memsize
= viaparinfo
->memsize
-
1821 viafb_second_offset
;
1822 viaparinfo
->memsize
= viafb_second_offset
;
1823 viaparinfo1
->fbmem
= viaparinfo
->fbmem
+ viafb_second_offset
;
1825 viaparinfo1
->fbmem_used
= viaparinfo
->fbmem_used
;
1826 viaparinfo1
->fbmem_free
= viaparinfo1
->memsize
-
1827 viaparinfo1
->fbmem_used
;
1828 viaparinfo
->fbmem_free
= viaparinfo
->memsize
;
1829 viaparinfo
->fbmem_used
= 0;
1831 viaparinfo
->iga_path
= IGA1
;
1832 viaparinfo1
->iga_path
= IGA2
;
1833 memcpy(viafbinfo1
, viafbinfo
, sizeof(struct fb_info
));
1834 viafbinfo1
->par
= viaparinfo1
;
1835 viafbinfo1
->screen_base
= viafbinfo
->screen_base
+
1836 viafb_second_offset
;
1838 default_var
.xres
= viafb_second_xres
;
1839 default_var
.yres
= viafb_second_yres
;
1840 default_var
.xres_virtual
= viafb_second_xres
;
1841 default_var
.yres_virtual
= viafb_second_yres
;
1842 default_var
.bits_per_pixel
= viafb_bpp1
;
1843 viafb_fill_var_timing_info(&default_var
, viafb_get_best_mode(
1844 default_var
.xres
, default_var
.yres
, viafb_refresh1
));
1846 viafb_setup_fixinfo(&viafbinfo1
->fix
, viaparinfo1
);
1847 viafb_check_var(&default_var
, viafbinfo1
);
1848 viafbinfo1
->var
= default_var
;
1849 viafb_update_fix(viafbinfo1
);
1850 viaparinfo1
->depth
= fb_get_color_depth(&viafbinfo1
->var
,
1854 viafb_check_var(&viafbinfo
->var
, viafbinfo
);
1855 viafb_update_fix(viafbinfo
);
1856 viaparinfo
->depth
= fb_get_color_depth(&viafbinfo
->var
,
1858 default_var
.activate
= FB_ACTIVATE_NOW
;
1859 rc
= fb_alloc_cmap(&viafbinfo
->cmap
, 256, 0);
1861 goto out_fb1_release
;
1863 if (viafb_dual_fb
&& (viafb_primary_dev
== LCD_Device
)
1864 && (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
)) {
1865 rc
= register_framebuffer(viafbinfo1
);
1867 goto out_dealloc_cmap
;
1869 rc
= register_framebuffer(viafbinfo
);
1871 goto out_fb1_unreg_lcd_cle266
;
1873 if (viafb_dual_fb
&& ((viafb_primary_dev
!= LCD_Device
)
1874 || (viaparinfo
->chip_info
->gfx_chip_name
!=
1875 UNICHROME_CLE266
))) {
1876 rc
= register_framebuffer(viafbinfo1
);
1880 DEBUG_MSG(KERN_INFO
"fb%d: %s frame buffer device %dx%d-%dbpp\n",
1881 viafbinfo
->node
, viafbinfo
->fix
.id
, default_var
.xres
,
1882 default_var
.yres
, default_var
.bits_per_pixel
);
1884 viafb_init_proc(viaparinfo
->shared
);
1885 viafb_init_dac(IGA2
);
1888 viafb_pm_register(&viafb_fb_pm_hooks
);
1893 unregister_framebuffer(viafbinfo
);
1894 out_fb1_unreg_lcd_cle266
:
1895 if (viafb_dual_fb
&& (viafb_primary_dev
== LCD_Device
)
1896 && (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
))
1897 unregister_framebuffer(viafbinfo1
);
1899 fb_dealloc_cmap(&viafbinfo
->cmap
);
1901 framebuffer_release(viafbinfo1
);
1903 i2c_bus_free(viaparinfo
->shared
);
1904 framebuffer_release(viafbinfo
);
1908 void via_fb_pci_remove(struct pci_dev
*pdev
)
1910 DEBUG_MSG(KERN_INFO
"via_pci_remove!\n");
1911 fb_dealloc_cmap(&viafbinfo
->cmap
);
1912 unregister_framebuffer(viafbinfo
);
1914 unregister_framebuffer(viafbinfo1
);
1915 viafb_remove_proc(viaparinfo
->shared
);
1916 i2c_bus_free(viaparinfo
->shared
);
1917 framebuffer_release(viafbinfo
);
1919 framebuffer_release(viafbinfo1
);
1923 static int __init
viafb_setup(void)
1928 DEBUG_MSG(KERN_INFO
"viafb_setup!\n");
1930 if (fb_get_options("viafb", &options
))
1933 if (!options
|| !*options
)
1936 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1940 if (!strncmp(this_opt
, "viafb_mode1=", 12)) {
1941 viafb_mode1
= kstrdup(this_opt
+ 12, GFP_KERNEL
);
1942 } else if (!strncmp(this_opt
, "viafb_mode=", 11)) {
1943 viafb_mode
= kstrdup(this_opt
+ 11, GFP_KERNEL
);
1944 } else if (!strncmp(this_opt
, "viafb_bpp1=", 11)) {
1945 if (kstrtouint(this_opt
+ 11, 0, &viafb_bpp1
) < 0)
1947 } else if (!strncmp(this_opt
, "viafb_bpp=", 10)) {
1948 if (kstrtouint(this_opt
+ 10, 0, &viafb_bpp
) < 0)
1950 } else if (!strncmp(this_opt
, "viafb_refresh1=", 15)) {
1951 if (kstrtoint(this_opt
+ 15, 0, &viafb_refresh1
) < 0)
1953 } else if (!strncmp(this_opt
, "viafb_refresh=", 14)) {
1954 if (kstrtoint(this_opt
+ 14, 0, &viafb_refresh
) < 0)
1956 } else if (!strncmp(this_opt
, "viafb_lcd_dsp_method=", 21)) {
1957 if (kstrtoint(this_opt
+ 21, 0,
1958 &viafb_lcd_dsp_method
) < 0)
1960 } else if (!strncmp(this_opt
, "viafb_lcd_panel_id=", 19)) {
1961 if (kstrtoint(this_opt
+ 19, 0,
1962 &viafb_lcd_panel_id
) < 0)
1964 } else if (!strncmp(this_opt
, "viafb_accel=", 12)) {
1965 if (kstrtoint(this_opt
+ 12, 0, &viafb_accel
) < 0)
1967 } else if (!strncmp(this_opt
, "viafb_SAMM_ON=", 14)) {
1968 if (kstrtoint(this_opt
+ 14, 0, &viafb_SAMM_ON
) < 0)
1970 } else if (!strncmp(this_opt
, "viafb_active_dev=", 17)) {
1971 viafb_active_dev
= kstrdup(this_opt
+ 17, GFP_KERNEL
);
1972 } else if (!strncmp(this_opt
,
1973 "viafb_display_hardware_layout=", 30)) {
1974 if (kstrtoint(this_opt
+ 30, 0,
1975 &viafb_display_hardware_layout
) < 0)
1977 } else if (!strncmp(this_opt
, "viafb_second_size=", 18)) {
1978 if (kstrtoint(this_opt
+ 18, 0, &viafb_second_size
) < 0)
1980 } else if (!strncmp(this_opt
,
1981 "viafb_platform_epia_dvi=", 24)) {
1982 if (kstrtoint(this_opt
+ 24, 0,
1983 &viafb_platform_epia_dvi
) < 0)
1985 } else if (!strncmp(this_opt
,
1986 "viafb_device_lcd_dualedge=", 26)) {
1987 if (kstrtoint(this_opt
+ 26, 0,
1988 &viafb_device_lcd_dualedge
) < 0)
1990 } else if (!strncmp(this_opt
, "viafb_bus_width=", 16)) {
1991 if (kstrtoint(this_opt
+ 16, 0, &viafb_bus_width
) < 0)
1993 } else if (!strncmp(this_opt
, "viafb_lcd_mode=", 15)) {
1994 if (kstrtoint(this_opt
+ 15, 0, &viafb_lcd_mode
) < 0)
1996 } else if (!strncmp(this_opt
, "viafb_lcd_port=", 15)) {
1997 viafb_lcd_port
= kstrdup(this_opt
+ 15, GFP_KERNEL
);
1998 } else if (!strncmp(this_opt
, "viafb_dvi_port=", 15)) {
1999 viafb_dvi_port
= kstrdup(this_opt
+ 15, GFP_KERNEL
);
2007 * These are called out of via-core for now.
2009 int __init
viafb_init(void)
2011 u32 dummy_x
, dummy_y
;
2014 if (machine_is_olpc())
2015 /* Apply XO-1.5-specific configuration. */
2016 viafb_lcd_panel_id
= 23;
2023 if (parse_mode(viafb_mode
, 0, &dummy_x
, &dummy_y
)
2024 || !viafb_get_best_mode(dummy_x
, dummy_y
, viafb_refresh
)
2025 || parse_mode(viafb_mode1
, 0, &dummy_x
, &dummy_y
)
2026 || !viafb_get_best_mode(dummy_x
, dummy_y
, viafb_refresh1
)
2027 || viafb_bpp
< 0 || viafb_bpp
> 32
2028 || viafb_bpp1
< 0 || viafb_bpp1
> 32
2029 || parse_active_dev())
2033 "VIA Graphics Integration Chipset framebuffer %d.%d initializing\n",
2034 VERSION_MAJOR
, VERSION_MINOR
);
2038 void __exit
viafb_exit(void)
2040 DEBUG_MSG(KERN_INFO
"viafb_exit!\n");
2043 static struct fb_ops viafb_ops
= {
2044 .owner
= THIS_MODULE
,
2045 .fb_open
= viafb_open
,
2046 .fb_release
= viafb_release
,
2047 .fb_check_var
= viafb_check_var
,
2048 .fb_set_par
= viafb_set_par
,
2049 .fb_setcolreg
= viafb_setcolreg
,
2050 .fb_pan_display
= viafb_pan_display
,
2051 .fb_blank
= viafb_blank
,
2052 .fb_fillrect
= viafb_fillrect
,
2053 .fb_copyarea
= viafb_copyarea
,
2054 .fb_imageblit
= viafb_imageblit
,
2055 .fb_cursor
= viafb_cursor
,
2056 .fb_ioctl
= viafb_ioctl
,
2057 .fb_sync
= viafb_sync
,
2062 module_param(viafb_mode
, charp
, S_IRUSR
);
2063 MODULE_PARM_DESC(viafb_mode
, "Set resolution (default=640x480)");
2065 module_param(viafb_mode1
, charp
, S_IRUSR
);
2066 MODULE_PARM_DESC(viafb_mode1
, "Set resolution (default=640x480)");
2068 module_param(viafb_bpp
, int, S_IRUSR
);
2069 MODULE_PARM_DESC(viafb_bpp
, "Set color depth (default=32bpp)");
2071 module_param(viafb_bpp1
, int, S_IRUSR
);
2072 MODULE_PARM_DESC(viafb_bpp1
, "Set color depth (default=32bpp)");
2074 module_param(viafb_refresh
, int, S_IRUSR
);
2075 MODULE_PARM_DESC(viafb_refresh
,
2076 "Set CRT viafb_refresh rate (default = 60)");
2078 module_param(viafb_refresh1
, int, S_IRUSR
);
2079 MODULE_PARM_DESC(viafb_refresh1
,
2080 "Set CRT refresh rate (default = 60)");
2082 module_param(viafb_lcd_panel_id
, int, S_IRUSR
);
2083 MODULE_PARM_DESC(viafb_lcd_panel_id
,
2084 "Set Flat Panel type(Default=1024x768)");
2086 module_param(viafb_lcd_dsp_method
, int, S_IRUSR
);
2087 MODULE_PARM_DESC(viafb_lcd_dsp_method
,
2088 "Set Flat Panel display scaling method.(Default=Expansion)");
2090 module_param(viafb_SAMM_ON
, int, S_IRUSR
);
2091 MODULE_PARM_DESC(viafb_SAMM_ON
,
2092 "Turn on/off flag of SAMM(Default=OFF)");
2094 module_param(viafb_accel
, int, S_IRUSR
);
2095 MODULE_PARM_DESC(viafb_accel
,
2096 "Set 2D Hardware Acceleration: 0 = OFF, 1 = ON (default)");
2098 module_param(viafb_active_dev
, charp
, S_IRUSR
);
2099 MODULE_PARM_DESC(viafb_active_dev
, "Specify active devices.");
2101 module_param(viafb_display_hardware_layout
, int, S_IRUSR
);
2102 MODULE_PARM_DESC(viafb_display_hardware_layout
,
2103 "Display Hardware Layout (LCD Only, DVI Only...,etc)");
2105 module_param(viafb_second_size
, int, S_IRUSR
);
2106 MODULE_PARM_DESC(viafb_second_size
,
2107 "Set secondary device memory size");
2109 module_param(viafb_dual_fb
, int, S_IRUSR
);
2110 MODULE_PARM_DESC(viafb_dual_fb
,
2111 "Turn on/off flag of dual framebuffer devices.(Default = OFF)");
2113 module_param(viafb_platform_epia_dvi
, int, S_IRUSR
);
2114 MODULE_PARM_DESC(viafb_platform_epia_dvi
,
2115 "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)");
2117 module_param(viafb_device_lcd_dualedge
, int, S_IRUSR
);
2118 MODULE_PARM_DESC(viafb_device_lcd_dualedge
,
2119 "Turn on/off flag of dual edge panel.(Default = OFF)");
2121 module_param(viafb_bus_width
, int, S_IRUSR
);
2122 MODULE_PARM_DESC(viafb_bus_width
,
2123 "Set bus width of panel.(Default = 12)");
2125 module_param(viafb_lcd_mode
, int, S_IRUSR
);
2126 MODULE_PARM_DESC(viafb_lcd_mode
,
2127 "Set Flat Panel mode(Default=OPENLDI)");
2129 module_param(viafb_lcd_port
, charp
, S_IRUSR
);
2130 MODULE_PARM_DESC(viafb_lcd_port
, "Specify LCD output port.");
2132 module_param(viafb_dvi_port
, charp
, S_IRUSR
);
2133 MODULE_PARM_DESC(viafb_dvi_port
, "Specify DVI output port.");
2135 MODULE_LICENSE("GPL");