diff options
Diffstat (limited to 'drivers/video/via/viafbdev.c')
-rw-r--r-- | drivers/video/via/viafbdev.c | 1049 |
1 files changed, 394 insertions, 655 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 72833f3334b..56ec696e8af 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -20,11 +20,12 @@ */ #include <linux/module.h> +#include <linux/seq_file.h> +#include <linux/stat.h> #define _MASTER_FILE #include "global.h" -static int MAX_CURS = 32; static struct fb_var_screeninfo default_var; static char *viafb_name = "Via"; static u32 pseudo_pal[17]; @@ -33,12 +34,11 @@ static u32 pseudo_pal[17]; static char *viafb_mode = "640x480"; static char *viafb_mode1 = "640x480"; +static int viafb_accel = 1; + /* Added for specifying active devices.*/ char *viafb_active_dev = ""; -/* Added for specifying video on devices.*/ -char *viafb_video_dev = ""; - /*Added for specify lcd output port*/ char *viafb_lcd_port = ""; char *viafb_dvi_port = ""; @@ -50,71 +50,20 @@ static void apply_second_mode_setting(struct fb_var_screeninfo *sec_var); static void retrieve_device_setting(struct viafb_ioctl_setting *setting_info); -static void viafb_set_video_device(u32 video_dev_info); -static void viafb_get_video_device(u32 *video_dev_info); - -/* Mode information */ -static const struct viafb_modeinfo viafb_modentry[] = { - {480, 640, VIA_RES_480X640}, - {640, 480, VIA_RES_640X480}, - {800, 480, VIA_RES_800X480}, - {800, 600, VIA_RES_800X600}, - {1024, 768, VIA_RES_1024X768}, - {1152, 864, VIA_RES_1152X864}, - {1280, 1024, VIA_RES_1280X1024}, - {1600, 1200, VIA_RES_1600X1200}, - {1440, 1050, VIA_RES_1440X1050}, - {1280, 768, VIA_RES_1280X768,}, - {1280, 800, VIA_RES_1280X800}, - {1280, 960, VIA_RES_1280X960}, - {1920, 1440, VIA_RES_1920X1440}, - {848, 480, VIA_RES_848X480}, - {1400, 1050, VIA_RES_1400X1050}, - {720, 480, VIA_RES_720X480}, - {720, 576, VIA_RES_720X576}, - {1024, 512, VIA_RES_1024X512}, - {1024, 576, VIA_RES_1024X576}, - {1024, 600, VIA_RES_1024X600}, - {1280, 720, VIA_RES_1280X720}, - {1920, 1080, VIA_RES_1920X1080}, - {1366, 768, VIA_RES_1368X768}, - {1680, 1050, VIA_RES_1680X1050}, - {960, 600, VIA_RES_960X600}, - {1000, 600, VIA_RES_1000X600}, - {1024, 576, VIA_RES_1024X576}, - {1024, 600, VIA_RES_1024X600}, - {1088, 612, VIA_RES_1088X612}, - {1152, 720, VIA_RES_1152X720}, - {1200, 720, VIA_RES_1200X720}, - {1280, 600, VIA_RES_1280X600}, - {1360, 768, VIA_RES_1360X768}, - {1440, 900, VIA_RES_1440X900}, - {1600, 900, VIA_RES_1600X900}, - {1600, 1024, VIA_RES_1600X1024}, - {1792, 1344, VIA_RES_1792X1344}, - {1856, 1392, VIA_RES_1856X1392}, - {1920, 1200, VIA_RES_1920X1200}, - {2048, 1536, VIA_RES_2048X1536}, - {0, 0, VIA_RES_INVALID} -}; static struct fb_ops viafb_ops; -static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) -{ - struct viafb_par *ppar; - ppar = info->par; - - DEBUG_MSG(KERN_INFO "viafb_update_fix!\n"); - fix->visual = - ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; - fix->line_length = ppar->linelength; +static void viafb_update_fix(struct fb_info *info) +{ + u32 bpp = info->var.bits_per_pixel; - return 0; + info->fix.visual = + bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + info->fix.line_length = + ((info->var.xres_virtual + 7) & ~7) * bpp / 8; } - static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, struct viafb_par *viaparinfo) { @@ -123,8 +72,6 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, fix->smem_start = viaparinfo->fbmem; fix->smem_len = viaparinfo->fbmem_free; - fix->mmio_start = viaparinfo->mmio_base; - fix->mmio_len = viaparinfo->mmio_len; fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; @@ -147,28 +94,12 @@ static int viafb_release(struct fb_info *info, int user) return 0; } -static void viafb_update_viafb_par(struct fb_info *info) -{ - struct viafb_par *ppar; - - ppar = info->par; - ppar->bpp = info->var.bits_per_pixel; - ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8; - ppar->hres = info->var.xres; - ppar->vres = info->var.yres; - ppar->xoffset = info->var.xoffset; - ppar->yoffset = info->var.yoffset; -} - static int viafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { int vmode_index, htotal, vtotal; - struct viafb_par *ppar; + struct viafb_par *ppar = info->par; u32 long_refresh; - struct viafb_par *p_viafb_par; - ppar = info->par; - DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); /* Sanity check */ @@ -212,23 +143,21 @@ static int viafb_check_var(struct fb_var_screeninfo *var, /* Adjust var according to our driver's own table */ viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); - - /* This is indeed a patch for VT3353 */ - if (!info->par) - return -1; - p_viafb_par = (struct viafb_par *)info->par; - if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800) - var->accel_flags = 0; + if (info->var.accel_flags & FB_ACCELF_TEXT && + !ppar->shared->engine_mmio) + info->var.accel_flags = 0; return 0; } static int viafb_set_par(struct fb_info *info) { + struct viafb_par *viapar = info->par; int vmode_index; int vmode_index1 = 0; DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); + viapar->depth = fb_get_color_depth(&info->var, &info->fix); viafb_update_device_setting(info->var.xres, info->var.yres, info->var.bits_per_pixel, viafb_refresh, 0); @@ -252,21 +181,12 @@ static int viafb_set_par(struct fb_info *info) info->var.bits_per_pixel, vmode_index1, viafb_second_xres, viafb_second_yres, viafb_bpp1); - /*We should set memory offset according virtual_x */ - /*Fix me:put this function into viafb_setmode */ - viafb_memory_pitch_patch(info); - - /* Update ***fb_par information */ - viafb_update_viafb_par(info); - - /* Update other fixed information */ - viafb_update_fix(&info->fix, info); + viafb_update_fix(info); viafb_bpp = info->var.bits_per_pixel; - /* Update viafb_accel, it is necessary to our 2D accelerate */ - viafb_accel = info->var.accel_flags; - - if (viafb_accel) - viafb_set_2d_color_depth(info->var.bits_per_pixel); + if (info->var.accel_flags & FB_ACCELF_TEXT) + info->flags &= ~FBINFO_HWACCEL_DISABLED; + else + info->flags |= FBINFO_HWACCEL_DISABLED; } return 0; @@ -503,12 +423,7 @@ static int viafb_pan_display(struct fb_var_screeninfo *var, var->bits_per_pixel / 16; DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); - - viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3); - viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff); - viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff); - viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff); - + viafb_set_primary_address(offset); return 0; } @@ -560,7 +475,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) u32 __user *argp = (u32 __user *) arg; u32 gpu32; - u32 video_dev_info = 0; DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); memset(&u, 0, sizeof(u)); @@ -792,15 +706,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (put_user(state_info, argp)) return -EFAULT; break; - case VIAFB_SET_VIDEO_DEVICE: - get_user(video_dev_info, argp); - viafb_set_video_device(video_dev_info); - break; - case VIAFB_GET_VIDEO_DEVICE: - viafb_get_video_device(&video_dev_info); - if (put_user(video_dev_info, argp)) - return -EFAULT; - break; case VIAFB_SYNC_SURFACE: DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n"); break; @@ -866,10 +771,12 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) static void viafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - u32 col = 0, rop = 0; - int pitch; + struct viafb_par *viapar = info->par; + struct viafb_shared *shared = viapar->shared; + u32 fg_color; + u8 rop; - if (!viafb_accel) { + if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { cfb_fillrect(info, rect); return; } @@ -877,68 +784,31 @@ static void viafb_fillrect(struct fb_info *info, if (!rect->width || !rect->height) return; - switch (rect->rop) { - case ROP_XOR: + if (info->fix.visual == FB_VISUAL_TRUECOLOR) + fg_color = ((u32 *)info->pseudo_palette)[rect->color]; + else + fg_color = rect->color; + + if (rect->rop == ROP_XOR) rop = 0x5A; - break; - case ROP_COPY: - default: + else rop = 0xF0; - break; - } - - switch (info->var.bits_per_pixel) { - case 8: - col = rect->color; - break; - case 16: - col = ((u32 *) (info->pseudo_palette))[rect->color]; - break; - case 32: - col = ((u32 *) (info->pseudo_palette))[rect->color]; - break; - } - - /* BitBlt Source Address */ - writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); - /* Source Base Address */ - writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); - /* Destination Base Address */ - writel(((unsigned long) (info->screen_base) - - (unsigned long) viafb_FB_MM) >> 3, - viaparinfo->io_virt + VIA_REG_DSTBASE); - /* Pitch */ - pitch = (info->var.xres_virtual + 7) & ~7; - writel(VIA_PITCH_ENABLE | - (((pitch * - info->var.bits_per_pixel >> 3) >> 3) | - (((pitch * info-> - var.bits_per_pixel >> 3) >> 3) << 16)), - viaparinfo->io_virt + VIA_REG_PITCH); - /* BitBlt Destination Address */ - writel(((rect->dy << 16) | rect->dx), - viaparinfo->io_virt + VIA_REG_DSTPOS); - /* Dimension: width & height */ - writel((((rect->height - 1) << 16) | (rect->width - 1)), - viaparinfo->io_virt + VIA_REG_DIMENSION); - /* Forground color or Destination color */ - writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR); - /* GE Command */ - writel((0x01 | 0x2000 | (rop << 24)), - viaparinfo->io_virt + VIA_REG_GECMD); + DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); + if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL, + rect->width, rect->height, info->var.bits_per_pixel, + viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, + NULL, 0, 0, 0, 0, fg_color, 0, rop)) + cfb_fillrect(info, rect); } static void viafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - u32 dy = area->dy, sy = area->sy, direction = 0x0; - u32 sx = area->sx, dx = area->dx, width = area->width; - int pitch; - - DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); + struct viafb_par *viapar = info->par; + struct viafb_shared *shared = viapar->shared; - if (!viafb_accel) { + if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt) { cfb_copyarea(info, area); return; } @@ -946,263 +816,148 @@ static void viafb_copyarea(struct fb_info *info, if (!area->width || !area->height) return; - if (sy < dy) { - dy += area->height - 1; - sy += area->height - 1; - direction |= 0x4000; - } - - if (sx < dx) { - dx += width - 1; - sx += width - 1; - direction |= 0x8000; - } - - /* Source Base Address */ - writel(((unsigned long) (info->screen_base) - - (unsigned long) viafb_FB_MM) >> 3, - viaparinfo->io_virt + VIA_REG_SRCBASE); - /* Destination Base Address */ - writel(((unsigned long) (info->screen_base) - - (unsigned long) viafb_FB_MM) >> 3, - viaparinfo->io_virt + VIA_REG_DSTBASE); - /* Pitch */ - pitch = (info->var.xres_virtual + 7) & ~7; - /* VIA_PITCH_ENABLE can be omitted now. */ - writel(VIA_PITCH_ENABLE | - (((pitch * - info->var.bits_per_pixel >> 3) >> 3) | (((pitch * - info->var. - bits_per_pixel - >> 3) >> 3) - << 16)), - viaparinfo->io_virt + VIA_REG_PITCH); - /* BitBlt Source Address */ - writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS); - /* BitBlt Destination Address */ - writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS); - /* Dimension: width & height */ - writel((((area->height - 1) << 16) | (area->width - 1)), - viaparinfo->io_virt + VIA_REG_DIMENSION); - /* GE Command */ - writel((0x01 | direction | (0xCC << 24)), - viaparinfo->io_virt + VIA_REG_GECMD); - + DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); + if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR, + area->width, area->height, info->var.bits_per_pixel, + viapar->vram_addr, info->fix.line_length, area->dx, area->dy, + NULL, viapar->vram_addr, info->fix.line_length, + area->sx, area->sy, 0, 0, 0)) + cfb_copyarea(info, area); } static void viafb_imageblit(struct fb_info *info, const struct fb_image *image) { - u32 size, bg_col = 0, fg_col = 0, *udata; - int i; - int pitch; + struct viafb_par *viapar = info->par; + struct viafb_shared *shared = viapar->shared; + u32 fg_color = 0, bg_color = 0; + u8 op; - if (!viafb_accel) { + if (info->flags & FBINFO_HWACCEL_DISABLED || !shared->hw_bitblt || + (image->depth != 1 && image->depth != viapar->depth)) { cfb_imageblit(info, image); return; } - udata = (u32 *) image->data; - - switch (info->var.bits_per_pixel) { - case 8: - bg_col = image->bg_color; - fg_col = image->fg_color; - break; - case 16: - bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; - fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; - break; - case 32: - bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; - fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; - break; - } - size = image->width * image->height; - - /* Source Base Address */ - writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); - /* Destination Base Address */ - writel(((unsigned long) (info->screen_base) - - (unsigned long) viafb_FB_MM) >> 3, - viaparinfo->io_virt + VIA_REG_DSTBASE); - /* Pitch */ - pitch = (info->var.xres_virtual + 7) & ~7; - writel(VIA_PITCH_ENABLE | - (((pitch * - info->var.bits_per_pixel >> 3) >> 3) | (((pitch * - info->var. - bits_per_pixel - >> 3) >> 3) - << 16)), - viaparinfo->io_virt + VIA_REG_PITCH); - /* BitBlt Source Address */ - writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); - /* BitBlt Destination Address */ - writel(((image->dy << 16) | image->dx), - viaparinfo->io_virt + VIA_REG_DSTPOS); - /* Dimension: width & height */ - writel((((image->height - 1) << 16) | (image->width - 1)), - viaparinfo->io_virt + VIA_REG_DIMENSION); - /* fb color */ - writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR); - /* bg color */ - writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR); - /* GE Command */ - writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD); - - for (i = 0; i < size / 4; i++) { - writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE); - udata++; - } + if (image->depth == 1) { + op = VIA_BITBLT_MONO; + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + fg_color = + ((u32 *)info->pseudo_palette)[image->fg_color]; + bg_color = + ((u32 *)info->pseudo_palette)[image->bg_color]; + } else { + fg_color = image->fg_color; + bg_color = image->bg_color; + } + } else + op = VIA_BITBLT_COLOR; + DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); + if (shared->hw_bitblt(shared->engine_mmio, op, + image->width, image->height, info->var.bits_per_pixel, + viapar->vram_addr, info->fix.line_length, image->dx, image->dy, + (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) + cfb_imageblit(info, image); } static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - u32 temp, xx, yy, bg_col = 0, fg_col = 0; - int i, j = 0; - static int hw_cursor; - struct viafb_par *p_viafb_par; - - if (viafb_accel) - hw_cursor = 1; - - if (!viafb_accel) { - if (hw_cursor) { - viafb_show_hw_cursor(info, HW_Cursor_OFF); - hw_cursor = 0; - } - return -ENODEV; - } + struct viafb_par *viapar = info->par; + void __iomem *engine = viapar->shared->engine_mmio; + u32 temp, xx, yy, bg_color = 0, fg_color = 0, + chip_name = viapar->shared->chip_info.gfx_chip_name; + int i, j = 0, cur_size = 64; - if ((((struct viafb_par *)(info->par))->iga_path == IGA2) - && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) + if (info->flags & FBINFO_HWACCEL_DISABLED || info != viafbinfo) return -ENODEV; - /* When duoview and using lcd , use soft cursor */ - if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview) + if (chip_name == UNICHROME_CLE266 && viapar->iga_path == IGA2) return -ENODEV; viafb_show_hw_cursor(info, HW_Cursor_OFF); - viacursor = *cursor; if (cursor->set & FB_CUR_SETHOT) { - viacursor.hot = cursor->hot; - temp = ((viacursor.hot.x) << 16) + viacursor.hot.y; - writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); + temp = (cursor->hot.x << 16) + cursor->hot.y; + writel(temp, engine + VIA_REG_CURSOR_ORG); } if (cursor->set & FB_CUR_SETPOS) { - viacursor.image.dx = cursor->image.dx; - viacursor.image.dy = cursor->image.dy; yy = cursor->image.dy - info->var.yoffset; xx = cursor->image.dx - info->var.xoffset; temp = yy & 0xFFFF; temp |= (xx << 16); - writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS); + writel(temp, engine + VIA_REG_CURSOR_POS); } - if (cursor->set & FB_CUR_SETSIZE) { - temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); + if (cursor->image.width <= 32 && cursor->image.height <= 32) + cur_size = 32; + else if (cursor->image.width <= 64 && cursor->image.height <= 64) + cur_size = 64; + else { + printk(KERN_WARNING "viafb_cursor: The cursor is too large " + "%dx%d", cursor->image.width, cursor->image.height); + return -ENXIO; + } - if ((cursor->image.width <= 32) - && (cursor->image.height <= 32)) { - MAX_CURS = 32; + if (cursor->set & FB_CUR_SETSIZE) { + temp = readl(engine + VIA_REG_CURSOR_MODE); + if (cur_size == 32) temp |= 0x2; - } else if ((cursor->image.width <= 64) - && (cursor->image.height <= 64)) { - MAX_CURS = 64; - temp &= 0xFFFFFFFD; - } else { - DEBUG_MSG(KERN_INFO - "The cursor image is biger than 64x64 bits...\n"); - return -ENXIO; - } - writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); + else + temp &= ~0x2; - viacursor.image.height = cursor->image.height; - viacursor.image.width = cursor->image.width; + writel(temp, engine + VIA_REG_CURSOR_MODE); } if (cursor->set & FB_CUR_SETCMAP) { - viacursor.image.fg_color = cursor->image.fg_color; - viacursor.image.bg_color = cursor->image.bg_color; - - switch (info->var.bits_per_pixel) { - case 8: - case 16: - case 32: - bg_col = - (0xFF << 24) | - (((info->cmap.red)[viacursor.image.bg_color] & - 0xFF00) << 8) | - ((info->cmap.green)[viacursor.image.bg_color] & - 0xFF00) | - (((info->cmap.blue)[viacursor.image.bg_color] & - 0xFF00) >> 8); - fg_col = - (0xFF << 24) | - (((info->cmap.red)[viacursor.image.fg_color] & - 0xFF00) << 8) | - ((info->cmap.green)[viacursor.image.fg_color] & - 0xFF00) | - (((info->cmap.blue)[viacursor.image.fg_color] & - 0xFF00) >> 8); - break; - default: - return 0; - } - - /* This is indeed a patch for VT3324/VT3353 */ - if (!info->par) - return 0; - p_viafb_par = (struct viafb_par *)info->par; - - if ((p_viafb_par->chip_info->gfx_chip_name == - UNICHROME_CX700) || - ((p_viafb_par->chip_info->gfx_chip_name == - UNICHROME_VX800))) { - bg_col = - (((info->cmap.red)[viacursor.image.bg_color] & - 0xFFC0) << 14) | - (((info->cmap.green)[viacursor.image.bg_color] & - 0xFFC0) << 4) | - (((info->cmap.blue)[viacursor.image.bg_color] & - 0xFFC0) >> 6); - fg_col = - (((info->cmap.red)[viacursor.image.fg_color] & - 0xFFC0) << 14) | - (((info->cmap.green)[viacursor.image.fg_color] & - 0xFFC0) << 4) | - (((info->cmap.blue)[viacursor.image.fg_color] & - 0xFFC0) >> 6); + fg_color = cursor->image.fg_color; + bg_color = cursor->image.bg_color; + if (chip_name == UNICHROME_CX700 || + chip_name == UNICHROME_VX800 || + chip_name == UNICHROME_VX855) { + fg_color = + ((info->cmap.red[fg_color] & 0xFFC0) << 14) | + ((info->cmap.green[fg_color] & 0xFFC0) << 4) | + ((info->cmap.blue[fg_color] & 0xFFC0) >> 6); + bg_color = + ((info->cmap.red[bg_color] & 0xFFC0) << 14) | + ((info->cmap.green[bg_color] & 0xFFC0) << 4) | + ((info->cmap.blue[bg_color] & 0xFFC0) >> 6); + } else { + fg_color = + ((info->cmap.red[fg_color] & 0xFF00) << 8) | + (info->cmap.green[fg_color] & 0xFF00) | + ((info->cmap.blue[fg_color] & 0xFF00) >> 8); + bg_color = + ((info->cmap.red[bg_color] & 0xFF00) << 8) | + (info->cmap.green[bg_color] & 0xFF00) | + ((info->cmap.blue[bg_color] & 0xFF00) >> 8); } - writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); - writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); + writel(bg_color, engine + VIA_REG_CURSOR_BG); + writel(fg_color, engine + VIA_REG_CURSOR_FG); } if (cursor->set & FB_CUR_SETSHAPE) { struct { - u8 data[CURSOR_SIZE / 8]; - u32 bak[CURSOR_SIZE / 32]; + u8 data[CURSOR_SIZE]; + u32 bak[CURSOR_SIZE / 4]; } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); - int size = - ((viacursor.image.width + 7) >> 3) * - viacursor.image.height; + int size = ((cursor->image.width + 7) >> 3) * + cursor->image.height; - if (cr_data == NULL) - goto out; + if (!cr_data) + return -ENOMEM; - if (MAX_CURS == 32) { - for (i = 0; i < (CURSOR_SIZE / 32); i++) { + if (cur_size == 32) { + for (i = 0; i < (CURSOR_SIZE / 4); i++) { cr_data->bak[i] = 0x0; cr_data->bak[i + 1] = 0xFFFFFFFF; i += 1; } - } else if (MAX_CURS == 64) { - for (i = 0; i < (CURSOR_SIZE / 32); i++) { + } else { + for (i = 0; i < (CURSOR_SIZE / 4); i++) { cr_data->bak[i] = 0x0; cr_data->bak[i + 1] = 0x0; cr_data->bak[i + 2] = 0xFFFFFFFF; @@ -1211,27 +966,27 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) } } - switch (viacursor.rop) { + switch (cursor->rop) { case ROP_XOR: for (i = 0; i < size; i++) - cr_data->data[i] = viacursor.mask[i]; + cr_data->data[i] = cursor->mask[i]; break; case ROP_COPY: for (i = 0; i < size; i++) - cr_data->data[i] = viacursor.mask[i]; + cr_data->data[i] = cursor->mask[i]; break; default: break; } - if (MAX_CURS == 32) { + if (cur_size == 32) { for (i = 0; i < size; i++) { cr_data->bak[j] = (u32) cr_data->data[i]; cr_data->bak[j + 1] = ~cr_data->bak[j]; j += 2; } - } else if (MAX_CURS == 64) { + } else { for (i = 0; i < size; i++) { cr_data->bak[j] = (u32) cr_data->data[i]; cr_data->bak[j + 1] = 0x0; @@ -1241,14 +996,12 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) } } - memcpy(((struct viafb_par *)(info->par))->fbmem_virt + - ((struct viafb_par *)(info->par))->cursor_start, - cr_data->bak, CURSOR_SIZE); -out: + memcpy_toio(viafbinfo->screen_base + viapar->shared-> + cursor_vram_addr, cr_data->bak, CURSOR_SIZE); kfree(cr_data); } - if (viacursor.enable) + if (cursor->enable) viafb_show_hw_cursor(info, HW_Cursor_ON); return 0; @@ -1256,8 +1009,8 @@ out: static int viafb_sync(struct fb_info *info) { - if (viafb_accel) - viafb_wait_engine_idle(); + if (!(info->flags & FBINFO_HWACCEL_DISABLED)) + viafb_wait_engine_idle(info); return 0; } @@ -1266,12 +1019,16 @@ int viafb_get_mode_index(int hres, int vres) u32 i; DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); - for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++) - if (viafb_modentry[i].xres == hres && - viafb_modentry[i].yres == vres) + for (i = 0; i < NUM_TOTAL_MODETABLE; i++) + if (CLE266Modes[i].mode_array && + CLE266Modes[i].crtc[0].crtc.hor_addr == hres && + CLE266Modes[i].crtc[0].crtc.ver_addr == vres) break; - return viafb_modentry[i].mode_index; + if (i == NUM_TOTAL_MODETABLE) + return VIA_RES_INVALID; + + return CLE266Modes[i].ModeIndex; } static void check_available_device_to_enable(int device_id) @@ -1375,36 +1132,11 @@ static void viafb_set_device(struct device_t active_dev) viafb_SAMM_ON = active_dev.samm; viafb_primary_dev = active_dev.primary_dev; - viafb_set_start_addr(); + viafb_set_primary_address(0); + viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); viafb_set_iga_path(); } -static void viafb_set_video_device(u32 video_dev_info) -{ - viaparinfo->video_on_crt = STATE_OFF; - viaparinfo->video_on_dvi = STATE_OFF; - viaparinfo->video_on_lcd = STATE_OFF; - - /* Check available device to enable: */ - if ((video_dev_info & CRT_Device) == CRT_Device) - viaparinfo->video_on_crt = STATE_ON; - else if ((video_dev_info & DVI_Device) == DVI_Device) - viaparinfo->video_on_dvi = STATE_ON; - else if ((video_dev_info & LCD_Device) == LCD_Device) - viaparinfo->video_on_lcd = STATE_ON; -} - -static void viafb_get_video_device(u32 *video_dev_info) -{ - *video_dev_info = None_Device; - if (viaparinfo->video_on_crt == STATE_ON) - *video_dev_info |= CRT_Device; - else if (viaparinfo->video_on_dvi == STATE_ON) - *video_dev_info |= DVI_Device; - else if (viaparinfo->video_on_lcd == STATE_ON) - *video_dev_info |= LCD_Device; -} - static int get_primary_device(void) { int primary_device = 0; @@ -1446,18 +1178,6 @@ static int get_primary_device(void) return primary_device; } -static u8 is_duoview(void) -{ - if (0 == viafb_SAMM_ON) { - if (viafb_LCD_ON + viafb_LCD2_ON + - viafb_DVI_ON + viafb_CRT_ON == 2) - return true; - return false; - } else { - return false; - } -} - static void apply_second_mode_setting(struct fb_var_screeninfo *sec_var) { @@ -1559,14 +1279,13 @@ static int apply_device_setting(struct viafb_ioctl_setting setting_info, if (viafb_SAMM_ON) viafb_primary_dev = setting_info.primary_device; - viafb_set_start_addr(); + viafb_set_primary_address(0); + viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); viafb_set_iga_path(); } need_set_mode = 1; } - viaparinfo->duoview = is_duoview(); - if (!need_set_mode) { ; } else { @@ -1589,18 +1308,6 @@ static void retrieve_device_setting(struct viafb_ioctl_setting setting_info->device_status |= LCD_Device; if (viafb_LCD2_ON == 1) setting_info->device_status |= LCD2_Device; - if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) { - setting_info->video_device_status = - viaparinfo->crt_setting_info->iga_path; - } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) { - setting_info->video_device_status = - viaparinfo->tmds_setting_info->iga_path; - } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) { - setting_info->video_device_status = - viaparinfo->lvds_setting_info->iga_path; - } else { - setting_info->video_device_status = 0; - } setting_info->samm_status = viafb_SAMM_ON; setting_info->primary_device = get_primary_device(); @@ -1687,25 +1394,6 @@ static void parse_active_dev(void) viafb_CRT_ON = STATE_ON; viafb_SAMM_ON = STATE_OFF; } - viaparinfo->duoview = is_duoview(); -} - -static void parse_video_dev(void) -{ - viaparinfo->video_on_crt = STATE_OFF; - viaparinfo->video_on_dvi = STATE_OFF; - viaparinfo->video_on_lcd = STATE_OFF; - - if (!strncmp(viafb_video_dev, "CRT", 3)) { - /* Video on CRT */ - viaparinfo->video_on_crt = STATE_ON; - } else if (!strncmp(viafb_video_dev, "DVI", 3)) { - /* Video on DVI */ - viaparinfo->video_on_dvi = STATE_ON; - } else if (!strncmp(viafb_video_dev, "LCD", 3)) { - /* Video on LCD */ - viaparinfo->video_on_lcd = STATE_ON; - } } static int parse_port(char *opt_str, int *output_interface) @@ -1754,10 +1442,8 @@ static void parse_dvi_port(void) * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], * CR9B, SR65, CR97, CR99 */ -static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset, -int count, int *eof, void *data) +static int viafb_dvp0_proc_show(struct seq_file *m, void *v) { - int len = 0; u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0; dvp0_data_dri = (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 | @@ -1766,13 +1452,17 @@ int count, int *eof, void *data) (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 | (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2; dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f; - len += - sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); - *eof = 1; /*Inform kernel end of data */ - return len; + seq_printf(m, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri); + return 0; } -static int viafb_dvp0_proc_write(struct file *file, - const char __user *buffer, unsigned long count, void *data) + +static int viafb_dvp0_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_dvp0_proc_show, NULL); +} + +static ssize_t viafb_dvp0_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { char buf[20], *value, *pbuf; u8 reg_val = 0; @@ -1816,21 +1506,33 @@ static int viafb_dvp0_proc_write(struct file *file, } return count; } -static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset, - int count, int *eof, void *data) + +static const struct file_operations viafb_dvp0_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_dvp0_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_dvp0_proc_write, +}; + +static int viafb_dvp1_proc_show(struct seq_file *m, void *v) { - int len = 0; u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0; dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f; dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2; dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03; - len += - sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); - *eof = 1; /*Inform kernel end of data */ - return len; + seq_printf(m, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri); + return 0; } -static int viafb_dvp1_proc_write(struct file *file, - const char __user *buffer, unsigned long count, void *data) + +static int viafb_dvp1_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_dvp1_proc_show, NULL); +} + +static ssize_t viafb_dvp1_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { char buf[20], *value, *pbuf; u8 reg_val = 0; @@ -1869,18 +1571,30 @@ static int viafb_dvp1_proc_write(struct file *file, return count; } -static int viafb_dfph_proc_read(char *buf, char **start, off_t offset, - int count, int *eof, void *data) +static const struct file_operations viafb_dvp1_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_dvp1_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_dvp1_proc_write, +}; + +static int viafb_dfph_proc_show(struct seq_file *m, void *v) { - int len = 0; u8 dfp_high = 0; dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f; - len += sprintf(buf + len, "%x\n", dfp_high); - *eof = 1; /*Inform kernel end of data */ - return len; + seq_printf(m, "%x\n", dfp_high); + return 0; } -static int viafb_dfph_proc_write(struct file *file, - const char __user *buffer, unsigned long count, void *data) + +static int viafb_dfph_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_dfph_proc_show, NULL); +} + +static ssize_t viafb_dfph_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { char buf[20]; u8 reg_val = 0; @@ -1895,18 +1609,31 @@ static int viafb_dfph_proc_write(struct file *file, viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); return count; } -static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset, - int count, int *eof, void *data) + +static const struct file_operations viafb_dfph_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_dfph_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_dfph_proc_write, +}; + +static int viafb_dfpl_proc_show(struct seq_file *m, void *v) { - int len = 0; u8 dfp_low = 0; dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f; - len += sprintf(buf + len, "%x\n", dfp_low); - *eof = 1; /*Inform kernel end of data */ - return len; + seq_printf(m, "%x\n", dfp_low); + return 0; } -static int viafb_dfpl_proc_write(struct file *file, - const char __user *buffer, unsigned long count, void *data) + +static int viafb_dfpl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_dfpl_proc_show, NULL); +} + +static ssize_t viafb_dfpl_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { char buf[20]; u8 reg_val = 0; @@ -1921,10 +1648,18 @@ static int viafb_dfpl_proc_write(struct file *file, viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); return count; } -static int viafb_vt1636_proc_read(char *buf, char **start, - off_t offset, int count, int *eof, void *data) + +static const struct file_operations viafb_dfpl_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_dfpl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_dfpl_proc_write, +}; + +static int viafb_vt1636_proc_show(struct seq_file *m, void *v) { - int len = 0; u8 vt1636_08 = 0, vt1636_09 = 0; switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { case VT1636_LVDS: @@ -1934,7 +1669,7 @@ static int viafb_vt1636_proc_read(char *buf, char **start, vt1636_09 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f; - len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09); + seq_printf(m, "%x %x\n", vt1636_08, vt1636_09); break; default: break; @@ -1947,16 +1682,21 @@ static int viafb_vt1636_proc_read(char *buf, char **start, vt1636_09 = viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f; - len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09); + seq_printf(m, " %x %x\n", vt1636_08, vt1636_09); break; default: break; } - *eof = 1; /*Inform kernel end of data */ - return len; + return 0; } -static int v |