/* * fbmem.c * * Copyright (C) 1994 Martin Schaller * * 2001 - Documented with DocBook * - Brad Douglas * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ #include "bas_types.h" #include "bas_printf.h" #include "bas_string.h" #include "fb.h" #include "radeonfb.h" #include "driver_mem.h" #define DBG_FBMEM #ifdef DBG_FBMEM #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #else #define dbg(format, arg...) do { ; } while (0) #endif /* DBG_FBMEM */ long mem_cmp(char *p1, char *p2, long size) { while(size--) { if (*p1++ != *p2++) return(1); } return(0); } /* * Frame buffer device initialization and setup routines */ #define FBPIXMAPSIZE (1024 * 8) int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) { int xoffset = var->xoffset; int yoffset = var->yoffset; int err; // DPRINT("fb_pan_display\r\n"); if ((xoffset < 0) || (yoffset < 0) || ((xoffset + info->var.xres) > info->var.xres_virtual)) return -1; //-EINVAL; if ((err = info->fbops->fb_pan_display(var, info))) return err; info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; if (var->vmode & FB_VMODE_YWRAP) info->var.vmode |= FB_VMODE_YWRAP; else info->var.vmode &= ~FB_VMODE_YWRAP; return 0; } int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) { int err; // DPRINT("fb_set_var\r\n"); if (var->activate & FB_ACTIVATE_INV_MODE) /* return 1 if equal */ return(!mem_cmp((char *)&info->var, (char *)var, sizeof(struct fb_var_screeninfo))); if ((var->activate & FB_ACTIVATE_FORCE) || mem_cmp((char *)&info->var, (char *)var, sizeof(struct fb_var_screeninfo))) { if ((err = info->fbops->fb_check_var(var, info))) return err; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { memcpy(&info->var, var, sizeof(struct fb_var_screeninfo)); info->fbops->fb_set_par(info); fb_pan_display(info, &info->var); } } return 0; } int fb_blank(struct fb_info *info, int blank) { dbg("fb_blank\r\n"); if (blank > FB_BLANK_POWERDOWN) blank = FB_BLANK_POWERDOWN; return(info->fbops->fb_blank(blank, info)); } int fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; void *argp = (void *) arg; int i; switch(cmd) { case FBIOGET_VSCREENINFO: memcpy(argp, &info->var, sizeof(var)); return 0; case FBIOPUT_VSCREENINFO: memcpy(&var, argp, sizeof(var)); i = fb_set_var(info, &var); if (i) return i; memcpy(argp, &var, sizeof(var)); return 0; case FBIOGET_FSCREENINFO: memcpy(argp, &info->fix, sizeof(fix)); return 0; case FBIOPAN_DISPLAY: memcpy(&var, argp, sizeof(var)); i = fb_pan_display(info, &var); if (i) return i; memcpy(argp, &var, sizeof(var)); return 0; case FBIOBLANK: i = fb_blank(info, arg); return i; case FBIO_ALLOC: return(offscreen_alloc(info,(long)arg)); case FBIO_FREE: return(offscreen_free(info,(long)arg)); default: return(info->fbops->fb_ioctl(cmd, arg, info)); } } /** * framebuffer_alloc - creates a new frame buffer info structure * * @size: size of driver private data, can be zero * @dev: pointer to the device for this fb, this can be NULL * * Creates a new frame buffer info structure. Also reserves @size bytes * for driver private data (info->par). info->par (if any) will be * aligned to sizeof(long). * * Returns the new structure, or NULL if an error occured. * */ struct fb_info *framebuffer_alloc(unsigned long size) { /* changed for BaS_gcc: * we do not allocate anything here anymore, info_fb is statically allocated in video.c * This leads to the (not really existing) limitation that we only support one Radeon * card in the system */ extern struct fb_info *info_fb; return info_fb; } /** * framebuffer_release - marks the structure available for freeing * * @info: frame buffer info structure * * Drop the reference count of the class_device embedded in the * framebuffer info structure. * */ void framebuffer_release(struct fb_info *info) { driver_mem_free(info->par); }