175 lines
4.7 KiB
C
175 lines
4.7 KiB
C
/*
|
|
* fbmem.c
|
|
*
|
|
* Copyright (C) 1994 Martin Schaller
|
|
*
|
|
* 2001 - Documented with DocBook
|
|
* - Brad Douglas <brad@neruo.com>
|
|
*
|
|
* 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);
|
|
}
|
|
|