|
@@ -710,7 +710,7 @@ static u_short *lofsprite, *shfsprite, *dummysprite;
|
|
|
* Current Video Mode
|
|
|
*/
|
|
|
|
|
|
-static struct amifb_par {
|
|
|
+struct amifb_par {
|
|
|
|
|
|
/* General Values */
|
|
|
|
|
@@ -773,15 +773,6 @@ static struct amifb_par {
|
|
|
/* Additional AGA Hardware Registers */
|
|
|
|
|
|
u_short fmode; /* vmode */
|
|
|
-} currentpar;
|
|
|
-
|
|
|
-
|
|
|
-static struct fb_info fb_info = {
|
|
|
- .fix = {
|
|
|
- .id = "Amiga ",
|
|
|
- .visual = FB_VISUAL_PSEUDOCOLOR,
|
|
|
- .accel = FB_ACCEL_AMIGABLITT
|
|
|
- }
|
|
|
};
|
|
|
|
|
|
|
|
@@ -1130,8 +1121,8 @@ static u_short sprfetchmode[3] = {
|
|
|
* it up, if it's too big, return -EINVAL.
|
|
|
*/
|
|
|
|
|
|
-static int ami_decode_var(struct fb_var_screeninfo *var,
|
|
|
- struct amifb_par *par)
|
|
|
+static int ami_decode_var(struct fb_var_screeninfo *var, struct amifb_par *par,
|
|
|
+ const struct fb_info *info)
|
|
|
{
|
|
|
u_short clk_shift, line_shift;
|
|
|
u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
|
|
@@ -1449,14 +1440,14 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
|
|
|
if (amifb_ilbm) {
|
|
|
par->next_plane = div8(upx(16 << maxfmode, par->vxres));
|
|
|
par->next_line = par->bpp * par->next_plane;
|
|
|
- if (par->next_line * par->vyres > fb_info.fix.smem_len) {
|
|
|
+ if (par->next_line * par->vyres > info->fix.smem_len) {
|
|
|
DPRINTK("too few video mem\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
} else {
|
|
|
par->next_line = div8(upx(16 << maxfmode, par->vxres));
|
|
|
par->next_plane = par->vyres * par->next_line;
|
|
|
- if (par->next_plane * par->bpp > fb_info.fix.smem_len) {
|
|
|
+ if (par->next_plane * par->bpp > info->fix.smem_len) {
|
|
|
DPRINTK("too few video mem\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -1519,8 +1510,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
|
|
|
* other values read out of the hardware.
|
|
|
*/
|
|
|
|
|
|
-static int ami_encode_var(struct fb_var_screeninfo *var,
|
|
|
- struct amifb_par *par)
|
|
|
+static void ami_encode_var(struct fb_var_screeninfo *var,
|
|
|
+ struct amifb_par *par)
|
|
|
{
|
|
|
u_short clk_shift, line_shift;
|
|
|
|
|
@@ -1596,8 +1587,6 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
|
|
|
var->sync |= FB_SYNC_EXT;
|
|
|
if (par->vmode & FB_VMODE_YWRAP)
|
|
|
var->vmode |= FB_VMODE_YWRAP;
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1605,9 +1594,9 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
|
|
|
* Update hardware
|
|
|
*/
|
|
|
|
|
|
-static int ami_update_par(void)
|
|
|
+static void ami_update_par(struct fb_info *info)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
+ struct amifb_par *par = info->par;
|
|
|
short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
|
|
|
|
|
|
clk_shift = par->clk_shift;
|
|
@@ -1649,11 +1638,11 @@ static int ami_update_par(void)
|
|
|
par->bpl1mod = par->bpl2mod;
|
|
|
|
|
|
if (par->yoffset) {
|
|
|
- par->bplpt0 = fb_info.fix.smem_start +
|
|
|
+ par->bplpt0 = info->fix.smem_start +
|
|
|
par->next_line * par->yoffset + move;
|
|
|
if (par->vmode & FB_VMODE_YWRAP) {
|
|
|
if (par->yoffset > par->vyres - par->yres) {
|
|
|
- par->bplpt0wrap = fb_info.fix.smem_start + move;
|
|
|
+ par->bplpt0wrap = info->fix.smem_start + move;
|
|
|
if (par->bplcon0 & BPC0_LACE &&
|
|
|
mod2(par->diwstrt_v + par->vyres -
|
|
|
par->yoffset))
|
|
@@ -1661,12 +1650,10 @@ static int ami_update_par(void)
|
|
|
}
|
|
|
}
|
|
|
} else
|
|
|
- par->bplpt0 = fb_info.fix.smem_start + move;
|
|
|
+ par->bplpt0 = info->fix.smem_start + move;
|
|
|
|
|
|
if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
|
|
|
par->bplpt0 += par->next_line;
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1677,9 +1664,9 @@ static int ami_update_par(void)
|
|
|
* in `var'.
|
|
|
*/
|
|
|
|
|
|
-static void ami_pan_var(struct fb_var_screeninfo *var)
|
|
|
+static void ami_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
+ struct amifb_par *par = info->par;
|
|
|
|
|
|
par->xoffset = var->xoffset;
|
|
|
par->yoffset = var->yoffset;
|
|
@@ -1689,15 +1676,13 @@ static void ami_pan_var(struct fb_var_screeninfo *var)
|
|
|
par->vmode &= ~FB_VMODE_YWRAP;
|
|
|
|
|
|
do_vmode_pan = 0;
|
|
|
- ami_update_par();
|
|
|
+ ami_update_par(info);
|
|
|
do_vmode_pan = 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void ami_update_display(void)
|
|
|
+static void ami_update_display(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
-
|
|
|
custom.bplcon1 = par->bplcon1;
|
|
|
custom.bpl1mod = par->bpl1mod;
|
|
|
custom.bpl2mod = par->bpl2mod;
|
|
@@ -1709,9 +1694,8 @@ static void ami_update_display(void)
|
|
|
* Change the video mode (called by VBlank interrupt)
|
|
|
*/
|
|
|
|
|
|
-static void ami_init_display(void)
|
|
|
+static void ami_init_display(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
int i;
|
|
|
|
|
|
custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
|
|
@@ -1764,9 +1748,8 @@ static void ami_init_display(void)
|
|
|
* (Un)Blank the screen (called by VBlank interrupt)
|
|
|
*/
|
|
|
|
|
|
-static void ami_do_blank(void)
|
|
|
+static void ami_do_blank(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
#if defined(CONFIG_FB_AMIGA_AGA)
|
|
|
u_short bplcon3 = par->bplcon3;
|
|
|
#endif
|
|
@@ -1843,10 +1826,9 @@ static void ami_do_blank(void)
|
|
|
is_blanked = do_blank > 0 ? do_blank : 0;
|
|
|
}
|
|
|
|
|
|
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
|
|
|
+static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix,
|
|
|
+ const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
-
|
|
|
fix->crsr_width = fix->crsr_xsize = par->crsr.width;
|
|
|
fix->crsr_height = fix->crsr_ysize = par->crsr.height;
|
|
|
fix->crsr_color1 = 17;
|
|
@@ -1854,9 +1836,10 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
|
|
|
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var,
|
|
|
+ u_char __user *data,
|
|
|
+ const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
register u_short *lspr, *sspr;
|
|
|
#ifdef __mc68000__
|
|
|
register u_long datawords asm ("d2");
|
|
@@ -1929,9 +1912,9 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
|
|
|
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var,
|
|
|
+ u_char __user *data, struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
register u_short *lspr, *sspr;
|
|
|
#ifdef __mc68000__
|
|
|
register u_long datawords asm ("d2");
|
|
@@ -2047,20 +2030,18 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ami_get_cursorstate(struct fb_cursorstate *state)
|
|
|
+static int ami_get_cursorstate(struct fb_cursorstate *state,
|
|
|
+ const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
-
|
|
|
state->xoffset = par->crsr.crsr_x;
|
|
|
state->yoffset = par->crsr.crsr_y;
|
|
|
state->mode = cursormode;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ami_set_cursorstate(struct fb_cursorstate *state)
|
|
|
+static int ami_set_cursorstate(struct fb_cursorstate *state,
|
|
|
+ struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
-
|
|
|
par->crsr.crsr_x = state->xoffset;
|
|
|
par->crsr.crsr_y = state->yoffset;
|
|
|
if ((cursormode = state->mode) == FB_CURSOR_OFF)
|
|
@@ -2069,9 +2050,8 @@ static int ami_set_cursorstate(struct fb_cursorstate *state)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void ami_set_sprite(void)
|
|
|
+static void ami_set_sprite(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
copins *copl, *cops;
|
|
|
u_short hs, vs, ve;
|
|
|
u_long pl, ps, pt;
|
|
@@ -2153,10 +2133,8 @@ static void __init ami_init_copper(void)
|
|
|
custom.copjmp1 = 0;
|
|
|
}
|
|
|
|
|
|
-static void ami_reinit_copper(void)
|
|
|
+static void ami_reinit_copper(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
-
|
|
|
copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0;
|
|
|
copdisplay.wait->l = CWAIT(32, par->diwstrt_v - 4);
|
|
|
}
|
|
@@ -2168,9 +2146,8 @@ static void ami_reinit_copper(void)
|
|
|
* We only change the things that are not static
|
|
|
*/
|
|
|
|
|
|
-static void ami_rebuild_copper(void)
|
|
|
+static void ami_rebuild_copper(const struct amifb_par *par)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
copins *copl, *cops;
|
|
|
u_short line, h_end1, h_end2;
|
|
|
short i;
|
|
@@ -2182,7 +2159,7 @@ static void ami_rebuild_copper(void)
|
|
|
h_end1 = par->htotal - 32;
|
|
|
h_end2 = par->ddfstop + 64;
|
|
|
|
|
|
- ami_set_sprite();
|
|
|
+ ami_set_sprite(par);
|
|
|
|
|
|
copl = copdisplay.rebuild[1];
|
|
|
p = par->bplpt0;
|
|
@@ -2259,9 +2236,9 @@ static void ami_rebuild_copper(void)
|
|
|
* Build the Copper List
|
|
|
*/
|
|
|
|
|
|
-static void ami_build_copper(void)
|
|
|
+static void ami_build_copper(struct fb_info *info)
|
|
|
{
|
|
|
- struct amifb_par *par = ¤tpar;
|
|
|
+ struct amifb_par *par = info->par;
|
|
|
copins *copl, *cops;
|
|
|
u_long p;
|
|
|
|
|
@@ -2326,8 +2303,8 @@ static void ami_build_copper(void)
|
|
|
}
|
|
|
copdisplay.rebuild[1] = copl;
|
|
|
|
|
|
- ami_update_par();
|
|
|
- ami_rebuild_copper();
|
|
|
+ ami_update_par(info);
|
|
|
+ ami_rebuild_copper(info->par);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2405,7 +2382,8 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
|
|
|
struct amifb_par par;
|
|
|
|
|
|
/* Validate wanted screen parameters */
|
|
|
- if ((err = ami_decode_var(var, &par)))
|
|
|
+ err = ami_decode_var(var, &par, info);
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
|
|
|
/* Encode (possibly rounded) screen parameters */
|
|
@@ -2417,15 +2395,18 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
|
|
|
static int amifb_set_par(struct fb_info *info)
|
|
|
{
|
|
|
struct amifb_par *par = info->par;
|
|
|
+ int error;
|
|
|
|
|
|
do_vmode_pan = 0;
|
|
|
do_vmode_full = 0;
|
|
|
|
|
|
/* Decode wanted screen parameters */
|
|
|
- ami_decode_var(&info->var, par);
|
|
|
+ error = ami_decode_var(&info->var, par, info);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
|
|
|
/* Set new videomode */
|
|
|
- ami_build_copper();
|
|
|
+ ami_build_copper(info);
|
|
|
|
|
|
/* Set VBlank trigger */
|
|
|
do_vmode_full = 1;
|
|
@@ -2471,10 +2452,12 @@ static int amifb_set_par(struct fb_info *info)
|
|
|
static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
|
|
u_int transp, struct fb_info *info)
|
|
|
{
|
|
|
+ const struct amifb_par *par = info->par;
|
|
|
+
|
|
|
if (IS_AGA) {
|
|
|
if (regno > 255)
|
|
|
return 1;
|
|
|
- } else if (currentpar.bplcon0 & BPC0_SHRES) {
|
|
|
+ } else if (par->bplcon0 & BPC0_SHRES) {
|
|
|
if (regno > 3)
|
|
|
return 1;
|
|
|
} else {
|
|
@@ -2501,7 +2484,7 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
|
|
if (regno || !is_blanked) {
|
|
|
#if defined(CONFIG_FB_AMIGA_AGA)
|
|
|
if (IS_AGA) {
|
|
|
- u_short bplcon3 = currentpar.bplcon3;
|
|
|
+ u_short bplcon3 = par->bplcon3;
|
|
|
VBlankOff();
|
|
|
custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
|
|
|
custom.color[regno & 31] = rgb2hw8_high(red, green,
|
|
@@ -2515,7 +2498,7 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
|
|
} else
|
|
|
#endif
|
|
|
#if defined(CONFIG_FB_AMIGA_ECS)
|
|
|
- if (currentpar.bplcon0 & BPC0_SHRES) {
|
|
|
+ if (par->bplcon0 & BPC0_SHRES) {
|
|
|
u_short color, mask;
|
|
|
int i;
|
|
|
|
|
@@ -2572,7 +2555,7 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
|
|
|
var->yoffset + info->var.yres > info->var.yres_virtual)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- ami_pan_var(var);
|
|
|
+ ami_pan_var(var, info);
|
|
|
info->var.xoffset = var->xoffset;
|
|
|
info->var.yoffset = var->yoffset;
|
|
|
if (var->vmode & FB_VMODE_YWRAP)
|
|
@@ -3418,7 +3401,7 @@ static int amifb_ioctl(struct fb_info *info,
|
|
|
|
|
|
switch (cmd) {
|
|
|
case FBIOGET_FCURSORINFO:
|
|
|
- i = ami_get_fix_cursorinfo(&crsr.fix);
|
|
|
+ i = ami_get_fix_cursorinfo(&crsr.fix, info->par);
|
|
|
if (i)
|
|
|
return i;
|
|
|
return copy_to_user(argp, &crsr.fix,
|
|
@@ -3426,7 +3409,8 @@ static int amifb_ioctl(struct fb_info *info,
|
|
|
|
|
|
case FBIOGET_VCURSORINFO:
|
|
|
i = ami_get_var_cursorinfo(&crsr.var,
|
|
|
- ((struct fb_var_cursorinfo __user *)arg)->data);
|
|
|
+ ((struct fb_var_cursorinfo __user *)arg)->data,
|
|
|
+ info->par);
|
|
|
if (i)
|
|
|
return i;
|
|
|
return copy_to_user(argp, &crsr.var,
|
|
@@ -3436,10 +3420,11 @@ static int amifb_ioctl(struct fb_info *info,
|
|
|
if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
|
|
|
return -EFAULT;
|
|
|
return ami_set_var_cursorinfo(&crsr.var,
|
|
|
- ((struct fb_var_cursorinfo __user *)arg)->data);
|
|
|
+ ((struct fb_var_cursorinfo __user *)arg)->data,
|
|
|
+ info->par);
|
|
|
|
|
|
case FBIOGET_CURSORSTATE:
|
|
|
- i = ami_get_cursorstate(&crsr.state);
|
|
|
+ i = ami_get_cursorstate(&crsr.state, info->par);
|
|
|
if (i)
|
|
|
return i;
|
|
|
return copy_to_user(argp, &crsr.state,
|
|
@@ -3448,7 +3433,7 @@ static int amifb_ioctl(struct fb_info *info,
|
|
|
case FBIOPUT_CURSORSTATE:
|
|
|
if (copy_from_user(&crsr.state, argp, sizeof(crsr.state)))
|
|
|
return -EFAULT;
|
|
|
- return ami_set_cursorstate(&crsr.state);
|
|
|
+ return ami_set_cursorstate(&crsr.state, info->par);
|
|
|
}
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -3479,32 +3464,34 @@ static int flash_cursor(void)
|
|
|
|
|
|
static irqreturn_t amifb_interrupt(int irq, void *dev_id)
|
|
|
{
|
|
|
+ struct amifb_par *par = dev_id;
|
|
|
+
|
|
|
if (do_vmode_pan || do_vmode_full)
|
|
|
- ami_update_display();
|
|
|
+ ami_update_display(par);
|
|
|
|
|
|
if (do_vmode_full)
|
|
|
- ami_init_display();
|
|
|
+ ami_init_display(par);
|
|
|
|
|
|
if (do_vmode_pan) {
|
|
|
flash_cursor();
|
|
|
- ami_rebuild_copper();
|
|
|
+ ami_rebuild_copper(par);
|
|
|
do_cursor = do_vmode_pan = 0;
|
|
|
} else if (do_cursor) {
|
|
|
flash_cursor();
|
|
|
- ami_set_sprite();
|
|
|
+ ami_set_sprite(par);
|
|
|
do_cursor = 0;
|
|
|
} else {
|
|
|
if (flash_cursor())
|
|
|
- ami_set_sprite();
|
|
|
+ ami_set_sprite(par);
|
|
|
}
|
|
|
|
|
|
if (do_blank) {
|
|
|
- ami_do_blank();
|
|
|
+ ami_do_blank(par);
|
|
|
do_blank = 0;
|
|
|
}
|
|
|
|
|
|
if (do_vmode_full) {
|
|
|
- ami_reinit_copper();
|
|
|
+ ami_reinit_copper(par);
|
|
|
do_vmode_full = 0;
|
|
|
}
|
|
|
return IRQ_HANDLED;
|
|
@@ -3549,23 +3536,13 @@ static inline void chipfree(void)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void amifb_deinit(struct platform_device *pdev)
|
|
|
-{
|
|
|
- if (fb_info.cmap.len)
|
|
|
- fb_dealloc_cmap(&fb_info.cmap);
|
|
|
- chipfree();
|
|
|
- if (videomemory)
|
|
|
- iounmap((void *)videomemory);
|
|
|
- custom.dmacon = DMAF_ALL | DMAF_MASTER;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
/*
|
|
|
* Initialisation
|
|
|
*/
|
|
|
|
|
|
static int __init amifb_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
+ struct fb_info *info;
|
|
|
int tag, i, err = 0;
|
|
|
u_long chipptr;
|
|
|
u_int defmode;
|
|
@@ -3581,10 +3558,20 @@ static int __init amifb_probe(struct platform_device *pdev)
|
|
|
#endif
|
|
|
custom.dmacon = DMAF_ALL | DMAF_MASTER;
|
|
|
|
|
|
+ info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);
|
|
|
+ if (!info) {
|
|
|
+ dev_err(&pdev->dev, "framebuffer_alloc failed\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ strcpy(info->fix.id, "Amiga ");
|
|
|
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
|
|
|
+ info->fix.accel = FB_ACCEL_AMIGABLITT;
|
|
|
+
|
|
|
switch (amiga_chipset) {
|
|
|
#ifdef CONFIG_FB_AMIGA_OCS
|
|
|
case CS_OCS:
|
|
|
- strcat(fb_info.fix.id, "OCS");
|
|
|
+ strcat(info->fix.id, "OCS");
|
|
|
default_chipset:
|
|
|
chipset = TAG_OCS;
|
|
|
maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
|
|
@@ -3592,13 +3579,13 @@ default_chipset:
|
|
|
maxdepth[TAG_LORES] = 6;
|
|
|
maxfmode = TAG_FMODE_1;
|
|
|
defmode = amiga_vblank == 50 ? DEFMODE_PAL : DEFMODE_NTSC;
|
|
|
- fb_info.fix.smem_len = VIDEOMEMSIZE_OCS;
|
|
|
+ info->fix.smem_len = VIDEOMEMSIZE_OCS;
|
|
|
break;
|
|
|
#endif /* CONFIG_FB_AMIGA_OCS */
|
|
|
|
|
|
#ifdef CONFIG_FB_AMIGA_ECS
|
|
|
case CS_ECS:
|
|
|
- strcat(fb_info.fix.id, "ECS");
|
|
|
+ strcat(info->fix.id, "ECS");
|
|
|
chipset = TAG_ECS;
|
|
|
maxdepth[TAG_SHRES] = 2;
|
|
|
maxdepth[TAG_HIRES] = 4;
|
|
@@ -3612,15 +3599,15 @@ default_chipset:
|
|
|
: DEFMODE_NTSC;
|
|
|
if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
|
|
|
VIDEOMEMSIZE_ECS_2M)
|
|
|
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
|
|
|
+ info->fix.smem_len = VIDEOMEMSIZE_ECS_2M;
|
|
|
else
|
|
|
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M;
|
|
|
+ info->fix.smem_len = VIDEOMEMSIZE_ECS_1M;
|
|
|
break;
|
|
|
#endif /* CONFIG_FB_AMIGA_ECS */
|
|
|
|
|
|
#ifdef CONFIG_FB_AMIGA_AGA
|
|
|
case CS_AGA:
|
|
|
- strcat(fb_info.fix.id, "AGA");
|
|
|
+ strcat(info->fix.id, "AGA");
|
|
|
chipset = TAG_AGA;
|
|
|
maxdepth[TAG_SHRES] = 8;
|
|
|
maxdepth[TAG_HIRES] = 8;
|
|
@@ -3629,20 +3616,20 @@ default_chipset:
|
|
|
defmode = DEFMODE_AGA;
|
|
|
if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
|
|
|
VIDEOMEMSIZE_AGA_2M)
|
|
|
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
|
|
|
+ info->fix.smem_len = VIDEOMEMSIZE_AGA_2M;
|
|
|
else
|
|
|
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
|
|
|
+ info->fix.smem_len = VIDEOMEMSIZE_AGA_1M;
|
|
|
break;
|
|
|
#endif /* CONFIG_FB_AMIGA_AGA */
|
|
|
|
|
|
default:
|
|
|
#ifdef CONFIG_FB_AMIGA_OCS
|
|
|
printk("Unknown graphics chipset, defaulting to OCS\n");
|
|
|
- strcat(fb_info.fix.id, "Unknown");
|
|
|
+ strcat(info->fix.id, "Unknown");
|
|
|
goto default_chipset;
|
|
|
#else /* CONFIG_FB_AMIGA_OCS */
|
|
|
err = -ENODEV;
|
|
|
- goto amifb_error;
|
|
|
+ goto release;
|
|
|
#endif /* CONFIG_FB_AMIGA_OCS */
|
|
|
break;
|
|
|
}
|
|
@@ -3672,44 +3659,43 @@ default_chipset:
|
|
|
}
|
|
|
|
|
|
if (amifb_hfmin) {
|
|
|
- fb_info.monspecs.hfmin = amifb_hfmin;
|
|
|
- fb_info.monspecs.hfmax = amifb_hfmax;
|
|
|
- fb_info.monspecs.vfmin = amifb_vfmin;
|
|
|
- fb_info.monspecs.vfmax = amifb_vfmax;
|
|
|
+ info->monspecs.hfmin = amifb_hfmin;
|
|
|
+ info->monspecs.hfmax = amifb_hfmax;
|
|
|
+ info->monspecs.vfmin = amifb_vfmin;
|
|
|
+ info->monspecs.vfmax = amifb_vfmax;
|
|
|
} else {
|
|
|
/*
|
|
|
* These are for a typical Amiga monitor (e.g. A1960)
|
|
|
*/
|
|
|
- fb_info.monspecs.hfmin = 15000;
|
|
|
- fb_info.monspecs.hfmax = 38000;
|
|
|
- fb_info.monspecs.vfmin = 49;
|
|
|
- fb_info.monspecs.vfmax = 90;
|
|
|
+ info->monspecs.hfmin = 15000;
|
|
|
+ info->monspecs.hfmax = 38000;
|
|
|
+ info->monspecs.vfmin = 49;
|
|
|
+ info->monspecs.vfmax = 90;
|
|
|
}
|
|
|
|
|
|
- fb_info.fbops = &amifb_ops;
|
|
|
- fb_info.par = ¤tpar;
|
|
|
- fb_info.flags = FBINFO_DEFAULT;
|
|
|
- fb_info.device = &pdev->dev;
|
|
|
+ info->fbops = &amifb_ops;
|
|
|
+ info->flags = FBINFO_DEFAULT;
|
|
|
+ info->device = &pdev->dev;
|
|
|
|
|
|
- if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
|
|
|
+ if (!fb_find_mode(&info->var, info, mode_option, ami_modedb,
|
|
|
NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
|
|
|
err = -EINVAL;
|
|
|
- goto amifb_error;
|
|
|
+ goto release;
|
|
|
}
|
|
|
|
|
|
fb_videomode_to_modelist(ami_modedb, NUM_TOTAL_MODES,
|
|
|
- &fb_info.modelist);
|
|
|
+ &info->modelist);
|
|
|
|
|
|
round_down_bpp = 0;
|
|
|
- chipptr = chipalloc(fb_info.fix.smem_len + SPRITEMEMSIZE +
|
|
|
+ chipptr = chipalloc(info->fix.smem_len + SPRITEMEMSIZE +
|
|
|
DUMMYSPRITEMEMSIZE + COPINITSIZE +
|
|
|
4 * COPLISTSIZE);
|
|
|
if (!chipptr) {
|
|
|
err = -ENOMEM;
|
|
|
- goto amifb_error;
|
|
|
+ goto release;
|
|
|
}
|
|
|
|
|
|
- assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len);
|
|
|
+ assignchunk(videomemory, u_long, chipptr, info->fix.smem_len);
|
|
|
assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE);
|
|
|
assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE);
|
|
|
assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE);
|
|
@@ -3721,14 +3707,15 @@ default_chipset:
|
|
|
/*
|
|
|
* access the videomem with writethrough cache
|
|
|
*/
|
|
|
- fb_info.fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
|
|
|
- videomemory = (u_long)ioremap_writethrough(fb_info.fix.smem_start,
|
|
|
- fb_info.fix.smem_len);
|
|
|
+ info->fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
|
|
|
+ videomemory = (u_long)ioremap_writethrough(info->fix.smem_start,
|
|
|
+ info->fix.smem_len);
|
|
|
if (!videomemory) {
|
|
|
- printk("amifb: WARNING! unable to map videomem cached writethrough\n");
|
|
|
- fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start);
|
|
|
+ dev_warn(&pdev->dev,
|
|
|
+ "Unable to map videomem cached writethrough\n");
|
|
|
+ info->screen_base = (char *)ZTWO_VADDR(info->fix.smem_start);
|
|
|
} else
|
|
|
- fb_info.screen_base = (char *)videomemory;
|
|
|
+ info->screen_base = (char *)videomemory;
|
|
|
|
|
|
memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
|
|
|
|
|
@@ -3743,36 +3730,55 @@ default_chipset:
|
|
|
custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
|
|
|
DMAF_BLITTER | DMAF_SPRITE;
|
|
|
|
|
|
- if (request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
|
|
|
- "fb vertb handler", ¤tpar)) {
|
|
|
- err = -EBUSY;
|
|
|
- goto amifb_error;
|
|
|
- }
|
|
|
+ err = request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
|
|
|
+ "fb vertb handler", info->par);
|
|
|
+ if (err)
|
|
|
+ goto disable_dma;
|
|
|
|
|
|
- err = fb_alloc_cmap(&fb_info.cmap, 1 << fb_info.var.bits_per_pixel, 0);
|
|
|
+ err = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
|
|
|
if (err)
|
|
|
- goto amifb_error;
|
|
|
+ goto free_irq;
|
|
|
|
|
|
- if (register_framebuffer(&fb_info) < 0) {
|
|
|
- err = -EINVAL;
|
|
|
- goto amifb_error;
|
|
|
- }
|
|
|
+ dev_set_drvdata(&pdev->dev, info);
|
|
|
+
|
|
|
+ err = register_framebuffer(info);
|
|
|
+ if (err)
|
|
|
+ goto unset_drvdata;
|
|
|
|
|
|
printk("fb%d: %s frame buffer device, using %dK of video memory\n",
|
|
|
- fb_info.node, fb_info.fix.id, fb_info.fix.smem_len>>10);
|
|
|
+ info->node, info->fix.id, info->fix.smem_len>>10);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
-amifb_error:
|
|
|
- amifb_deinit(pdev);
|
|
|
+unset_drvdata:
|
|
|
+ dev_set_drvdata(&pdev->dev, NULL);
|
|
|
+ fb_dealloc_cmap(&info->cmap);
|
|
|
+free_irq:
|
|
|
+ free_irq(IRQ_AMIGA_COPPER, info->par);
|
|
|
+disable_dma:
|
|
|
+ custom.dmacon = DMAF_ALL | DMAF_MASTER;
|
|
|
+ if (videomemory)
|
|
|
+ iounmap((void *)videomemory);
|
|
|
+ chipfree();
|
|
|
+release:
|
|
|
+ framebuffer_release(info);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
|
|
|
static int __exit amifb_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
- unregister_framebuffer(&fb_info);
|
|
|
- amifb_deinit(pdev);
|
|
|
+ struct fb_info *info = dev_get_drvdata(&pdev->dev);
|
|
|
+
|
|
|
+ unregister_framebuffer(info);
|
|
|
+ dev_set_drvdata(&pdev->dev, NULL);
|
|
|
+ fb_dealloc_cmap(&info->cmap);
|
|
|
+ free_irq(IRQ_AMIGA_COPPER, info->par);
|
|
|
+ custom.dmacon = DMAF_ALL | DMAF_MASTER;
|
|
|
+ if (videomemory)
|
|
|
+ iounmap((void *)videomemory);
|
|
|
+ chipfree();
|
|
|
+ framebuffer_release(info);
|
|
|
amifb_video_off();
|
|
|
return 0;
|
|
|
}
|