📄 viafbdev.c
字号:
}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"); if (!viafb_accel) { cfb_copyarea(info, area); return; } 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);}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; if (!viafb_accel) { 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++; }}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; } if ((((struct viafb_par *)(info->par))->iga_path == IGA2) && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) return -ENODEV; /* When duoview and using lcd , use soft cursor */ if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview) 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); } 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); } if (cursor->set & FB_CUR_SETSIZE) { temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); if ((cursor->image.width <= 32) && (cursor->image.height <= 32)) { MAX_CURS = 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); viacursor.image.height = cursor->image.height; viacursor.image.width = cursor->image.width; } 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); } writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG); writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG); } if (cursor->set & FB_CUR_SETSHAPE) { struct { u8 data[CURSOR_SIZE / 8]; u32 bak[CURSOR_SIZE / 32]; } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); int size = ((viacursor.image.width + 7) >> 3) * viacursor.image.height; if (cr_data == NULL) goto out; if (MAX_CURS == 32) { for (i = 0; i < (CURSOR_SIZE / 32); 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++) { cr_data->bak[i] = 0x0; cr_data->bak[i + 1] = 0x0; cr_data->bak[i + 2] = 0xFFFFFFFF; cr_data->bak[i + 3] = 0xFFFFFFFF; i += 3; } } switch (viacursor.rop) { case ROP_XOR: for (i = 0; i < size; i++) cr_data->data[i] = viacursor.mask[i]; break; case ROP_COPY: for (i = 0; i < size; i++) cr_data->data[i] = viacursor.mask[i]; break; default: break; } if (MAX_CURS == 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) { for (i = 0; i < size; i++) { cr_data->bak[j] = (u32) cr_data->data[i]; cr_data->bak[j + 1] = 0x0; cr_data->bak[j + 2] = ~cr_data->bak[j]; cr_data->bak[j + 3] = ~cr_data->bak[j + 1]; j += 4; } } memcpy(((struct viafb_par *)(info->par))->fbmem_virt + ((struct viafb_par *)(info->par))->cursor_start, cr_data->bak, CURSOR_SIZE);out: kfree(cr_data); } if (viacursor.enable) viafb_show_hw_cursor(info, HW_Cursor_ON); return 0;}static int viafb_sync(struct fb_info *info){ if (viafb_accel) viafb_wait_engine_idle(); return 0;}int viafb_get_mode_index(int hres, int vres, int flag){ 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) break; viafb_resMode = viafb_modentry[i].mode_index; if (flag) viafb_mode1 = viafb_modentry[i].mode_res; else viafb_mode = viafb_modentry[i].mode_res; return viafb_resMode;}static void check_available_device_to_enable(int device_id){ int device_num = 0; /* Initialize: */ viafb_CRT_ON = STATE_OFF; viafb_DVI_ON = STATE_OFF; viafb_LCD_ON = STATE_OFF; viafb_LCD2_ON = STATE_OFF; viafb_DeviceStatus = None_Device; if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { viafb_CRT_ON = STATE_ON; device_num++; viafb_DeviceStatus |= CRT_Device; } if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { viafb_DVI_ON = STATE_ON; device_num++; viafb_DeviceStatus |= DVI_Device; } if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { viafb_LCD_ON = STATE_ON; device_num++; viafb_DeviceStatus |= LCD_Device; } if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) { viafb_LCD2_ON = STATE_ON; device_num++; viafb_DeviceStatus |= LCD2_Device; } if (viafb_DeviceStatus == None_Device) { /* Use CRT as default active device: */ viafb_CRT_ON = STATE_ON; viafb_DeviceStatus = CRT_Device; } DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);}static void viafb_set_device(struct device_t active_dev){ /* Check available device to enable: */ int device_id = None_Device; if (active_dev.crt) device_id |= CRT_Device; if (active_dev.dvi) device_id |= DVI_Device; if (active_dev.lcd) device_id |= LCD_Device; check_available_device_to_enable(device_id); /* Check property of LCD: */ if (viafb_LCD_ON) { if (active_dev.lcd_dsp_cent) { viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method = LCD_CENTERING; } else { viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method = LCD_EXPANDSION; } if (active_dev.lcd_mode == LCD_SPWG) { viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode = LCD_SPWG; } else { viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode = LCD_OPENLDI; } if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) { viafb_lcd_panel_id = active_dev.lcd_panel_id; viafb_init_lcd_size(); } } /* Check property of mode: */ if (!active_dev.xres1) viafb_second_xres = 640; else viafb_second_xres = active_dev.xres1; if (!active_dev.yres1) viafb_second_yres = 480; else viafb_second_yres = active_dev.yres1; if (active_dev.bpp != 0) viafb_bpp = active_dev.bpp; if (active_dev.bpp1 != 0) viafb_bpp1 = active_dev.bpp1; if (active_dev.refresh != 0) viafb_refresh = active_dev.refresh; if (active_dev.refresh1 != 0) viafb_refresh1 = active_dev.refresh1; if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON)) viafb_SAMM_ON = active_dev.samm; viafb_primary_dev = active_dev.primary_dev; viafb_set_start_addr(); 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: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -