162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. 462306a36Sopenharmony_ci * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/compiler.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/seq_file.h> 1162306a36Sopenharmony_ci#include <linux/slab.h> 1262306a36Sopenharmony_ci#include <linux/stat.h> 1362306a36Sopenharmony_ci#include <linux/via-core.h> 1462306a36Sopenharmony_ci#include <linux/via_i2c.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define _MASTER_FILE 1762306a36Sopenharmony_ci#include "global.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic char *viafb_name = "Via"; 2062306a36Sopenharmony_cistatic u32 pseudo_pal[17]; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* video mode */ 2362306a36Sopenharmony_cistatic char *viafb_mode; 2462306a36Sopenharmony_cistatic char *viafb_mode1; 2562306a36Sopenharmony_cistatic int viafb_bpp = 32; 2662306a36Sopenharmony_cistatic int viafb_bpp1 = 32; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic unsigned int viafb_second_offset; 2962306a36Sopenharmony_cistatic int viafb_second_size; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic int viafb_accel = 1; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* Added for specifying active devices.*/ 3462306a36Sopenharmony_cistatic char *viafb_active_dev; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/*Added for specify lcd output port*/ 3762306a36Sopenharmony_cistatic char *viafb_lcd_port = ""; 3862306a36Sopenharmony_cistatic char *viafb_dvi_port = ""; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic void retrieve_device_setting(struct viafb_ioctl_setting 4162306a36Sopenharmony_ci *setting_info); 4262306a36Sopenharmony_cistatic int viafb_pan_display(struct fb_var_screeninfo *var, 4362306a36Sopenharmony_ci struct fb_info *info); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic struct fb_ops viafb_ops; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* supported output devices on each IGP 4862306a36Sopenharmony_ci * only CX700, VX800, VX855, VX900 were documented 4962306a36Sopenharmony_ci * VIA_CRT should be everywhere 5062306a36Sopenharmony_ci * VIA_6C can be onle pre-CX700 (probably only on CLE266) as 6C is used for PLL 5162306a36Sopenharmony_ci * source selection on CX700 and later 5262306a36Sopenharmony_ci * K400 seems to support VIA_96, VIA_DVP1, VIA_LVDS{1,2} as in viamode.c 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_cistatic const u32 supported_odev_map[] = { 5562306a36Sopenharmony_ci [UNICHROME_CLE266] = VIA_CRT | VIA_LDVP0 | VIA_LDVP1, 5662306a36Sopenharmony_ci [UNICHROME_K400] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 5762306a36Sopenharmony_ci | VIA_LVDS2, 5862306a36Sopenharmony_ci [UNICHROME_K800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 5962306a36Sopenharmony_ci | VIA_LVDS2, 6062306a36Sopenharmony_ci [UNICHROME_PM800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 6162306a36Sopenharmony_ci | VIA_LVDS2, 6262306a36Sopenharmony_ci [UNICHROME_CN700] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 6362306a36Sopenharmony_ci | VIA_LVDS2, 6462306a36Sopenharmony_ci [UNICHROME_CX700] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 6562306a36Sopenharmony_ci [UNICHROME_CN750] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 6662306a36Sopenharmony_ci [UNICHROME_K8M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 6762306a36Sopenharmony_ci [UNICHROME_P4M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 6862306a36Sopenharmony_ci [UNICHROME_P4M900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 6962306a36Sopenharmony_ci [UNICHROME_VX800] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 7062306a36Sopenharmony_ci [UNICHROME_VX855] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 7162306a36Sopenharmony_ci [UNICHROME_VX900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci var->grayscale = 0; 7762306a36Sopenharmony_ci var->red.msb_right = 0; 7862306a36Sopenharmony_ci var->green.msb_right = 0; 7962306a36Sopenharmony_ci var->blue.msb_right = 0; 8062306a36Sopenharmony_ci var->transp.offset = 0; 8162306a36Sopenharmony_ci var->transp.length = 0; 8262306a36Sopenharmony_ci var->transp.msb_right = 0; 8362306a36Sopenharmony_ci var->nonstd = 0; 8462306a36Sopenharmony_ci switch (depth) { 8562306a36Sopenharmony_ci case 8: 8662306a36Sopenharmony_ci var->bits_per_pixel = 8; 8762306a36Sopenharmony_ci var->red.offset = 0; 8862306a36Sopenharmony_ci var->green.offset = 0; 8962306a36Sopenharmony_ci var->blue.offset = 0; 9062306a36Sopenharmony_ci var->red.length = 8; 9162306a36Sopenharmony_ci var->green.length = 8; 9262306a36Sopenharmony_ci var->blue.length = 8; 9362306a36Sopenharmony_ci break; 9462306a36Sopenharmony_ci case 15: 9562306a36Sopenharmony_ci var->bits_per_pixel = 16; 9662306a36Sopenharmony_ci var->red.offset = 10; 9762306a36Sopenharmony_ci var->green.offset = 5; 9862306a36Sopenharmony_ci var->blue.offset = 0; 9962306a36Sopenharmony_ci var->red.length = 5; 10062306a36Sopenharmony_ci var->green.length = 5; 10162306a36Sopenharmony_ci var->blue.length = 5; 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci case 16: 10462306a36Sopenharmony_ci var->bits_per_pixel = 16; 10562306a36Sopenharmony_ci var->red.offset = 11; 10662306a36Sopenharmony_ci var->green.offset = 5; 10762306a36Sopenharmony_ci var->blue.offset = 0; 10862306a36Sopenharmony_ci var->red.length = 5; 10962306a36Sopenharmony_ci var->green.length = 6; 11062306a36Sopenharmony_ci var->blue.length = 5; 11162306a36Sopenharmony_ci break; 11262306a36Sopenharmony_ci case 24: 11362306a36Sopenharmony_ci var->bits_per_pixel = 32; 11462306a36Sopenharmony_ci var->red.offset = 16; 11562306a36Sopenharmony_ci var->green.offset = 8; 11662306a36Sopenharmony_ci var->blue.offset = 0; 11762306a36Sopenharmony_ci var->red.length = 8; 11862306a36Sopenharmony_ci var->green.length = 8; 11962306a36Sopenharmony_ci var->blue.length = 8; 12062306a36Sopenharmony_ci break; 12162306a36Sopenharmony_ci case 30: 12262306a36Sopenharmony_ci var->bits_per_pixel = 32; 12362306a36Sopenharmony_ci var->red.offset = 20; 12462306a36Sopenharmony_ci var->green.offset = 10; 12562306a36Sopenharmony_ci var->blue.offset = 0; 12662306a36Sopenharmony_ci var->red.length = 10; 12762306a36Sopenharmony_ci var->green.length = 10; 12862306a36Sopenharmony_ci var->blue.length = 10; 12962306a36Sopenharmony_ci break; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic void viafb_update_fix(struct fb_info *info) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci u32 bpp = info->var.bits_per_pixel; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci info->fix.visual = 13862306a36Sopenharmony_ci bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 13962306a36Sopenharmony_ci info->fix.line_length = ALIGN(info->var.xres_virtual * bpp / 8, 14062306a36Sopenharmony_ci VIA_PITCH_SIZE); 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, 14462306a36Sopenharmony_ci struct viafb_par *viaparinfo) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 14762306a36Sopenharmony_ci strcpy(fix->id, viafb_name); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci fix->smem_start = viaparinfo->fbmem; 15062306a36Sopenharmony_ci fix->smem_len = viaparinfo->fbmem_free; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci fix->type = FB_TYPE_PACKED_PIXELS; 15362306a36Sopenharmony_ci fix->type_aux = 0; 15462306a36Sopenharmony_ci fix->visual = FB_VISUAL_TRUECOLOR; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci fix->xpanstep = fix->ywrapstep = 0; 15762306a36Sopenharmony_ci fix->ypanstep = 1; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci /* Just tell the accel name */ 16062306a36Sopenharmony_ci viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME; 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_cistatic int viafb_open(struct fb_info *info, int user) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_open!\n"); 16562306a36Sopenharmony_ci return 0; 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic int viafb_release(struct fb_info *info, int user) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_release!\n"); 17162306a36Sopenharmony_ci return 0; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic inline int get_var_refresh(struct fb_var_screeninfo *var) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci u32 htotal, vtotal; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci htotal = var->left_margin + var->xres + var->right_margin 17962306a36Sopenharmony_ci + var->hsync_len; 18062306a36Sopenharmony_ci vtotal = var->upper_margin + var->yres + var->lower_margin 18162306a36Sopenharmony_ci + var->vsync_len; 18262306a36Sopenharmony_ci return PICOS2KHZ(var->pixclock) * 1000 / (htotal * vtotal); 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic int viafb_check_var(struct fb_var_screeninfo *var, 18662306a36Sopenharmony_ci struct fb_info *info) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci int depth, refresh; 18962306a36Sopenharmony_ci struct viafb_par *ppar = info->par; 19062306a36Sopenharmony_ci u32 line; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); 19362306a36Sopenharmony_ci /* Sanity check */ 19462306a36Sopenharmony_ci /* HW neither support interlacte nor double-scaned mode */ 19562306a36Sopenharmony_ci if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) 19662306a36Sopenharmony_ci return -EINVAL; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci /* the refresh rate is not important here, as we only want to know 19962306a36Sopenharmony_ci * whether the resolution exists 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_ci if (!viafb_get_best_mode(var->xres, var->yres, 60)) { 20262306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO 20362306a36Sopenharmony_ci "viafb: Mode %dx%dx%d not supported!!\n", 20462306a36Sopenharmony_ci var->xres, var->yres, var->bits_per_pixel); 20562306a36Sopenharmony_ci return -EINVAL; 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci depth = fb_get_color_depth(var, &info->fix); 20962306a36Sopenharmony_ci if (!depth) 21062306a36Sopenharmony_ci depth = var->bits_per_pixel; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (depth < 0 || depth > 32) 21362306a36Sopenharmony_ci return -EINVAL; 21462306a36Sopenharmony_ci else if (!depth) 21562306a36Sopenharmony_ci depth = 24; 21662306a36Sopenharmony_ci else if (depth == 15 && viafb_dual_fb && ppar->iga_path == IGA1) 21762306a36Sopenharmony_ci depth = 15; 21862306a36Sopenharmony_ci else if (depth == 30) 21962306a36Sopenharmony_ci depth = 30; 22062306a36Sopenharmony_ci else if (depth <= 8) 22162306a36Sopenharmony_ci depth = 8; 22262306a36Sopenharmony_ci else if (depth <= 16) 22362306a36Sopenharmony_ci depth = 16; 22462306a36Sopenharmony_ci else 22562306a36Sopenharmony_ci depth = 24; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci viafb_fill_var_color_info(var, depth); 22862306a36Sopenharmony_ci if (var->xres_virtual < var->xres) 22962306a36Sopenharmony_ci var->xres_virtual = var->xres; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci line = ALIGN(var->xres_virtual * var->bits_per_pixel / 8, 23262306a36Sopenharmony_ci VIA_PITCH_SIZE); 23362306a36Sopenharmony_ci if (line > VIA_PITCH_MAX || line * var->yres_virtual > ppar->memsize) 23462306a36Sopenharmony_ci return -EINVAL; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci /* Based on var passed in to calculate the refresh, 23762306a36Sopenharmony_ci * because our driver use some modes special. 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_ci refresh = viafb_get_refresh(var->xres, var->yres, 24062306a36Sopenharmony_ci get_var_refresh(var)); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci /* Adjust var according to our driver's own table */ 24362306a36Sopenharmony_ci viafb_fill_var_timing_info(var, 24462306a36Sopenharmony_ci viafb_get_best_mode(var->xres, var->yres, refresh)); 24562306a36Sopenharmony_ci if (var->accel_flags & FB_ACCELF_TEXT && 24662306a36Sopenharmony_ci !ppar->shared->vdev->engine_mmio) 24762306a36Sopenharmony_ci var->accel_flags = 0; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci return 0; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic int viafb_set_par(struct fb_info *info) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 25562306a36Sopenharmony_ci int refresh; 25662306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci viafb_update_fix(info); 25962306a36Sopenharmony_ci viapar->depth = fb_get_color_depth(&info->var, &info->fix); 26062306a36Sopenharmony_ci viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 26162306a36Sopenharmony_ci viafbinfo->var.bits_per_pixel, 0); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (viafb_dual_fb) { 26462306a36Sopenharmony_ci viafb_update_device_setting(viafbinfo1->var.xres, 26562306a36Sopenharmony_ci viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, 26662306a36Sopenharmony_ci 1); 26762306a36Sopenharmony_ci } else if (viafb_SAMM_ON == 1) { 26862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO 26962306a36Sopenharmony_ci "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", 27062306a36Sopenharmony_ci viafb_second_xres, viafb_second_yres, viafb_bpp1); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci viafb_update_device_setting(viafb_second_xres, 27362306a36Sopenharmony_ci viafb_second_yres, viafb_bpp1, 1); 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci refresh = get_var_refresh(&info->var); 27762306a36Sopenharmony_ci if (viafb_dual_fb && viapar->iga_path == IGA2) { 27862306a36Sopenharmony_ci viafb_bpp1 = info->var.bits_per_pixel; 27962306a36Sopenharmony_ci viafb_refresh1 = refresh; 28062306a36Sopenharmony_ci } else { 28162306a36Sopenharmony_ci viafb_bpp = info->var.bits_per_pixel; 28262306a36Sopenharmony_ci viafb_refresh = refresh; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (info->var.accel_flags & FB_ACCELF_TEXT) 28662306a36Sopenharmony_ci info->flags &= ~FBINFO_HWACCEL_DISABLED; 28762306a36Sopenharmony_ci else 28862306a36Sopenharmony_ci info->flags |= FBINFO_HWACCEL_DISABLED; 28962306a36Sopenharmony_ci viafb_setmode(); 29062306a36Sopenharmony_ci viafb_pan_display(&info->var, info); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci return 0; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/* Set one color register */ 29662306a36Sopenharmony_cistatic int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, 29762306a36Sopenharmony_ciunsigned blue, unsigned transp, struct fb_info *info) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 30062306a36Sopenharmony_ci u32 r, g, b; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { 30362306a36Sopenharmony_ci if (regno > 255) 30462306a36Sopenharmony_ci return -EINVAL; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci if (!viafb_dual_fb || viapar->iga_path == IGA1) 30762306a36Sopenharmony_ci viafb_set_primary_color_register(regno, red >> 8, 30862306a36Sopenharmony_ci green >> 8, blue >> 8); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci if (!viafb_dual_fb || viapar->iga_path == IGA2) 31162306a36Sopenharmony_ci viafb_set_secondary_color_register(regno, red >> 8, 31262306a36Sopenharmony_ci green >> 8, blue >> 8); 31362306a36Sopenharmony_ci } else { 31462306a36Sopenharmony_ci if (regno > 15) 31562306a36Sopenharmony_ci return -EINVAL; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci r = (red >> (16 - info->var.red.length)) 31862306a36Sopenharmony_ci << info->var.red.offset; 31962306a36Sopenharmony_ci b = (blue >> (16 - info->var.blue.length)) 32062306a36Sopenharmony_ci << info->var.blue.offset; 32162306a36Sopenharmony_ci g = (green >> (16 - info->var.green.length)) 32262306a36Sopenharmony_ci << info->var.green.offset; 32362306a36Sopenharmony_ci ((u32 *) info->pseudo_palette)[regno] = r | g | b; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci return 0; 32762306a36Sopenharmony_ci} 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_cistatic int viafb_pan_display(struct fb_var_screeninfo *var, 33062306a36Sopenharmony_ci struct fb_info *info) 33162306a36Sopenharmony_ci{ 33262306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 33362306a36Sopenharmony_ci u32 vram_addr = viapar->vram_addr 33462306a36Sopenharmony_ci + var->yoffset * info->fix.line_length 33562306a36Sopenharmony_ci + var->xoffset * info->var.bits_per_pixel / 8; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr); 33862306a36Sopenharmony_ci if (!viafb_dual_fb) { 33962306a36Sopenharmony_ci via_set_primary_address(vram_addr); 34062306a36Sopenharmony_ci via_set_secondary_address(vram_addr); 34162306a36Sopenharmony_ci } else if (viapar->iga_path == IGA1) 34262306a36Sopenharmony_ci via_set_primary_address(vram_addr); 34362306a36Sopenharmony_ci else 34462306a36Sopenharmony_ci via_set_secondary_address(vram_addr); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci return 0; 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic int viafb_blank(int blank_mode, struct fb_info *info) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_blank!\n"); 35262306a36Sopenharmony_ci /* clear DPMS setting */ 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci switch (blank_mode) { 35562306a36Sopenharmony_ci case FB_BLANK_UNBLANK: 35662306a36Sopenharmony_ci /* Screen: On, HSync: On, VSync: On */ 35762306a36Sopenharmony_ci /* control CRT monitor power management */ 35862306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_ON); 35962306a36Sopenharmony_ci break; 36062306a36Sopenharmony_ci case FB_BLANK_HSYNC_SUSPEND: 36162306a36Sopenharmony_ci /* Screen: Off, HSync: Off, VSync: On */ 36262306a36Sopenharmony_ci /* control CRT monitor power management */ 36362306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_STANDBY); 36462306a36Sopenharmony_ci break; 36562306a36Sopenharmony_ci case FB_BLANK_VSYNC_SUSPEND: 36662306a36Sopenharmony_ci /* Screen: Off, HSync: On, VSync: Off */ 36762306a36Sopenharmony_ci /* control CRT monitor power management */ 36862306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_SUSPEND); 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci case FB_BLANK_POWERDOWN: 37162306a36Sopenharmony_ci /* Screen: Off, HSync: Off, VSync: Off */ 37262306a36Sopenharmony_ci /* control CRT monitor power management */ 37362306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_OFF); 37462306a36Sopenharmony_ci break; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci return 0; 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci union { 38362306a36Sopenharmony_ci struct viafb_ioctl_mode viamode; 38462306a36Sopenharmony_ci struct viafb_ioctl_samm viasamm; 38562306a36Sopenharmony_ci struct viafb_driver_version driver_version; 38662306a36Sopenharmony_ci struct fb_var_screeninfo sec_var; 38762306a36Sopenharmony_ci struct _panel_size_pos_info panel_pos_size_para; 38862306a36Sopenharmony_ci struct viafb_ioctl_setting viafb_setting; 38962306a36Sopenharmony_ci struct device_t active_dev; 39062306a36Sopenharmony_ci } u; 39162306a36Sopenharmony_ci u32 state_info = 0; 39262306a36Sopenharmony_ci u32 *viafb_gamma_table; 39362306a36Sopenharmony_ci char driver_name[] = "viafb"; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci u32 __user *argp = (u32 __user *) arg; 39662306a36Sopenharmony_ci u32 gpu32; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); 39962306a36Sopenharmony_ci printk(KERN_WARNING "viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n"); 40062306a36Sopenharmony_ci memset(&u, 0, sizeof(u)); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci switch (cmd) { 40362306a36Sopenharmony_ci case VIAFB_GET_CHIP_INFO: 40462306a36Sopenharmony_ci if (copy_to_user(argp, viaparinfo->chip_info, 40562306a36Sopenharmony_ci sizeof(struct chip_information))) 40662306a36Sopenharmony_ci return -EFAULT; 40762306a36Sopenharmony_ci break; 40862306a36Sopenharmony_ci case VIAFB_GET_INFO_SIZE: 40962306a36Sopenharmony_ci return put_user((u32)sizeof(struct viafb_ioctl_info), argp); 41062306a36Sopenharmony_ci case VIAFB_GET_INFO: 41162306a36Sopenharmony_ci return viafb_ioctl_get_viafb_info(arg); 41262306a36Sopenharmony_ci case VIAFB_HOTPLUG: 41362306a36Sopenharmony_ci return put_user(viafb_ioctl_hotplug(info->var.xres, 41462306a36Sopenharmony_ci info->var.yres, 41562306a36Sopenharmony_ci info->var.bits_per_pixel), argp); 41662306a36Sopenharmony_ci case VIAFB_SET_HOTPLUG_FLAG: 41762306a36Sopenharmony_ci if (copy_from_user(&gpu32, argp, sizeof(gpu32))) 41862306a36Sopenharmony_ci return -EFAULT; 41962306a36Sopenharmony_ci viafb_hotplug = (gpu32) ? 1 : 0; 42062306a36Sopenharmony_ci break; 42162306a36Sopenharmony_ci case VIAFB_GET_RESOLUTION: 42262306a36Sopenharmony_ci u.viamode.xres = (u32) viafb_hotplug_Xres; 42362306a36Sopenharmony_ci u.viamode.yres = (u32) viafb_hotplug_Yres; 42462306a36Sopenharmony_ci u.viamode.refresh = (u32) viafb_hotplug_refresh; 42562306a36Sopenharmony_ci u.viamode.bpp = (u32) viafb_hotplug_bpp; 42662306a36Sopenharmony_ci if (viafb_SAMM_ON == 1) { 42762306a36Sopenharmony_ci u.viamode.xres_sec = viafb_second_xres; 42862306a36Sopenharmony_ci u.viamode.yres_sec = viafb_second_yres; 42962306a36Sopenharmony_ci u.viamode.virtual_xres_sec = viafb_dual_fb ? viafbinfo1->var.xres_virtual : viafbinfo->var.xres_virtual; 43062306a36Sopenharmony_ci u.viamode.virtual_yres_sec = viafb_dual_fb ? viafbinfo1->var.yres_virtual : viafbinfo->var.yres_virtual; 43162306a36Sopenharmony_ci u.viamode.refresh_sec = viafb_refresh1; 43262306a36Sopenharmony_ci u.viamode.bpp_sec = viafb_bpp1; 43362306a36Sopenharmony_ci } else { 43462306a36Sopenharmony_ci u.viamode.xres_sec = 0; 43562306a36Sopenharmony_ci u.viamode.yres_sec = 0; 43662306a36Sopenharmony_ci u.viamode.virtual_xres_sec = 0; 43762306a36Sopenharmony_ci u.viamode.virtual_yres_sec = 0; 43862306a36Sopenharmony_ci u.viamode.refresh_sec = 0; 43962306a36Sopenharmony_ci u.viamode.bpp_sec = 0; 44062306a36Sopenharmony_ci } 44162306a36Sopenharmony_ci if (copy_to_user(argp, &u.viamode, sizeof(u.viamode))) 44262306a36Sopenharmony_ci return -EFAULT; 44362306a36Sopenharmony_ci break; 44462306a36Sopenharmony_ci case VIAFB_GET_SAMM_INFO: 44562306a36Sopenharmony_ci u.viasamm.samm_status = viafb_SAMM_ON; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci if (viafb_SAMM_ON == 1) { 44862306a36Sopenharmony_ci if (viafb_dual_fb) { 44962306a36Sopenharmony_ci u.viasamm.size_prim = viaparinfo->fbmem_free; 45062306a36Sopenharmony_ci u.viasamm.size_sec = viaparinfo1->fbmem_free; 45162306a36Sopenharmony_ci } else { 45262306a36Sopenharmony_ci if (viafb_second_size) { 45362306a36Sopenharmony_ci u.viasamm.size_prim = 45462306a36Sopenharmony_ci viaparinfo->fbmem_free - 45562306a36Sopenharmony_ci viafb_second_size * 1024 * 1024; 45662306a36Sopenharmony_ci u.viasamm.size_sec = 45762306a36Sopenharmony_ci viafb_second_size * 1024 * 1024; 45862306a36Sopenharmony_ci } else { 45962306a36Sopenharmony_ci u.viasamm.size_prim = 46062306a36Sopenharmony_ci viaparinfo->fbmem_free >> 1; 46162306a36Sopenharmony_ci u.viasamm.size_sec = 46262306a36Sopenharmony_ci (viaparinfo->fbmem_free >> 1); 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci } 46562306a36Sopenharmony_ci u.viasamm.mem_base = viaparinfo->fbmem; 46662306a36Sopenharmony_ci u.viasamm.offset_sec = viafb_second_offset; 46762306a36Sopenharmony_ci } else { 46862306a36Sopenharmony_ci u.viasamm.size_prim = 46962306a36Sopenharmony_ci viaparinfo->memsize - viaparinfo->fbmem_used; 47062306a36Sopenharmony_ci u.viasamm.size_sec = 0; 47162306a36Sopenharmony_ci u.viasamm.mem_base = viaparinfo->fbmem; 47262306a36Sopenharmony_ci u.viasamm.offset_sec = 0; 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci if (copy_to_user(argp, &u.viasamm, sizeof(u.viasamm))) 47662306a36Sopenharmony_ci return -EFAULT; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci break; 47962306a36Sopenharmony_ci case VIAFB_TURN_ON_OUTPUT_DEVICE: 48062306a36Sopenharmony_ci if (copy_from_user(&gpu32, argp, sizeof(gpu32))) 48162306a36Sopenharmony_ci return -EFAULT; 48262306a36Sopenharmony_ci if (gpu32 & CRT_Device) 48362306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_ON); 48462306a36Sopenharmony_ci if (gpu32 & DVI_Device) 48562306a36Sopenharmony_ci viafb_dvi_enable(); 48662306a36Sopenharmony_ci if (gpu32 & LCD_Device) 48762306a36Sopenharmony_ci viafb_lcd_enable(); 48862306a36Sopenharmony_ci break; 48962306a36Sopenharmony_ci case VIAFB_TURN_OFF_OUTPUT_DEVICE: 49062306a36Sopenharmony_ci if (copy_from_user(&gpu32, argp, sizeof(gpu32))) 49162306a36Sopenharmony_ci return -EFAULT; 49262306a36Sopenharmony_ci if (gpu32 & CRT_Device) 49362306a36Sopenharmony_ci via_set_state(VIA_CRT, VIA_STATE_OFF); 49462306a36Sopenharmony_ci if (gpu32 & DVI_Device) 49562306a36Sopenharmony_ci viafb_dvi_disable(); 49662306a36Sopenharmony_ci if (gpu32 & LCD_Device) 49762306a36Sopenharmony_ci viafb_lcd_disable(); 49862306a36Sopenharmony_ci break; 49962306a36Sopenharmony_ci case VIAFB_GET_DEVICE: 50062306a36Sopenharmony_ci u.active_dev.crt = viafb_CRT_ON; 50162306a36Sopenharmony_ci u.active_dev.dvi = viafb_DVI_ON; 50262306a36Sopenharmony_ci u.active_dev.lcd = viafb_LCD_ON; 50362306a36Sopenharmony_ci u.active_dev.samm = viafb_SAMM_ON; 50462306a36Sopenharmony_ci u.active_dev.primary_dev = viafb_primary_dev; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci u.active_dev.lcd_dsp_cent = viafb_lcd_dsp_method; 50762306a36Sopenharmony_ci u.active_dev.lcd_panel_id = viafb_lcd_panel_id; 50862306a36Sopenharmony_ci u.active_dev.lcd_mode = viafb_lcd_mode; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci u.active_dev.xres = viafb_hotplug_Xres; 51162306a36Sopenharmony_ci u.active_dev.yres = viafb_hotplug_Yres; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci u.active_dev.xres1 = viafb_second_xres; 51462306a36Sopenharmony_ci u.active_dev.yres1 = viafb_second_yres; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci u.active_dev.bpp = viafb_bpp; 51762306a36Sopenharmony_ci u.active_dev.bpp1 = viafb_bpp1; 51862306a36Sopenharmony_ci u.active_dev.refresh = viafb_refresh; 51962306a36Sopenharmony_ci u.active_dev.refresh1 = viafb_refresh1; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci u.active_dev.epia_dvi = viafb_platform_epia_dvi; 52262306a36Sopenharmony_ci u.active_dev.lcd_dual_edge = viafb_device_lcd_dualedge; 52362306a36Sopenharmony_ci u.active_dev.bus_width = viafb_bus_width; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci if (copy_to_user(argp, &u.active_dev, sizeof(u.active_dev))) 52662306a36Sopenharmony_ci return -EFAULT; 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci case VIAFB_GET_DRIVER_VERSION: 53062306a36Sopenharmony_ci u.driver_version.iMajorNum = VERSION_MAJOR; 53162306a36Sopenharmony_ci u.driver_version.iKernelNum = VERSION_KERNEL; 53262306a36Sopenharmony_ci u.driver_version.iOSNum = VERSION_OS; 53362306a36Sopenharmony_ci u.driver_version.iMinorNum = VERSION_MINOR; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci if (copy_to_user(argp, &u.driver_version, 53662306a36Sopenharmony_ci sizeof(u.driver_version))) 53762306a36Sopenharmony_ci return -EFAULT; 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci break; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci case VIAFB_GET_DEVICE_INFO: 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci retrieve_device_setting(&u.viafb_setting); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci if (copy_to_user(argp, &u.viafb_setting, 54662306a36Sopenharmony_ci sizeof(u.viafb_setting))) 54762306a36Sopenharmony_ci return -EFAULT; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci break; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci case VIAFB_GET_DEVICE_SUPPORT: 55262306a36Sopenharmony_ci viafb_get_device_support_state(&state_info); 55362306a36Sopenharmony_ci if (put_user(state_info, argp)) 55462306a36Sopenharmony_ci return -EFAULT; 55562306a36Sopenharmony_ci break; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci case VIAFB_GET_DEVICE_CONNECT: 55862306a36Sopenharmony_ci viafb_get_device_connect_state(&state_info); 55962306a36Sopenharmony_ci if (put_user(state_info, argp)) 56062306a36Sopenharmony_ci return -EFAULT; 56162306a36Sopenharmony_ci break; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci case VIAFB_GET_PANEL_SUPPORT_EXPAND: 56462306a36Sopenharmony_ci state_info = 56562306a36Sopenharmony_ci viafb_lcd_get_support_expand_state(info->var.xres, 56662306a36Sopenharmony_ci info->var.yres); 56762306a36Sopenharmony_ci if (put_user(state_info, argp)) 56862306a36Sopenharmony_ci return -EFAULT; 56962306a36Sopenharmony_ci break; 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci case VIAFB_GET_DRIVER_NAME: 57262306a36Sopenharmony_ci if (copy_to_user(argp, driver_name, sizeof(driver_name))) 57362306a36Sopenharmony_ci return -EFAULT; 57462306a36Sopenharmony_ci break; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci case VIAFB_SET_GAMMA_LUT: 57762306a36Sopenharmony_ci viafb_gamma_table = memdup_user(argp, 256 * sizeof(u32)); 57862306a36Sopenharmony_ci if (IS_ERR(viafb_gamma_table)) 57962306a36Sopenharmony_ci return PTR_ERR(viafb_gamma_table); 58062306a36Sopenharmony_ci viafb_set_gamma_table(viafb_bpp, viafb_gamma_table); 58162306a36Sopenharmony_ci kfree(viafb_gamma_table); 58262306a36Sopenharmony_ci break; 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci case VIAFB_GET_GAMMA_LUT: 58562306a36Sopenharmony_ci viafb_gamma_table = kmalloc_array(256, sizeof(u32), 58662306a36Sopenharmony_ci GFP_KERNEL); 58762306a36Sopenharmony_ci if (!viafb_gamma_table) 58862306a36Sopenharmony_ci return -ENOMEM; 58962306a36Sopenharmony_ci viafb_get_gamma_table(viafb_gamma_table); 59062306a36Sopenharmony_ci if (copy_to_user(argp, viafb_gamma_table, 59162306a36Sopenharmony_ci 256 * sizeof(u32))) { 59262306a36Sopenharmony_ci kfree(viafb_gamma_table); 59362306a36Sopenharmony_ci return -EFAULT; 59462306a36Sopenharmony_ci } 59562306a36Sopenharmony_ci kfree(viafb_gamma_table); 59662306a36Sopenharmony_ci break; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci case VIAFB_GET_GAMMA_SUPPORT_STATE: 59962306a36Sopenharmony_ci viafb_get_gamma_support_state(viafb_bpp, &state_info); 60062306a36Sopenharmony_ci if (put_user(state_info, argp)) 60162306a36Sopenharmony_ci return -EFAULT; 60262306a36Sopenharmony_ci break; 60362306a36Sopenharmony_ci case VIAFB_SYNC_SURFACE: 60462306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci case VIAFB_GET_DRIVER_CAPS: 60762306a36Sopenharmony_ci break; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci case VIAFB_GET_PANEL_MAX_SIZE: 61062306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 61162306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 61262306a36Sopenharmony_ci return -EFAULT; 61362306a36Sopenharmony_ci u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; 61462306a36Sopenharmony_ci if (copy_to_user(argp, &u.panel_pos_size_para, 61562306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 61662306a36Sopenharmony_ci return -EFAULT; 61762306a36Sopenharmony_ci break; 61862306a36Sopenharmony_ci case VIAFB_GET_PANEL_MAX_POSITION: 61962306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 62062306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 62162306a36Sopenharmony_ci return -EFAULT; 62262306a36Sopenharmony_ci u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; 62362306a36Sopenharmony_ci if (copy_to_user(argp, &u.panel_pos_size_para, 62462306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 62562306a36Sopenharmony_ci return -EFAULT; 62662306a36Sopenharmony_ci break; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci case VIAFB_GET_PANEL_POSITION: 62962306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 63062306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 63162306a36Sopenharmony_ci return -EFAULT; 63262306a36Sopenharmony_ci u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; 63362306a36Sopenharmony_ci if (copy_to_user(argp, &u.panel_pos_size_para, 63462306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 63562306a36Sopenharmony_ci return -EFAULT; 63662306a36Sopenharmony_ci break; 63762306a36Sopenharmony_ci case VIAFB_GET_PANEL_SIZE: 63862306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 63962306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 64062306a36Sopenharmony_ci return -EFAULT; 64162306a36Sopenharmony_ci u.panel_pos_size_para.x = u.panel_pos_size_para.y = 0; 64262306a36Sopenharmony_ci if (copy_to_user(argp, &u.panel_pos_size_para, 64362306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 64462306a36Sopenharmony_ci return -EFAULT; 64562306a36Sopenharmony_ci break; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci case VIAFB_SET_PANEL_POSITION: 64862306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 64962306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 65062306a36Sopenharmony_ci return -EFAULT; 65162306a36Sopenharmony_ci break; 65262306a36Sopenharmony_ci case VIAFB_SET_PANEL_SIZE: 65362306a36Sopenharmony_ci if (copy_from_user(&u.panel_pos_size_para, argp, 65462306a36Sopenharmony_ci sizeof(u.panel_pos_size_para))) 65562306a36Sopenharmony_ci return -EFAULT; 65662306a36Sopenharmony_ci break; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci default: 65962306a36Sopenharmony_ci return -EINVAL; 66062306a36Sopenharmony_ci } 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci return 0; 66362306a36Sopenharmony_ci} 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_cistatic void viafb_fillrect(struct fb_info *info, 66662306a36Sopenharmony_ci const struct fb_fillrect *rect) 66762306a36Sopenharmony_ci{ 66862306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 66962306a36Sopenharmony_ci struct viafb_shared *shared = viapar->shared; 67062306a36Sopenharmony_ci u32 fg_color; 67162306a36Sopenharmony_ci u8 rop; 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { 67462306a36Sopenharmony_ci cfb_fillrect(info, rect); 67562306a36Sopenharmony_ci return; 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci if (!rect->width || !rect->height) 67962306a36Sopenharmony_ci return; 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci if (info->fix.visual == FB_VISUAL_TRUECOLOR) 68262306a36Sopenharmony_ci fg_color = ((u32 *)info->pseudo_palette)[rect->color]; 68362306a36Sopenharmony_ci else 68462306a36Sopenharmony_ci fg_color = rect->color; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci if (rect->rop == ROP_XOR) 68762306a36Sopenharmony_ci rop = 0x5A; 68862306a36Sopenharmony_ci else 68962306a36Sopenharmony_ci rop = 0xF0; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); 69262306a36Sopenharmony_ci if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_FILL, 69362306a36Sopenharmony_ci rect->width, rect->height, info->var.bits_per_pixel, 69462306a36Sopenharmony_ci viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, 69562306a36Sopenharmony_ci NULL, 0, 0, 0, 0, fg_color, 0, rop)) 69662306a36Sopenharmony_ci cfb_fillrect(info, rect); 69762306a36Sopenharmony_ci} 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_cistatic void viafb_copyarea(struct fb_info *info, 70062306a36Sopenharmony_ci const struct fb_copyarea *area) 70162306a36Sopenharmony_ci{ 70262306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 70362306a36Sopenharmony_ci struct viafb_shared *shared = viapar->shared; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { 70662306a36Sopenharmony_ci cfb_copyarea(info, area); 70762306a36Sopenharmony_ci return; 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci if (!area->width || !area->height) 71162306a36Sopenharmony_ci return; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); 71462306a36Sopenharmony_ci if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_COLOR, 71562306a36Sopenharmony_ci area->width, area->height, info->var.bits_per_pixel, 71662306a36Sopenharmony_ci viapar->vram_addr, info->fix.line_length, area->dx, area->dy, 71762306a36Sopenharmony_ci NULL, viapar->vram_addr, info->fix.line_length, 71862306a36Sopenharmony_ci area->sx, area->sy, 0, 0, 0)) 71962306a36Sopenharmony_ci cfb_copyarea(info, area); 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_cistatic void viafb_imageblit(struct fb_info *info, 72362306a36Sopenharmony_ci const struct fb_image *image) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 72662306a36Sopenharmony_ci struct viafb_shared *shared = viapar->shared; 72762306a36Sopenharmony_ci u32 fg_color = 0, bg_color = 0; 72862306a36Sopenharmony_ci u8 op; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt || 73162306a36Sopenharmony_ci (image->depth != 1 && image->depth != viapar->depth)) { 73262306a36Sopenharmony_ci cfb_imageblit(info, image); 73362306a36Sopenharmony_ci return; 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci if (image->depth == 1) { 73762306a36Sopenharmony_ci op = VIA_BITBLT_MONO; 73862306a36Sopenharmony_ci if (info->fix.visual == FB_VISUAL_TRUECOLOR) { 73962306a36Sopenharmony_ci fg_color = 74062306a36Sopenharmony_ci ((u32 *)info->pseudo_palette)[image->fg_color]; 74162306a36Sopenharmony_ci bg_color = 74262306a36Sopenharmony_ci ((u32 *)info->pseudo_palette)[image->bg_color]; 74362306a36Sopenharmony_ci } else { 74462306a36Sopenharmony_ci fg_color = image->fg_color; 74562306a36Sopenharmony_ci bg_color = image->bg_color; 74662306a36Sopenharmony_ci } 74762306a36Sopenharmony_ci } else 74862306a36Sopenharmony_ci op = VIA_BITBLT_COLOR; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); 75162306a36Sopenharmony_ci if (shared->hw_bitblt(shared->vdev->engine_mmio, op, 75262306a36Sopenharmony_ci image->width, image->height, info->var.bits_per_pixel, 75362306a36Sopenharmony_ci viapar->vram_addr, info->fix.line_length, image->dx, image->dy, 75462306a36Sopenharmony_ci (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) 75562306a36Sopenharmony_ci cfb_imageblit(info, image); 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_cistatic int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 75962306a36Sopenharmony_ci{ 76062306a36Sopenharmony_ci struct viafb_par *viapar = info->par; 76162306a36Sopenharmony_ci void __iomem *engine = viapar->shared->vdev->engine_mmio; 76262306a36Sopenharmony_ci u32 temp, xx, yy, bg_color = 0, fg_color = 0, 76362306a36Sopenharmony_ci chip_name = viapar->shared->chip_info.gfx_chip_name; 76462306a36Sopenharmony_ci int i, j = 0, cur_size = 64; 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) 76762306a36Sopenharmony_ci return -ENODEV; 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci /* LCD ouput does not support hw cursors (at least on VN896) */ 77062306a36Sopenharmony_ci if ((chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) || 77162306a36Sopenharmony_ci viafb_LCD_ON) 77262306a36Sopenharmony_ci return -ENODEV; 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci viafb_show_hw_cursor(info, HW_Cursor_OFF); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci if (cursor->set & FB_CUR_SETHOT) { 77762306a36Sopenharmony_ci temp = (cursor->hot.x << 16) + cursor->hot.y; 77862306a36Sopenharmony_ci writel(temp, engine + VIA_REG_CURSOR_ORG); 77962306a36Sopenharmony_ci } 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci if (cursor->set & FB_CUR_SETPOS) { 78262306a36Sopenharmony_ci yy = cursor->image.dy - info->var.yoffset; 78362306a36Sopenharmony_ci xx = cursor->image.dx - info->var.xoffset; 78462306a36Sopenharmony_ci temp = yy & 0xFFFF; 78562306a36Sopenharmony_ci temp |= (xx << 16); 78662306a36Sopenharmony_ci writel(temp, engine + VIA_REG_CURSOR_POS); 78762306a36Sopenharmony_ci } 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci if (cursor->image.width <= 32 && cursor->image.height <= 32) 79062306a36Sopenharmony_ci cur_size = 32; 79162306a36Sopenharmony_ci else if (cursor->image.width <= 64 && cursor->image.height <= 64) 79262306a36Sopenharmony_ci cur_size = 64; 79362306a36Sopenharmony_ci else { 79462306a36Sopenharmony_ci printk(KERN_WARNING "viafb_cursor: The cursor is too large " 79562306a36Sopenharmony_ci "%dx%d", cursor->image.width, cursor->image.height); 79662306a36Sopenharmony_ci return -ENXIO; 79762306a36Sopenharmony_ci } 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci if (cursor->set & FB_CUR_SETSIZE) { 80062306a36Sopenharmony_ci temp = readl(engine + VIA_REG_CURSOR_MODE); 80162306a36Sopenharmony_ci if (cur_size == 32) 80262306a36Sopenharmony_ci temp |= 0x2; 80362306a36Sopenharmony_ci else 80462306a36Sopenharmony_ci temp &= ~0x2; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci writel(temp, engine + VIA_REG_CURSOR_MODE); 80762306a36Sopenharmony_ci } 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci if (cursor->set & FB_CUR_SETCMAP) { 81062306a36Sopenharmony_ci fg_color = cursor->image.fg_color; 81162306a36Sopenharmony_ci bg_color = cursor->image.bg_color; 81262306a36Sopenharmony_ci if (chip_name == UNICHROME_CX700 || 81362306a36Sopenharmony_ci chip_name == UNICHROME_VX800 || 81462306a36Sopenharmony_ci chip_name == UNICHROME_VX855 || 81562306a36Sopenharmony_ci chip_name == UNICHROME_VX900) { 81662306a36Sopenharmony_ci fg_color = 81762306a36Sopenharmony_ci ((info->cmap.red[fg_color] & 0xFFC0) << 14) | 81862306a36Sopenharmony_ci ((info->cmap.green[fg_color] & 0xFFC0) << 4) | 81962306a36Sopenharmony_ci ((info->cmap.blue[fg_color] & 0xFFC0) >> 6); 82062306a36Sopenharmony_ci bg_color = 82162306a36Sopenharmony_ci ((info->cmap.red[bg_color] & 0xFFC0) << 14) | 82262306a36Sopenharmony_ci ((info->cmap.green[bg_color] & 0xFFC0) << 4) | 82362306a36Sopenharmony_ci ((info->cmap.blue[bg_color] & 0xFFC0) >> 6); 82462306a36Sopenharmony_ci } else { 82562306a36Sopenharmony_ci fg_color = 82662306a36Sopenharmony_ci ((info->cmap.red[fg_color] & 0xFF00) << 8) | 82762306a36Sopenharmony_ci (info->cmap.green[fg_color] & 0xFF00) | 82862306a36Sopenharmony_ci ((info->cmap.blue[fg_color] & 0xFF00) >> 8); 82962306a36Sopenharmony_ci bg_color = 83062306a36Sopenharmony_ci ((info->cmap.red[bg_color] & 0xFF00) << 8) | 83162306a36Sopenharmony_ci (info->cmap.green[bg_color] & 0xFF00) | 83262306a36Sopenharmony_ci ((info->cmap.blue[bg_color] & 0xFF00) >> 8); 83362306a36Sopenharmony_ci } 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci writel(bg_color, engine + VIA_REG_CURSOR_BG); 83662306a36Sopenharmony_ci writel(fg_color, engine + VIA_REG_CURSOR_FG); 83762306a36Sopenharmony_ci } 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci if (cursor->set & FB_CUR_SETSHAPE) { 84062306a36Sopenharmony_ci struct { 84162306a36Sopenharmony_ci u8 data[CURSOR_SIZE]; 84262306a36Sopenharmony_ci u32 bak[CURSOR_SIZE / 4]; 84362306a36Sopenharmony_ci } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); 84462306a36Sopenharmony_ci int size = ((cursor->image.width + 7) >> 3) * 84562306a36Sopenharmony_ci cursor->image.height; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci if (!cr_data) 84862306a36Sopenharmony_ci return -ENOMEM; 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci if (cur_size == 32) { 85162306a36Sopenharmony_ci for (i = 0; i < (CURSOR_SIZE / 4); i++) { 85262306a36Sopenharmony_ci cr_data->bak[i] = 0x0; 85362306a36Sopenharmony_ci cr_data->bak[i + 1] = 0xFFFFFFFF; 85462306a36Sopenharmony_ci i += 1; 85562306a36Sopenharmony_ci } 85662306a36Sopenharmony_ci } else { 85762306a36Sopenharmony_ci for (i = 0; i < (CURSOR_SIZE / 4); i++) { 85862306a36Sopenharmony_ci cr_data->bak[i] = 0x0; 85962306a36Sopenharmony_ci cr_data->bak[i + 1] = 0x0; 86062306a36Sopenharmony_ci cr_data->bak[i + 2] = 0xFFFFFFFF; 86162306a36Sopenharmony_ci cr_data->bak[i + 3] = 0xFFFFFFFF; 86262306a36Sopenharmony_ci i += 3; 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci } 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci switch (cursor->rop) { 86762306a36Sopenharmony_ci case ROP_XOR: 86862306a36Sopenharmony_ci for (i = 0; i < size; i++) 86962306a36Sopenharmony_ci cr_data->data[i] = cursor->mask[i]; 87062306a36Sopenharmony_ci break; 87162306a36Sopenharmony_ci case ROP_COPY: 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci for (i = 0; i < size; i++) 87462306a36Sopenharmony_ci cr_data->data[i] = cursor->mask[i]; 87562306a36Sopenharmony_ci break; 87662306a36Sopenharmony_ci default: 87762306a36Sopenharmony_ci break; 87862306a36Sopenharmony_ci } 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci if (cur_size == 32) { 88162306a36Sopenharmony_ci for (i = 0; i < size; i++) { 88262306a36Sopenharmony_ci cr_data->bak[j] = (u32) cr_data->data[i]; 88362306a36Sopenharmony_ci cr_data->bak[j + 1] = ~cr_data->bak[j]; 88462306a36Sopenharmony_ci j += 2; 88562306a36Sopenharmony_ci } 88662306a36Sopenharmony_ci } else { 88762306a36Sopenharmony_ci for (i = 0; i < size; i++) { 88862306a36Sopenharmony_ci cr_data->bak[j] = (u32) cr_data->data[i]; 88962306a36Sopenharmony_ci cr_data->bak[j + 1] = 0x0; 89062306a36Sopenharmony_ci cr_data->bak[j + 2] = ~cr_data->bak[j]; 89162306a36Sopenharmony_ci cr_data->bak[j + 3] = ~cr_data->bak[j + 1]; 89262306a36Sopenharmony_ci j += 4; 89362306a36Sopenharmony_ci } 89462306a36Sopenharmony_ci } 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci memcpy_toio(viafbinfo->screen_base + viapar->shared-> 89762306a36Sopenharmony_ci cursor_vram_addr, cr_data->bak, CURSOR_SIZE); 89862306a36Sopenharmony_ci kfree(cr_data); 89962306a36Sopenharmony_ci } 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci if (cursor->enable) 90262306a36Sopenharmony_ci viafb_show_hw_cursor(info, HW_Cursor_ON); 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci return 0; 90562306a36Sopenharmony_ci} 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_cistatic int viafb_sync(struct fb_info *info) 90862306a36Sopenharmony_ci{ 90962306a36Sopenharmony_ci if (!(info->flags & FBINFO_HWACCEL_DISABLED)) 91062306a36Sopenharmony_ci viafb_wait_engine_idle(info); 91162306a36Sopenharmony_ci return 0; 91262306a36Sopenharmony_ci} 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_cistatic int get_primary_device(void) 91562306a36Sopenharmony_ci{ 91662306a36Sopenharmony_ci int primary_device = 0; 91762306a36Sopenharmony_ci /* Rule: device on iga1 path are the primary device. */ 91862306a36Sopenharmony_ci if (viafb_SAMM_ON) { 91962306a36Sopenharmony_ci if (viafb_CRT_ON) { 92062306a36Sopenharmony_ci if (viaparinfo->shared->iga1_devices & VIA_CRT) { 92162306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", IGA1); 92262306a36Sopenharmony_ci primary_device = CRT_Device; 92362306a36Sopenharmony_ci } 92462306a36Sopenharmony_ci } 92562306a36Sopenharmony_ci if (viafb_DVI_ON) { 92662306a36Sopenharmony_ci if (viaparinfo->tmds_setting_info->iga_path == IGA1) { 92762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n", 92862306a36Sopenharmony_ci viaparinfo-> 92962306a36Sopenharmony_ci tmds_setting_info->iga_path); 93062306a36Sopenharmony_ci primary_device = DVI_Device; 93162306a36Sopenharmony_ci } 93262306a36Sopenharmony_ci } 93362306a36Sopenharmony_ci if (viafb_LCD_ON) { 93462306a36Sopenharmony_ci if (viaparinfo->lvds_setting_info->iga_path == IGA1) { 93562306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n", 93662306a36Sopenharmony_ci viaparinfo-> 93762306a36Sopenharmony_ci lvds_setting_info->iga_path); 93862306a36Sopenharmony_ci primary_device = LCD_Device; 93962306a36Sopenharmony_ci } 94062306a36Sopenharmony_ci } 94162306a36Sopenharmony_ci if (viafb_LCD2_ON) { 94262306a36Sopenharmony_ci if (viaparinfo->lvds_setting_info2->iga_path == IGA1) { 94362306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n", 94462306a36Sopenharmony_ci viaparinfo-> 94562306a36Sopenharmony_ci lvds_setting_info2->iga_path); 94662306a36Sopenharmony_ci primary_device = LCD2_Device; 94762306a36Sopenharmony_ci } 94862306a36Sopenharmony_ci } 94962306a36Sopenharmony_ci } 95062306a36Sopenharmony_ci return primary_device; 95162306a36Sopenharmony_ci} 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_cistatic void retrieve_device_setting(struct viafb_ioctl_setting 95462306a36Sopenharmony_ci *setting_info) 95562306a36Sopenharmony_ci{ 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci /* get device status */ 95862306a36Sopenharmony_ci if (viafb_CRT_ON == 1) 95962306a36Sopenharmony_ci setting_info->device_status = CRT_Device; 96062306a36Sopenharmony_ci if (viafb_DVI_ON == 1) 96162306a36Sopenharmony_ci setting_info->device_status |= DVI_Device; 96262306a36Sopenharmony_ci if (viafb_LCD_ON == 1) 96362306a36Sopenharmony_ci setting_info->device_status |= LCD_Device; 96462306a36Sopenharmony_ci if (viafb_LCD2_ON == 1) 96562306a36Sopenharmony_ci setting_info->device_status |= LCD2_Device; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci setting_info->samm_status = viafb_SAMM_ON; 96862306a36Sopenharmony_ci setting_info->primary_device = get_primary_device(); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci setting_info->first_dev_bpp = viafb_bpp; 97162306a36Sopenharmony_ci setting_info->second_dev_bpp = viafb_bpp1; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci setting_info->first_dev_refresh = viafb_refresh; 97462306a36Sopenharmony_ci setting_info->second_dev_refresh = viafb_refresh1; 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci setting_info->first_dev_hor_res = viafb_hotplug_Xres; 97762306a36Sopenharmony_ci setting_info->first_dev_ver_res = viafb_hotplug_Yres; 97862306a36Sopenharmony_ci setting_info->second_dev_hor_res = viafb_second_xres; 97962306a36Sopenharmony_ci setting_info->second_dev_ver_res = viafb_second_yres; 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci /* Get lcd attributes */ 98262306a36Sopenharmony_ci setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method; 98362306a36Sopenharmony_ci setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id; 98462306a36Sopenharmony_ci setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; 98562306a36Sopenharmony_ci} 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_cistatic int __init parse_active_dev(void) 98862306a36Sopenharmony_ci{ 98962306a36Sopenharmony_ci viafb_CRT_ON = STATE_OFF; 99062306a36Sopenharmony_ci viafb_DVI_ON = STATE_OFF; 99162306a36Sopenharmony_ci viafb_LCD_ON = STATE_OFF; 99262306a36Sopenharmony_ci viafb_LCD2_ON = STATE_OFF; 99362306a36Sopenharmony_ci /* 1. Modify the active status of devices. */ 99462306a36Sopenharmony_ci /* 2. Keep the order of devices, so we can set corresponding 99562306a36Sopenharmony_ci IGA path to devices in SAMM case. */ 99662306a36Sopenharmony_ci /* Note: The previous of active_dev is primary device, 99762306a36Sopenharmony_ci and the following is secondary device. */ 99862306a36Sopenharmony_ci if (!viafb_active_dev) { 99962306a36Sopenharmony_ci if (machine_is_olpc()) { /* LCD only */ 100062306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 100162306a36Sopenharmony_ci viafb_SAMM_ON = STATE_OFF; 100262306a36Sopenharmony_ci } else { 100362306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 100462306a36Sopenharmony_ci viafb_SAMM_ON = STATE_OFF; 100562306a36Sopenharmony_ci } 100662306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "CRT+DVI")) { 100762306a36Sopenharmony_ci /* CRT+DVI */ 100862306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 100962306a36Sopenharmony_ci viafb_DVI_ON = STATE_ON; 101062306a36Sopenharmony_ci viafb_primary_dev = CRT_Device; 101162306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "DVI+CRT")) { 101262306a36Sopenharmony_ci /* DVI+CRT */ 101362306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 101462306a36Sopenharmony_ci viafb_DVI_ON = STATE_ON; 101562306a36Sopenharmony_ci viafb_primary_dev = DVI_Device; 101662306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "CRT+LCD")) { 101762306a36Sopenharmony_ci /* CRT+LCD */ 101862306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 101962306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 102062306a36Sopenharmony_ci viafb_primary_dev = CRT_Device; 102162306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "LCD+CRT")) { 102262306a36Sopenharmony_ci /* LCD+CRT */ 102362306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 102462306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 102562306a36Sopenharmony_ci viafb_primary_dev = LCD_Device; 102662306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "DVI+LCD")) { 102762306a36Sopenharmony_ci /* DVI+LCD */ 102862306a36Sopenharmony_ci viafb_DVI_ON = STATE_ON; 102962306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 103062306a36Sopenharmony_ci viafb_primary_dev = DVI_Device; 103162306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "LCD+DVI")) { 103262306a36Sopenharmony_ci /* LCD+DVI */ 103362306a36Sopenharmony_ci viafb_DVI_ON = STATE_ON; 103462306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 103562306a36Sopenharmony_ci viafb_primary_dev = LCD_Device; 103662306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "LCD+LCD2")) { 103762306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 103862306a36Sopenharmony_ci viafb_LCD2_ON = STATE_ON; 103962306a36Sopenharmony_ci viafb_primary_dev = LCD_Device; 104062306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "LCD2+LCD")) { 104162306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 104262306a36Sopenharmony_ci viafb_LCD2_ON = STATE_ON; 104362306a36Sopenharmony_ci viafb_primary_dev = LCD2_Device; 104462306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "CRT")) { 104562306a36Sopenharmony_ci /* CRT only */ 104662306a36Sopenharmony_ci viafb_CRT_ON = STATE_ON; 104762306a36Sopenharmony_ci viafb_SAMM_ON = STATE_OFF; 104862306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "DVI")) { 104962306a36Sopenharmony_ci /* DVI only */ 105062306a36Sopenharmony_ci viafb_DVI_ON = STATE_ON; 105162306a36Sopenharmony_ci viafb_SAMM_ON = STATE_OFF; 105262306a36Sopenharmony_ci } else if (!strcmp(viafb_active_dev, "LCD")) { 105362306a36Sopenharmony_ci /* LCD only */ 105462306a36Sopenharmony_ci viafb_LCD_ON = STATE_ON; 105562306a36Sopenharmony_ci viafb_SAMM_ON = STATE_OFF; 105662306a36Sopenharmony_ci } else 105762306a36Sopenharmony_ci return -EINVAL; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci return 0; 106062306a36Sopenharmony_ci} 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_cistatic int parse_port(char *opt_str, int *output_interface) 106362306a36Sopenharmony_ci{ 106462306a36Sopenharmony_ci if (!strncmp(opt_str, "DVP0", 4)) 106562306a36Sopenharmony_ci *output_interface = INTERFACE_DVP0; 106662306a36Sopenharmony_ci else if (!strncmp(opt_str, "DVP1", 4)) 106762306a36Sopenharmony_ci *output_interface = INTERFACE_DVP1; 106862306a36Sopenharmony_ci else if (!strncmp(opt_str, "DFP_HIGHLOW", 11)) 106962306a36Sopenharmony_ci *output_interface = INTERFACE_DFP; 107062306a36Sopenharmony_ci else if (!strncmp(opt_str, "DFP_HIGH", 8)) 107162306a36Sopenharmony_ci *output_interface = INTERFACE_DFP_HIGH; 107262306a36Sopenharmony_ci else if (!strncmp(opt_str, "DFP_LOW", 7)) 107362306a36Sopenharmony_ci *output_interface = INTERFACE_DFP_LOW; 107462306a36Sopenharmony_ci else 107562306a36Sopenharmony_ci *output_interface = INTERFACE_NONE; 107662306a36Sopenharmony_ci return 0; 107762306a36Sopenharmony_ci} 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_cistatic void parse_lcd_port(void) 108062306a36Sopenharmony_ci{ 108162306a36Sopenharmony_ci parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info. 108262306a36Sopenharmony_ci output_interface); 108362306a36Sopenharmony_ci /*Initialize to avoid unexpected behavior */ 108462306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info2.output_interface = 108562306a36Sopenharmony_ci INTERFACE_NONE; 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n", 108862306a36Sopenharmony_ci viafb_lcd_port, viaparinfo->chip_info->lvds_chip_info. 108962306a36Sopenharmony_ci output_interface); 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic void parse_dvi_port(void) 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info. 109562306a36Sopenharmony_ci output_interface); 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n", 109862306a36Sopenharmony_ci viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info. 109962306a36Sopenharmony_ci output_interface); 110062306a36Sopenharmony_ci} 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci#ifdef CONFIG_FB_VIA_DIRECT_PROCFS 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci/* 110562306a36Sopenharmony_ci * The proc filesystem read/write function, a simple proc implement to 110662306a36Sopenharmony_ci * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, 110762306a36Sopenharmony_ci * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], 110862306a36Sopenharmony_ci * CR9B, SR65, CR97, CR99 110962306a36Sopenharmony_ci */ 111062306a36Sopenharmony_cistatic int viafb_dvp0_proc_show(struct seq_file *m, void *v) 111162306a36Sopenharmony_ci{ 111262306a36Sopenharmony_ci u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; 111362306a36Sopenharmony_ci dvp0_data_dri = 111462306a36Sopenharmony_ci (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | 111562306a36Sopenharmony_ci (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1; 111662306a36Sopenharmony_ci dvp0_clk_dri = 111762306a36Sopenharmony_ci (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | 111862306a36Sopenharmony_ci (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; 111962306a36Sopenharmony_ci dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; 112062306a36Sopenharmony_ci seq_printf(m, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); 112162306a36Sopenharmony_ci return 0; 112262306a36Sopenharmony_ci} 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_cistatic int viafb_dvp0_proc_open(struct inode *inode, struct file *file) 112562306a36Sopenharmony_ci{ 112662306a36Sopenharmony_ci return single_open(file, viafb_dvp0_proc_show, NULL); 112762306a36Sopenharmony_ci} 112862306a36Sopenharmony_ci 112962306a36Sopenharmony_cistatic ssize_t viafb_dvp0_proc_write(struct file *file, 113062306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 113162306a36Sopenharmony_ci{ 113262306a36Sopenharmony_ci char buf[20], *value, *pbuf; 113362306a36Sopenharmony_ci u8 reg_val = 0; 113462306a36Sopenharmony_ci unsigned long length, i; 113562306a36Sopenharmony_ci if (count < 1) 113662306a36Sopenharmony_ci return -EINVAL; 113762306a36Sopenharmony_ci length = count > 20 ? 20 : count; 113862306a36Sopenharmony_ci if (copy_from_user(&buf[0], buffer, length)) 113962306a36Sopenharmony_ci return -EFAULT; 114062306a36Sopenharmony_ci buf[length - 1] = '\0'; /*Ensure end string */ 114162306a36Sopenharmony_ci pbuf = &buf[0]; 114262306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 114362306a36Sopenharmony_ci value = strsep(&pbuf, " "); 114462306a36Sopenharmony_ci if (value != NULL) { 114562306a36Sopenharmony_ci if (kstrtou8(value, 0, ®_val) < 0) 114662306a36Sopenharmony_ci return -EINVAL; 114762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "DVP0:reg_val[%lu]=:%x\n", i, 114862306a36Sopenharmony_ci reg_val); 114962306a36Sopenharmony_ci switch (i) { 115062306a36Sopenharmony_ci case 0: 115162306a36Sopenharmony_ci viafb_write_reg_mask(CR96, VIACR, 115262306a36Sopenharmony_ci reg_val, 0x0f); 115362306a36Sopenharmony_ci break; 115462306a36Sopenharmony_ci case 1: 115562306a36Sopenharmony_ci viafb_write_reg_mask(SR2A, VIASR, 115662306a36Sopenharmony_ci reg_val << 4, BIT5); 115762306a36Sopenharmony_ci viafb_write_reg_mask(SR1B, VIASR, 115862306a36Sopenharmony_ci reg_val << 1, BIT1); 115962306a36Sopenharmony_ci break; 116062306a36Sopenharmony_ci case 2: 116162306a36Sopenharmony_ci viafb_write_reg_mask(SR2A, VIASR, 116262306a36Sopenharmony_ci reg_val << 3, BIT4); 116362306a36Sopenharmony_ci viafb_write_reg_mask(SR1E, VIASR, 116462306a36Sopenharmony_ci reg_val << 2, BIT2); 116562306a36Sopenharmony_ci break; 116662306a36Sopenharmony_ci default: 116762306a36Sopenharmony_ci break; 116862306a36Sopenharmony_ci } 116962306a36Sopenharmony_ci } else { 117062306a36Sopenharmony_ci break; 117162306a36Sopenharmony_ci } 117262306a36Sopenharmony_ci } 117362306a36Sopenharmony_ci return count; 117462306a36Sopenharmony_ci} 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_cistatic const struct proc_ops viafb_dvp0_proc_ops = { 117762306a36Sopenharmony_ci .proc_open = viafb_dvp0_proc_open, 117862306a36Sopenharmony_ci .proc_read = seq_read, 117962306a36Sopenharmony_ci .proc_lseek = seq_lseek, 118062306a36Sopenharmony_ci .proc_release = single_release, 118162306a36Sopenharmony_ci .proc_write = viafb_dvp0_proc_write, 118262306a36Sopenharmony_ci}; 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_cistatic int viafb_dvp1_proc_show(struct seq_file *m, void *v) 118562306a36Sopenharmony_ci{ 118662306a36Sopenharmony_ci u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; 118762306a36Sopenharmony_ci dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; 118862306a36Sopenharmony_ci dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; 118962306a36Sopenharmony_ci dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; 119062306a36Sopenharmony_ci seq_printf(m, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); 119162306a36Sopenharmony_ci return 0; 119262306a36Sopenharmony_ci} 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_cistatic int viafb_dvp1_proc_open(struct inode *inode, struct file *file) 119562306a36Sopenharmony_ci{ 119662306a36Sopenharmony_ci return single_open(file, viafb_dvp1_proc_show, NULL); 119762306a36Sopenharmony_ci} 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_cistatic ssize_t viafb_dvp1_proc_write(struct file *file, 120062306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 120162306a36Sopenharmony_ci{ 120262306a36Sopenharmony_ci char buf[20], *value, *pbuf; 120362306a36Sopenharmony_ci u8 reg_val = 0; 120462306a36Sopenharmony_ci unsigned long length, i; 120562306a36Sopenharmony_ci if (count < 1) 120662306a36Sopenharmony_ci return -EINVAL; 120762306a36Sopenharmony_ci length = count > 20 ? 20 : count; 120862306a36Sopenharmony_ci if (copy_from_user(&buf[0], buffer, length)) 120962306a36Sopenharmony_ci return -EFAULT; 121062306a36Sopenharmony_ci buf[length - 1] = '\0'; /*Ensure end string */ 121162306a36Sopenharmony_ci pbuf = &buf[0]; 121262306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 121362306a36Sopenharmony_ci value = strsep(&pbuf, " "); 121462306a36Sopenharmony_ci if (value != NULL) { 121562306a36Sopenharmony_ci if (kstrtou8(value, 0, ®_val) < 0) 121662306a36Sopenharmony_ci return -EINVAL; 121762306a36Sopenharmony_ci switch (i) { 121862306a36Sopenharmony_ci case 0: 121962306a36Sopenharmony_ci viafb_write_reg_mask(CR9B, VIACR, 122062306a36Sopenharmony_ci reg_val, 0x0f); 122162306a36Sopenharmony_ci break; 122262306a36Sopenharmony_ci case 1: 122362306a36Sopenharmony_ci viafb_write_reg_mask(SR65, VIASR, 122462306a36Sopenharmony_ci reg_val << 2, 0x0c); 122562306a36Sopenharmony_ci break; 122662306a36Sopenharmony_ci case 2: 122762306a36Sopenharmony_ci viafb_write_reg_mask(SR65, VIASR, 122862306a36Sopenharmony_ci reg_val, 0x03); 122962306a36Sopenharmony_ci break; 123062306a36Sopenharmony_ci default: 123162306a36Sopenharmony_ci break; 123262306a36Sopenharmony_ci } 123362306a36Sopenharmony_ci } else { 123462306a36Sopenharmony_ci break; 123562306a36Sopenharmony_ci } 123662306a36Sopenharmony_ci } 123762306a36Sopenharmony_ci return count; 123862306a36Sopenharmony_ci} 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_cistatic const struct proc_ops viafb_dvp1_proc_ops = { 124162306a36Sopenharmony_ci .proc_open = viafb_dvp1_proc_open, 124262306a36Sopenharmony_ci .proc_read = seq_read, 124362306a36Sopenharmony_ci .proc_lseek = seq_lseek, 124462306a36Sopenharmony_ci .proc_release = single_release, 124562306a36Sopenharmony_ci .proc_write = viafb_dvp1_proc_write, 124662306a36Sopenharmony_ci}; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_cistatic int viafb_dfph_proc_show(struct seq_file *m, void *v) 124962306a36Sopenharmony_ci{ 125062306a36Sopenharmony_ci u8 dfp_high = 0; 125162306a36Sopenharmony_ci dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; 125262306a36Sopenharmony_ci seq_printf(m, "%x\n", dfp_high); 125362306a36Sopenharmony_ci return 0; 125462306a36Sopenharmony_ci} 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_cistatic int viafb_dfph_proc_open(struct inode *inode, struct file *file) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci return single_open(file, viafb_dfph_proc_show, NULL); 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic ssize_t viafb_dfph_proc_write(struct file *file, 126262306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 126362306a36Sopenharmony_ci{ 126462306a36Sopenharmony_ci int err; 126562306a36Sopenharmony_ci u8 reg_val; 126662306a36Sopenharmony_ci err = kstrtou8_from_user(buffer, count, 0, ®_val); 126762306a36Sopenharmony_ci if (err) 126862306a36Sopenharmony_ci return err; 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_ci viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); 127162306a36Sopenharmony_ci return count; 127262306a36Sopenharmony_ci} 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_cistatic const struct proc_ops viafb_dfph_proc_ops = { 127562306a36Sopenharmony_ci .proc_open = viafb_dfph_proc_open, 127662306a36Sopenharmony_ci .proc_read = seq_read, 127762306a36Sopenharmony_ci .proc_lseek = seq_lseek, 127862306a36Sopenharmony_ci .proc_release = single_release, 127962306a36Sopenharmony_ci .proc_write = viafb_dfph_proc_write, 128062306a36Sopenharmony_ci}; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_cistatic int viafb_dfpl_proc_show(struct seq_file *m, void *v) 128362306a36Sopenharmony_ci{ 128462306a36Sopenharmony_ci u8 dfp_low = 0; 128562306a36Sopenharmony_ci dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; 128662306a36Sopenharmony_ci seq_printf(m, "%x\n", dfp_low); 128762306a36Sopenharmony_ci return 0; 128862306a36Sopenharmony_ci} 128962306a36Sopenharmony_ci 129062306a36Sopenharmony_cistatic int viafb_dfpl_proc_open(struct inode *inode, struct file *file) 129162306a36Sopenharmony_ci{ 129262306a36Sopenharmony_ci return single_open(file, viafb_dfpl_proc_show, NULL); 129362306a36Sopenharmony_ci} 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_cistatic ssize_t viafb_dfpl_proc_write(struct file *file, 129662306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 129762306a36Sopenharmony_ci{ 129862306a36Sopenharmony_ci int err; 129962306a36Sopenharmony_ci u8 reg_val; 130062306a36Sopenharmony_ci err = kstrtou8_from_user(buffer, count, 0, ®_val); 130162306a36Sopenharmony_ci if (err) 130262306a36Sopenharmony_ci return err; 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); 130562306a36Sopenharmony_ci return count; 130662306a36Sopenharmony_ci} 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_cistatic const struct proc_ops viafb_dfpl_proc_ops = { 130962306a36Sopenharmony_ci .proc_open = viafb_dfpl_proc_open, 131062306a36Sopenharmony_ci .proc_read = seq_read, 131162306a36Sopenharmony_ci .proc_lseek = seq_lseek, 131262306a36Sopenharmony_ci .proc_release = single_release, 131362306a36Sopenharmony_ci .proc_write = viafb_dfpl_proc_write, 131462306a36Sopenharmony_ci}; 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_cistatic int viafb_vt1636_proc_show(struct seq_file *m, void *v) 131762306a36Sopenharmony_ci{ 131862306a36Sopenharmony_ci u8 vt1636_08 = 0, vt1636_09 = 0; 131962306a36Sopenharmony_ci switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 132062306a36Sopenharmony_ci case VT1636_LVDS: 132162306a36Sopenharmony_ci vt1636_08 = 132262306a36Sopenharmony_ci viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, 132362306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f; 132462306a36Sopenharmony_ci vt1636_09 = 132562306a36Sopenharmony_ci viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, 132662306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; 132762306a36Sopenharmony_ci seq_printf(m, "%x %x\n", vt1636_08, vt1636_09); 132862306a36Sopenharmony_ci break; 132962306a36Sopenharmony_ci default: 133062306a36Sopenharmony_ci break; 133162306a36Sopenharmony_ci } 133262306a36Sopenharmony_ci switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { 133362306a36Sopenharmony_ci case VT1636_LVDS: 133462306a36Sopenharmony_ci vt1636_08 = 133562306a36Sopenharmony_ci viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, 133662306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f; 133762306a36Sopenharmony_ci vt1636_09 = 133862306a36Sopenharmony_ci viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, 133962306a36Sopenharmony_ci &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; 134062306a36Sopenharmony_ci seq_printf(m, " %x %x\n", vt1636_08, vt1636_09); 134162306a36Sopenharmony_ci break; 134262306a36Sopenharmony_ci default: 134362306a36Sopenharmony_ci break; 134462306a36Sopenharmony_ci } 134562306a36Sopenharmony_ci return 0; 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_cistatic int viafb_vt1636_proc_open(struct inode *inode, struct file *file) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci return single_open(file, viafb_vt1636_proc_show, NULL); 135162306a36Sopenharmony_ci} 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_cistatic ssize_t viafb_vt1636_proc_write(struct file *file, 135462306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 135562306a36Sopenharmony_ci{ 135662306a36Sopenharmony_ci char buf[30], *value, *pbuf; 135762306a36Sopenharmony_ci struct IODATA reg_val; 135862306a36Sopenharmony_ci unsigned long length, i; 135962306a36Sopenharmony_ci if (count < 1) 136062306a36Sopenharmony_ci return -EINVAL; 136162306a36Sopenharmony_ci length = count > 30 ? 30 : count; 136262306a36Sopenharmony_ci if (copy_from_user(&buf[0], buffer, length)) 136362306a36Sopenharmony_ci return -EFAULT; 136462306a36Sopenharmony_ci buf[length - 1] = '\0'; /*Ensure end string */ 136562306a36Sopenharmony_ci pbuf = &buf[0]; 136662306a36Sopenharmony_ci switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { 136762306a36Sopenharmony_ci case VT1636_LVDS: 136862306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 136962306a36Sopenharmony_ci value = strsep(&pbuf, " "); 137062306a36Sopenharmony_ci if (value != NULL) { 137162306a36Sopenharmony_ci if (kstrtou8(value, 0, ®_val.Data) < 0) 137262306a36Sopenharmony_ci return -EINVAL; 137362306a36Sopenharmony_ci switch (i) { 137462306a36Sopenharmony_ci case 0: 137562306a36Sopenharmony_ci reg_val.Index = 0x08; 137662306a36Sopenharmony_ci reg_val.Mask = 0x0f; 137762306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds 137862306a36Sopenharmony_ci (viaparinfo->lvds_setting_info, 137962306a36Sopenharmony_ci &viaparinfo-> 138062306a36Sopenharmony_ci chip_info->lvds_chip_info, 138162306a36Sopenharmony_ci reg_val); 138262306a36Sopenharmony_ci break; 138362306a36Sopenharmony_ci case 1: 138462306a36Sopenharmony_ci reg_val.Index = 0x09; 138562306a36Sopenharmony_ci reg_val.Mask = 0x1f; 138662306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds 138762306a36Sopenharmony_ci (viaparinfo->lvds_setting_info, 138862306a36Sopenharmony_ci &viaparinfo-> 138962306a36Sopenharmony_ci chip_info->lvds_chip_info, 139062306a36Sopenharmony_ci reg_val); 139162306a36Sopenharmony_ci break; 139262306a36Sopenharmony_ci default: 139362306a36Sopenharmony_ci break; 139462306a36Sopenharmony_ci } 139562306a36Sopenharmony_ci } else { 139662306a36Sopenharmony_ci break; 139762306a36Sopenharmony_ci } 139862306a36Sopenharmony_ci } 139962306a36Sopenharmony_ci break; 140062306a36Sopenharmony_ci default: 140162306a36Sopenharmony_ci break; 140262306a36Sopenharmony_ci } 140362306a36Sopenharmony_ci switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { 140462306a36Sopenharmony_ci case VT1636_LVDS: 140562306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 140662306a36Sopenharmony_ci value = strsep(&pbuf, " "); 140762306a36Sopenharmony_ci if (value != NULL) { 140862306a36Sopenharmony_ci if (kstrtou8(value, 0, ®_val.Data) < 0) 140962306a36Sopenharmony_ci return -EINVAL; 141062306a36Sopenharmony_ci switch (i) { 141162306a36Sopenharmony_ci case 0: 141262306a36Sopenharmony_ci reg_val.Index = 0x08; 141362306a36Sopenharmony_ci reg_val.Mask = 0x0f; 141462306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds 141562306a36Sopenharmony_ci (viaparinfo->lvds_setting_info2, 141662306a36Sopenharmony_ci &viaparinfo-> 141762306a36Sopenharmony_ci chip_info->lvds_chip_info2, 141862306a36Sopenharmony_ci reg_val); 141962306a36Sopenharmony_ci break; 142062306a36Sopenharmony_ci case 1: 142162306a36Sopenharmony_ci reg_val.Index = 0x09; 142262306a36Sopenharmony_ci reg_val.Mask = 0x1f; 142362306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds 142462306a36Sopenharmony_ci (viaparinfo->lvds_setting_info2, 142562306a36Sopenharmony_ci &viaparinfo-> 142662306a36Sopenharmony_ci chip_info->lvds_chip_info2, 142762306a36Sopenharmony_ci reg_val); 142862306a36Sopenharmony_ci break; 142962306a36Sopenharmony_ci default: 143062306a36Sopenharmony_ci break; 143162306a36Sopenharmony_ci } 143262306a36Sopenharmony_ci } else { 143362306a36Sopenharmony_ci break; 143462306a36Sopenharmony_ci } 143562306a36Sopenharmony_ci } 143662306a36Sopenharmony_ci break; 143762306a36Sopenharmony_ci default: 143862306a36Sopenharmony_ci break; 143962306a36Sopenharmony_ci } 144062306a36Sopenharmony_ci return count; 144162306a36Sopenharmony_ci} 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_cistatic const struct proc_ops viafb_vt1636_proc_ops = { 144462306a36Sopenharmony_ci .proc_open = viafb_vt1636_proc_open, 144562306a36Sopenharmony_ci .proc_read = seq_read, 144662306a36Sopenharmony_ci .proc_lseek = seq_lseek, 144762306a36Sopenharmony_ci .proc_release = single_release, 144862306a36Sopenharmony_ci .proc_write = viafb_vt1636_proc_write, 144962306a36Sopenharmony_ci}; 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_cistatic int __maybe_unused viafb_sup_odev_proc_show(struct seq_file *m, void *v) 145462306a36Sopenharmony_ci{ 145562306a36Sopenharmony_ci via_odev_to_seq(m, supported_odev_map[ 145662306a36Sopenharmony_ci viaparinfo->shared->chip_info.gfx_chip_name]); 145762306a36Sopenharmony_ci return 0; 145862306a36Sopenharmony_ci} 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_cistatic ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev) 146162306a36Sopenharmony_ci{ 146262306a36Sopenharmony_ci char buf[64], *ptr = buf; 146362306a36Sopenharmony_ci u32 devices; 146462306a36Sopenharmony_ci bool add, sub; 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci if (count < 1 || count > 63) 146762306a36Sopenharmony_ci return -EINVAL; 146862306a36Sopenharmony_ci if (copy_from_user(&buf[0], buffer, count)) 146962306a36Sopenharmony_ci return -EFAULT; 147062306a36Sopenharmony_ci buf[count] = '\0'; 147162306a36Sopenharmony_ci add = buf[0] == '+'; 147262306a36Sopenharmony_ci sub = buf[0] == '-'; 147362306a36Sopenharmony_ci if (add || sub) 147462306a36Sopenharmony_ci ptr++; 147562306a36Sopenharmony_ci devices = via_parse_odev(ptr, &ptr); 147662306a36Sopenharmony_ci if (*ptr == '\n') 147762306a36Sopenharmony_ci ptr++; 147862306a36Sopenharmony_ci if (*ptr != 0) 147962306a36Sopenharmony_ci return -EINVAL; 148062306a36Sopenharmony_ci if (add) 148162306a36Sopenharmony_ci *odev |= devices; 148262306a36Sopenharmony_ci else if (sub) 148362306a36Sopenharmony_ci *odev &= ~devices; 148462306a36Sopenharmony_ci else 148562306a36Sopenharmony_ci *odev = devices; 148662306a36Sopenharmony_ci return count; 148762306a36Sopenharmony_ci} 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_cistatic int viafb_iga1_odev_proc_show(struct seq_file *m, void *v) 149062306a36Sopenharmony_ci{ 149162306a36Sopenharmony_ci via_odev_to_seq(m, viaparinfo->shared->iga1_devices); 149262306a36Sopenharmony_ci return 0; 149362306a36Sopenharmony_ci} 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_cistatic int viafb_iga1_odev_proc_open(struct inode *inode, struct file *file) 149662306a36Sopenharmony_ci{ 149762306a36Sopenharmony_ci return single_open(file, viafb_iga1_odev_proc_show, NULL); 149862306a36Sopenharmony_ci} 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_cistatic ssize_t viafb_iga1_odev_proc_write(struct file *file, 150162306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 150262306a36Sopenharmony_ci{ 150362306a36Sopenharmony_ci u32 dev_on, dev_off, dev_old, dev_new; 150462306a36Sopenharmony_ci ssize_t res; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci dev_old = dev_new = viaparinfo->shared->iga1_devices; 150762306a36Sopenharmony_ci res = odev_update(buffer, count, &dev_new); 150862306a36Sopenharmony_ci if (res != count) 150962306a36Sopenharmony_ci return res; 151062306a36Sopenharmony_ci dev_off = dev_old & ~dev_new; 151162306a36Sopenharmony_ci dev_on = dev_new & ~dev_old; 151262306a36Sopenharmony_ci viaparinfo->shared->iga1_devices = dev_new; 151362306a36Sopenharmony_ci viaparinfo->shared->iga2_devices &= ~dev_new; 151462306a36Sopenharmony_ci via_set_state(dev_off, VIA_STATE_OFF); 151562306a36Sopenharmony_ci via_set_source(dev_new, IGA1); 151662306a36Sopenharmony_ci via_set_state(dev_on, VIA_STATE_ON); 151762306a36Sopenharmony_ci return res; 151862306a36Sopenharmony_ci} 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_cistatic const struct proc_ops viafb_iga1_odev_proc_ops = { 152162306a36Sopenharmony_ci .proc_open = viafb_iga1_odev_proc_open, 152262306a36Sopenharmony_ci .proc_read = seq_read, 152362306a36Sopenharmony_ci .proc_lseek = seq_lseek, 152462306a36Sopenharmony_ci .proc_release = single_release, 152562306a36Sopenharmony_ci .proc_write = viafb_iga1_odev_proc_write, 152662306a36Sopenharmony_ci}; 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_cistatic int viafb_iga2_odev_proc_show(struct seq_file *m, void *v) 152962306a36Sopenharmony_ci{ 153062306a36Sopenharmony_ci via_odev_to_seq(m, viaparinfo->shared->iga2_devices); 153162306a36Sopenharmony_ci return 0; 153262306a36Sopenharmony_ci} 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_cistatic int viafb_iga2_odev_proc_open(struct inode *inode, struct file *file) 153562306a36Sopenharmony_ci{ 153662306a36Sopenharmony_ci return single_open(file, viafb_iga2_odev_proc_show, NULL); 153762306a36Sopenharmony_ci} 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_cistatic ssize_t viafb_iga2_odev_proc_write(struct file *file, 154062306a36Sopenharmony_ci const char __user *buffer, size_t count, loff_t *pos) 154162306a36Sopenharmony_ci{ 154262306a36Sopenharmony_ci u32 dev_on, dev_off, dev_old, dev_new; 154362306a36Sopenharmony_ci ssize_t res; 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci dev_old = dev_new = viaparinfo->shared->iga2_devices; 154662306a36Sopenharmony_ci res = odev_update(buffer, count, &dev_new); 154762306a36Sopenharmony_ci if (res != count) 154862306a36Sopenharmony_ci return res; 154962306a36Sopenharmony_ci dev_off = dev_old & ~dev_new; 155062306a36Sopenharmony_ci dev_on = dev_new & ~dev_old; 155162306a36Sopenharmony_ci viaparinfo->shared->iga2_devices = dev_new; 155262306a36Sopenharmony_ci viaparinfo->shared->iga1_devices &= ~dev_new; 155362306a36Sopenharmony_ci via_set_state(dev_off, VIA_STATE_OFF); 155462306a36Sopenharmony_ci via_set_source(dev_new, IGA2); 155562306a36Sopenharmony_ci via_set_state(dev_on, VIA_STATE_ON); 155662306a36Sopenharmony_ci return res; 155762306a36Sopenharmony_ci} 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_cistatic const struct proc_ops viafb_iga2_odev_proc_ops = { 156062306a36Sopenharmony_ci .proc_open = viafb_iga2_odev_proc_open, 156162306a36Sopenharmony_ci .proc_read = seq_read, 156262306a36Sopenharmony_ci .proc_lseek = seq_lseek, 156362306a36Sopenharmony_ci .proc_release = single_release, 156462306a36Sopenharmony_ci .proc_write = viafb_iga2_odev_proc_write, 156562306a36Sopenharmony_ci}; 156662306a36Sopenharmony_ci 156762306a36Sopenharmony_ci#define IS_VT1636(lvds_chip) ((lvds_chip).lvds_chip_name == VT1636_LVDS) 156862306a36Sopenharmony_cistatic void viafb_init_proc(struct viafb_shared *shared) 156962306a36Sopenharmony_ci{ 157062306a36Sopenharmony_ci struct proc_dir_entry *iga1_entry, *iga2_entry, 157162306a36Sopenharmony_ci *viafb_entry = proc_mkdir("viafb", NULL); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci shared->proc_entry = viafb_entry; 157462306a36Sopenharmony_ci if (viafb_entry) { 157562306a36Sopenharmony_ci#ifdef CONFIG_FB_VIA_DIRECT_PROCFS 157662306a36Sopenharmony_ci proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_ops); 157762306a36Sopenharmony_ci proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_ops); 157862306a36Sopenharmony_ci proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_ops); 157962306a36Sopenharmony_ci proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_ops); 158062306a36Sopenharmony_ci if (IS_VT1636(shared->chip_info.lvds_chip_info) 158162306a36Sopenharmony_ci || IS_VT1636(shared->chip_info.lvds_chip_info2)) 158262306a36Sopenharmony_ci proc_create("vt1636", 0, viafb_entry, 158362306a36Sopenharmony_ci &viafb_vt1636_proc_ops); 158462306a36Sopenharmony_ci#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci proc_create_single("supported_output_devices", 0, viafb_entry, 158762306a36Sopenharmony_ci viafb_sup_odev_proc_show); 158862306a36Sopenharmony_ci iga1_entry = proc_mkdir("iga1", viafb_entry); 158962306a36Sopenharmony_ci shared->iga1_proc_entry = iga1_entry; 159062306a36Sopenharmony_ci proc_create("output_devices", 0, iga1_entry, 159162306a36Sopenharmony_ci &viafb_iga1_odev_proc_ops); 159262306a36Sopenharmony_ci iga2_entry = proc_mkdir("iga2", viafb_entry); 159362306a36Sopenharmony_ci shared->iga2_proc_entry = iga2_entry; 159462306a36Sopenharmony_ci proc_create("output_devices", 0, iga2_entry, 159562306a36Sopenharmony_ci &viafb_iga2_odev_proc_ops); 159662306a36Sopenharmony_ci } 159762306a36Sopenharmony_ci} 159862306a36Sopenharmony_cistatic void viafb_remove_proc(struct viafb_shared *shared) 159962306a36Sopenharmony_ci{ 160062306a36Sopenharmony_ci struct proc_dir_entry *viafb_entry = shared->proc_entry; 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci if (!viafb_entry) 160362306a36Sopenharmony_ci return; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci remove_proc_entry("output_devices", shared->iga2_proc_entry); 160662306a36Sopenharmony_ci remove_proc_entry("iga2", viafb_entry); 160762306a36Sopenharmony_ci remove_proc_entry("output_devices", shared->iga1_proc_entry); 160862306a36Sopenharmony_ci remove_proc_entry("iga1", viafb_entry); 160962306a36Sopenharmony_ci remove_proc_entry("supported_output_devices", viafb_entry); 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci#ifdef CONFIG_FB_VIA_DIRECT_PROCFS 161262306a36Sopenharmony_ci remove_proc_entry("dvp0", viafb_entry);/* parent dir */ 161362306a36Sopenharmony_ci remove_proc_entry("dvp1", viafb_entry); 161462306a36Sopenharmony_ci remove_proc_entry("dfph", viafb_entry); 161562306a36Sopenharmony_ci remove_proc_entry("dfpl", viafb_entry); 161662306a36Sopenharmony_ci if (IS_VT1636(shared->chip_info.lvds_chip_info) 161762306a36Sopenharmony_ci || IS_VT1636(shared->chip_info.lvds_chip_info2)) 161862306a36Sopenharmony_ci remove_proc_entry("vt1636", viafb_entry); 161962306a36Sopenharmony_ci#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci remove_proc_entry("viafb", NULL); 162262306a36Sopenharmony_ci} 162362306a36Sopenharmony_ci#undef IS_VT1636 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_cistatic int parse_mode(const char *str, u32 devices, u32 *xres, u32 *yres) 162662306a36Sopenharmony_ci{ 162762306a36Sopenharmony_ci const struct fb_videomode *mode = NULL; 162862306a36Sopenharmony_ci char *ptr; 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci if (!str) { 163162306a36Sopenharmony_ci if (devices == VIA_CRT) 163262306a36Sopenharmony_ci mode = via_aux_get_preferred_mode( 163362306a36Sopenharmony_ci viaparinfo->shared->i2c_26); 163462306a36Sopenharmony_ci else if (devices == VIA_DVP1) 163562306a36Sopenharmony_ci mode = via_aux_get_preferred_mode( 163662306a36Sopenharmony_ci viaparinfo->shared->i2c_31); 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci if (mode) { 163962306a36Sopenharmony_ci *xres = mode->xres; 164062306a36Sopenharmony_ci *yres = mode->yres; 164162306a36Sopenharmony_ci } else if (machine_is_olpc()) { 164262306a36Sopenharmony_ci *xres = 1200; 164362306a36Sopenharmony_ci *yres = 900; 164462306a36Sopenharmony_ci } else { 164562306a36Sopenharmony_ci *xres = 640; 164662306a36Sopenharmony_ci *yres = 480; 164762306a36Sopenharmony_ci } 164862306a36Sopenharmony_ci return 0; 164962306a36Sopenharmony_ci } 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_ci *xres = simple_strtoul(str, &ptr, 10); 165262306a36Sopenharmony_ci if (ptr[0] != 'x') 165362306a36Sopenharmony_ci return -EINVAL; 165462306a36Sopenharmony_ci 165562306a36Sopenharmony_ci *yres = simple_strtoul(&ptr[1], &ptr, 10); 165662306a36Sopenharmony_ci if (ptr[0]) 165762306a36Sopenharmony_ci return -EINVAL; 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci return 0; 166062306a36Sopenharmony_ci} 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci#ifdef CONFIG_PM 166462306a36Sopenharmony_cistatic int viafb_suspend(void *unused) 166562306a36Sopenharmony_ci{ 166662306a36Sopenharmony_ci console_lock(); 166762306a36Sopenharmony_ci fb_set_suspend(viafbinfo, 1); 166862306a36Sopenharmony_ci viafb_sync(viafbinfo); 166962306a36Sopenharmony_ci console_unlock(); 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci return 0; 167262306a36Sopenharmony_ci} 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_cistatic int viafb_resume(void *unused) 167562306a36Sopenharmony_ci{ 167662306a36Sopenharmony_ci console_lock(); 167762306a36Sopenharmony_ci if (viaparinfo->shared->vdev->engine_mmio) 167862306a36Sopenharmony_ci viafb_reset_engine(viaparinfo); 167962306a36Sopenharmony_ci viafb_set_par(viafbinfo); 168062306a36Sopenharmony_ci if (viafb_dual_fb) 168162306a36Sopenharmony_ci viafb_set_par(viafbinfo1); 168262306a36Sopenharmony_ci fb_set_suspend(viafbinfo, 0); 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci console_unlock(); 168562306a36Sopenharmony_ci return 0; 168662306a36Sopenharmony_ci} 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_cistatic struct viafb_pm_hooks viafb_fb_pm_hooks = { 168962306a36Sopenharmony_ci .suspend = viafb_suspend, 169062306a36Sopenharmony_ci .resume = viafb_resume 169162306a36Sopenharmony_ci}; 169262306a36Sopenharmony_ci 169362306a36Sopenharmony_ci#endif 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_cistatic void i2c_bus_probe(struct viafb_shared *shared) 169662306a36Sopenharmony_ci{ 169762306a36Sopenharmony_ci /* should be always CRT */ 169862306a36Sopenharmony_ci printk(KERN_INFO "viafb: Probing I2C bus 0x26\n"); 169962306a36Sopenharmony_ci shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26)); 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci /* seems to be usually DVP1 */ 170262306a36Sopenharmony_ci printk(KERN_INFO "viafb: Probing I2C bus 0x31\n"); 170362306a36Sopenharmony_ci shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31)); 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci /* FIXME: what is this? */ 170662306a36Sopenharmony_ci if (!machine_is_olpc()) { 170762306a36Sopenharmony_ci printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n"); 170862306a36Sopenharmony_ci shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C)); 170962306a36Sopenharmony_ci } 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci printk(KERN_INFO "viafb: Finished I2C bus probing"); 171262306a36Sopenharmony_ci} 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_cistatic void i2c_bus_free(struct viafb_shared *shared) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci via_aux_free(shared->i2c_26); 171762306a36Sopenharmony_ci via_aux_free(shared->i2c_31); 171862306a36Sopenharmony_ci via_aux_free(shared->i2c_2C); 171962306a36Sopenharmony_ci} 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ciint via_fb_pci_probe(struct viafb_dev *vdev) 172262306a36Sopenharmony_ci{ 172362306a36Sopenharmony_ci u32 default_xres, default_yres; 172462306a36Sopenharmony_ci struct fb_var_screeninfo default_var; 172562306a36Sopenharmony_ci int rc; 172662306a36Sopenharmony_ci u32 viafb_par_length; 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); 172962306a36Sopenharmony_ci memset(&default_var, 0, sizeof(default_var)); 173062306a36Sopenharmony_ci viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci /* Allocate fb_info and ***_par here, also including some other needed 173362306a36Sopenharmony_ci * variables 173462306a36Sopenharmony_ci */ 173562306a36Sopenharmony_ci viafbinfo = framebuffer_alloc(viafb_par_length + 173662306a36Sopenharmony_ci ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), 173762306a36Sopenharmony_ci &vdev->pdev->dev); 173862306a36Sopenharmony_ci if (!viafbinfo) 173962306a36Sopenharmony_ci return -ENOMEM; 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci viaparinfo = (struct viafb_par *)viafbinfo->par; 174262306a36Sopenharmony_ci viaparinfo->shared = viafbinfo->par + viafb_par_length; 174362306a36Sopenharmony_ci viaparinfo->shared->vdev = vdev; 174462306a36Sopenharmony_ci viaparinfo->vram_addr = 0; 174562306a36Sopenharmony_ci viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; 174662306a36Sopenharmony_ci viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; 174762306a36Sopenharmony_ci viaparinfo->lvds_setting_info2 = 174862306a36Sopenharmony_ci &viaparinfo->shared->lvds_setting_info2; 174962306a36Sopenharmony_ci viaparinfo->chip_info = &viaparinfo->shared->chip_info; 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci i2c_bus_probe(viaparinfo->shared); 175262306a36Sopenharmony_ci if (viafb_dual_fb) 175362306a36Sopenharmony_ci viafb_SAMM_ON = 1; 175462306a36Sopenharmony_ci parse_lcd_port(); 175562306a36Sopenharmony_ci parse_dvi_port(); 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci viafb_init_chip_info(vdev->chip_type); 175862306a36Sopenharmony_ci /* 175962306a36Sopenharmony_ci * The framebuffer will have been successfully mapped by 176062306a36Sopenharmony_ci * the core (or we'd not be here), but we still need to 176162306a36Sopenharmony_ci * set up our own accounting. 176262306a36Sopenharmony_ci */ 176362306a36Sopenharmony_ci viaparinfo->fbmem = vdev->fbmem_start; 176462306a36Sopenharmony_ci viaparinfo->memsize = vdev->fbmem_len; 176562306a36Sopenharmony_ci viaparinfo->fbmem_free = viaparinfo->memsize; 176662306a36Sopenharmony_ci viaparinfo->fbmem_used = 0; 176762306a36Sopenharmony_ci viafbinfo->screen_base = vdev->fbmem; 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci viafbinfo->fix.mmio_start = vdev->engine_start; 177062306a36Sopenharmony_ci viafbinfo->fix.mmio_len = vdev->engine_len; 177162306a36Sopenharmony_ci viafbinfo->node = 0; 177262306a36Sopenharmony_ci viafbinfo->fbops = &viafb_ops; 177362306a36Sopenharmony_ci viafbinfo->flags = FBINFO_HWACCEL_YPAN; 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci viafbinfo->pseudo_palette = pseudo_pal; 177662306a36Sopenharmony_ci if (viafb_accel && !viafb_setup_engine(viafbinfo)) { 177762306a36Sopenharmony_ci viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | 177862306a36Sopenharmony_ci FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; 177962306a36Sopenharmony_ci default_var.accel_flags = FB_ACCELF_TEXT; 178062306a36Sopenharmony_ci } else { 178162306a36Sopenharmony_ci viafbinfo->flags |= FBINFO_HWACCEL_DISABLED; 178262306a36Sopenharmony_ci default_var.accel_flags = 0; 178362306a36Sopenharmony_ci } 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci if (viafb_second_size && (viafb_second_size < 8)) { 178662306a36Sopenharmony_ci viafb_second_offset = viaparinfo->fbmem_free - 178762306a36Sopenharmony_ci viafb_second_size * 1024 * 1024; 178862306a36Sopenharmony_ci } else { 178962306a36Sopenharmony_ci viafb_second_size = 8; 179062306a36Sopenharmony_ci viafb_second_offset = viaparinfo->fbmem_free - 179162306a36Sopenharmony_ci viafb_second_size * 1024 * 1024; 179262306a36Sopenharmony_ci } 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci parse_mode(viafb_mode, viaparinfo->shared->iga1_devices, 179562306a36Sopenharmony_ci &default_xres, &default_yres); 179662306a36Sopenharmony_ci if (viafb_SAMM_ON == 1) 179762306a36Sopenharmony_ci parse_mode(viafb_mode1, viaparinfo->shared->iga2_devices, 179862306a36Sopenharmony_ci &viafb_second_xres, &viafb_second_yres); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci default_var.xres = default_xres; 180162306a36Sopenharmony_ci default_var.yres = default_yres; 180262306a36Sopenharmony_ci default_var.xres_virtual = default_xres; 180362306a36Sopenharmony_ci default_var.yres_virtual = default_yres; 180462306a36Sopenharmony_ci default_var.bits_per_pixel = viafb_bpp; 180562306a36Sopenharmony_ci viafb_fill_var_timing_info(&default_var, viafb_get_best_mode( 180662306a36Sopenharmony_ci default_var.xres, default_var.yres, viafb_refresh)); 180762306a36Sopenharmony_ci viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 180862306a36Sopenharmony_ci viafbinfo->var = default_var; 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci if (viafb_dual_fb) { 181162306a36Sopenharmony_ci viafbinfo1 = framebuffer_alloc(viafb_par_length, 181262306a36Sopenharmony_ci &vdev->pdev->dev); 181362306a36Sopenharmony_ci if (!viafbinfo1) { 181462306a36Sopenharmony_ci rc = -ENOMEM; 181562306a36Sopenharmony_ci goto out_fb_release; 181662306a36Sopenharmony_ci } 181762306a36Sopenharmony_ci viaparinfo1 = viafbinfo1->par; 181862306a36Sopenharmony_ci memcpy(viaparinfo1, viaparinfo, viafb_par_length); 181962306a36Sopenharmony_ci viaparinfo1->vram_addr = viafb_second_offset; 182062306a36Sopenharmony_ci viaparinfo1->memsize = viaparinfo->memsize - 182162306a36Sopenharmony_ci viafb_second_offset; 182262306a36Sopenharmony_ci viaparinfo->memsize = viafb_second_offset; 182362306a36Sopenharmony_ci viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset; 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci viaparinfo1->fbmem_used = viaparinfo->fbmem_used; 182662306a36Sopenharmony_ci viaparinfo1->fbmem_free = viaparinfo1->memsize - 182762306a36Sopenharmony_ci viaparinfo1->fbmem_used; 182862306a36Sopenharmony_ci viaparinfo->fbmem_free = viaparinfo->memsize; 182962306a36Sopenharmony_ci viaparinfo->fbmem_used = 0; 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci viaparinfo->iga_path = IGA1; 183262306a36Sopenharmony_ci viaparinfo1->iga_path = IGA2; 183362306a36Sopenharmony_ci memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info)); 183462306a36Sopenharmony_ci viafbinfo1->par = viaparinfo1; 183562306a36Sopenharmony_ci viafbinfo1->screen_base = viafbinfo->screen_base + 183662306a36Sopenharmony_ci viafb_second_offset; 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_ci default_var.xres = viafb_second_xres; 183962306a36Sopenharmony_ci default_var.yres = viafb_second_yres; 184062306a36Sopenharmony_ci default_var.xres_virtual = viafb_second_xres; 184162306a36Sopenharmony_ci default_var.yres_virtual = viafb_second_yres; 184262306a36Sopenharmony_ci default_var.bits_per_pixel = viafb_bpp1; 184362306a36Sopenharmony_ci viafb_fill_var_timing_info(&default_var, viafb_get_best_mode( 184462306a36Sopenharmony_ci default_var.xres, default_var.yres, viafb_refresh1)); 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_ci viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 184762306a36Sopenharmony_ci viafb_check_var(&default_var, viafbinfo1); 184862306a36Sopenharmony_ci viafbinfo1->var = default_var; 184962306a36Sopenharmony_ci viafb_update_fix(viafbinfo1); 185062306a36Sopenharmony_ci viaparinfo1->depth = fb_get_color_depth(&viafbinfo1->var, 185162306a36Sopenharmony_ci &viafbinfo1->fix); 185262306a36Sopenharmony_ci } 185362306a36Sopenharmony_ci 185462306a36Sopenharmony_ci viafb_check_var(&viafbinfo->var, viafbinfo); 185562306a36Sopenharmony_ci viafb_update_fix(viafbinfo); 185662306a36Sopenharmony_ci viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, 185762306a36Sopenharmony_ci &viafbinfo->fix); 185862306a36Sopenharmony_ci default_var.activate = FB_ACTIVATE_NOW; 185962306a36Sopenharmony_ci rc = fb_alloc_cmap(&viafbinfo->cmap, 256, 0); 186062306a36Sopenharmony_ci if (rc) 186162306a36Sopenharmony_ci goto out_fb1_release; 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci if (viafb_dual_fb && (viafb_primary_dev == LCD_Device) 186462306a36Sopenharmony_ci && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) { 186562306a36Sopenharmony_ci rc = register_framebuffer(viafbinfo1); 186662306a36Sopenharmony_ci if (rc) 186762306a36Sopenharmony_ci goto out_dealloc_cmap; 186862306a36Sopenharmony_ci } 186962306a36Sopenharmony_ci rc = register_framebuffer(viafbinfo); 187062306a36Sopenharmony_ci if (rc) 187162306a36Sopenharmony_ci goto out_fb1_unreg_lcd_cle266; 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device) 187462306a36Sopenharmony_ci || (viaparinfo->chip_info->gfx_chip_name != 187562306a36Sopenharmony_ci UNICHROME_CLE266))) { 187662306a36Sopenharmony_ci rc = register_framebuffer(viafbinfo1); 187762306a36Sopenharmony_ci if (rc) 187862306a36Sopenharmony_ci goto out_fb_unreg; 187962306a36Sopenharmony_ci } 188062306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n", 188162306a36Sopenharmony_ci viafbinfo->node, viafbinfo->fix.id, default_var.xres, 188262306a36Sopenharmony_ci default_var.yres, default_var.bits_per_pixel); 188362306a36Sopenharmony_ci 188462306a36Sopenharmony_ci viafb_init_proc(viaparinfo->shared); 188562306a36Sopenharmony_ci viafb_init_dac(IGA2); 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci#ifdef CONFIG_PM 188862306a36Sopenharmony_ci viafb_pm_register(&viafb_fb_pm_hooks); 188962306a36Sopenharmony_ci#endif 189062306a36Sopenharmony_ci return 0; 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ciout_fb_unreg: 189362306a36Sopenharmony_ci unregister_framebuffer(viafbinfo); 189462306a36Sopenharmony_ciout_fb1_unreg_lcd_cle266: 189562306a36Sopenharmony_ci if (viafb_dual_fb && (viafb_primary_dev == LCD_Device) 189662306a36Sopenharmony_ci && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) 189762306a36Sopenharmony_ci unregister_framebuffer(viafbinfo1); 189862306a36Sopenharmony_ciout_dealloc_cmap: 189962306a36Sopenharmony_ci fb_dealloc_cmap(&viafbinfo->cmap); 190062306a36Sopenharmony_ciout_fb1_release: 190162306a36Sopenharmony_ci framebuffer_release(viafbinfo1); 190262306a36Sopenharmony_ciout_fb_release: 190362306a36Sopenharmony_ci i2c_bus_free(viaparinfo->shared); 190462306a36Sopenharmony_ci framebuffer_release(viafbinfo); 190562306a36Sopenharmony_ci return rc; 190662306a36Sopenharmony_ci} 190762306a36Sopenharmony_ci 190862306a36Sopenharmony_civoid via_fb_pci_remove(struct pci_dev *pdev) 190962306a36Sopenharmony_ci{ 191062306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); 191162306a36Sopenharmony_ci fb_dealloc_cmap(&viafbinfo->cmap); 191262306a36Sopenharmony_ci unregister_framebuffer(viafbinfo); 191362306a36Sopenharmony_ci if (viafb_dual_fb) 191462306a36Sopenharmony_ci unregister_framebuffer(viafbinfo1); 191562306a36Sopenharmony_ci viafb_remove_proc(viaparinfo->shared); 191662306a36Sopenharmony_ci i2c_bus_free(viaparinfo->shared); 191762306a36Sopenharmony_ci framebuffer_release(viafbinfo); 191862306a36Sopenharmony_ci if (viafb_dual_fb) 191962306a36Sopenharmony_ci framebuffer_release(viafbinfo1); 192062306a36Sopenharmony_ci} 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_ci#ifndef MODULE 192362306a36Sopenharmony_cistatic int __init viafb_setup(void) 192462306a36Sopenharmony_ci{ 192562306a36Sopenharmony_ci char *this_opt; 192662306a36Sopenharmony_ci char *options; 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_setup!\n"); 192962306a36Sopenharmony_ci 193062306a36Sopenharmony_ci if (fb_get_options("viafb", &options)) 193162306a36Sopenharmony_ci return -ENODEV; 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci if (!options || !*options) 193462306a36Sopenharmony_ci return 0; 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci while ((this_opt = strsep(&options, ",")) != NULL) { 193762306a36Sopenharmony_ci if (!*this_opt) 193862306a36Sopenharmony_ci continue; 193962306a36Sopenharmony_ci 194062306a36Sopenharmony_ci if (!strncmp(this_opt, "viafb_mode1=", 12)) { 194162306a36Sopenharmony_ci viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL); 194262306a36Sopenharmony_ci if (!viafb_mode1) 194362306a36Sopenharmony_ci return -ENOMEM; 194462306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_mode=", 11)) { 194562306a36Sopenharmony_ci viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL); 194662306a36Sopenharmony_ci if (!viafb_mode) 194762306a36Sopenharmony_ci return -ENOMEM; 194862306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_bpp1=", 11)) { 194962306a36Sopenharmony_ci if (kstrtouint(this_opt + 11, 0, &viafb_bpp1) < 0) 195062306a36Sopenharmony_ci return -EINVAL; 195162306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_bpp=", 10)) { 195262306a36Sopenharmony_ci if (kstrtouint(this_opt + 10, 0, &viafb_bpp) < 0) 195362306a36Sopenharmony_ci return -EINVAL; 195462306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_refresh1=", 15)) { 195562306a36Sopenharmony_ci if (kstrtoint(this_opt + 15, 0, &viafb_refresh1) < 0) 195662306a36Sopenharmony_ci return -EINVAL; 195762306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_refresh=", 14)) { 195862306a36Sopenharmony_ci if (kstrtoint(this_opt + 14, 0, &viafb_refresh) < 0) 195962306a36Sopenharmony_ci return -EINVAL; 196062306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21)) { 196162306a36Sopenharmony_ci if (kstrtoint(this_opt + 21, 0, 196262306a36Sopenharmony_ci &viafb_lcd_dsp_method) < 0) 196362306a36Sopenharmony_ci return -EINVAL; 196462306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19)) { 196562306a36Sopenharmony_ci if (kstrtoint(this_opt + 19, 0, 196662306a36Sopenharmony_ci &viafb_lcd_panel_id) < 0) 196762306a36Sopenharmony_ci return -EINVAL; 196862306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_accel=", 12)) { 196962306a36Sopenharmony_ci if (kstrtoint(this_opt + 12, 0, &viafb_accel) < 0) 197062306a36Sopenharmony_ci return -EINVAL; 197162306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14)) { 197262306a36Sopenharmony_ci if (kstrtoint(this_opt + 14, 0, &viafb_SAMM_ON) < 0) 197362306a36Sopenharmony_ci return -EINVAL; 197462306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_active_dev=", 17)) { 197562306a36Sopenharmony_ci viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL); 197662306a36Sopenharmony_ci if (!viafb_active_dev) 197762306a36Sopenharmony_ci return -ENOMEM; 197862306a36Sopenharmony_ci } else if (!strncmp(this_opt, 197962306a36Sopenharmony_ci "viafb_display_hardware_layout=", 30)) { 198062306a36Sopenharmony_ci if (kstrtoint(this_opt + 30, 0, 198162306a36Sopenharmony_ci &viafb_display_hardware_layout) < 0) 198262306a36Sopenharmony_ci return -EINVAL; 198362306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_second_size=", 18)) { 198462306a36Sopenharmony_ci if (kstrtoint(this_opt + 18, 0, &viafb_second_size) < 0) 198562306a36Sopenharmony_ci return -EINVAL; 198662306a36Sopenharmony_ci } else if (!strncmp(this_opt, 198762306a36Sopenharmony_ci "viafb_platform_epia_dvi=", 24)) { 198862306a36Sopenharmony_ci if (kstrtoint(this_opt + 24, 0, 198962306a36Sopenharmony_ci &viafb_platform_epia_dvi) < 0) 199062306a36Sopenharmony_ci return -EINVAL; 199162306a36Sopenharmony_ci } else if (!strncmp(this_opt, 199262306a36Sopenharmony_ci "viafb_device_lcd_dualedge=", 26)) { 199362306a36Sopenharmony_ci if (kstrtoint(this_opt + 26, 0, 199462306a36Sopenharmony_ci &viafb_device_lcd_dualedge) < 0) 199562306a36Sopenharmony_ci return -EINVAL; 199662306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_bus_width=", 16)) { 199762306a36Sopenharmony_ci if (kstrtoint(this_opt + 16, 0, &viafb_bus_width) < 0) 199862306a36Sopenharmony_ci return -EINVAL; 199962306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) { 200062306a36Sopenharmony_ci if (kstrtoint(this_opt + 15, 0, &viafb_lcd_mode) < 0) 200162306a36Sopenharmony_ci return -EINVAL; 200262306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) { 200362306a36Sopenharmony_ci viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); 200462306a36Sopenharmony_ci if (!viafb_lcd_port) 200562306a36Sopenharmony_ci return -ENOMEM; 200662306a36Sopenharmony_ci } else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) { 200762306a36Sopenharmony_ci viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL); 200862306a36Sopenharmony_ci if (!viafb_dvi_port) 200962306a36Sopenharmony_ci return -ENOMEM; 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci return 0; 201362306a36Sopenharmony_ci} 201462306a36Sopenharmony_ci#endif 201562306a36Sopenharmony_ci 201662306a36Sopenharmony_ci/* 201762306a36Sopenharmony_ci * These are called out of via-core for now. 201862306a36Sopenharmony_ci */ 201962306a36Sopenharmony_ciint __init viafb_init(void) 202062306a36Sopenharmony_ci{ 202162306a36Sopenharmony_ci u32 dummy_x, dummy_y; 202262306a36Sopenharmony_ci int r = 0; 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_ci if (machine_is_olpc()) 202562306a36Sopenharmony_ci /* Apply XO-1.5-specific configuration. */ 202662306a36Sopenharmony_ci viafb_lcd_panel_id = 23; 202762306a36Sopenharmony_ci 202862306a36Sopenharmony_ci#ifndef MODULE 202962306a36Sopenharmony_ci r = viafb_setup(); 203062306a36Sopenharmony_ci if (r < 0) 203162306a36Sopenharmony_ci return r; 203262306a36Sopenharmony_ci#endif 203362306a36Sopenharmony_ci if (parse_mode(viafb_mode, 0, &dummy_x, &dummy_y) 203462306a36Sopenharmony_ci || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh) 203562306a36Sopenharmony_ci || parse_mode(viafb_mode1, 0, &dummy_x, &dummy_y) 203662306a36Sopenharmony_ci || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1) 203762306a36Sopenharmony_ci || viafb_bpp < 0 || viafb_bpp > 32 203862306a36Sopenharmony_ci || viafb_bpp1 < 0 || viafb_bpp1 > 32 203962306a36Sopenharmony_ci || parse_active_dev()) 204062306a36Sopenharmony_ci return -EINVAL; 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci printk(KERN_INFO 204362306a36Sopenharmony_ci "VIA Graphics Integration Chipset framebuffer %d.%d initializing\n", 204462306a36Sopenharmony_ci VERSION_MAJOR, VERSION_MINOR); 204562306a36Sopenharmony_ci return r; 204662306a36Sopenharmony_ci} 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_civoid __exit viafb_exit(void) 204962306a36Sopenharmony_ci{ 205062306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_exit!\n"); 205162306a36Sopenharmony_ci} 205262306a36Sopenharmony_ci 205362306a36Sopenharmony_cistatic struct fb_ops viafb_ops = { 205462306a36Sopenharmony_ci .owner = THIS_MODULE, 205562306a36Sopenharmony_ci .fb_open = viafb_open, 205662306a36Sopenharmony_ci .fb_release = viafb_release, 205762306a36Sopenharmony_ci .fb_check_var = viafb_check_var, 205862306a36Sopenharmony_ci .fb_set_par = viafb_set_par, 205962306a36Sopenharmony_ci .fb_setcolreg = viafb_setcolreg, 206062306a36Sopenharmony_ci .fb_pan_display = viafb_pan_display, 206162306a36Sopenharmony_ci .fb_blank = viafb_blank, 206262306a36Sopenharmony_ci .fb_fillrect = viafb_fillrect, 206362306a36Sopenharmony_ci .fb_copyarea = viafb_copyarea, 206462306a36Sopenharmony_ci .fb_imageblit = viafb_imageblit, 206562306a36Sopenharmony_ci .fb_cursor = viafb_cursor, 206662306a36Sopenharmony_ci .fb_ioctl = viafb_ioctl, 206762306a36Sopenharmony_ci .fb_sync = viafb_sync, 206862306a36Sopenharmony_ci}; 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci 207162306a36Sopenharmony_ci#ifdef MODULE 207262306a36Sopenharmony_cimodule_param(viafb_mode, charp, S_IRUSR); 207362306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); 207462306a36Sopenharmony_ci 207562306a36Sopenharmony_cimodule_param(viafb_mode1, charp, S_IRUSR); 207662306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)"); 207762306a36Sopenharmony_ci 207862306a36Sopenharmony_cimodule_param(viafb_bpp, int, S_IRUSR); 207962306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)"); 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_cimodule_param(viafb_bpp1, int, S_IRUSR); 208262306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)"); 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_cimodule_param(viafb_refresh, int, S_IRUSR); 208562306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_refresh, 208662306a36Sopenharmony_ci "Set CRT viafb_refresh rate (default = 60)"); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_cimodule_param(viafb_refresh1, int, S_IRUSR); 208962306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_refresh1, 209062306a36Sopenharmony_ci "Set CRT refresh rate (default = 60)"); 209162306a36Sopenharmony_ci 209262306a36Sopenharmony_cimodule_param(viafb_lcd_panel_id, int, S_IRUSR); 209362306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_lcd_panel_id, 209462306a36Sopenharmony_ci "Set Flat Panel type(Default=1024x768)"); 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_cimodule_param(viafb_lcd_dsp_method, int, S_IRUSR); 209762306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_lcd_dsp_method, 209862306a36Sopenharmony_ci "Set Flat Panel display scaling method.(Default=Expansion)"); 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_cimodule_param(viafb_SAMM_ON, int, S_IRUSR); 210162306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_SAMM_ON, 210262306a36Sopenharmony_ci "Turn on/off flag of SAMM(Default=OFF)"); 210362306a36Sopenharmony_ci 210462306a36Sopenharmony_cimodule_param(viafb_accel, int, S_IRUSR); 210562306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_accel, 210662306a36Sopenharmony_ci "Set 2D Hardware Acceleration: 0 = OFF, 1 = ON (default)"); 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_cimodule_param(viafb_active_dev, charp, S_IRUSR); 210962306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_active_dev, "Specify active devices."); 211062306a36Sopenharmony_ci 211162306a36Sopenharmony_cimodule_param(viafb_display_hardware_layout, int, S_IRUSR); 211262306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_display_hardware_layout, 211362306a36Sopenharmony_ci "Display Hardware Layout (LCD Only, DVI Only...,etc)"); 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_cimodule_param(viafb_second_size, int, S_IRUSR); 211662306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_second_size, 211762306a36Sopenharmony_ci "Set secondary device memory size"); 211862306a36Sopenharmony_ci 211962306a36Sopenharmony_cimodule_param(viafb_dual_fb, int, S_IRUSR); 212062306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_dual_fb, 212162306a36Sopenharmony_ci "Turn on/off flag of dual framebuffer devices.(Default = OFF)"); 212262306a36Sopenharmony_ci 212362306a36Sopenharmony_cimodule_param(viafb_platform_epia_dvi, int, S_IRUSR); 212462306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_platform_epia_dvi, 212562306a36Sopenharmony_ci "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)"); 212662306a36Sopenharmony_ci 212762306a36Sopenharmony_cimodule_param(viafb_device_lcd_dualedge, int, S_IRUSR); 212862306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_device_lcd_dualedge, 212962306a36Sopenharmony_ci "Turn on/off flag of dual edge panel.(Default = OFF)"); 213062306a36Sopenharmony_ci 213162306a36Sopenharmony_cimodule_param(viafb_bus_width, int, S_IRUSR); 213262306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_bus_width, 213362306a36Sopenharmony_ci "Set bus width of panel.(Default = 12)"); 213462306a36Sopenharmony_ci 213562306a36Sopenharmony_cimodule_param(viafb_lcd_mode, int, S_IRUSR); 213662306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_lcd_mode, 213762306a36Sopenharmony_ci "Set Flat Panel mode(Default=OPENLDI)"); 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_cimodule_param(viafb_lcd_port, charp, S_IRUSR); 214062306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port."); 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_cimodule_param(viafb_dvi_port, charp, S_IRUSR); 214362306a36Sopenharmony_ciMODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port."); 214462306a36Sopenharmony_ci 214562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 214662306a36Sopenharmony_ci#endif 2147