📄 sa1100fb.c
字号:
par->palette_size = 0; break;#endif default: return -EINVAL; } palette_mem_size = SA1100_PALETTE_MEM_SIZE(par->bits_per_pixel); palette_mem_phys = (u_long)VideoMemRegion_phys + PAGE_SIZE - palette_mem_size; par->p_palette_base = (u_short *)palette_mem_phys; par->v_palette_base = (u_short *)((u_long)VideoMemRegion + PAGE_SIZE - palette_mem_size); par->p_screen_base = (u_char *)((u_long)VideoMemRegion_phys + PAGE_SIZE); par->v_screen_base = (u_char *)((u_long)VideoMemRegion + PAGE_SIZE); DPRINTK("p_palette_base = 0x%08lx\n",(u_long)par->p_palette_base); DPRINTK("v_palette_base = 0x%08lx\n",(u_long)par->v_palette_base); DPRINTK("palette_size = 0x%08lx\n",(u_long)par->palette_size); DPRINTK("palette_mem_size = 0x%08lx\n",(u_long)palette_mem_size); DPRINTK("p_screen_base = 0x%08lx\n",(u_long)par->p_screen_base); DPRINTK("v_screen_base = 0x%08lx\n",(u_long)par->v_screen_base); DPRINTK("VideoMemRegion = 0x%08lx\n",(u_long)VideoMemRegion); DPRINTK("VideoMemRegion_phys = 0x%08lx\n",(u_long)VideoMemRegion_phys); return 0;}static intsa1100fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct sa1100fb_par par; DPRINTK("con=%d\n", con); if (con == -1) { sa1100fb_get_par(&par); sa1100fb_encode_var(var, &par); } else *var = fb_display[con].var; return 0;}/* * sa1100fb_set_var(): * Set the user defined part of the display for the specified console */static intsa1100fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct display *display; int err, chgvar = 0; struct sa1100fb_par par; if (con >= 0) display = &fb_display[con]; /* Display settings for console */ else display = &global_disp; /* Default display settings */ /* Decode var contents into a par structure, adjusting any */ /* out of range values. */ if ((err = sa1100fb_decode_var(var, &par))) return err; // Store adjusted par values into var structure sa1100fb_encode_var(var, &par); if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST) return 0; else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) && ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN)) return -EINVAL; if (con >= 0) { if ((display->var.xres != var->xres) || (display->var.yres != var->yres) || (display->var.xres_virtual != var->xres_virtual) || (display->var.yres_virtual != var->yres_virtual) || (display->var.sync != var->sync) || (display->var.bits_per_pixel != var->bits_per_pixel) || (memcmp(&display->var.red, &var->red, sizeof(var->red))) || (memcmp(&display->var.green, &var->green, sizeof(var->green))) || (memcmp(&display->var.blue, &var->blue, sizeof(var->blue)))) chgvar = 1; } display->var = *var; display->screen_base = par.v_screen_base; display->visual = par.visual; display->type = FB_TYPE_PACKED_PIXELS; display->type_aux = 0; display->ypanstep = 0; display->ywrapstep = 0; display->line_length = display->next_line = (var->xres * var->bits_per_pixel) / 8; display->can_soft_blank = 1; display->inverse = 0; switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB4 case 4: display->dispsw = &fbcon_cfb4; break;#endif#ifdef FBCON_HAS_CFB8 case 8: display->dispsw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: display->dispsw = &fbcon_cfb16; break;#endif default: display->dispsw = &fbcon_dummy; break; } /* If the console has changed and the console has defined */ /* a changevar function, call that function. */ if (chgvar && info && info->changevar) info->changevar(con); /* If the current console is selected and it's not truecolor, * update the palette */ if ((con == current_par.currcon) && (current_par.visual != FB_VISUAL_TRUECOLOR)) { struct fb_cmap *cmap; current_par = par; if (display->cmap.len) cmap = &display->cmap; else cmap = fb_default_cmap(current_par.palette_size); fb_set_cmap(cmap, 1, sa1100fb_setcolreg, info); } /* If the current console is selected, activate the new var. */ if (con == current_par.currcon) sa1100fb_activate_var(var); return 0;}static intsa1100fb_updatevar(int con, struct fb_info *info){ DPRINTK("entered\n"); return 0;}static intsa1100fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct display *display; memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, SA1100_NAME); if (con >= 0) { DPRINTK("Using console specific display for con=%d\n",con); display = &fb_display[con]; /* Display settings for console */ } else display = &global_disp; /* Default display settings */ fix->smem_start = (unsigned long)current_par.p_screen_base; fix->smem_len = current_par.screen_size; fix->type = display->type; fix->type_aux = display->type_aux; fix->xpanstep = 0; fix->ypanstep = display->ypanstep; fix->ywrapstep = display->ywrapstep; fix->visual = display->visual; fix->line_length = display->line_length; fix->accel = FB_ACCEL_NONE; return 0;}static void__init sa1100fb_init_fbinfo(void){ strcpy(fb_info.modename, SA1100_NAME); strcpy(fb_info.fontname, "Acorn8x8"); fb_info.node = -1; fb_info.flags = FBINFO_FLAG_DEFAULT; fb_info.fbops = &sa1100fb_ops; fb_info.monspecs = monspecs; fb_info.disp = &global_disp; fb_info.changevar = NULL; fb_info.switch_con = sa1100fb_switch; fb_info.updatevar = sa1100fb_updatevar; fb_info.blank = sa1100fb_blank; /* * setup initial parameters */ memset(&init_var, 0, sizeof(init_var)); init_var.transp.length = 0; init_var.nonstd = 0; init_var.activate = FB_ACTIVATE_NOW; init_var.xoffset = 0; init_var.yoffset = 0; init_var.height = -1; init_var.width = -1; init_var.vmode = FB_VMODE_NONINTERLACED; if (machine_is_assabet()) { current_par.max_xres = 320; current_par.max_yres = 240; current_par.max_bpp = 16; init_var.red.length = 5; init_var.green.length = 6; init_var.blue.length = 5; init_var.grayscale = 0; init_var.sync = 0; init_var.pixclock = 171521; } else if (machine_is_cerf()) { current_par.max_xres = 320; current_par.max_yres = 240; current_par.max_bpp = 8; init_var.red.length = 4; init_var.green.length = 4; init_var.blue.length = 4; init_var.grayscale = 0; init_var.sync = 0; init_var.pixclock = 171521; } else if (machine_is_bitsy()) { current_par.max_xres = 320; current_par.max_yres = 240; current_par.max_bpp = 16; init_var.red.length = 4; init_var.green.length = 4; init_var.blue.length = 4; init_var.red.offset = 12; init_var.green.offset = 7; init_var.blue.offset = 1; init_var.grayscale = 0; } else if (machine_is_brutus()) { current_par.max_xres = 320; current_par.max_yres = 240; current_par.max_bpp = 8; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.sync = 0; } else if (machine_is_lart()) { current_par.max_xres = 320; current_par.max_yres = 240; current_par.max_bpp = 4; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.grayscale = 1; init_var.pixclock = 150000; init_var.sync = 0; } else if (machine_is_penny()) { current_par.max_xres = 640; current_par.max_yres = 480; current_par.max_bpp = 8; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.sync = 0; } else if (machine_is_thinclient() || machine_is_graphicsclient()) { current_par.max_xres = 640; current_par.max_yres = 480; current_par.max_bpp = 8; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.sync = 0; } else if (machine_is_tifon()) { current_par.max_xres = 640; current_par.max_yres = 200; current_par.max_bpp = 4; current_par.inv_4bpp = 1; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.grayscale = 1; init_var.pixclock = 150000; init_var.left_margin = 20; init_var.right_margin = 255; init_var.upper_margin = 20; init_var.lower_margin = 0; init_var.hsync_len = 2; init_var.vsync_len = 1; init_var.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT; init_var.vmode = 0; } else if (machine_is_xp860()) { current_par.max_xres = 1024; current_par.max_yres = 768; current_par.max_bpp = 8; init_var.red.length = 4; init_var.green = init_var.red; init_var.blue = init_var.red; init_var.hsync_len = 4; init_var.left_margin = 3; init_var.right_margin = 2; init_var.vsync_len = 3; init_var.upper_margin = 2; init_var.lower_margin = 1; } current_par.p_palette_base = NULL; current_par.v_palette_base = NULL; current_par.p_screen_base = NULL; current_par.v_screen_base = NULL; current_par.palette_size = MAX_PALETTE_NUM_ENTRIES; current_par.screen_size = MAX_PIXEL_MEM_SIZE; current_par.montype = -1; current_par.currcon = -1; current_par.allow_modeset = 1; current_par.controller_state = LCD_MODE_DISABLED; init_var.xres = current_par.max_xres; init_var.yres = current_par.max_yres; init_var.xres_virtual = init_var.xres; init_var.yres_virtual = init_var.yres; init_var.bits_per_pixel = current_par.max_bpp; }/* * sa1100fb_map_video_memory(): * Allocates the DRAM memory for the frame buffer. This buffer is * remapped into a non-cached, non-buffered, memory region to * allow palette and pixel writes to occur without flushing the * cache. Once this area is remapped, all virtual memory * access to the video memory should occur at the new region. */static int__init sa1100fb_map_video_memory(void){ u_int required_pages; u_int extra_pages; u_int order; struct page *page; char *allocated_region; if (VideoMemRegion != NULL) return -EINVAL; DPRINTK("-1-"); /* Find order required to allocate enough memory for framebuffer */ required_pages = ALLOCATED_FB_MEM_SIZE >> PAGE_SHIFT; for (order = 0 ; required_pages >> order ; order++) {;} extra_pages = (1 << order) - required_pages; if ((allocated_region = (char *)__get_free_pages(GFP_KERNEL | GFP_DMA, order)) == NULL) return -ENOMEM; VideoMemRegion = (u_char *)allocated_region + (extra_pages << PAGE_SHIFT); VideoMemRegion_phys = (u_char *)__virt_to_phys((u_long)VideoMemRegion); /* Free all pages that we don't need but were given to us because */ /* __get_free_pages() works on powers of 2. */ for (;extra_pages;extra_pages--) free_page((u_int)allocated_region + ((extra_pages-1) << PAGE_SHIFT)); /* Set reserved flag for fb memory to allow it to be remapped into */ /* user space by the common fbmem driver using remap_page_range(). */ for(page = virt_to_page(VideoMemRegion); page < virt_to_page(VideoMemRegion + ALLOCATED_FB_MEM_SIZE); page++) mem_map_reserve(page); /* Remap the fb memory to a non-buffered, non-cached region */ VideoMemRegion = (u_char *)__ioremap((u_long)VideoMemRegion_phys, ALLOCATED_FB_MEM_SIZE, L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE); return (VideoMemRegion == NULL ? -EINVAL : 0);}static const int frequency[16] = { 59000000, 73700000, 88500000, 103200000, 118000000, 132700000, 147500000, 162200000, 176900000, 191700000, 206400000, 230000000, 245000000, 260000000, 275000000, 290000000};static inline int get_pcd(unsigned int pixclock){ unsigned int pcd = 0; if (machine_is_tifon()) { pcd = frequency[PPCR &0xf] / 1000; pcd *= pixclock/1000; pcd = pcd / 10000000 * 12; /* the last multiplication by 1.2 is to handle */ /* sync problems */ } if (machine_is_assabet()) { pcd = frequency[PPCR & 0xf] / 1000; pcd *= pixclock / 1000; pcd = pcd / 1000000; pcd++; /* make up for integer math truncations */ } return pcd;}/* * sa1100fb_activate_var(): * Configures LCD Controller based on entries in var parameter. Settings are * only written to the controller if changes were made. */static intsa1100fb_activate_var(struct fb_var_screeninfo *var){ u_long flags; int pcd = get_pcd(var->pixclock); DPRINTK("Configuring SA1100 LCD\n"); if (current_par.p_palette_base == NULL) return -EINVAL; DPRINTK("activating\n"); /* Disable interrupts and save status */ local_irq_save(flags); // disable the interrupts and save flags /* Reset the LCD Controller's DMA address if it has changed */ lcd_shadow.dbar1 = (Address)current_par.p_palette_base; lcd_shadow.dbar2 = (Address)(current_par.p_screen_base + (current_par.xres * current_par.yres * current_par.bits_per_pixel / 8 / 2));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -