* Re: [PATCH] video: Fix return value of fb_notifier_call_chain
From: Joonyoung Shim @ 2011-11-22 0:58 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <4ECAD9F0.9050508@gmx.de>
11/22/2011 08:08 AM, Florian Tobias Schandinat 쓴 글:
> On 11/21/2011 06:55 AM, Joonyoung Shim wrote:
>> The return value of blocking_notifier_call_chain isn't errno value, it
>> is just notify return value. The ret of fb_notifier_call_chain should is
>> restored to error value from notify return value using
>> notifier_to_errno().
> If I'm not wrong this patch would rather break things than fix them. As I
> understand the notifier_calls would be required to encode the return value with
> notifier_from_errno. This does not happen at the moment for fb clients, for
> example fbcon_event_notify in drivers/video/console/fbcon.c, so this patch would
> screw up the return values, I think.
OK, but it is wrong to return error value than notify value many
callback of fb notify clients and some fb notify clients returns notify
value, please see sh_mobile_lcdc_notify() and sh_hdmi_notify().
We should use only one, notify value or error value, i think it's right
to use notify value.
Thanks.
>
> Best regards,
>
> Florian Tobias Schandinat
>
>> Signed-off-by: Joonyoung Shim<jy0922.shim@samsung.com>
>> ---
>> drivers/video/fb_notify.c | 4 +++-
>> 1 files changed, 3 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
>> index 74c2da5..49a64a3 100644
>> --- a/drivers/video/fb_notify.c
>> +++ b/drivers/video/fb_notify.c
>> @@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
>> */
>> int fb_notifier_call_chain(unsigned long val, void *v)
>> {
>> - return blocking_notifier_call_chain(&fb_notifier_list, val, v);
>> + int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
>> +
>> + return notifier_to_errno(ret);
>> }
>> EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
>
^ permalink raw reply
* Re: [PATCH] video: Fix return value of fb_notifier_call_chain
From: Florian Tobias Schandinat @ 2011-11-21 23:08 UTC (permalink / raw)
To: Joonyoung Shim; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1321858524-19368-1-git-send-email-jy0922.shim@samsung.com>
On 11/21/2011 06:55 AM, Joonyoung Shim wrote:
> The return value of blocking_notifier_call_chain isn't errno value, it
> is just notify return value. The ret of fb_notifier_call_chain should is
> restored to error value from notify return value using
> notifier_to_errno().
If I'm not wrong this patch would rather break things than fix them. As I
understand the notifier_calls would be required to encode the return value with
notifier_from_errno. This does not happen at the moment for fb clients, for
example fbcon_event_notify in drivers/video/console/fbcon.c, so this patch would
screw up the return values, I think.
Best regards,
Florian Tobias Schandinat
> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
> ---
> drivers/video/fb_notify.c | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
> index 74c2da5..49a64a3 100644
> --- a/drivers/video/fb_notify.c
> +++ b/drivers/video/fb_notify.c
> @@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
> */
> int fb_notifier_call_chain(unsigned long val, void *v)
> {
> - return blocking_notifier_call_chain(&fb_notifier_list, val, v);
> + int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
> +
> + return notifier_to_errno(ret);
> }
> EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
^ permalink raw reply
* [PATCH 8/8] fbdev/amifb: Use framebuffer_alloc()
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
Use framebuffer_alloc() instead of static fb_info and currentpar variables.
Also sanitize the error path and cleanup code (e.g. missing free_irq()).
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 286 +++++++++++++++++++++++++------------------------
1 files changed, 146 insertions(+), 140 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 2bfaf1b..f23cae0 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -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;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 7/8] fbdev/amifb: Enable Copper DMA after setting up the Copper
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
Else the Copper may start executing random instructions
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 13e7a17..2bfaf1b 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -3733,17 +3733,15 @@ default_chipset:
memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
/*
- * Enable Display DMA
+ * Make sure the Copper has something to do
*/
-
- custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
- DMAF_BLITTER | DMAF_SPRITE;
+ ami_init_copper();
/*
- * Make sure the Copper has something to do
+ * Enable Display DMA
*/
-
- ami_init_copper();
+ 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)) {
--
1.7.0.4
^ permalink raw reply related
* [PATCH 6/8] fbdev/amifb: Store monitor limits in separate __initdata variables
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
The static fb_info will go away soon.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 26 ++++++++++++++++++--------
1 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 421c1f9..13e7a17 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -961,6 +961,11 @@ static int round_down_bpp = 1; /* for mode probing */
static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
static int amifb_inverse = 0;
+static u32 amifb_hfmin __initdata; /* monitor hfreq lower limit (Hz) */
+static u32 amifb_hfmax __initdata; /* monitor hfreq upper limit (Hz) */
+static u16 amifb_vfmin __initdata; /* monitor vfreq lower limit (Hz) */
+static u16 amifb_vfmax __initdata; /* monitor vfreq upper limit (Hz) */
+
/*
* Macros for the conversion from real world values to hardware register
@@ -2357,10 +2362,10 @@ static void __init amifb_setup_mcap(char *spec)
if (hmax <= 0 || hmax <= hmin)
return;
- fb_info.monspecs.vfmin = vmin;
- fb_info.monspecs.vfmax = vmax;
- fb_info.monspecs.hfmin = hmin;
- fb_info.monspecs.hfmax = hmax;
+ amifb_hfmin = hmin;
+ amifb_hfmax = hmax;
+ amifb_vfmin = vmin;
+ amifb_vfmax = vmax;
}
static int __init amifb_setup(char *options)
@@ -3666,10 +3671,15 @@ default_chipset:
}
}
- /*
- * These monitor specs are for a typical Amiga monitor (e.g. A1960)
- */
- if (fb_info.monspecs.hfmin = 0) {
+ 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;
+ } 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;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/8] fbdev/amifb: Remove superfluous casts when assigning void *
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index d3847e7..421c1f9 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2411,7 +2411,7 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
static int amifb_set_par(struct fb_info *info)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
do_vmode_pan = 0;
do_vmode_full = 0;
@@ -3181,7 +3181,7 @@ static inline void xor_one_line(int bpp, unsigned long next_plane,
static void amifb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int dst_idx, x2, y2;
unsigned long *dst;
u32 width, height;
@@ -3259,7 +3259,7 @@ static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
static void amifb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int x2, y2;
u32 dx, dy, sx, sy, width, height;
unsigned long *dst, *src;
@@ -3352,7 +3352,7 @@ static inline void expand_one_line(int bpp, unsigned long next_plane,
static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int x2, y2;
unsigned long *dst;
int dst_idx;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/8] fbdev/amifb: Make amifb_setup() static
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index d7961bd..d3847e7 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2363,7 +2363,7 @@ static void __init amifb_setup_mcap(char *spec)
fb_info.monspecs.hfmax = hmax;
}
-int __init amifb_setup(char *options)
+static int __init amifb_setup(char *options)
{
char *this_opt;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/8] fbdev/amifb: Reorder functions to remove forward declarations
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
No functional changes
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 2767 ++++++++++++++++++++++++-------------------------
1 files changed, 1356 insertions(+), 1411 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 39d211a..d7961bd 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1118,82 +1118,1213 @@ static u_short sprfetchmode[3] = {
};
+/* --------------------------- Hardware routines --------------------------- */
+
/*
- * Interface used by the world
+ * Get the video params out of `var'. If a value doesn't fit, round
+ * it up, if it's too big, return -EINVAL.
*/
-int amifb_setup(char*);
+static int ami_decode_var(struct fb_var_screeninfo *var,
+ struct amifb_par *par)
+{
+ u_short clk_shift, line_shift;
+ u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
+ u_int htotal, vtotal;
-static int amifb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int amifb_set_par(struct fb_info *info);
-static int amifb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-static int amifb_blank(int blank, struct fb_info *info);
-static int amifb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static void amifb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect);
-static void amifb_copyarea(struct fb_info *info,
- const struct fb_copyarea *region);
-static void amifb_imageblit(struct fb_info *info,
- const struct fb_image *image);
-static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+ /*
+ * Find a matching Pixel Clock
+ */
+ for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
+ if (var->pixclock <= pixclock[clk_shift])
+ break;
+ if (clk_shift > TAG_LORES) {
+ DPRINTK("pixclock too high\n");
+ return -EINVAL;
+ }
+ par->clk_shift = clk_shift;
/*
- * Interface to the low level console driver
+ * Check the Geometry Values
*/
-static void amifb_deinit(struct platform_device *pdev);
+ if ((par->xres = var->xres) < 64)
+ par->xres = 64;
+ if ((par->yres = var->yres) < 64)
+ par->yres = 64;
+ if ((par->vxres = var->xres_virtual) < par->xres)
+ par->vxres = par->xres;
+ if ((par->vyres = var->yres_virtual) < par->yres)
+ par->vyres = par->yres;
+
+ par->bpp = var->bits_per_pixel;
+ if (!var->nonstd) {
+ if (par->bpp < 1)
+ par->bpp = 1;
+ if (par->bpp > maxdepth[clk_shift]) {
+ if (round_down_bpp && maxdepth[clk_shift])
+ par->bpp = maxdepth[clk_shift];
+ else {
+ DPRINTK("invalid bpp\n");
+ return -EINVAL;
+ }
+ }
+ } else if (var->nonstd = FB_NONSTD_HAM) {
+ if (par->bpp < 6)
+ par->bpp = 6;
+ if (par->bpp != 6) {
+ if (par->bpp < 8)
+ par->bpp = 8;
+ if (par->bpp != 8 || !IS_AGA) {
+ DPRINTK("invalid bpp for ham mode\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ DPRINTK("unknown nonstd mode\n");
+ return -EINVAL;
+ }
/*
- * Internal routines
+ * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
+ * checks failed and smooth scrolling is not possible
*/
-static int flash_cursor(void);
-static irqreturn_t amifb_interrupt(int irq, void *dev_id);
-static u_long chipalloc(u_long size);
-static void chipfree(void);
+ par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN;
+ switch (par->vmode & FB_VMODE_MASK) {
+ case FB_VMODE_INTERLACED:
+ line_shift = 0;
+ break;
+ case FB_VMODE_NONINTERLACED:
+ line_shift = 1;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (!IS_AGA) {
+ DPRINTK("double mode only possible with aga\n");
+ return -EINVAL;
+ }
+ line_shift = 2;
+ break;
+ default:
+ DPRINTK("unknown video mode\n");
+ return -EINVAL;
+ break;
+ }
+ par->line_shift = line_shift;
/*
- * Hardware routines
+ * Vertical and Horizontal Timings
+ */
+
+ xres_n = par->xres << clk_shift;
+ yres_n = par->yres << line_shift;
+ par->htotal = down8((var->left_margin + par->xres + var->right_margin +
+ var->hsync_len) << clk_shift);
+ par->vtotal + down2(((var->upper_margin + par->yres + var->lower_margin +
+ var->vsync_len) << line_shift) + 1);
+
+ if (IS_AGA)
+ par->bplcon3 = sprpixmode[clk_shift];
+ else
+ par->bplcon3 = 0;
+ if (var->sync & FB_SYNC_BROADCAST) {
+ par->diwstop_h = par->htotal -
+ ((var->right_margin - var->hsync_len) << clk_shift);
+ if (IS_AGA)
+ par->diwstop_h += mod4(var->hsync_len);
+ else
+ par->diwstop_h = down4(par->diwstop_h);
+
+ par->diwstrt_h = par->diwstop_h - xres_n;
+ par->diwstop_v = par->vtotal -
+ ((var->lower_margin - var->vsync_len) << line_shift);
+ par->diwstrt_v = par->diwstop_v - yres_n;
+ if (par->diwstop_h >= par->htotal + 8) {
+ DPRINTK("invalid diwstop_h\n");
+ return -EINVAL;
+ }
+ if (par->diwstop_v > par->vtotal) {
+ DPRINTK("invalid diwstop_v\n");
+ return -EINVAL;
+ }
+
+ if (!IS_OCS) {
+ /* Initialize sync with some reasonable values for pwrsave */
+ par->hsstrt = 160;
+ par->hsstop = 320;
+ par->vsstrt = 30;
+ par->vsstop = 34;
+ } else {
+ par->hsstrt = 0;
+ par->hsstop = 0;
+ par->vsstrt = 0;
+ par->vsstop = 0;
+ }
+ if (par->vtotal > (PAL_VTOTAL + NTSC_VTOTAL) / 2) {
+ /* PAL video mode */
+ if (par->htotal != PAL_HTOTAL) {
+ DPRINTK("htotal invalid for pal\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_h < PAL_DIWSTRT_H) {
+ DPRINTK("diwstrt_h too low for pal\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_v < PAL_DIWSTRT_V) {
+ DPRINTK("diwstrt_v too low for pal\n");
+ return -EINVAL;
+ }
+ htotal = PAL_HTOTAL>>clk_shift;
+ vtotal = PAL_VTOTAL>>1;
+ if (!IS_OCS) {
+ par->beamcon0 = BMC0_PAL;
+ par->bplcon3 |= BPC3_BRDRBLNK;
+ } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ par->beamcon0 = BMC0_PAL;
+ par->hsstop = 1;
+ } else if (amiga_vblank != 50) {
+ DPRINTK("pal not supported by this chipset\n");
+ return -EINVAL;
+ }
+ } else {
+ /* NTSC video mode
+ * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
+ * and NTSC activated, so than better let diwstop_h <= 1812
+ */
+ if (par->htotal != NTSC_HTOTAL) {
+ DPRINTK("htotal invalid for ntsc\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_h < NTSC_DIWSTRT_H) {
+ DPRINTK("diwstrt_h too low for ntsc\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_v < NTSC_DIWSTRT_V) {
+ DPRINTK("diwstrt_v too low for ntsc\n");
+ return -EINVAL;
+ }
+ htotal = NTSC_HTOTAL>>clk_shift;
+ vtotal = NTSC_VTOTAL>>1;
+ if (!IS_OCS) {
+ par->beamcon0 = 0;
+ par->bplcon3 |= BPC3_BRDRBLNK;
+ } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ par->beamcon0 = 0;
+ par->hsstop = 1;
+ } else if (amiga_vblank != 60) {
+ DPRINTK("ntsc not supported by this chipset\n");
+ return -EINVAL;
+ }
+ }
+ if (IS_OCS) {
+ if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
+ par->diwstrt_v >= 512 || par->diwstop_v < 256) {
+ DPRINTK("invalid position for display on ocs\n");
+ return -EINVAL;
+ }
+ }
+ } else if (!IS_OCS) {
+ /* Programmable video mode */
+ par->hsstrt = var->right_margin << clk_shift;
+ par->hsstop = (var->right_margin + var->hsync_len) << clk_shift;
+ par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift);
+ if (!IS_AGA)
+ par->diwstop_h = down4(par->diwstop_h) - 16;
+ par->diwstrt_h = par->diwstop_h - xres_n;
+ par->hbstop = par->diwstrt_h + 4;
+ par->hbstrt = par->diwstop_h + 4;
+ if (par->hbstrt >= par->htotal + 8)
+ par->hbstrt -= par->htotal;
+ par->hcenter = par->hsstrt + (par->htotal >> 1);
+ par->vsstrt = var->lower_margin << line_shift;
+ par->vsstop = (var->lower_margin + var->vsync_len) << line_shift;
+ par->diwstop_v = par->vtotal;
+ if ((par->vmode & FB_VMODE_MASK) = FB_VMODE_INTERLACED)
+ par->diwstop_v -= 2;
+ par->diwstrt_v = par->diwstop_v - yres_n;
+ par->vbstop = par->diwstrt_v - 2;
+ par->vbstrt = par->diwstop_v - 2;
+ if (par->vtotal > 2048) {
+ DPRINTK("vtotal too high\n");
+ return -EINVAL;
+ }
+ if (par->htotal > 2048) {
+ DPRINTK("htotal too high\n");
+ return -EINVAL;
+ }
+ par->bplcon3 |= BPC3_EXTBLKEN;
+ par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
+ BMC0_PAL | BMC0_VARCSYEN;
+ if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+ par->beamcon0 |= BMC0_HSYTRUE;
+ if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+ par->beamcon0 |= BMC0_VSYTRUE;
+ if (var->sync & FB_SYNC_COMP_HIGH_ACT)
+ par->beamcon0 |= BMC0_CSYTRUE;
+ htotal = par->htotal>>clk_shift;
+ vtotal = par->vtotal>>1;
+ } else {
+ DPRINTK("only broadcast modes possible for ocs\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Checking the DMA timing
+ */
+
+ fconst = 16 << maxfmode << clk_shift;
+
+ /*
+ * smallest window start value without turn off other dma cycles
+ * than sprite1-7, unless you change min_fstrt
+ */
+
+
+ fsize = ((maxfmode + clk_shift <= 1) ? fconst : 64);
+ fstrt = downx(fconst, par->diwstrt_h - 4) - fsize;
+ if (fstrt < min_fstrt) {
+ DPRINTK("fetch start too low\n");
+ return -EINVAL;
+ }
+
+ /*
+ * smallest window start value where smooth scrolling is possible
+ */
+
+ fstrt = downx(fconst, par->diwstrt_h - fconst + (1 << clk_shift) - 4) -
+ fsize;
+ if (fstrt < min_fstrt)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ maxfetchstop = down16(par->htotal - 80);
+
+ fstrt = downx(fconst, par->diwstrt_h - 4) - 64 - fconst;
+ fsize = upx(fconst, xres_n +
+ modx(fconst, downx(1 << clk_shift, par->diwstrt_h - 4)));
+ if (fstrt + fsize > maxfetchstop)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ fsize = upx(fconst, xres_n);
+ if (fstrt + fsize > maxfetchstop) {
+ DPRINTK("fetch stop too high\n");
+ return -EINVAL;
+ }
+
+ if (maxfmode + clk_shift <= 1) {
+ fsize = up64(xres_n + fconst - 1);
+ if (min_fstrt + fsize - 64 > maxfetchstop)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ fsize = up64(xres_n);
+ if (min_fstrt + fsize - 64 > maxfetchstop) {
+ DPRINTK("fetch size too high\n");
+ return -EINVAL;
+ }
+
+ fsize -= 64;
+ } else
+ fsize -= fconst;
+
+ /*
+ * Check if there is enough time to update the bitplane pointers for ywrap
+ */
+
+ if (par->htotal - fsize - 64 < par->bpp * 64)
+ par->vmode &= ~FB_VMODE_YWRAP;
+
+ /*
+ * Bitplane calculations and check the Memory Requirements
+ */
+
+ 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) {
+ 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) {
+ DPRINTK("too few video mem\n");
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * Hardware Register Values
+ */
+
+ par->bplcon0 = BPC0_COLOR | bplpixmode[clk_shift];
+ if (!IS_OCS)
+ par->bplcon0 |= BPC0_ECSENA;
+ if (par->bpp = 8)
+ par->bplcon0 |= BPC0_BPU3;
+ else
+ par->bplcon0 |= par->bpp << 12;
+ if (var->nonstd = FB_NONSTD_HAM)
+ par->bplcon0 |= BPC0_HAM;
+ if (var->sync & FB_SYNC_EXT)
+ par->bplcon0 |= BPC0_ERSY;
+
+ if (IS_AGA)
+ par->fmode = bplfetchmode[maxfmode];
+
+ switch (par->vmode & FB_VMODE_MASK) {
+ case FB_VMODE_INTERLACED:
+ par->bplcon0 |= BPC0_LACE;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (IS_AGA)
+ par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
+ break;
+ }
+
+ if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
+ par->xoffset = var->xoffset;
+ par->yoffset = var->yoffset;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if (par->xoffset || par->yoffset < 0 ||
+ par->yoffset >= par->vyres)
+ par->xoffset = par->yoffset = 0;
+ } else {
+ if (par->xoffset < 0 ||
+ par->xoffset > upx(16 << maxfmode, par->vxres - par->xres) ||
+ par->yoffset < 0 || par->yoffset > par->vyres - par->yres)
+ par->xoffset = par->yoffset = 0;
+ }
+ } else
+ par->xoffset = par->yoffset = 0;
+
+ par->crsr.crsr_x = par->crsr.crsr_y = 0;
+ par->crsr.spot_x = par->crsr.spot_y = 0;
+ par->crsr.height = par->crsr.width = 0;
+
+ return 0;
+}
+
+ /*
+ * Fill the `var' structure based on the values in `par' and maybe
+ * other values read out of the hardware.
*/
-static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
-static void ami_pan_var(struct fb_var_screeninfo *var);
-static int ami_update_par(void);
-static void ami_update_display(void);
-static void ami_init_display(void);
-static void ami_do_blank(void);
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
-static int ami_get_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);
-static int ami_get_cursorstate(struct fb_cursorstate *state);
-static int ami_set_cursorstate(struct fb_cursorstate *state);
-static void ami_set_sprite(void);
-static void ami_init_copper(void);
-static void ami_reinit_copper(void);
-static void ami_build_copper(void);
-static void ami_rebuild_copper(void);
+ struct amifb_par *par)
+{
+ u_short clk_shift, line_shift;
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+ clk_shift = par->clk_shift;
+ line_shift = par->line_shift;
+
+ var->xres = par->xres;
+ var->yres = par->yres;
+ var->xres_virtual = par->vxres;
+ var->yres_virtual = par->vyres;
+ var->xoffset = par->xoffset;
+ var->yoffset = par->yoffset;
+
+ var->bits_per_pixel = par->bpp;
+ var->grayscale = 0;
+
+ var->red.offset = 0;
+ var->red.msb_right = 0;
+ var->red.length = par->bpp;
+ if (par->bplcon0 & BPC0_HAM)
+ var->red.length -= 2;
+ var->blue = var->green = var->red;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->transp.msb_right = 0;
+
+ if (par->bplcon0 & BPC0_HAM)
+ var->nonstd = FB_NONSTD_HAM;
+ else
+ var->nonstd = 0;
+ var->activate = 0;
+
+ var->height = -1;
+ var->width = -1;
+
+ var->pixclock = pixclock[clk_shift];
+
+ if (IS_AGA && par->fmode & FMODE_BSCAN2)
+ var->vmode = FB_VMODE_DOUBLE;
+ else if (par->bplcon0 & BPC0_LACE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) {
+ var->hsync_len = (par->hsstop - par->hsstrt)>>clk_shift;
+ var->right_margin = par->hsstrt>>clk_shift;
+ var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
+ var->vsync_len = (par->vsstop - par->vsstrt)>>line_shift;
+ var->lower_margin = par->vsstrt>>line_shift;
+ var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len;
+ var->sync = 0;
+ if (par->beamcon0 & BMC0_HSYTRUE)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (par->beamcon0 & BMC0_VSYTRUE)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (par->beamcon0 & BMC0_CSYTRUE)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+ } else {
+ var->sync = FB_SYNC_BROADCAST;
+ var->hsync_len = (152>>clk_shift) + mod4(par->diwstop_h);
+ var->right_margin = ((par->htotal - down4(par->diwstop_h))>>clk_shift) + var->hsync_len;
+ var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
+ var->vsync_len = 4>>line_shift;
+ var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len;
+ var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres -
+ var->lower_margin - var->vsync_len;
+ }
+
+ if (par->bplcon0 & BPC0_ERSY)
+ var->sync |= FB_SYNC_EXT;
+ if (par->vmode & FB_VMODE_YWRAP)
+ var->vmode |= FB_VMODE_YWRAP;
+
+ return 0;
+}
+
+
+ /*
+ * Update hardware
+ */
+
+static int ami_update_par(void)
+{
+ struct amifb_par *par = ¤tpar;
+ short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
+
+ clk_shift = par->clk_shift;
+
+ if (!(par->vmode & FB_VMODE_SMOOTH_XPAN))
+ par->xoffset = upx(16 << maxfmode, par->xoffset);
+
+ fconst = 16 << maxfmode << clk_shift;
+ vshift = modx(16 << maxfmode, par->xoffset);
+ fstrt = par->diwstrt_h - (vshift << clk_shift) - 4;
+ fsize = (par->xres + vshift) << clk_shift;
+ shift = modx(fconst, fstrt);
+ move = downx(2 << maxfmode, div8(par->xoffset));
+ if (maxfmode + clk_shift > 1) {
+ fstrt = downx(fconst, fstrt) - 64;
+ fsize = upx(fconst, fsize);
+ fstop = fstrt + fsize - fconst;
+ } else {
+ mod = fstrt = downx(fconst, fstrt) - fconst;
+ fstop = fstrt + upx(fconst, fsize) - 64;
+ fsize = up64(fsize);
+ fstrt = fstop - fsize + 64;
+ if (fstrt < min_fstrt) {
+ fstop += min_fstrt - fstrt;
+ fstrt = min_fstrt;
+ }
+ move = move - div8((mod - fstrt)>>clk_shift);
+ }
+ mod = par->next_line - div8(fsize>>clk_shift);
+ par->ddfstrt = fstrt;
+ par->ddfstop = fstop;
+ par->bplcon1 = hscroll2hw(shift);
+ par->bpl2mod = mod;
+ if (par->bplcon0 & BPC0_LACE)
+ par->bpl2mod += par->next_line;
+ if (IS_AGA && (par->fmode & FMODE_BSCAN2))
+ par->bpl1mod = -div8(fsize>>clk_shift);
+ else
+ par->bpl1mod = par->bpl2mod;
+
+ if (par->yoffset) {
+ par->bplpt0 = fb_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;
+ if (par->bplcon0 & BPC0_LACE &&
+ mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
+ par->bplpt0wrap += par->next_line;
+ }
+ }
+ } else
+ par->bplpt0 = fb_info.fix.smem_start + move;
+
+ if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
+ par->bplpt0 += par->next_line;
+
+ return 0;
+}
+
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ * in `var'.
+ */
+
+static void ami_pan_var(struct fb_var_screeninfo *var)
+{
+ struct amifb_par *par = ¤tpar;
+
+ par->xoffset = var->xoffset;
+ par->yoffset = var->yoffset;
+ if (var->vmode & FB_VMODE_YWRAP)
+ par->vmode |= FB_VMODE_YWRAP;
+ else
+ par->vmode &= ~FB_VMODE_YWRAP;
+
+ do_vmode_pan = 0;
+ ami_update_par();
+ do_vmode_pan = 1;
+}
+
+
+static void ami_update_display(void)
+{
+ struct amifb_par *par = ¤tpar;
+
+ custom.bplcon1 = par->bplcon1;
+ custom.bpl1mod = par->bpl1mod;
+ custom.bpl2mod = par->bpl2mod;
+ custom.ddfstrt = ddfstrt2hw(par->ddfstrt);
+ custom.ddfstop = ddfstop2hw(par->ddfstop);
+}
+
+ /*
+ * Change the video mode (called by VBlank interrupt)
+ */
+
+static void ami_init_display(void)
+{
+ struct amifb_par *par = ¤tpar;
+ int i;
+
+ custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
+ custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
+ if (!IS_OCS) {
+ custom.bplcon3 = par->bplcon3;
+ if (IS_AGA)
+ custom.bplcon4 = BPC4_ESPRM4 | BPC4_OSPRM4;
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ custom.htotal = htotal2hw(par->htotal);
+ custom.hbstrt = hbstrt2hw(par->hbstrt);
+ custom.hbstop = hbstop2hw(par->hbstop);
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.hcenter = hcenter2hw(par->hcenter);
+ custom.vtotal = vtotal2hw(par->vtotal);
+ custom.vbstrt = vbstrt2hw(par->vbstrt);
+ custom.vbstop = vbstop2hw(par->vbstop);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstop2hw(par->vsstop);
+ }
+ }
+ if (!IS_OCS || par->hsstop)
+ custom.beamcon0 = par->beamcon0;
+ if (IS_AGA)
+ custom.fmode = par->fmode;
+
+ /*
+ * The minimum period for audio depends on htotal
+ */
+
+ amiga_audio_min_period = div16(par->htotal);
+
+ is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0;
+#if 1
+ if (is_lace) {
+ i = custom.vposr >> 15;
+ } else {
+ custom.vposw = custom.vposr | 0x8000;
+ i = 1;
+ }
+#else
+ i = 1;
+ custom.vposw = custom.vposr | 0x8000;
+#endif
+ custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][i]);
+}
+
+ /*
+ * (Un)Blank the screen (called by VBlank interrupt)
+ */
+
+static void ami_do_blank(void)
+{
+ struct amifb_par *par = ¤tpar;
+#if defined(CONFIG_FB_AMIGA_AGA)
+ u_short bplcon3 = par->bplcon3;
+#endif
+ u_char red, green, blue;
+
+ if (do_blank > 0) {
+ custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
+ red = green = blue = 0;
+ if (!IS_OCS && do_blank > 1) {
+ switch (do_blank) {
+ case FB_BLANK_VSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstrt2hw(par->vsstop);
+ break;
+ case FB_BLANK_POWERDOWN:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
+ }
+ if (!(par->beamcon0 & BMC0_VARBEAMEN)) {
+ custom.htotal = htotal2hw(par->htotal);
+ custom.vtotal = vtotal2hw(par->vtotal);
+ custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN |
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
+ }
+ }
+ } else {
+ custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE;
+ red = red0;
+ green = green0;
+ blue = blue0;
+ if (!IS_OCS) {
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstop2hw(par->vsstop);
+ custom.beamcon0 = par->beamcon0;
+ }
+ }
+#if defined(CONFIG_FB_AMIGA_AGA)
+ if (IS_AGA) {
+ custom.bplcon3 = bplcon3;
+ custom.color[0] = rgb2hw8_high(red, green, blue);
+ custom.bplcon3 = bplcon3 | BPC3_LOCT;
+ custom.color[0] = rgb2hw8_low(red, green, blue);
+ custom.bplcon3 = bplcon3;
+ } else
+#endif
+#if defined(CONFIG_FB_AMIGA_ECS)
+ if (par->bplcon0 & BPC0_SHRES) {
+ u_short color, mask;
+ int i;
+
+ mask = 0x3333;
+ color = rgb2hw2(red, green, blue);
+ for (i = 12; i >= 0; i -= 4)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ mask <<= 2; color >>= 2;
+ for (i = 3; i >= 0; i--)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ } else
+#endif
+ custom.color[0] = rgb2hw4(red, green, blue);
+ is_blanked = do_blank > 0 ? do_blank : 0;
+}
+
+static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
+{
+ 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;
+ fix->crsr_color2 = 18;
+ return 0;
+}
+
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
+{
+ struct amifb_par *par = ¤tpar;
+ register u_short *lspr, *sspr;
+#ifdef __mc68000__
+ register u_long datawords asm ("d2");
+#else
+ register u_long datawords;
+#endif
+ register short delta;
+ register u_char color;
+ short height, width, bits, words;
+ int size, alloc;
+
+ size = par->crsr.height * par->crsr.width;
+ alloc = var->height * var->width;
+ var->height = par->crsr.height;
+ var->width = par->crsr.width;
+ var->xspot = par->crsr.spot_x;
+ var->yspot = par->crsr.spot_y;
+ if (size > var->height * var->width)
+ return -ENAMETOOLONG;
+ if (!access_ok(VERIFY_WRITE, data, size))
+ return -EFAULT;
+ delta = 1 << par->crsr.fmode;
+ lspr = lofsprite + (delta << 1);
+ if (par->bplcon0 & BPC0_LACE)
+ sspr = shfsprite + (delta << 1);
+ else
+ sspr = NULL;
+ for (height = (short)var->height - 1; height >= 0; height--) {
+ bits = 0; words = delta; datawords = 0;
+ for (width = (short)var->width - 1; width >= 0; width--) {
+ if (bits = 0) {
+ bits = 16; --words;
+#ifdef __mc68000__
+ asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0"
+ : "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta));
+#else
+ datawords = (*(lspr + delta) << 16) | (*lspr++);
+#endif
+ }
+ --bits;
+#ifdef __mc68000__
+ asm volatile (
+ "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
+ "swap %1 ; lslw #1,%1 ; roxlb #1,%0"
+ : "=d" (color), "=d" (datawords) : "1" (datawords));
+#else
+ color = (((datawords >> 30) & 2)
+ | ((datawords >> 15) & 1));
+ datawords <<= 1;
+#endif
+ put_user(color, data++);
+ }
+ if (bits > 0) {
+ --words; ++lspr;
+ }
+ while (--words >= 0)
+ ++lspr;
+#ifdef __mc68000__
+ asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
+ : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
+#else
+ lspr += delta;
+ if (sspr) {
+ u_short *tmp = lspr;
+ lspr = sspr;
+ sspr = tmp;
+ }
+#endif
+ }
+ return 0;
+}
+
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
+{
+ struct amifb_par *par = ¤tpar;
+ register u_short *lspr, *sspr;
+#ifdef __mc68000__
+ register u_long datawords asm ("d2");
+#else
+ register u_long datawords;
+#endif
+ register short delta;
+ u_short fmode;
+ short height, width, bits, words;
+
+ if (!var->width)
+ return -EINVAL;
+ else if (var->width <= 16)
+ fmode = TAG_FMODE_1;
+ else if (var->width <= 32)
+ fmode = TAG_FMODE_2;
+ else if (var->width <= 64)
+ fmode = TAG_FMODE_4;
+ else
+ return -EINVAL;
+ if (fmode > maxfmode)
+ return -EINVAL;
+ if (!var->height)
+ return -EINVAL;
+ if (!access_ok(VERIFY_READ, data, var->width * var->height))
+ return -EFAULT;
+ delta = 1 << fmode;
+ lofsprite = shfsprite = (u_short *)spritememory;
+ lspr = lofsprite + (delta << 1);
+ if (par->bplcon0 & BPC0_LACE) {
+ if (((var->height + 4) << fmode << 2) > SPRITEMEMSIZE)
+ return -EINVAL;
+ memset(lspr, 0, (var->height + 4) << fmode << 2);
+ shfsprite += ((var->height + 5)&-2) << fmode;
+ sspr = shfsprite + (delta << 1);
+ } else {
+ if (((var->height + 2) << fmode << 2) > SPRITEMEMSIZE)
+ return -EINVAL;
+ memset(lspr, 0, (var->height + 2) << fmode << 2);
+ sspr = NULL;
+ }
+ for (height = (short)var->height - 1; height >= 0; height--) {
+ bits = 16; words = delta; datawords = 0;
+ for (width = (short)var->width - 1; width >= 0; width--) {
+ unsigned long tdata = 0;
+ get_user(tdata, data);
+ data++;
+#ifdef __mc68000__
+ asm volatile (
+ "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
+ "lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
+ : "=d" (datawords)
+ : "0" (datawords), "d" (tdata));
+#else
+ datawords = ((datawords << 1) & 0xfffefffe);
+ datawords |= tdata & 1;
+ datawords |= (tdata & 2) << (16 - 1);
+#endif
+ if (--bits = 0) {
+ bits = 16; --words;
+#ifdef __mc68000__
+ asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta));
+#else
+ *(lspr + delta) = (u_short) (datawords >> 16);
+ *lspr++ = (u_short) (datawords & 0xffff);
+#endif
+ }
+ }
+ if (bits < 16) {
+ --words;
+#ifdef __mc68000__
+ asm volatile (
+ "swap %2 ; lslw %4,%2 ; movew %2,%0@(%3:w:2) ; "
+ "swap %2 ; lslw %4,%2 ; movew %2,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits));
+#else
+ *(lspr + delta) = (u_short) (datawords >> (16 + bits));
+ *lspr++ = (u_short) ((datawords & 0x0000ffff) >> bits);
+#endif
+ }
+ while (--words >= 0) {
+#ifdef __mc68000__
+ asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (delta) : "d0");
+#else
+ *(lspr + delta) = 0;
+ *lspr++ = 0;
+#endif
+ }
+#ifdef __mc68000__
+ asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
+ : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
+#else
+ lspr += delta;
+ if (sspr) {
+ u_short *tmp = lspr;
+ lspr = sspr;
+ sspr = tmp;
+ }
+#endif
+ }
+ par->crsr.height = var->height;
+ par->crsr.width = var->width;
+ par->crsr.spot_x = var->xspot;
+ par->crsr.spot_y = var->yspot;
+ par->crsr.fmode = fmode;
+ if (IS_AGA) {
+ par->fmode &= ~(FMODE_SPAGEM | FMODE_SPR32);
+ par->fmode |= sprfetchmode[fmode];
+ custom.fmode = par->fmode;
+ }
+ return 0;
+}
+
+static int ami_get_cursorstate(struct fb_cursorstate *state)
+{
+ 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)
+{
+ struct amifb_par *par = ¤tpar;
+
+ par->crsr.crsr_x = state->xoffset;
+ par->crsr.crsr_y = state->yoffset;
+ if ((cursormode = state->mode) = FB_CURSOR_OFF)
+ cursorstate = -1;
+ do_cursor = 1;
+ return 0;
+}
+
+static void ami_set_sprite(void)
+{
+ struct amifb_par *par = ¤tpar;
+ copins *copl, *cops;
+ u_short hs, vs, ve;
+ u_long pl, ps, pt;
+ short mx, my;
+
+ cops = copdisplay.list[currentcop][0];
+ copl = copdisplay.list[currentcop][1];
+ ps = pl = ZTWO_PADDR(dummysprite);
+ mx = par->crsr.crsr_x - par->crsr.spot_x;
+ my = par->crsr.crsr_y - par->crsr.spot_y;
+ if (!(par->vmode & FB_VMODE_YWRAP)) {
+ mx -= par->xoffset;
+ my -= par->yoffset;
+ }
+ if (!is_blanked && cursorstate > 0 && par->crsr.height > 0 &&
+ mx > -(short)par->crsr.width && mx < par->xres &&
+ my > -(short)par->crsr.height && my < par->yres) {
+ pl = ZTWO_PADDR(lofsprite);
+ hs = par->diwstrt_h + (mx << par->clk_shift) - 4;
+ vs = par->diwstrt_v + (my << par->line_shift);
+ ve = vs + (par->crsr.height << par->line_shift);
+ if (par->bplcon0 & BPC0_LACE) {
+ ps = ZTWO_PADDR(shfsprite);
+ lofsprite[0] = spr2hw_pos(vs, hs);
+ shfsprite[0] = spr2hw_pos(vs + 1, hs);
+ if (mod2(vs)) {
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
+ pt = pl; pl = ps; ps = pt;
+ } else {
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);
+ }
+ } else {
+ lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0);
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ }
+ }
+ copl[cop_spr0ptrh].w[1] = highw(pl);
+ copl[cop_spr0ptrl].w[1] = loww(pl);
+ if (par->bplcon0 & BPC0_LACE) {
+ cops[cop_spr0ptrh].w[1] = highw(ps);
+ cops[cop_spr0ptrl].w[1] = loww(ps);
+ }
+}
+
+
+ /*
+ * Initialise the Copper Initialisation List
+ */
+
+static void __init ami_init_copper(void)
+{
+ copins *cop = copdisplay.init;
+ u_long p;
+ int i;
+
+ if (!IS_OCS) {
+ (cop++)->l = CMOVE(BPC0_COLOR | BPC0_SHRES | BPC0_ECSENA, bplcon0);
+ (cop++)->l = CMOVE(0x0181, diwstrt);
+ (cop++)->l = CMOVE(0x0281, diwstop);
+ (cop++)->l = CMOVE(0x0000, diwhigh);
+ } else
+ (cop++)->l = CMOVE(BPC0_COLOR, bplcon0);
+ p = ZTWO_PADDR(dummysprite);
+ for (i = 0; i < 8; i++) {
+ (cop++)->l = CMOVE(0, spr[i].pos);
+ (cop++)->l = CMOVE(highw(p), sprpt[i]);
+ (cop++)->l = CMOVE2(loww(p), sprpt[i]);
+ }
+
+ (cop++)->l = CMOVE(IF_SETCLR | IF_COPER, intreq);
+ copdisplay.wait = cop;
+ (cop++)->l = CEND;
+ (cop++)->l = CMOVE(0, copjmp2);
+ cop->l = CEND;
+
+ custom.cop1lc = (u_short *)ZTWO_PADDR(copdisplay.init);
+ custom.copjmp1 = 0;
+}
+
+static void ami_reinit_copper(void)
+{
+ 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);
+}
+
+
+ /*
+ * Rebuild the Copper List
+ *
+ * We only change the things that are not static
+ */
+
+static void ami_rebuild_copper(void)
+{
+ struct amifb_par *par = ¤tpar;
+ copins *copl, *cops;
+ u_short line, h_end1, h_end2;
+ short i;
+ u_long p;
+
+ if (IS_AGA && maxfmode + par->clk_shift = 0)
+ h_end1 = par->diwstrt_h - 64;
+ else
+ h_end1 = par->htotal - 32;
+ h_end2 = par->ddfstop + 64;
+
+ ami_set_sprite();
+
+ copl = copdisplay.rebuild[1];
+ p = par->bplpt0;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if ((par->vyres - par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres) {
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (copl++)->l = CMOVE(highw(p), bplpt[i]);
+ (copl++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 1;
+ while (line >= 512) {
+ (copl++)->l = CWAIT(h_end1, 510);
+ line -= 512;
+ }
+ if (line >= 510 && IS_AGA && maxfmode + par->clk_shift = 0)
+ (copl++)->l = CWAIT(h_end1, line);
+ else
+ (copl++)->l = CWAIT(h_end2, line);
+ p = par->bplpt0wrap;
+ }
+ } else
+ p = par->bplpt0wrap;
+ }
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (copl++)->l = CMOVE(highw(p), bplpt[i]);
+ (copl++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ copl->l = CEND;
+
+ if (par->bplcon0 & BPC0_LACE) {
+ cops = copdisplay.rebuild[0];
+ p = par->bplpt0;
+ if (mod2(par->diwstrt_v))
+ p -= par->next_line;
+ else
+ p += par->next_line;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if ((par->vyres - par->yoffset) != 1 || mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres + 1) {
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (cops++)->l = CMOVE(highw(p), bplpt[i]);
+ (cops++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 2;
+ while (line >= 512) {
+ (cops++)->l = CWAIT(h_end1, 510);
+ line -= 512;
+ }
+ if (line > 510 && IS_AGA && maxfmode + par->clk_shift = 0)
+ (cops++)->l = CWAIT(h_end1, line);
+ else
+ (cops++)->l = CWAIT(h_end2, line);
+ p = par->bplpt0wrap;
+ if (mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
+ p -= par->next_line;
+ else
+ p += par->next_line;
+ }
+ } else
+ p = par->bplpt0wrap - par->next_line;
+ }
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (cops++)->l = CMOVE(highw(p), bplpt[i]);
+ (cops++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ cops->l = CEND;
+ }
+}
+
+
+ /*
+ * Build the Copper List
+ */
+
+static void ami_build_copper(void)
+{
+ struct amifb_par *par = ¤tpar;
+ copins *copl, *cops;
+ u_long p;
+
+ currentcop = 1 - currentcop;
+
+ copl = copdisplay.list[currentcop][1];
+
+ (copl++)->l = CWAIT(0, 10);
+ (copl++)->l = CMOVE(par->bplcon0, bplcon0);
+ (copl++)->l = CMOVE(0, sprpt[0]);
+ (copl++)->l = CMOVE2(0, sprpt[0]);
+
+ if (par->bplcon0 & BPC0_LACE) {
+ cops = copdisplay.list[currentcop][0];
+
+ (cops++)->l = CWAIT(0, 10);
+ (cops++)->l = CMOVE(par->bplcon0, bplcon0);
+ (cops++)->l = CMOVE(0, sprpt[0]);
+ (cops++)->l = CMOVE2(0, sprpt[0]);
+
+ (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v + 1), diwstrt);
+ (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v + 1), diwstop);
+ (cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
+ (cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
+ if (!IS_OCS) {
+ (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v + 1,
+ par->diwstop_h, par->diwstop_v + 1), diwhigh);
+ (cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
+ par->diwstop_h, par->diwstop_v), diwhigh);
+#if 0
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt + 1), vbstrt);
+ (copl++)->l = CMOVE(vbstop2hw(par->vbstop + 1), vbstop);
+ (cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
+ (cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
+ }
+#endif
+ }
+ p = ZTWO_PADDR(copdisplay.list[currentcop][0]);
+ (copl++)->l = CMOVE(highw(p), cop2lc);
+ (copl++)->l = CMOVE2(loww(p), cop2lc);
+ p = ZTWO_PADDR(copdisplay.list[currentcop][1]);
+ (cops++)->l = CMOVE(highw(p), cop2lc);
+ (cops++)->l = CMOVE2(loww(p), cop2lc);
+ copdisplay.rebuild[0] = cops;
+ } else {
+ (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
+ (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
+ if (!IS_OCS) {
+ (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
+ par->diwstop_h, par->diwstop_v), diwhigh);
+#if 0
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
+ (copl++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
+ }
+#endif
+ }
+ }
+ copdisplay.rebuild[1] = copl;
+
+ ami_update_par();
+ ami_rebuild_copper();
+}
-static struct fb_ops amifb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = amifb_check_var,
- .fb_set_par = amifb_set_par,
- .fb_setcolreg = amifb_setcolreg,
- .fb_blank = amifb_blank,
- .fb_pan_display = amifb_pan_display,
- .fb_fillrect = amifb_fillrect,
- .fb_copyarea = amifb_copyarea,
- .fb_imageblit = amifb_imageblit,
- .fb_ioctl = amifb_ioctl,
-};
static void __init amifb_setup_mcap(char *spec)
{
@@ -1327,6 +2458,93 @@ static int amifb_set_par(struct fb_info *info)
/*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ if (IS_AGA) {
+ if (regno > 255)
+ return 1;
+ } else if (currentpar.bplcon0 & BPC0_SHRES) {
+ if (regno > 3)
+ return 1;
+ } else {
+ if (regno > 31)
+ return 1;
+ }
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ if (!regno) {
+ red0 = red;
+ green0 = green;
+ blue0 = blue;
+ }
+
+ /*
+ * Update the corresponding Hardware Color Register, unless it's Color
+ * Register 0 and the screen is blanked.
+ *
+ * VBlank is switched off to protect bplcon3 or ecs_palette[] from
+ * being changed by ami_do_blank() during the VBlank.
+ */
+
+ if (regno || !is_blanked) {
+#if defined(CONFIG_FB_AMIGA_AGA)
+ if (IS_AGA) {
+ u_short bplcon3 = currentpar.bplcon3;
+ VBlankOff();
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
+ custom.color[regno & 31] = rgb2hw8_high(red, green,
+ blue);
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000) |
+ BPC3_LOCT;
+ custom.color[regno & 31] = rgb2hw8_low(red, green,
+ blue);
+ custom.bplcon3 = bplcon3;
+ VBlankOn();
+ } else
+#endif
+#if defined(CONFIG_FB_AMIGA_ECS)
+ if (currentpar.bplcon0 & BPC0_SHRES) {
+ u_short color, mask;
+ int i;
+
+ mask = 0x3333;
+ color = rgb2hw2(red, green, blue);
+ VBlankOff();
+ for (i = regno + 12; i >= (int)regno; i -= 4)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ mask <<= 2; color >>= 2;
+ regno = down16(regno) + mul4(mod4(regno));
+ for (i = regno + 3; i >= (int)regno; i--)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ VBlankOn();
+ } else
+#endif
+ custom.color[regno] = rgb2hw4(red, green, blue);
+ }
+ return 0;
+}
+
+
+ /*
+ * Blank the display.
+ */
+
+static int amifb_blank(int blank, struct fb_info *info)
+{
+ do_blank = blank ? blank : -1;
+
+ return 0;
+}
+
+
+ /*
* Pan or Wrap the Display
*
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
@@ -2232,6 +3450,77 @@ static int amifb_ioctl(struct fb_info *info,
/*
+ * Flash the cursor (called by VBlank interrupt)
+ */
+
+static int flash_cursor(void)
+{
+ static int cursorcount = 1;
+
+ if (cursormode = FB_CURSOR_FLASH) {
+ if (!--cursorcount) {
+ cursorstate = -cursorstate;
+ cursorcount = cursorrate;
+ if (!is_blanked)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+ /*
+ * VBlank Display Interrupt
+ */
+
+static irqreturn_t amifb_interrupt(int irq, void *dev_id)
+{
+ if (do_vmode_pan || do_vmode_full)
+ ami_update_display();
+
+ if (do_vmode_full)
+ ami_init_display();
+
+ if (do_vmode_pan) {
+ flash_cursor();
+ ami_rebuild_copper();
+ do_cursor = do_vmode_pan = 0;
+ } else if (do_cursor) {
+ flash_cursor();
+ ami_set_sprite();
+ do_cursor = 0;
+ } else {
+ if (flash_cursor())
+ ami_set_sprite();
+ }
+
+ if (do_blank) {
+ ami_do_blank();
+ do_blank = 0;
+ }
+
+ if (do_vmode_full) {
+ ami_reinit_copper();
+ do_vmode_full = 0;
+ }
+ return IRQ_HANDLED;
+}
+
+
+static struct fb_ops amifb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = amifb_check_var,
+ .fb_set_par = amifb_set_par,
+ .fb_setcolreg = amifb_setcolreg,
+ .fb_blank = amifb_blank,
+ .fb_pan_display = amifb_pan_display,
+ .fb_fillrect = amifb_fillrect,
+ .fb_copyarea = amifb_copyarea,
+ .fb_imageblit = amifb_imageblit,
+ .fb_ioctl = amifb_ioctl,
+};
+
+
+ /*
* Allocate, Clear and Align a Block of Chip Memory
*/
@@ -2255,6 +3544,17 @@ 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
*/
@@ -2460,1361 +3760,6 @@ amifb_error:
return err;
}
-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;
-}
-
-
- /*
- * Blank the display.
- */
-
-static int amifb_blank(int blank, struct fb_info *info)
-{
- do_blank = blank ? blank : -1;
-
- return 0;
-}
-
- /*
- * Flash the cursor (called by VBlank interrupt)
- */
-
-static int flash_cursor(void)
-{
- static int cursorcount = 1;
-
- if (cursormode = FB_CURSOR_FLASH) {
- if (!--cursorcount) {
- cursorstate = -cursorstate;
- cursorcount = cursorrate;
- if (!is_blanked)
- return 1;
- }
- }
- return 0;
-}
-
- /*
- * VBlank Display Interrupt
- */
-
-static irqreturn_t amifb_interrupt(int irq, void *dev_id)
-{
- if (do_vmode_pan || do_vmode_full)
- ami_update_display();
-
- if (do_vmode_full)
- ami_init_display();
-
- if (do_vmode_pan) {
- flash_cursor();
- ami_rebuild_copper();
- do_cursor = do_vmode_pan = 0;
- } else if (do_cursor) {
- flash_cursor();
- ami_set_sprite();
- do_cursor = 0;
- } else {
- if (flash_cursor())
- ami_set_sprite();
- }
-
- if (do_blank) {
- ami_do_blank();
- do_blank = 0;
- }
-
- if (do_vmode_full) {
- ami_reinit_copper();
- do_vmode_full = 0;
- }
- return IRQ_HANDLED;
-}
-
-/* --------------------------- Hardware routines --------------------------- */
-
- /*
- * Get the video params out of `var'. If a value doesn't fit, round
- * it up, if it's too big, return -EINVAL.
- */
-
-static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
-{
- u_short clk_shift, line_shift;
- u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
- u_int htotal, vtotal;
-
- /*
- * Find a matching Pixel Clock
- */
-
- for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
- if (var->pixclock <= pixclock[clk_shift])
- break;
- if (clk_shift > TAG_LORES) {
- DPRINTK("pixclock too high\n");
- return -EINVAL;
- }
- par->clk_shift = clk_shift;
-
- /*
- * Check the Geometry Values
- */
-
- if ((par->xres = var->xres) < 64)
- par->xres = 64;
- if ((par->yres = var->yres) < 64)
- par->yres = 64;
- if ((par->vxres = var->xres_virtual) < par->xres)
- par->vxres = par->xres;
- if ((par->vyres = var->yres_virtual) < par->yres)
- par->vyres = par->yres;
-
- par->bpp = var->bits_per_pixel;
- if (!var->nonstd) {
- if (par->bpp < 1)
- par->bpp = 1;
- if (par->bpp > maxdepth[clk_shift]) {
- if (round_down_bpp && maxdepth[clk_shift])
- par->bpp = maxdepth[clk_shift];
- else {
- DPRINTK("invalid bpp\n");
- return -EINVAL;
- }
- }
- } else if (var->nonstd = FB_NONSTD_HAM) {
- if (par->bpp < 6)
- par->bpp = 6;
- if (par->bpp != 6) {
- if (par->bpp < 8)
- par->bpp = 8;
- if (par->bpp != 8 || !IS_AGA) {
- DPRINTK("invalid bpp for ham mode\n");
- return -EINVAL;
- }
- }
- } else {
- DPRINTK("unknown nonstd mode\n");
- return -EINVAL;
- }
-
- /*
- * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
- * checks failed and smooth scrolling is not possible
- */
-
- par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN;
- switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- line_shift = 0;
- break;
- case FB_VMODE_NONINTERLACED:
- line_shift = 1;
- break;
- case FB_VMODE_DOUBLE:
- if (!IS_AGA) {
- DPRINTK("double mode only possible with aga\n");
- return -EINVAL;
- }
- line_shift = 2;
- break;
- default:
- DPRINTK("unknown video mode\n");
- return -EINVAL;
- break;
- }
- par->line_shift = line_shift;
-
- /*
- * Vertical and Horizontal Timings
- */
-
- xres_n = par->xres << clk_shift;
- yres_n = par->yres << line_shift;
- par->htotal = down8((var->left_margin + par->xres + var->right_margin +
- var->hsync_len) << clk_shift);
- par->vtotal - down2(((var->upper_margin + par->yres + var->lower_margin +
- var->vsync_len) << line_shift) + 1);
-
- if (IS_AGA)
- par->bplcon3 = sprpixmode[clk_shift];
- else
- par->bplcon3 = 0;
- if (var->sync & FB_SYNC_BROADCAST) {
- par->diwstop_h = par->htotal -
- ((var->right_margin - var->hsync_len) << clk_shift);
- if (IS_AGA)
- par->diwstop_h += mod4(var->hsync_len);
- else
- par->diwstop_h = down4(par->diwstop_h);
-
- par->diwstrt_h = par->diwstop_h - xres_n;
- par->diwstop_v = par->vtotal -
- ((var->lower_margin - var->vsync_len) << line_shift);
- par->diwstrt_v = par->diwstop_v - yres_n;
- if (par->diwstop_h >= par->htotal + 8) {
- DPRINTK("invalid diwstop_h\n");
- return -EINVAL;
- }
- if (par->diwstop_v > par->vtotal) {
- DPRINTK("invalid diwstop_v\n");
- return -EINVAL;
- }
-
- if (!IS_OCS) {
- /* Initialize sync with some reasonable values for pwrsave */
- par->hsstrt = 160;
- par->hsstop = 320;
- par->vsstrt = 30;
- par->vsstop = 34;
- } else {
- par->hsstrt = 0;
- par->hsstop = 0;
- par->vsstrt = 0;
- par->vsstop = 0;
- }
- if (par->vtotal > (PAL_VTOTAL + NTSC_VTOTAL) / 2) {
- /* PAL video mode */
- if (par->htotal != PAL_HTOTAL) {
- DPRINTK("htotal invalid for pal\n");
- return -EINVAL;
- }
- if (par->diwstrt_h < PAL_DIWSTRT_H) {
- DPRINTK("diwstrt_h too low for pal\n");
- return -EINVAL;
- }
- if (par->diwstrt_v < PAL_DIWSTRT_V) {
- DPRINTK("diwstrt_v too low for pal\n");
- return -EINVAL;
- }
- htotal = PAL_HTOTAL>>clk_shift;
- vtotal = PAL_VTOTAL>>1;
- if (!IS_OCS) {
- par->beamcon0 = BMC0_PAL;
- par->bplcon3 |= BPC3_BRDRBLNK;
- } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
- par->beamcon0 = BMC0_PAL;
- par->hsstop = 1;
- } else if (amiga_vblank != 50) {
- DPRINTK("pal not supported by this chipset\n");
- return -EINVAL;
- }
- } else {
- /* NTSC video mode
- * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
- * and NTSC activated, so than better let diwstop_h <= 1812
- */
- if (par->htotal != NTSC_HTOTAL) {
- DPRINTK("htotal invalid for ntsc\n");
- return -EINVAL;
- }
- if (par->diwstrt_h < NTSC_DIWSTRT_H) {
- DPRINTK("diwstrt_h too low for ntsc\n");
- return -EINVAL;
- }
- if (par->diwstrt_v < NTSC_DIWSTRT_V) {
- DPRINTK("diwstrt_v too low for ntsc\n");
- return -EINVAL;
- }
- htotal = NTSC_HTOTAL>>clk_shift;
- vtotal = NTSC_VTOTAL>>1;
- if (!IS_OCS) {
- par->beamcon0 = 0;
- par->bplcon3 |= BPC3_BRDRBLNK;
- } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
- par->beamcon0 = 0;
- par->hsstop = 1;
- } else if (amiga_vblank != 60) {
- DPRINTK("ntsc not supported by this chipset\n");
- return -EINVAL;
- }
- }
- if (IS_OCS) {
- if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
- par->diwstrt_v >= 512 || par->diwstop_v < 256) {
- DPRINTK("invalid position for display on ocs\n");
- return -EINVAL;
- }
- }
- } else if (!IS_OCS) {
- /* Programmable video mode */
- par->hsstrt = var->right_margin << clk_shift;
- par->hsstop = (var->right_margin + var->hsync_len) << clk_shift;
- par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift);
- if (!IS_AGA)
- par->diwstop_h = down4(par->diwstop_h) - 16;
- par->diwstrt_h = par->diwstop_h - xres_n;
- par->hbstop = par->diwstrt_h + 4;
- par->hbstrt = par->diwstop_h + 4;
- if (par->hbstrt >= par->htotal + 8)
- par->hbstrt -= par->htotal;
- par->hcenter = par->hsstrt + (par->htotal >> 1);
- par->vsstrt = var->lower_margin << line_shift;
- par->vsstop = (var->lower_margin + var->vsync_len) << line_shift;
- par->diwstop_v = par->vtotal;
- if ((par->vmode & FB_VMODE_MASK) = FB_VMODE_INTERLACED)
- par->diwstop_v -= 2;
- par->diwstrt_v = par->diwstop_v - yres_n;
- par->vbstop = par->diwstrt_v - 2;
- par->vbstrt = par->diwstop_v - 2;
- if (par->vtotal > 2048) {
- DPRINTK("vtotal too high\n");
- return -EINVAL;
- }
- if (par->htotal > 2048) {
- DPRINTK("htotal too high\n");
- return -EINVAL;
- }
- par->bplcon3 |= BPC3_EXTBLKEN;
- par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
- BMC0_PAL | BMC0_VARCSYEN;
- if (var->sync & FB_SYNC_HOR_HIGH_ACT)
- par->beamcon0 |= BMC0_HSYTRUE;
- if (var->sync & FB_SYNC_VERT_HIGH_ACT)
- par->beamcon0 |= BMC0_VSYTRUE;
- if (var->sync & FB_SYNC_COMP_HIGH_ACT)
- par->beamcon0 |= BMC0_CSYTRUE;
- htotal = par->htotal>>clk_shift;
- vtotal = par->vtotal>>1;
- } else {
- DPRINTK("only broadcast modes possible for ocs\n");
- return -EINVAL;
- }
-
- /*
- * Checking the DMA timing
- */
-
- fconst = 16 << maxfmode << clk_shift;
-
- /*
- * smallest window start value without turn off other dma cycles
- * than sprite1-7, unless you change min_fstrt
- */
-
-
- fsize = ((maxfmode + clk_shift <= 1) ? fconst : 64);
- fstrt = downx(fconst, par->diwstrt_h - 4) - fsize;
- if (fstrt < min_fstrt) {
- DPRINTK("fetch start too low\n");
- return -EINVAL;
- }
-
- /*
- * smallest window start value where smooth scrolling is possible
- */
-
- fstrt = downx(fconst, par->diwstrt_h - fconst + (1 << clk_shift) - 4) -
- fsize;
- if (fstrt < min_fstrt)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- maxfetchstop = down16(par->htotal - 80);
-
- fstrt = downx(fconst, par->diwstrt_h - 4) - 64 - fconst;
- fsize = upx(fconst, xres_n +
- modx(fconst, downx(1 << clk_shift, par->diwstrt_h - 4)));
- if (fstrt + fsize > maxfetchstop)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- fsize = upx(fconst, xres_n);
- if (fstrt + fsize > maxfetchstop) {
- DPRINTK("fetch stop too high\n");
- return -EINVAL;
- }
-
- if (maxfmode + clk_shift <= 1) {
- fsize = up64(xres_n + fconst - 1);
- if (min_fstrt + fsize - 64 > maxfetchstop)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- fsize = up64(xres_n);
- if (min_fstrt + fsize - 64 > maxfetchstop) {
- DPRINTK("fetch size too high\n");
- return -EINVAL;
- }
-
- fsize -= 64;
- } else
- fsize -= fconst;
-
- /*
- * Check if there is enough time to update the bitplane pointers for ywrap
- */
-
- if (par->htotal - fsize - 64 < par->bpp * 64)
- par->vmode &= ~FB_VMODE_YWRAP;
-
- /*
- * Bitplane calculations and check the Memory Requirements
- */
-
- 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) {
- 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) {
- DPRINTK("too few video mem\n");
- return -EINVAL;
- }
- }
-
- /*
- * Hardware Register Values
- */
-
- par->bplcon0 = BPC0_COLOR | bplpixmode[clk_shift];
- if (!IS_OCS)
- par->bplcon0 |= BPC0_ECSENA;
- if (par->bpp = 8)
- par->bplcon0 |= BPC0_BPU3;
- else
- par->bplcon0 |= par->bpp << 12;
- if (var->nonstd = FB_NONSTD_HAM)
- par->bplcon0 |= BPC0_HAM;
- if (var->sync & FB_SYNC_EXT)
- par->bplcon0 |= BPC0_ERSY;
-
- if (IS_AGA)
- par->fmode = bplfetchmode[maxfmode];
-
- switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- par->bplcon0 |= BPC0_LACE;
- break;
- case FB_VMODE_DOUBLE:
- if (IS_AGA)
- par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
- break;
- }
-
- if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
- par->xoffset = var->xoffset;
- par->yoffset = var->yoffset;
- if (par->vmode & FB_VMODE_YWRAP) {
- if (par->xoffset || par->yoffset < 0 ||
- par->yoffset >= par->vyres)
- par->xoffset = par->yoffset = 0;
- } else {
- if (par->xoffset < 0 ||
- par->xoffset > upx(16 << maxfmode, par->vxres - par->xres) ||
- par->yoffset < 0 || par->yoffset > par->vyres - par->yres)
- par->xoffset = par->yoffset = 0;
- }
- } else
- par->xoffset = par->yoffset = 0;
-
- par->crsr.crsr_x = par->crsr.crsr_y = 0;
- par->crsr.spot_x = par->crsr.spot_y = 0;
- par->crsr.height = par->crsr.width = 0;
-
- return 0;
-}
-
- /*
- * Fill the `var' structure based on the values in `par' and maybe
- * other values read out of the hardware.
- */
-
-static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
-{
- u_short clk_shift, line_shift;
-
- memset(var, 0, sizeof(struct fb_var_screeninfo));
-
- clk_shift = par->clk_shift;
- line_shift = par->line_shift;
-
- var->xres = par->xres;
- var->yres = par->yres;
- var->xres_virtual = par->vxres;
- var->yres_virtual = par->vyres;
- var->xoffset = par->xoffset;
- var->yoffset = par->yoffset;
-
- var->bits_per_pixel = par->bpp;
- var->grayscale = 0;
-
- var->red.offset = 0;
- var->red.msb_right = 0;
- var->red.length = par->bpp;
- if (par->bplcon0 & BPC0_HAM)
- var->red.length -= 2;
- var->blue = var->green = var->red;
- var->transp.offset = 0;
- var->transp.length = 0;
- var->transp.msb_right = 0;
-
- if (par->bplcon0 & BPC0_HAM)
- var->nonstd = FB_NONSTD_HAM;
- else
- var->nonstd = 0;
- var->activate = 0;
-
- var->height = -1;
- var->width = -1;
-
- var->pixclock = pixclock[clk_shift];
-
- if (IS_AGA && par->fmode & FMODE_BSCAN2)
- var->vmode = FB_VMODE_DOUBLE;
- else if (par->bplcon0 & BPC0_LACE)
- var->vmode = FB_VMODE_INTERLACED;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-
- if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) {
- var->hsync_len = (par->hsstop - par->hsstrt)>>clk_shift;
- var->right_margin = par->hsstrt>>clk_shift;
- var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
- var->vsync_len = (par->vsstop - par->vsstrt)>>line_shift;
- var->lower_margin = par->vsstrt>>line_shift;
- var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len;
- var->sync = 0;
- if (par->beamcon0 & BMC0_HSYTRUE)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (par->beamcon0 & BMC0_VSYTRUE)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (par->beamcon0 & BMC0_CSYTRUE)
- var->sync |= FB_SYNC_COMP_HIGH_ACT;
- } else {
- var->sync = FB_SYNC_BROADCAST;
- var->hsync_len = (152>>clk_shift) + mod4(par->diwstop_h);
- var->right_margin = ((par->htotal - down4(par->diwstop_h))>>clk_shift) + var->hsync_len;
- var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
- var->vsync_len = 4>>line_shift;
- var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len;
- var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres -
- var->lower_margin - var->vsync_len;
- }
-
- if (par->bplcon0 & BPC0_ERSY)
- var->sync |= FB_SYNC_EXT;
- if (par->vmode & FB_VMODE_YWRAP)
- var->vmode |= FB_VMODE_YWRAP;
-
- return 0;
-}
-
-
- /*
- * Pan or Wrap the Display
- *
- * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
- * in `var'.
- */
-
-static void ami_pan_var(struct fb_var_screeninfo *var)
-{
- struct amifb_par *par = ¤tpar;
-
- par->xoffset = var->xoffset;
- par->yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- par->vmode |= FB_VMODE_YWRAP;
- else
- par->vmode &= ~FB_VMODE_YWRAP;
-
- do_vmode_pan = 0;
- ami_update_par();
- do_vmode_pan = 1;
-}
-
- /*
- * Update hardware
- */
-
-static int ami_update_par(void)
-{
- struct amifb_par *par = ¤tpar;
- short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
-
- clk_shift = par->clk_shift;
-
- if (!(par->vmode & FB_VMODE_SMOOTH_XPAN))
- par->xoffset = upx(16 << maxfmode, par->xoffset);
-
- fconst = 16 << maxfmode << clk_shift;
- vshift = modx(16 << maxfmode, par->xoffset);
- fstrt = par->diwstrt_h - (vshift << clk_shift) - 4;
- fsize = (par->xres + vshift) << clk_shift;
- shift = modx(fconst, fstrt);
- move = downx(2 << maxfmode, div8(par->xoffset));
- if (maxfmode + clk_shift > 1) {
- fstrt = downx(fconst, fstrt) - 64;
- fsize = upx(fconst, fsize);
- fstop = fstrt + fsize - fconst;
- } else {
- mod = fstrt = downx(fconst, fstrt) - fconst;
- fstop = fstrt + upx(fconst, fsize) - 64;
- fsize = up64(fsize);
- fstrt = fstop - fsize + 64;
- if (fstrt < min_fstrt) {
- fstop += min_fstrt - fstrt;
- fstrt = min_fstrt;
- }
- move = move - div8((mod - fstrt)>>clk_shift);
- }
- mod = par->next_line - div8(fsize>>clk_shift);
- par->ddfstrt = fstrt;
- par->ddfstop = fstop;
- par->bplcon1 = hscroll2hw(shift);
- par->bpl2mod = mod;
- if (par->bplcon0 & BPC0_LACE)
- par->bpl2mod += par->next_line;
- if (IS_AGA && (par->fmode & FMODE_BSCAN2))
- par->bpl1mod = -div8(fsize>>clk_shift);
- else
- par->bpl1mod = par->bpl2mod;
-
- if (par->yoffset) {
- par->bplpt0 = fb_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;
- if (par->bplcon0 & BPC0_LACE &&
- mod2(par->diwstrt_v + par->vyres -
- par->yoffset))
- par->bplpt0wrap += par->next_line;
- }
- }
- } else
- par->bplpt0 = fb_info.fix.smem_start + move;
-
- if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
- par->bplpt0 += par->next_line;
-
- return 0;
-}
-
-
- /*
- * Set a single color register. The values supplied are already
- * rounded down to the hardware's capabilities (according to the
- * entries in the var structure). Return != 0 for invalid regno.
- */
-
-static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- if (IS_AGA) {
- if (regno > 255)
- return 1;
- } else if (currentpar.bplcon0 & BPC0_SHRES) {
- if (regno > 3)
- return 1;
- } else {
- if (regno > 31)
- return 1;
- }
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- if (!regno) {
- red0 = red;
- green0 = green;
- blue0 = blue;
- }
-
- /*
- * Update the corresponding Hardware Color Register, unless it's Color
- * Register 0 and the screen is blanked.
- *
- * VBlank is switched off to protect bplcon3 or ecs_palette[] from
- * being changed by ami_do_blank() during the VBlank.
- */
-
- if (regno || !is_blanked) {
-#if defined(CONFIG_FB_AMIGA_AGA)
- if (IS_AGA) {
- u_short bplcon3 = currentpar.bplcon3;
- VBlankOff();
- custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
- custom.color[regno & 31] = rgb2hw8_high(red, green,
- blue);
- custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000) |
- BPC3_LOCT;
- custom.color[regno & 31] = rgb2hw8_low(red, green,
- blue);
- custom.bplcon3 = bplcon3;
- VBlankOn();
- } else
-#endif
-#if defined(CONFIG_FB_AMIGA_ECS)
- if (currentpar.bplcon0 & BPC0_SHRES) {
- u_short color, mask;
- int i;
-
- mask = 0x3333;
- color = rgb2hw2(red, green, blue);
- VBlankOff();
- for (i = regno + 12; i >= (int)regno; i -= 4)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<= 2; color >>= 2;
- regno = down16(regno) + mul4(mod4(regno));
- for (i = regno + 3; i >= (int)regno; i--)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- VBlankOn();
- } else
-#endif
- custom.color[regno] = rgb2hw4(red, green, blue);
- }
- return 0;
-}
-
-static void ami_update_display(void)
-{
- struct amifb_par *par = ¤tpar;
-
- custom.bplcon1 = par->bplcon1;
- custom.bpl1mod = par->bpl1mod;
- custom.bpl2mod = par->bpl2mod;
- custom.ddfstrt = ddfstrt2hw(par->ddfstrt);
- custom.ddfstop = ddfstop2hw(par->ddfstop);
-}
-
- /*
- * Change the video mode (called by VBlank interrupt)
- */
-
-static void ami_init_display(void)
-{
- struct amifb_par *par = ¤tpar;
- int i;
-
- custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
- custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
- if (!IS_OCS) {
- custom.bplcon3 = par->bplcon3;
- if (IS_AGA)
- custom.bplcon4 = BPC4_ESPRM4 | BPC4_OSPRM4;
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- custom.htotal = htotal2hw(par->htotal);
- custom.hbstrt = hbstrt2hw(par->hbstrt);
- custom.hbstop = hbstop2hw(par->hbstop);
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.hcenter = hcenter2hw(par->hcenter);
- custom.vtotal = vtotal2hw(par->vtotal);
- custom.vbstrt = vbstrt2hw(par->vbstrt);
- custom.vbstop = vbstop2hw(par->vbstop);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstop2hw(par->vsstop);
- }
- }
- if (!IS_OCS || par->hsstop)
- custom.beamcon0 = par->beamcon0;
- if (IS_AGA)
- custom.fmode = par->fmode;
-
- /*
- * The minimum period for audio depends on htotal
- */
-
- amiga_audio_min_period = div16(par->htotal);
-
- is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0;
-#if 1
- if (is_lace) {
- i = custom.vposr >> 15;
- } else {
- custom.vposw = custom.vposr | 0x8000;
- i = 1;
- }
-#else
- i = 1;
- custom.vposw = custom.vposr | 0x8000;
-#endif
- custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][i]);
-}
-
- /*
- * (Un)Blank the screen (called by VBlank interrupt)
- */
-
-static void ami_do_blank(void)
-{
- struct amifb_par *par = ¤tpar;
-#if defined(CONFIG_FB_AMIGA_AGA)
- u_short bplcon3 = par->bplcon3;
-#endif
- u_char red, green, blue;
-
- if (do_blank > 0) {
- custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
- red = green = blue = 0;
- if (!IS_OCS && do_blank > 1) {
- switch (do_blank) {
- case FB_BLANK_VSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.vsstrt = vsstrt2hw(par->vtotal + 4);
- custom.vsstop = vsstop2hw(par->vtotal + 4);
- break;
- case FB_BLANK_HSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->htotal + 16);
- custom.hsstop = hsstop2hw(par->htotal + 16);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstrt2hw(par->vsstop);
- break;
- case FB_BLANK_POWERDOWN:
- custom.hsstrt = hsstrt2hw(par->htotal + 16);
- custom.hsstop = hsstop2hw(par->htotal + 16);
- custom.vsstrt = vsstrt2hw(par->vtotal + 4);
- custom.vsstop = vsstop2hw(par->vtotal + 4);
- break;
- }
- if (!(par->beamcon0 & BMC0_VARBEAMEN)) {
- custom.htotal = htotal2hw(par->htotal);
- custom.vtotal = vtotal2hw(par->vtotal);
- custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
- }
- }
- } else {
- custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE;
- red = red0;
- green = green0;
- blue = blue0;
- if (!IS_OCS) {
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstop2hw(par->vsstop);
- custom.beamcon0 = par->beamcon0;
- }
- }
-#if defined(CONFIG_FB_AMIGA_AGA)
- if (IS_AGA) {
- custom.bplcon3 = bplcon3;
- custom.color[0] = rgb2hw8_high(red, green, blue);
- custom.bplcon3 = bplcon3 | BPC3_LOCT;
- custom.color[0] = rgb2hw8_low(red, green, blue);
- custom.bplcon3 = bplcon3;
- } else
-#endif
-#if defined(CONFIG_FB_AMIGA_ECS)
- if (par->bplcon0 & BPC0_SHRES) {
- u_short color, mask;
- int i;
-
- mask = 0x3333;
- color = rgb2hw2(red, green, blue);
- for (i = 12; i >= 0; i -= 4)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<= 2; color >>= 2;
- for (i = 3; i >= 0; i--)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- } else
-#endif
- custom.color[0] = rgb2hw4(red, green, blue);
- is_blanked = do_blank > 0 ? do_blank : 0;
-}
-
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
-{
- 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;
- fix->crsr_color2 = 18;
- return 0;
-}
-
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
-{
- struct amifb_par *par = ¤tpar;
- register u_short *lspr, *sspr;
-#ifdef __mc68000__
- register u_long datawords asm ("d2");
-#else
- register u_long datawords;
-#endif
- register short delta;
- register u_char color;
- short height, width, bits, words;
- int size, alloc;
-
- size = par->crsr.height * par->crsr.width;
- alloc = var->height * var->width;
- var->height = par->crsr.height;
- var->width = par->crsr.width;
- var->xspot = par->crsr.spot_x;
- var->yspot = par->crsr.spot_y;
- if (size > var->height * var->width)
- return -ENAMETOOLONG;
- if (!access_ok(VERIFY_WRITE, data, size))
- return -EFAULT;
- delta = 1 << par->crsr.fmode;
- lspr = lofsprite + (delta << 1);
- if (par->bplcon0 & BPC0_LACE)
- sspr = shfsprite + (delta << 1);
- else
- sspr = NULL;
- for (height = (short)var->height - 1; height >= 0; height--) {
- bits = 0; words = delta; datawords = 0;
- for (width = (short)var->width - 1; width >= 0; width--) {
- if (bits = 0) {
- bits = 16; --words;
-#ifdef __mc68000__
- asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0"
- : "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta));
-#else
- datawords = (*(lspr + delta) << 16) | (*lspr++);
-#endif
- }
- --bits;
-#ifdef __mc68000__
- asm volatile (
- "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
- "swap %1 ; lslw #1,%1 ; roxlb #1,%0"
- : "=d" (color), "=d" (datawords) : "1" (datawords));
-#else
- color = (((datawords >> 30) & 2)
- | ((datawords >> 15) & 1));
- datawords <<= 1;
-#endif
- put_user(color, data++);
- }
- if (bits > 0) {
- --words; ++lspr;
- }
- while (--words >= 0)
- ++lspr;
-#ifdef __mc68000__
- asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
- : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
-#else
- lspr += delta;
- if (sspr) {
- u_short *tmp = lspr;
- lspr = sspr;
- sspr = tmp;
- }
-#endif
- }
- return 0;
-}
-
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
-{
- struct amifb_par *par = ¤tpar;
- register u_short *lspr, *sspr;
-#ifdef __mc68000__
- register u_long datawords asm ("d2");
-#else
- register u_long datawords;
-#endif
- register short delta;
- u_short fmode;
- short height, width, bits, words;
-
- if (!var->width)
- return -EINVAL;
- else if (var->width <= 16)
- fmode = TAG_FMODE_1;
- else if (var->width <= 32)
- fmode = TAG_FMODE_2;
- else if (var->width <= 64)
- fmode = TAG_FMODE_4;
- else
- return -EINVAL;
- if (fmode > maxfmode)
- return -EINVAL;
- if (!var->height)
- return -EINVAL;
- if (!access_ok(VERIFY_READ, data, var->width * var->height))
- return -EFAULT;
- delta = 1 << fmode;
- lofsprite = shfsprite = (u_short *)spritememory;
- lspr = lofsprite + (delta << 1);
- if (par->bplcon0 & BPC0_LACE) {
- if (((var->height + 4) << fmode << 2) > SPRITEMEMSIZE)
- return -EINVAL;
- memset(lspr, 0, (var->height + 4) << fmode << 2);
- shfsprite += ((var->height + 5)&-2) << fmode;
- sspr = shfsprite + (delta << 1);
- } else {
- if (((var->height + 2) << fmode << 2) > SPRITEMEMSIZE)
- return -EINVAL;
- memset(lspr, 0, (var->height + 2) << fmode << 2);
- sspr = NULL;
- }
- for (height = (short)var->height - 1; height >= 0; height--) {
- bits = 16; words = delta; datawords = 0;
- for (width = (short)var->width - 1; width >= 0; width--) {
- unsigned long tdata = 0;
- get_user(tdata, data);
- data++;
-#ifdef __mc68000__
- asm volatile (
- "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
- "lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
- : "=d" (datawords)
- : "0" (datawords), "d" (tdata));
-#else
- datawords = ((datawords << 1) & 0xfffefffe);
- datawords |= tdata & 1;
- datawords |= (tdata & 2) << (16 - 1);
-#endif
- if (--bits = 0) {
- bits = 16; --words;
-#ifdef __mc68000__
- asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta));
-#else
- *(lspr + delta) = (u_short) (datawords >> 16);
- *lspr++ = (u_short) (datawords & 0xffff);
-#endif
- }
- }
- if (bits < 16) {
- --words;
-#ifdef __mc68000__
- asm volatile (
- "swap %2 ; lslw %4,%2 ; movew %2,%0@(%3:w:2) ; "
- "swap %2 ; lslw %4,%2 ; movew %2,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits));
-#else
- *(lspr + delta) = (u_short) (datawords >> (16 + bits));
- *lspr++ = (u_short) ((datawords & 0x0000ffff) >> bits);
-#endif
- }
- while (--words >= 0) {
-#ifdef __mc68000__
- asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (delta) : "d0");
-#else
- *(lspr + delta) = 0;
- *lspr++ = 0;
-#endif
- }
-#ifdef __mc68000__
- asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
- : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
-#else
- lspr += delta;
- if (sspr) {
- u_short *tmp = lspr;
- lspr = sspr;
- sspr = tmp;
- }
-#endif
- }
- par->crsr.height = var->height;
- par->crsr.width = var->width;
- par->crsr.spot_x = var->xspot;
- par->crsr.spot_y = var->yspot;
- par->crsr.fmode = fmode;
- if (IS_AGA) {
- par->fmode &= ~(FMODE_SPAGEM | FMODE_SPR32);
- par->fmode |= sprfetchmode[fmode];
- custom.fmode = par->fmode;
- }
- return 0;
-}
-
-static int ami_get_cursorstate(struct fb_cursorstate *state)
-{
- 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)
-{
- struct amifb_par *par = ¤tpar;
-
- par->crsr.crsr_x = state->xoffset;
- par->crsr.crsr_y = state->yoffset;
- if ((cursormode = state->mode) = FB_CURSOR_OFF)
- cursorstate = -1;
- do_cursor = 1;
- return 0;
-}
-
-static void ami_set_sprite(void)
-{
- struct amifb_par *par = ¤tpar;
- copins *copl, *cops;
- u_short hs, vs, ve;
- u_long pl, ps, pt;
- short mx, my;
-
- cops = copdisplay.list[currentcop][0];
- copl = copdisplay.list[currentcop][1];
- ps = pl = ZTWO_PADDR(dummysprite);
- mx = par->crsr.crsr_x - par->crsr.spot_x;
- my = par->crsr.crsr_y - par->crsr.spot_y;
- if (!(par->vmode & FB_VMODE_YWRAP)) {
- mx -= par->xoffset;
- my -= par->yoffset;
- }
- if (!is_blanked && cursorstate > 0 && par->crsr.height > 0 &&
- mx > -(short)par->crsr.width && mx < par->xres &&
- my > -(short)par->crsr.height && my < par->yres) {
- pl = ZTWO_PADDR(lofsprite);
- hs = par->diwstrt_h + (mx << par->clk_shift) - 4;
- vs = par->diwstrt_v + (my << par->line_shift);
- ve = vs + (par->crsr.height << par->line_shift);
- if (par->bplcon0 & BPC0_LACE) {
- ps = ZTWO_PADDR(shfsprite);
- lofsprite[0] = spr2hw_pos(vs, hs);
- shfsprite[0] = spr2hw_pos(vs + 1, hs);
- if (mod2(vs)) {
- lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
- shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
- pt = pl; pl = ps; ps = pt;
- } else {
- lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
- shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);
- }
- } else {
- lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0);
- lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
- }
- }
- copl[cop_spr0ptrh].w[1] = highw(pl);
- copl[cop_spr0ptrl].w[1] = loww(pl);
- if (par->bplcon0 & BPC0_LACE) {
- cops[cop_spr0ptrh].w[1] = highw(ps);
- cops[cop_spr0ptrl].w[1] = loww(ps);
- }
-}
-
-
- /*
- * Initialise the Copper Initialisation List
- */
-
-static void __init ami_init_copper(void)
-{
- copins *cop = copdisplay.init;
- u_long p;
- int i;
-
- if (!IS_OCS) {
- (cop++)->l = CMOVE(BPC0_COLOR | BPC0_SHRES | BPC0_ECSENA, bplcon0);
- (cop++)->l = CMOVE(0x0181, diwstrt);
- (cop++)->l = CMOVE(0x0281, diwstop);
- (cop++)->l = CMOVE(0x0000, diwhigh);
- } else
- (cop++)->l = CMOVE(BPC0_COLOR, bplcon0);
- p = ZTWO_PADDR(dummysprite);
- for (i = 0; i < 8; i++) {
- (cop++)->l = CMOVE(0, spr[i].pos);
- (cop++)->l = CMOVE(highw(p), sprpt[i]);
- (cop++)->l = CMOVE2(loww(p), sprpt[i]);
- }
-
- (cop++)->l = CMOVE(IF_SETCLR | IF_COPER, intreq);
- copdisplay.wait = cop;
- (cop++)->l = CEND;
- (cop++)->l = CMOVE(0, copjmp2);
- cop->l = CEND;
-
- custom.cop1lc = (u_short *)ZTWO_PADDR(copdisplay.init);
- custom.copjmp1 = 0;
-}
-
-static void ami_reinit_copper(void)
-{
- 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);
-}
-
- /*
- * Build the Copper List
- */
-
-static void ami_build_copper(void)
-{
- struct amifb_par *par = ¤tpar;
- copins *copl, *cops;
- u_long p;
-
- currentcop = 1 - currentcop;
-
- copl = copdisplay.list[currentcop][1];
-
- (copl++)->l = CWAIT(0, 10);
- (copl++)->l = CMOVE(par->bplcon0, bplcon0);
- (copl++)->l = CMOVE(0, sprpt[0]);
- (copl++)->l = CMOVE2(0, sprpt[0]);
-
- if (par->bplcon0 & BPC0_LACE) {
- cops = copdisplay.list[currentcop][0];
-
- (cops++)->l = CWAIT(0, 10);
- (cops++)->l = CMOVE(par->bplcon0, bplcon0);
- (cops++)->l = CMOVE(0, sprpt[0]);
- (cops++)->l = CMOVE2(0, sprpt[0]);
-
- (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v + 1), diwstrt);
- (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v + 1), diwstop);
- (cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
- (cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
- if (!IS_OCS) {
- (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v + 1,
- par->diwstop_h, par->diwstop_v + 1), diwhigh);
- (cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
-#if 0
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt + 1), vbstrt);
- (copl++)->l = CMOVE(vbstop2hw(par->vbstop + 1), vbstop);
- (cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
- (cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
- }
-#endif
- }
- p = ZTWO_PADDR(copdisplay.list[currentcop][0]);
- (copl++)->l = CMOVE(highw(p), cop2lc);
- (copl++)->l = CMOVE2(loww(p), cop2lc);
- p = ZTWO_PADDR(copdisplay.list[currentcop][1]);
- (cops++)->l = CMOVE(highw(p), cop2lc);
- (cops++)->l = CMOVE2(loww(p), cop2lc);
- copdisplay.rebuild[0] = cops;
- } else {
- (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
- (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
- if (!IS_OCS) {
- (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
-#if 0
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
- (copl++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
- }
-#endif
- }
- }
- copdisplay.rebuild[1] = copl;
-
- ami_update_par();
- ami_rebuild_copper();
-}
-
- /*
- * Rebuild the Copper List
- *
- * We only change the things that are not static
- */
-
-static void ami_rebuild_copper(void)
-{
- struct amifb_par *par = ¤tpar;
- copins *copl, *cops;
- u_short line, h_end1, h_end2;
- short i;
- u_long p;
-
- if (IS_AGA && maxfmode + par->clk_shift = 0)
- h_end1 = par->diwstrt_h - 64;
- else
- h_end1 = par->htotal - 32;
- h_end2 = par->ddfstop + 64;
-
- ami_set_sprite();
-
- copl = copdisplay.rebuild[1];
- p = par->bplpt0;
- if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres - par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres - par->yres) {
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (copl++)->l = CMOVE(highw(p), bplpt[i]);
- (copl++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 1;
- while (line >= 512) {
- (copl++)->l = CWAIT(h_end1, 510);
- line -= 512;
- }
- if (line >= 510 && IS_AGA && maxfmode + par->clk_shift = 0)
- (copl++)->l = CWAIT(h_end1, line);
- else
- (copl++)->l = CWAIT(h_end2, line);
- p = par->bplpt0wrap;
- }
- } else
- p = par->bplpt0wrap;
- }
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (copl++)->l = CMOVE(highw(p), bplpt[i]);
- (copl++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- copl->l = CEND;
-
- if (par->bplcon0 & BPC0_LACE) {
- cops = copdisplay.rebuild[0];
- p = par->bplpt0;
- if (mod2(par->diwstrt_v))
- p -= par->next_line;
- else
- p += par->next_line;
- if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres - par->yoffset) != 1 || mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres - par->yres + 1) {
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (cops++)->l = CMOVE(highw(p), bplpt[i]);
- (cops++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 2;
- while (line >= 512) {
- (cops++)->l = CWAIT(h_end1, 510);
- line -= 512;
- }
- if (line > 510 && IS_AGA && maxfmode + par->clk_shift = 0)
- (cops++)->l = CWAIT(h_end1, line);
- else
- (cops++)->l = CWAIT(h_end2, line);
- p = par->bplpt0wrap;
- if (mod2(par->diwstrt_v + par->vyres -
- par->yoffset))
- p -= par->next_line;
- else
- p += par->next_line;
- }
- } else
- p = par->bplpt0wrap - par->next_line;
- }
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (cops++)->l = CMOVE(highw(p), bplpt[i]);
- (cops++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- cops->l = CEND;
- }
-}
static int __exit amifb_remove(struct platform_device *pdev)
{
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/8] fbdev/amifb: Fix double free
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1321908839-11419-1-git-send-email-geert@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 72454c7..39d211a 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2464,7 +2464,6 @@ static void amifb_deinit(struct platform_device *pdev)
{
if (fb_info.cmap.len)
fb_dealloc_cmap(&fb_info.cmap);
- fb_dealloc_cmap(&fb_info.cmap);
chipfree();
if (videomemory)
iounmap((void *)videomemory);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/8] fbdev/amifb: Correct whitespace
From: Geert Uytterhoeven @ 2011-11-21 20:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-m68k, linux-kernel, Geert Uytterhoeven
- indentation
- spacing around binary operators
No functional changes
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/amifb.c | 1186 +++++++++++++++++++++++++------------------------
1 files changed, 606 insertions(+), 580 deletions(-)
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 5ea6596..72454c7 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -152,10 +152,10 @@
- hsstrt: Start of horizontal synchronization pulse
- hsstop: End of horizontal synchronization pulse
- - htotal: Last value on the line (i.e. line length = htotal+1)
+ - htotal: Last value on the line (i.e. line length = htotal + 1)
- vsstrt: Start of vertical synchronization pulse
- vsstop: End of vertical synchronization pulse
- - vtotal: Last line value (i.e. number of lines = vtotal+1)
+ - vtotal: Last line value (i.e. number of lines = vtotal + 1)
- hcenter: Start of vertical retrace for interlace
You can specify the blanking timings independently. Currently I just set
@@ -184,7 +184,7 @@
clock):
- diwstrt_h: Horizontal start of the visible window
- - diwstop_h: Horizontal stop+1(*) of the visible window
+ - diwstop_h: Horizontal stop + 1(*) of the visible window
- diwstrt_v: Vertical start of the visible window
- diwstop_v: Vertical stop of the visible window
- ddfstrt: Horizontal start of display DMA
@@ -193,7 +193,7 @@
Sprite positioning:
- - sprstrt_h: Horizontal start-4 of sprite
+ - sprstrt_h: Horizontal start - 4 of sprite
- sprstrt_v: Vertical start of sprite
(*) Even Commodore did it wrong in the AGA monitor drivers by not adding 1.
@@ -212,21 +212,21 @@
display parameters. Here's what I found out:
- ddfstrt and ddfstop are best aligned to 64 pixels.
- - the chipset needs 64+4 horizontal pixels after the DMA start before the
- first pixel is output, so diwstrt_h = ddfstrt+64+4 if you want to
- display the first pixel on the line too. Increase diwstrt_h for virtual
- screen panning.
+ - the chipset needs 64 + 4 horizontal pixels after the DMA start before
+ the first pixel is output, so diwstrt_h = ddfstrt + 64 + 4 if you want
+ to display the first pixel on the line too. Increase diwstrt_h for
+ virtual screen panning.
- the display DMA always fetches 64 pixels at a time (fmode = 3).
- - ddfstop is ddfstrt+#pixels-64.
- - diwstop_h = diwstrt_h+xres+1. Because of the additional 1 this can be 1
- more than htotal.
+ - ddfstop is ddfstrt+#pixels - 64.
+ - diwstop_h = diwstrt_h + xres + 1. Because of the additional 1 this can
+ be 1 more than htotal.
- hscroll simply adds a delay to the display output. Smooth horizontal
- panning needs an extra 64 pixels on the left to prefetch the pixels that
- `fall off' on the left.
+ panning needs an extra 64 pixels on the left to prefetch the pixels that
+ `fall off' on the left.
- if ddfstrt < 192, the sprite DMA cycles are all stolen by the bitplane
- DMA, so it's best to make the DMA start as late as possible.
+ DMA, so it's best to make the DMA start as late as possible.
- you really don't want to make ddfstrt < 128, since this will steal DMA
- cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
+ cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
- I make diwstop_h and diwstop_v as large as possible.
General dependencies
@@ -234,8 +234,8 @@
- all values are SHRES pixel (35ns)
- table 1:fetchstart table 2:prefetch table 3:fetchsize
- ------------------ ---------------- -----------------
+ table 1:fetchstart table 2:prefetch table 3:fetchsize
+ ------------------ ---------------- -----------------
Pixclock # SHRES|HIRES|LORES # SHRES|HIRES|LORES # SHRES|HIRES|LORES
-------------#------+-----+------#------+-----+------#------+-----+------
Bus width 1x # 16 | 32 | 64 # 16 | 32 | 64 # 64 | 64 | 64
@@ -245,21 +245,21 @@
- chipset needs 4 pixels before the first pixel is output
- ddfstrt must be aligned to fetchstart (table 1)
- chipset needs also prefetch (table 2) to get first pixel data, so
- ddfstrt = ((diwstrt_h-4) & -fetchstart) - prefetch
+ ddfstrt = ((diwstrt_h - 4) & -fetchstart) - prefetch
- for horizontal panning decrease diwstrt_h
- the length of a fetchline must be aligned to fetchsize (table 3)
- if fetchstart is smaller than fetchsize, then ddfstrt can a little bit
- moved to optimize use of dma (useful for OCS/ECS overscan displays)
- - ddfstop is ddfstrt+ddfsize-fetchsize
+ moved to optimize use of dma (useful for OCS/ECS overscan displays)
+ - ddfstop is ddfstrt + ddfsize - fetchsize
- If C= didn't change anything for AGA, then at following positions the
- dma bus is already used:
- ddfstrt < 48 -> memory refresh
- < 96 -> disk dma
- < 160 -> audio dma
- < 192 -> sprite 0 dma
- < 416 -> sprite dma (32 per sprite)
+ dma bus is already used:
+ ddfstrt < 48 -> memory refresh
+ < 96 -> disk dma
+ < 160 -> audio dma
+ < 192 -> sprite 0 dma
+ < 416 -> sprite dma (32 per sprite)
- in accordance with the hardware reference manual a hardware stop is at
- 192, but AGA (ECS?) can go below this.
+ 192, but AGA (ECS?) can go below this.
DMA priorities
--------------
@@ -269,7 +269,7 @@
the hardware cursor:
- if you want to start display DMA too early, you lose the ability to
- do smooth horizontal panning (xpanstep 1 -> 64).
+ do smooth horizontal panning (xpanstep 1 -> 64).
- if you want to go even further, you lose the hardware cursor too.
IMHO a hardware cursor is more important for X than horizontal scrolling,
@@ -286,8 +286,8 @@
Standard VGA timings
--------------------
- xres yres left right upper lower hsync vsync
- ---- ---- ---- ----- ----- ----- ----- -----
+ xres yres left right upper lower hsync vsync
+ ---- ---- ---- ----- ----- ----- ----- -----
80x25 720 400 27 45 35 12 108 2
80x30 720 480 27 45 30 9 108 2
@@ -297,8 +297,8 @@
As a comparison, graphics/monitor.h suggests the following:
- xres yres left right upper lower hsync vsync
- ---- ---- ---- ----- ----- ----- ----- -----
+ xres yres left right upper lower hsync vsync
+ ---- ---- ---- ----- ----- ----- ----- -----
VGA 640 480 52 112 24 19 112 - 2 +
VGA70 640 400 52 112 27 21 112 - 2 -
@@ -309,10 +309,10 @@
VSYNC HSYNC Vertical size Vertical total
----- ----- ------------- --------------
- + + Reserved Reserved
- + - 400 414
- - + 350 362
- - - 480 496
+ + + Reserved Reserved
+ + - 400 414
+ - + 350 362
+ - - 480 496
Source: CL-GD542X Technical Reference Manual, Cirrus Logic, Oct 1992
@@ -326,33 +326,34 @@
-----------
- a scanline is 64 µs long, of which 52.48 µs are visible. This is about
- 736 visible 70 ns pixels per line.
+ 736 visible 70 ns pixels per line.
- we have 625 scanlines, of which 575 are visible (interlaced); after
- rounding this becomes 576.
+ rounding this becomes 576.
RETMA -> NTSC
-------------
- a scanline is 63.5 µs long, of which 53.5 µs are visible. This is about
- 736 visible 70 ns pixels per line.
+ 736 visible 70 ns pixels per line.
- we have 525 scanlines, of which 485 are visible (interlaced); after
- rounding this becomes 484.
+ rounding this becomes 484.
Thus if you want a PAL compatible display, you have to do the following:
- set the FB_SYNC_BROADCAST flag to indicate that standard broadcast
- timings are to be used.
- - make sure upper_margin+yres+lower_margin+vsync_len = 625 for an
- interlaced, 312 for a non-interlaced and 156 for a doublescanned
- display.
- - make sure left_margin+xres+right_margin+hsync_len = 1816 for a SHRES,
- 908 for a HIRES and 454 for a LORES display.
+ timings are to be used.
+ - make sure upper_margin + yres + lower_margin + vsync_len = 625 for an
+ interlaced, 312 for a non-interlaced and 156 for a doublescanned
+ display.
+ - make sure left_margin + xres + right_margin + hsync_len = 1816 for a
+ SHRES, 908 for a HIRES and 454 for a LORES display.
- the left visible part begins at 360 (SHRES; HIRES:180, LORES:90),
- left_margin+2*hsync_len must be greater or equal.
+ left_margin + 2 * hsync_len must be greater or equal.
- the upper visible part begins at 48 (interlaced; non-interlaced:24,
- doublescanned:12), upper_margin+2*vsync_len must be greater or equal.
+ doublescanned:12), upper_margin + 2 * vsync_len must be greater or
+ equal.
- ami_encode_var() calculates margins with a hsync of 5320 ns and a vsync
- of 4 scanlines
+ of 4 scanlines
The settings for a NTSC compatible display are straightforward.
@@ -361,7 +362,7 @@
anything about horizontal/vertical synchronization nor refresh rates.
- -- Geert --
+ -- Geert --
*******************************************************************************/
@@ -540,45 +541,45 @@ static u_short maxfmode, chipset;
* Various macros
*/
-#define up2(v) (((v)+1) & -2)
+#define up2(v) (((v) + 1) & -2)
#define down2(v) ((v) & -2)
#define div2(v) ((v)>>1)
#define mod2(v) ((v) & 1)
-#define up4(v) (((v)+3) & -4)
+#define up4(v) (((v) + 3) & -4)
#define down4(v) ((v) & -4)
-#define mul4(v) ((v)<<2)
+#define mul4(v) ((v) << 2)
#define div4(v) ((v)>>2)
#define mod4(v) ((v) & 3)
-#define up8(v) (((v)+7) & -8)
+#define up8(v) (((v) + 7) & -8)
#define down8(v) ((v) & -8)
#define div8(v) ((v)>>3)
#define mod8(v) ((v) & 7)
-#define up16(v) (((v)+15) & -16)
+#define up16(v) (((v) + 15) & -16)
#define down16(v) ((v) & -16)
#define div16(v) ((v)>>4)
#define mod16(v) ((v) & 15)
-#define up32(v) (((v)+31) & -32)
+#define up32(v) (((v) + 31) & -32)
#define down32(v) ((v) & -32)
#define div32(v) ((v)>>5)
#define mod32(v) ((v) & 31)
-#define up64(v) (((v)+63) & -64)
+#define up64(v) (((v) + 63) & -64)
#define down64(v) ((v) & -64)
#define div64(v) ((v)>>6)
#define mod64(v) ((v) & 63)
-#define upx(x,v) (((v)+(x)-1) & -(x))
-#define downx(x,v) ((v) & -(x))
-#define modx(x,v) ((v) & ((x)-1))
+#define upx(x, v) (((v) + (x) - 1) & -(x))
+#define downx(x, v) ((v) & -(x))
+#define modx(x, v) ((v) & ((x) - 1))
/* if x1 is not a constant, this macro won't make real sense :-) */
#ifdef __mc68000__
#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \
- "d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})
+ "d" (x2), "d" ((long)((x1) / 0x100000000ULL)), "0" ((long)(x1))); res;})
#else
/* We know a bit about the numbers, so we can do it this way */
#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \
@@ -607,7 +608,7 @@ static u_short maxfmode, chipset;
#define VIDEOMEMSIZE_ECS_1M (393216) /* ECS (1MB) : max 1024*768*16 */
#define VIDEOMEMSIZE_OCS (262144) /* OCS : max ca. 800*600*16 */
-#define SPRITEMEMSIZE (64*64/4) /* max 64*64*4 */
+#define SPRITEMEMSIZE (64 * 64 / 4) /* max 64*64*4 */
#define DUMMYSPRITEMEMSIZE (8)
static u_long spritememory;
@@ -634,9 +635,9 @@ static u_long min_fstrt = 192;
* Copper Instructions
*/
-#define CMOVE(val, reg) (CUSTOM_OFS(reg)<<16 | (val))
-#define CMOVE2(val, reg) ((CUSTOM_OFS(reg)+2)<<16 | (val))
-#define CWAIT(x, y) (((y) & 0x1fe)<<23 | ((x) & 0x7f0)<<13 | 0x0001fffe)
+#define CMOVE(val, reg) (CUSTOM_OFS(reg) << 16 | (val))
+#define CMOVE2(val, reg) ((CUSTOM_OFS(reg) + 2) << 16 | (val))
+#define CWAIT(x, y) (((y) & 0x1fe) << 23 | ((x) & 0x7f0) << 13 | 0x0001fffe)
#define CEND (0xfffffffe)
@@ -776,11 +777,11 @@ static struct amifb_par {
static struct fb_info fb_info = {
- .fix = {
- .id = "Amiga ",
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .accel = FB_ACCEL_AMIGABLITT
- }
+ .fix = {
+ .id = "Amiga ",
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .accel = FB_ACCEL_AMIGABLITT
+ }
};
@@ -820,116 +821,123 @@ static u_short is_lace = 0; /* Screen is laced */
static struct fb_videomode ami_modedb[] __initdata = {
- /*
- * AmigaOS Video Modes
- *
- * If you change these, make sure to update DEFMODE_* as well!
- */
-
- {
- /* 640x200, 15 kHz, 60 Hz (NTSC) */
- "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
- "ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x256, 15 kHz, 50 Hz (PAL) */
- "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
- "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x480, 29 kHz, 57 Hz */
- "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x960, 29 kHz, 57 Hz interlaced */
- "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x200, 15 kHz, 72 Hz */
- "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 15 kHz, 72 Hz interlaced */
- "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 29 kHz, 68 Hz */
- "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x800, 29 kHz, 68 Hz interlaced */
- "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 800x300, 23 kHz, 70 Hz */
- "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 800x600, 23 kHz, 70 Hz interlaced */
- "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x200, 27 kHz, 57 Hz doublescan */
- "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }, {
- /* 640x400, 27 kHz, 57 Hz */
- "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x800, 27 kHz, 57 Hz interlaced */
- "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x256, 27 kHz, 47 Hz doublescan */
- "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }, {
- /* 640x512, 27 kHz, 47 Hz */
- "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x1024, 27 kHz, 47 Hz interlaced */
- "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- },
-
- /*
- * VGA Video Modes
- */
-
- {
- /* 640x480, 31 kHz, 60 Hz (VGA) */
- "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 31 kHz, 70 Hz (VGA) */
- "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
- FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- },
+ /*
+ * AmigaOS Video Modes
+ *
+ * If you change these, make sure to update DEFMODE_* as well!
+ */
+
+ {
+ /* 640x200, 15 kHz, 60 Hz (NTSC) */
+ "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
+ "ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x256, 15 kHz, 50 Hz (PAL) */
+ "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
+ "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x480, 29 kHz, 57 Hz */
+ "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x960, 29 kHz, 57 Hz interlaced */
+ "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72,
+ 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x200, 15 kHz, 72 Hz */
+ "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 15 kHz, 72 Hz interlaced */
+ "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52,
+ 10,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 29 kHz, 68 Hz */
+ "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x800, 29 kHz, 68 Hz interlaced */
+ "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80,
+ 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 800x300, 23 kHz, 70 Hz */
+ "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 800x600, 23 kHz, 70 Hz interlaced */
+ "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x200, 27 kHz, 57 Hz doublescan */
+ "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 27 kHz, 57 Hz */
+ "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x800, 27 kHz, 57 Hz interlaced */
+ "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x256, 27 kHz, 47 Hz doublescan */
+ "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+ }, {
+ /* 640x512, 27 kHz, 47 Hz */
+ "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x1024, 27 kHz, 47 Hz interlaced */
+ "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ },
+
+ /*
+ * VGA Video Modes
+ */
+
+ {
+ /* 640x480, 31 kHz, 60 Hz (VGA) */
+ "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 31 kHz, 70 Hz (VGA) */
+ "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ },
#if 0
- /*
- * A2024 video modes
- * These modes don't work yet because there's no A2024 driver.
- */
-
- {
- /* 1024x800, 10 Hz */
- "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 1024x800, 15 Hz */
- "a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /*
+ * A2024 video modes
+ * These modes don't work yet because there's no A2024 driver.
+ */
+
+ {
+ /* 1024x800, 10 Hz */
+ "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 1024x800, 15 Hz */
+ "a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }
#endif
};
@@ -992,19 +1000,20 @@ static int amifb_inverse = 0;
/* bplcon1 (smooth scrolling) */
#define hscroll2hw(hscroll) \
- (((hscroll)<<12 & 0x3000) | ((hscroll)<<8 & 0xc300) | \
- ((hscroll)<<4 & 0x0c00) | ((hscroll)<<2 & 0x00f0) | ((hscroll)>>2 & 0x000f))
+ (((hscroll) << 12 & 0x3000) | ((hscroll) << 8 & 0xc300) | \
+ ((hscroll) << 4 & 0x0c00) | ((hscroll) << 2 & 0x00f0) | \
+ ((hscroll)>>2 & 0x000f))
/* diwstrt/diwstop/diwhigh (visible display window) */
#define diwstrt2hw(diwstrt_h, diwstrt_v) \
- (((diwstrt_v)<<7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff))
+ (((diwstrt_v) << 7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff))
#define diwstop2hw(diwstop_h, diwstop_v) \
- (((diwstop_v)<<7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff))
+ (((diwstop_v) << 7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff))
#define diwhigh2hw(diwstrt_h, diwstrt_v, diwstop_h, diwstop_v) \
- (((diwstop_h)<<3 & 0x2000) | ((diwstop_h)<<11 & 0x1800) | \
+ (((diwstop_h) << 3 & 0x2000) | ((diwstop_h) << 11 & 0x1800) | \
((diwstop_v)>>1 & 0x0700) | ((diwstrt_h)>>5 & 0x0020) | \
- ((diwstrt_h)<<3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007))
+ ((diwstrt_h) << 3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007))
/* ddfstrt/ddfstop (display DMA) */
@@ -1015,38 +1024,39 @@ static int amifb_inverse = 0;
#define hsstrt2hw(hsstrt) (div8(hsstrt))
#define hsstop2hw(hsstop) (div8(hsstop))
-#define htotal2hw(htotal) (div8(htotal)-1)
+#define htotal2hw(htotal) (div8(htotal) - 1)
#define vsstrt2hw(vsstrt) (div2(vsstrt))
#define vsstop2hw(vsstop) (div2(vsstop))
-#define vtotal2hw(vtotal) (div2(vtotal)-1)
+#define vtotal2hw(vtotal) (div2(vtotal) - 1)
#define hcenter2hw(htotal) (div8(htotal))
/* hbstrt/hbstop/vbstrt/vbstop (blanking timings) */
-#define hbstrt2hw(hbstrt) (((hbstrt)<<8 & 0x0700) | ((hbstrt)>>3 & 0x00ff))
-#define hbstop2hw(hbstop) (((hbstop)<<8 & 0x0700) | ((hbstop)>>3 & 0x00ff))
+#define hbstrt2hw(hbstrt) (((hbstrt) << 8 & 0x0700) | ((hbstrt)>>3 & 0x00ff))
+#define hbstop2hw(hbstop) (((hbstop) << 8 & 0x0700) | ((hbstop)>>3 & 0x00ff))
#define vbstrt2hw(vbstrt) (div2(vbstrt))
#define vbstop2hw(vbstop) (div2(vbstop))
/* colour */
#define rgb2hw8_high(red, green, blue) \
- (((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
+ (((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0)>>4))
#define rgb2hw8_low(red, green, blue) \
- (((red & 0x0f)<<8) | ((green & 0x0f)<<4) | (blue & 0x0f))
+ (((red & 0x0f) << 8) | ((green & 0x0f) << 4) | (blue & 0x0f))
#define rgb2hw4(red, green, blue) \
- (((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
+ (((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0)>>4))
#define rgb2hw2(red, green, blue) \
- (((red & 0xc0)<<4) | (green & 0xc0) | ((blue & 0xc0)>>4))
+ (((red & 0xc0) << 4) | (green & 0xc0) | ((blue & 0xc0)>>4))
/* sprpos/sprctl (sprite positioning) */
#define spr2hw_pos(start_v, start_h) \
- (((start_v)<<7&0xff00) | ((start_h)>>3&0x00ff))
+ (((start_v) << 7 & 0xff00) | ((start_h)>>3 & 0x00ff))
#define spr2hw_ctl(start_v, start_h, stop_v) \
- (((stop_v)<<7&0xff00) | ((start_v)>>4&0x0040) | ((stop_v)>>5&0x0020) | \
- ((start_h)<<3&0x0018) | ((start_v)>>7&0x0004) | ((stop_v)>>8&0x0002) | \
- ((start_h)>>2&0x0001))
+ (((stop_v) << 7 & 0xff00) | ((start_v)>>4 & 0x0040) | \
+ ((stop_v)>>5 & 0x0020) | ((start_h) << 3 & 0x0018) | \
+ ((start_v)>>7 & 0x0004) | ((stop_v)>>8 & 0x0002) | \
+ ((start_h)>>2 & 0x0001))
/* get current vertical position of beam */
#define get_vbpos() ((u_short)((*(u_long volatile *)&custom.vposr >> 7) & 0xffe))
@@ -1055,7 +1065,7 @@ static int amifb_inverse = 0;
* Copper Initialisation List
*/
-#define COPINITSIZE (sizeof(copins)*40)
+#define COPINITSIZE (sizeof(copins) * 40)
enum {
cip_bplcon0
@@ -1066,7 +1076,7 @@ enum {
* Don't change the order, build_copper()/rebuild_copper() rely on this
*/
-#define COPLISTSIZE (sizeof(copins)*64)
+#define COPLISTSIZE (sizeof(copins) * 64)
enum {
cop_wait, cop_bplcon0,
@@ -1152,9 +1162,9 @@ static void chipfree(void);
*/
static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
+ struct amifb_par *par);
static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
+ struct amifb_par *par);
static void ami_pan_var(struct fb_var_screeninfo *var);
static int ami_update_par(void);
static void ami_update_display(void);
@@ -1238,9 +1248,9 @@ int __init amifb_setup(char *options)
} else if (!strcmp(this_opt, "ilbm"))
amifb_ilbm = 1;
else if (!strncmp(this_opt, "monitorcap:", 11))
- amifb_setup_mcap(this_opt+11);
+ amifb_setup_mcap(this_opt + 11);
else if (!strncmp(this_opt, "fstart:", 7))
- min_fstrt = simple_strtoul(this_opt+7, NULL, 0);
+ min_fstrt = simple_strtoul(this_opt + 7, NULL, 0);
else
mode_option = this_opt;
}
@@ -1295,20 +1305,20 @@ static int amifb_set_par(struct fb_info *info)
info->fix.type = FB_TYPE_PLANES;
info->fix.type_aux = 0;
}
- info->fix.line_length = div8(upx(16<<maxfmode, par->vxres));
+ info->fix.line_length = div8(upx(16 << maxfmode, par->vxres));
if (par->vmode & FB_VMODE_YWRAP) {
info->fix.ywrapstep = 1;
info->fix.xpanstep = 0;
info->fix.ypanstep = 0;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YWRAP |
- FBINFO_READS_FAST; /* override SCROLL_REDRAW */
+ FBINFO_READS_FAST; /* override SCROLL_REDRAW */
} else {
info->fix.ywrapstep = 0;
if (par->vmode & FB_VMODE_SMOOTH_XPAN)
info->fix.xpanstep = 1;
else
- info->fix.xpanstep = 16<<maxfmode;
+ info->fix.xpanstep = 16 << maxfmode;
info->fix.ypanstep = 1;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
}
@@ -1327,15 +1337,16 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
{
if (var->vmode & FB_VMODE_YWRAP) {
if (var->yoffset < 0 ||
- var->yoffset >= info->var.yres_virtual || var->xoffset)
- return -EINVAL;
+ var->yoffset >= info->var.yres_virtual || var->xoffset)
+ return -EINVAL;
} else {
/*
* TODO: There will be problems when xpan!=1, so some columns
* on the right side will never be seen
*/
- if (var->xoffset+info->var.xres > upx(16<<maxfmode, info->var.xres_virtual) ||
- var->yoffset+info->var.yres > info->var.yres_virtual)
+ if (var->xoffset + info->var.xres >
+ upx(16 << maxfmode, info->var.xres_virtual) ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
ami_pan_var(var);
@@ -1360,10 +1371,10 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
#endif
- /*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
static inline unsigned long comp(unsigned long a, unsigned long b,
unsigned long mask)
@@ -1379,29 +1390,29 @@ static inline unsigned long xor(unsigned long a, unsigned long b,
}
- /*
- * Unaligned forward bit copy using 32-bit or 64-bit memory accesses
- */
+ /*
+ * Unaligned forward bit copy using 32-bit or 64-bit memory accesses
+ */
static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- shift = dst_idx-src_idx;
+ shift = dst_idx - src_idx;
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
if (!shift) {
// Same alignment for source and dest
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1413,7 +1424,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
*dst = comp(*src, *dst, first);
dst++;
src++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1439,17 +1450,17 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single destination word
if (last)
first &= last;
if (shift > 0) {
// Single source word
*dst = comp(*src >> right, *dst, first);
- } else if (src_idx+n <= BITS_PER_LONG) {
+ } else if (src_idx + n <= BITS_PER_LONG) {
// Single source word
*dst = comp(*src << left, *dst, first);
} else {
@@ -1467,7 +1478,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
// Single source word
*dst = comp(d0 >> right, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
} else {
// 2 source words
d1 = *src++;
@@ -1475,7 +1486,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
first);
d0 = d1;
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1519,40 +1530,40 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
}
- /*
- * Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
- */
+ /*
+ * Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
+ */
static void bitcpy_rev(unsigned long *dst, int dst_idx,
const unsigned long *src, int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- dst += (n-1)/BITS_PER_LONG;
- src += (n-1)/BITS_PER_LONG;
- if ((n-1) % BITS_PER_LONG) {
- dst_idx += (n-1) % BITS_PER_LONG;
+ dst += (n - 1) / BITS_PER_LONG;
+ src += (n - 1) / BITS_PER_LONG;
+ if ((n - 1) % BITS_PER_LONG) {
+ dst_idx += (n - 1) % BITS_PER_LONG;
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= BITS_PER_LONG-1;
- src_idx += (n-1) % BITS_PER_LONG;
+ dst_idx &= BITS_PER_LONG - 1;
+ src_idx += (n - 1) % BITS_PER_LONG;
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= BITS_PER_LONG-1;
+ src_idx &= BITS_PER_LONG - 1;
}
- shift = dst_idx-src_idx;
- first = ~0UL << (BITS_PER_LONG-1-dst_idx);
- last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
+ shift = dst_idx - src_idx;
+ first = ~0UL << (BITS_PER_LONG - 1 - dst_idx);
+ last = ~(~0UL << (BITS_PER_LONG - 1 - ((dst_idx - n) % BITS_PER_LONG)));
if (!shift) {
// Same alignment for source and dest
- if ((unsigned long)dst_idx+1 >= n) {
+ if ((unsigned long)dst_idx + 1 >= n) {
// Single word
if (last)
first &= last;
@@ -1564,7 +1575,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
*dst = comp(*src, *dst, first);
dst--;
src--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
}
// Main chunk
@@ -1590,17 +1601,17 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if ((unsigned long)dst_idx+1 >= n) {
+ if ((unsigned long)dst_idx + 1 >= n) {
// Single destination word
if (last)
first &= last;
if (shift < 0) {
// Single source word
*dst = comp(*src << left, *dst, first);
- } else if (1+(unsigned long)src_idx >= n) {
+ } else if (1 + (unsigned long)src_idx >= n) {
// Single source word
*dst = comp(*src >> right, *dst, first);
} else {
@@ -1618,7 +1629,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
// Single source word
*dst = comp(d0 << left, *dst, first);
dst--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
} else {
// 2 source words
d1 = *src--;
@@ -1626,7 +1637,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
first);
d0 = d1;
dst--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
}
// Main chunk
@@ -1670,30 +1681,30 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
}
- /*
- * Unaligned forward inverting bit copy using 32-bit or 64-bit memory
- * accesses
- */
+ /*
+ * Unaligned forward inverting bit copy using 32-bit or 64-bit memory
+ * accesses
+ */
static void bitcpy_not(unsigned long *dst, int dst_idx,
const unsigned long *src, int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- shift = dst_idx-src_idx;
+ shift = dst_idx - src_idx;
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
if (!shift) {
// Same alignment for source and dest
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1705,7 +1716,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
*dst = comp(~*src, *dst, first);
dst++;
src++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1731,17 +1742,17 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single destination word
if (last)
first &= last;
if (shift > 0) {
// Single source word
*dst = comp(~*src >> right, *dst, first);
- } else if (src_idx+n <= BITS_PER_LONG) {
+ } else if (src_idx + n <= BITS_PER_LONG) {
// Single source word
*dst = comp(~*src << left, *dst, first);
} else {
@@ -1759,7 +1770,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
// Single source word
*dst = comp(d0 >> right, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
} else {
// 2 source words
d1 = ~*src++;
@@ -1767,7 +1778,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
first);
d0 = d1;
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1811,9 +1822,9 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
}
- /*
- * Unaligned 32-bit pattern fill using 32/64-bit memory accesses
- */
+ /*
+ * Unaligned 32-bit pattern fill using 32/64-bit memory accesses
+ */
static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
{
@@ -1828,9 +1839,9 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
#endif
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1841,7 +1852,7 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
if (first) {
*dst = comp(val, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1867,9 +1878,9 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
}
- /*
- * Unaligned 32-bit pattern xor using 32/64-bit memory accesses
- */
+ /*
+ * Unaligned 32-bit pattern xor using 32/64-bit memory accesses
+ */
static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
{
@@ -1884,9 +1895,9 @@ static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
#endif
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1897,7 +1908,7 @@ static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
if (first) {
*dst = xor(val, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1924,12 +1935,12 @@ static inline void fill_one_line(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
bitfill32(dst, dst_idx, color & 1 ? ~0 : 0, n);
if (!--bpp)
break;
color >>= 1;
- dst_idx += next_plane*8;
+ dst_idx += next_plane * 8;
}
}
@@ -1939,12 +1950,12 @@ static inline void xor_one_line(int bpp, unsigned long next_plane,
{
while (color) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
bitxor32(dst, dst_idx, color & 1 ? ~0 : 0, n);
if (!--bpp)
break;
color >>= 1;
- dst_idx += next_plane*8;
+ dst_idx += next_plane * 8;
}
}
@@ -1972,23 +1983,23 @@ static void amifb_fillrect(struct fb_info *info,
height = y2 - rect->dy;
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
- dst_idx += rect->dy*par->next_line*8+rect->dx;
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
+ dst_idx += rect->dy * par->next_line * 8 + rect->dx;
while (height--) {
switch (rect->rop) {
- case ROP_COPY:
+ case ROP_COPY:
fill_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, width,
rect->color);
break;
- case ROP_XOR:
+ case ROP_XOR:
xor_one_line(info->var.bits_per_pixel, par->next_plane,
dst, dst_idx, width, rect->color);
break;
}
- dst_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
}
}
@@ -1998,14 +2009,14 @@ static inline void copy_one_line(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= (BITS_PER_LONG-1);
+ src_idx &= (BITS_PER_LONG - 1);
bitcpy(dst, dst_idx, src, src_idx, n);
if (!--bpp)
break;
- dst_idx += next_plane*8;
- src_idx += next_plane*8;
+ dst_idx += next_plane * 8;
+ src_idx += next_plane * 8;
}
}
@@ -2015,14 +2026,14 @@ static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= (BITS_PER_LONG-1);
+ src_idx &= (BITS_PER_LONG - 1);
bitcpy_rev(dst, dst_idx, src, src_idx, n);
if (!--bpp)
break;
- dst_idx += next_plane*8;
- src_idx += next_plane*8;
+ dst_idx += next_plane * 8;
+ src_idx += next_plane * 8;
}
}
@@ -2065,16 +2076,16 @@ static void amifb_copyarea(struct fb_info *info,
rev_copy = 1;
}
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
src = dst;
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
src_idx = dst_idx;
- dst_idx += dy*par->next_line*8+dx;
- src_idx += sy*par->next_line*8+sx;
+ dst_idx += dy * par->next_line * 8 + dx;
+ src_idx += sy * par->next_line * 8 + sx;
if (rev_copy) {
while (height--) {
- dst_idx -= par->next_line*8;
- src_idx -= par->next_line*8;
+ dst_idx -= par->next_line * 8;
+ src_idx -= par->next_line * 8;
copy_one_line_rev(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
src_idx, width);
@@ -2084,8 +2095,8 @@ static void amifb_copyarea(struct fb_info *info,
copy_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
src_idx, width);
- dst_idx += par->next_line*8;
- src_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
+ src_idx += par->next_line * 8;
}
}
}
@@ -2095,28 +2106,29 @@ static inline void expand_one_line(int bpp, unsigned long next_plane,
unsigned long *dst, int dst_idx, u32 n,
const u8 *data, u32 bgcolor, u32 fgcolor)
{
- const unsigned long *src;
- int src_idx;
-
- while (1) {
- dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
- if ((bgcolor ^ fgcolor) & 1) {
- src = (unsigned long *)((unsigned long)data & ~(BYTES_PER_LONG-1));
- src_idx = ((unsigned long)data & (BYTES_PER_LONG-1))*8;
- if (fgcolor & 1)
- bitcpy(dst, dst_idx, src, src_idx, n);
- else
- bitcpy_not(dst, dst_idx, src, src_idx, n);
- /* set or clear */
- } else
- bitfill32(dst, dst_idx, fgcolor & 1 ? ~0 : 0, n);
- if (!--bpp)
- break;
- bgcolor >>= 1;
- fgcolor >>= 1;
- dst_idx += next_plane*8;
- }
+ const unsigned long *src;
+ int src_idx;
+
+ while (1) {
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BITS_PER_LONG - 1);
+ if ((bgcolor ^ fgcolor) & 1) {
+ src = (unsigned long *)
+ ((unsigned long)data & ~(BYTES_PER_LONG - 1));
+ src_idx = ((unsigned long)data & (BYTES_PER_LONG - 1)) * 8;
+ if (fgcolor & 1)
+ bitcpy(dst, dst_idx, src, src_idx, n);
+ else
+ bitcpy_not(dst, dst_idx, src, src_idx, n);
+ /* set or clear */
+ } else
+ bitfill32(dst, dst_idx, fgcolor & 1 ? ~0 : 0, n);
+ if (!--bpp)
+ break;
+ bgcolor >>= 1;
+ fgcolor >>= 1;
+ dst_idx += next_plane * 8;
+ }
}
@@ -2145,17 +2157,17 @@ static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
if (image->depth = 1) {
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
- dst_idx += dy*par->next_line*8+dx;
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
+ dst_idx += dy * par->next_line * 8 + dx;
src = image->data;
- pitch = (image->width+7)/8;
+ pitch = (image->width + 7) / 8;
while (height--) {
expand_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, width,
src, image->bg_color,
image->fg_color);
- dst_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
src += pitch;
}
} else {
@@ -2182,39 +2194,38 @@ static int amifb_ioctl(struct fb_info *info,
int i;
switch (cmd) {
- case FBIOGET_FCURSORINFO:
- i = ami_get_fix_cursorinfo(&crsr.fix);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.fix,
- sizeof(crsr.fix)) ? -EFAULT : 0;
-
- case FBIOGET_VCURSORINFO:
- i = ami_get_var_cursorinfo(&crsr.var,
- ((struct fb_var_cursorinfo __user *)arg)->data);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.var,
- sizeof(crsr.var)) ? -EFAULT : 0;
-
- case FBIOPUT_VCURSORINFO:
- 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);
-
- case FBIOGET_CURSORSTATE:
- i = ami_get_cursorstate(&crsr.state);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.state,
- sizeof(crsr.state)) ? -EFAULT : 0;
-
- case FBIOPUT_CURSORSTATE:
- if (copy_from_user(&crsr.state, argp,
- sizeof(crsr.state)))
- return -EFAULT;
- return ami_set_cursorstate(&crsr.state);
+ case FBIOGET_FCURSORINFO:
+ i = ami_get_fix_cursorinfo(&crsr.fix);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.fix,
+ sizeof(crsr.fix)) ? -EFAULT : 0;
+
+ case FBIOGET_VCURSORINFO:
+ i = ami_get_var_cursorinfo(&crsr.var,
+ ((struct fb_var_cursorinfo __user *)arg)->data);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.var,
+ sizeof(crsr.var)) ? -EFAULT : 0;
+
+ case FBIOPUT_VCURSORINFO:
+ 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);
+
+ case FBIOGET_CURSORSTATE:
+ i = ami_get_cursorstate(&crsr.state);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.state,
+ sizeof(crsr.state)) ? -EFAULT : 0;
+
+ case FBIOPUT_CURSORSTATE:
+ if (copy_from_user(&crsr.state, argp, sizeof(crsr.state)))
+ return -EFAULT;
+ return ami_set_cursorstate(&crsr.state);
}
return -EINVAL;
}
@@ -2267,69 +2278,68 @@ static int __init amifb_probe(struct platform_device *pdev)
switch (amiga_chipset) {
#ifdef CONFIG_FB_AMIGA_OCS
- case CS_OCS:
- strcat(fb_info.fix.id, "OCS");
+ case CS_OCS:
+ strcat(fb_info.fix.id, "OCS");
default_chipset:
- chipset = TAG_OCS;
- maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
- maxdepth[TAG_HIRES] = 4;
- maxdepth[TAG_LORES] = 6;
- maxfmode = TAG_FMODE_1;
- defmode = amiga_vblank = 50 ? DEFMODE_PAL
- : DEFMODE_NTSC;
- fb_info.fix.smem_len = VIDEOMEMSIZE_OCS;
- break;
+ chipset = TAG_OCS;
+ maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
+ maxdepth[TAG_HIRES] = 4;
+ maxdepth[TAG_LORES] = 6;
+ maxfmode = TAG_FMODE_1;
+ defmode = amiga_vblank = 50 ? DEFMODE_PAL : DEFMODE_NTSC;
+ fb_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");
- chipset = TAG_ECS;
- maxdepth[TAG_SHRES] = 2;
- maxdepth[TAG_HIRES] = 4;
- maxdepth[TAG_LORES] = 6;
- maxfmode = TAG_FMODE_1;
- if (AMIGAHW_PRESENT(AMBER_FF))
- defmode = amiga_vblank = 50 ? DEFMODE_AMBER_PAL
- : DEFMODE_AMBER_NTSC;
- else
- defmode = amiga_vblank = 50 ? DEFMODE_PAL
- : DEFMODE_NTSC;
- if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
- VIDEOMEMSIZE_ECS_2M)
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
- else
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M;
- break;
+ case CS_ECS:
+ strcat(fb_info.fix.id, "ECS");
+ chipset = TAG_ECS;
+ maxdepth[TAG_SHRES] = 2;
+ maxdepth[TAG_HIRES] = 4;
+ maxdepth[TAG_LORES] = 6;
+ maxfmode = TAG_FMODE_1;
+ if (AMIGAHW_PRESENT(AMBER_FF))
+ defmode = amiga_vblank = 50 ? DEFMODE_AMBER_PAL
+ : DEFMODE_AMBER_NTSC;
+ else
+ defmode = amiga_vblank = 50 ? DEFMODE_PAL
+ : DEFMODE_NTSC;
+ if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
+ VIDEOMEMSIZE_ECS_2M)
+ fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
+ else
+ fb_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");
- chipset = TAG_AGA;
- maxdepth[TAG_SHRES] = 8;
- maxdepth[TAG_HIRES] = 8;
- maxdepth[TAG_LORES] = 8;
- maxfmode = TAG_FMODE_4;
- defmode = DEFMODE_AGA;
- if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
- VIDEOMEMSIZE_AGA_2M)
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
- else
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
- break;
+ case CS_AGA:
+ strcat(fb_info.fix.id, "AGA");
+ chipset = TAG_AGA;
+ maxdepth[TAG_SHRES] = 8;
+ maxdepth[TAG_HIRES] = 8;
+ maxdepth[TAG_LORES] = 8;
+ maxfmode = TAG_FMODE_4;
+ defmode = DEFMODE_AGA;
+ if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
+ VIDEOMEMSIZE_AGA_2M)
+ fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
+ else
+ fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
+ break;
#endif /* CONFIG_FB_AMIGA_AGA */
- default:
+ default:
#ifdef CONFIG_FB_AMIGA_OCS
- printk("Unknown graphics chipset, defaulting to OCS\n");
- strcat(fb_info.fix.id, "Unknown");
- goto default_chipset;
+ printk("Unknown graphics chipset, defaulting to OCS\n");
+ strcat(fb_info.fix.id, "Unknown");
+ goto default_chipset;
#else /* CONFIG_FB_AMIGA_OCS */
- err = -ENODEV;
- goto amifb_error;
+ err = -ENODEV;
+ goto amifb_error;
#endif /* CONFIG_FB_AMIGA_OCS */
- break;
+ break;
}
/*
@@ -2360,10 +2370,10 @@ default_chipset:
* These monitor specs are for a typical Amiga monitor (e.g. A1960)
*/
if (fb_info.monspecs.hfmin = 0) {
- fb_info.monspecs.hfmin = 15000;
- fb_info.monspecs.hfmax = 38000;
- fb_info.monspecs.vfmin = 49;
- fb_info.monspecs.vfmax = 90;
+ fb_info.monspecs.hfmin = 15000;
+ fb_info.monspecs.hfmax = 38000;
+ fb_info.monspecs.vfmin = 49;
+ fb_info.monspecs.vfmax = 90;
}
fb_info.fbops = &amifb_ops;
@@ -2381,11 +2391,9 @@ default_chipset:
&fb_info.modelist);
round_down_bpp = 0;
- chipptr = chipalloc(fb_info.fix.smem_len+
- SPRITEMEMSIZE+
- DUMMYSPRITEMEMSIZE+
- COPINITSIZE+
- 4*COPLISTSIZE);
+ chipptr = chipalloc(fb_info.fix.smem_len + SPRITEMEMSIZE +
+ DUMMYSPRITEMEMSIZE + COPINITSIZE +
+ 4 * COPLISTSIZE);
if (!chipptr) {
err = -ENOMEM;
goto amifb_error;
@@ -2419,7 +2427,7 @@ default_chipset:
*/
custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
- DMAF_BLITTER | DMAF_SPRITE;
+ DMAF_BLITTER | DMAF_SPRITE;
/*
* Make sure the Copper has something to do
@@ -2428,12 +2436,12 @@ default_chipset:
ami_init_copper();
if (request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
- "fb vertb handler", ¤tpar)) {
+ "fb vertb handler", ¤tpar)) {
err = -EBUSY;
goto amifb_error;
}
- err = fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
+ err = fb_alloc_cmap(&fb_info.cmap, 1 << fb_info.var.bits_per_pixel, 0);
if (err)
goto amifb_error;
@@ -2459,7 +2467,7 @@ static void amifb_deinit(struct platform_device *pdev)
fb_dealloc_cmap(&fb_info.cmap);
chipfree();
if (videomemory)
- iounmap((void*)videomemory);
+ iounmap((void *)videomemory);
custom.dmacon = DMAF_ALL | DMAF_MASTER;
}
@@ -2539,7 +2547,7 @@ static irqreturn_t amifb_interrupt(int irq, void *dev_id)
*/
static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
+ struct amifb_par *par)
{
u_short clk_shift, line_shift;
u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
@@ -2606,23 +2614,23 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN;
switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- line_shift = 0;
- break;
- case FB_VMODE_NONINTERLACED:
- line_shift = 1;
- break;
- case FB_VMODE_DOUBLE:
- if (!IS_AGA) {
- DPRINTK("double mode only possible with aga\n");
- return -EINVAL;
- }
- line_shift = 2;
- break;
- default:
- DPRINTK("unknown video mode\n");
+ case FB_VMODE_INTERLACED:
+ line_shift = 0;
+ break;
+ case FB_VMODE_NONINTERLACED:
+ line_shift = 1;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (!IS_AGA) {
+ DPRINTK("double mode only possible with aga\n");
return -EINVAL;
- break;
+ }
+ line_shift = 2;
+ break;
+ default:
+ DPRINTK("unknown video mode\n");
+ return -EINVAL;
+ break;
}
par->line_shift = line_shift;
@@ -2630,26 +2638,31 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
* Vertical and Horizontal Timings
*/
- xres_n = par->xres<<clk_shift;
- yres_n = par->yres<<line_shift;
- par->htotal = down8((var->left_margin+par->xres+var->right_margin+var->hsync_len)<<clk_shift);
- par->vtotal = down2(((var->upper_margin+par->yres+var->lower_margin+var->vsync_len)<<line_shift)+1);
+ xres_n = par->xres << clk_shift;
+ yres_n = par->yres << line_shift;
+ par->htotal = down8((var->left_margin + par->xres + var->right_margin +
+ var->hsync_len) << clk_shift);
+ par->vtotal + down2(((var->upper_margin + par->yres + var->lower_margin +
+ var->vsync_len) << line_shift) + 1);
if (IS_AGA)
par->bplcon3 = sprpixmode[clk_shift];
else
par->bplcon3 = 0;
if (var->sync & FB_SYNC_BROADCAST) {
- par->diwstop_h = par->htotal-((var->right_margin-var->hsync_len)<<clk_shift);
+ par->diwstop_h = par->htotal -
+ ((var->right_margin - var->hsync_len) << clk_shift);
if (IS_AGA)
par->diwstop_h += mod4(var->hsync_len);
else
par->diwstop_h = down4(par->diwstop_h);
par->diwstrt_h = par->diwstop_h - xres_n;
- par->diwstop_v = par->vtotal-((var->lower_margin-var->vsync_len)<<line_shift);
+ par->diwstop_v = par->vtotal -
+ ((var->lower_margin - var->vsync_len) << line_shift);
par->diwstrt_v = par->diwstop_v - yres_n;
- if (par->diwstop_h >= par->htotal+8) {
+ if (par->diwstop_h >= par->htotal + 8) {
DPRINTK("invalid diwstop_h\n");
return -EINVAL;
}
@@ -2670,7 +2683,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->vsstrt = 0;
par->vsstop = 0;
}
- if (par->vtotal > (PAL_VTOTAL+NTSC_VTOTAL)/2) {
+ if (par->vtotal > (PAL_VTOTAL + NTSC_VTOTAL) / 2) {
/* PAL video mode */
if (par->htotal != PAL_HTOTAL) {
DPRINTK("htotal invalid for pal\n");
@@ -2690,7 +2703,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->beamcon0 = BMC0_PAL;
par->bplcon3 |= BPC3_BRDRBLNK;
} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
par->beamcon0 = BMC0_PAL;
par->hsstop = 1;
} else if (amiga_vblank != 50) {
@@ -2720,7 +2733,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->beamcon0 = 0;
par->bplcon3 |= BPC3_BRDRBLNK;
} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
par->beamcon0 = 0;
par->hsstop = 1;
} else if (amiga_vblank != 60) {
@@ -2737,8 +2750,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
}
} else if (!IS_OCS) {
/* Programmable video mode */
- par->hsstrt = var->right_margin<<clk_shift;
- par->hsstop = (var->right_margin+var->hsync_len)<<clk_shift;
+ par->hsstrt = var->right_margin << clk_shift;
+ par->hsstop = (var->right_margin + var->hsync_len) << clk_shift;
par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift);
if (!IS_AGA)
par->diwstop_h = down4(par->diwstop_h) - 16;
@@ -2748,8 +2761,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
if (par->hbstrt >= par->htotal + 8)
par->hbstrt -= par->htotal;
par->hcenter = par->hsstrt + (par->htotal >> 1);
- par->vsstrt = var->lower_margin<<line_shift;
- par->vsstop = (var->lower_margin+var->vsync_len)<<line_shift;
+ par->vsstrt = var->lower_margin << line_shift;
+ par->vsstop = (var->lower_margin + var->vsync_len) << line_shift;
par->diwstop_v = par->vtotal;
if ((par->vmode & FB_VMODE_MASK) = FB_VMODE_INTERLACED)
par->diwstop_v -= 2;
@@ -2766,8 +2779,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
}
par->bplcon3 |= BPC3_EXTBLKEN;
par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
- BMC0_PAL | BMC0_VARCSYEN;
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
+ BMC0_PAL | BMC0_VARCSYEN;
if (var->sync & FB_SYNC_HOR_HIGH_ACT)
par->beamcon0 |= BMC0_HSYTRUE;
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
@@ -2785,7 +2798,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
* Checking the DMA timing
*/
- fconst = 16<<maxfmode<<clk_shift;
+ fconst = 16 << maxfmode << clk_shift;
/*
* smallest window start value without turn off other dma cycles
@@ -2793,8 +2806,8 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
*/
- fsize = ((maxfmode+clk_shift <= 1) ? fconst : 64);
- fstrt = downx(fconst, par->diwstrt_h-4) - fsize;
+ fsize = ((maxfmode + clk_shift <= 1) ? fconst : 64);
+ fstrt = downx(fconst, par->diwstrt_h - 4) - fsize;
if (fstrt < min_fstrt) {
DPRINTK("fetch start too low\n");
return -EINVAL;
@@ -2804,14 +2817,16 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
* smallest window start value where smooth scrolling is possible
*/
- fstrt = downx(fconst, par->diwstrt_h-fconst+(1<<clk_shift)-4) - fsize;
+ fstrt = downx(fconst, par->diwstrt_h - fconst + (1 << clk_shift) - 4) -
+ fsize;
if (fstrt < min_fstrt)
par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
maxfetchstop = down16(par->htotal - 80);
- fstrt = downx(fconst, par->diwstrt_h-4) - 64 - fconst;
- fsize = upx(fconst, xres_n + modx(fconst, downx(1<<clk_shift, par->diwstrt_h-4)));
+ fstrt = downx(fconst, par->diwstrt_h - 4) - 64 - fconst;
+ fsize = upx(fconst, xres_n +
+ modx(fconst, downx(1 << clk_shift, par->diwstrt_h - 4)));
if (fstrt + fsize > maxfetchstop)
par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
@@ -2840,7 +2855,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
* Check if there is enough time to update the bitplane pointers for ywrap
*/
- if (par->htotal-fsize-64 < par->bpp*64)
+ if (par->htotal - fsize - 64 < par->bpp * 64)
par->vmode &= ~FB_VMODE_YWRAP;
/*
@@ -2848,15 +2863,15 @@ 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;
+ 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) {
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;
+ 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) {
DPRINTK("too few video mem\n");
return -EINVAL;
@@ -2873,7 +2888,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
if (par->bpp = 8)
par->bplcon0 |= BPC0_BPU3;
else
- par->bplcon0 |= par->bpp<<12;
+ par->bplcon0 |= par->bpp << 12;
if (var->nonstd = FB_NONSTD_HAM)
par->bplcon0 |= BPC0_HAM;
if (var->sync & FB_SYNC_EXT)
@@ -2883,24 +2898,26 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
par->fmode = bplfetchmode[maxfmode];
switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- par->bplcon0 |= BPC0_LACE;
- break;
- case FB_VMODE_DOUBLE:
- if (IS_AGA)
- par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
- break;
+ case FB_VMODE_INTERLACED:
+ par->bplcon0 |= BPC0_LACE;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (IS_AGA)
+ par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
+ break;
}
if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
par->xoffset = var->xoffset;
par->yoffset = var->yoffset;
if (par->vmode & FB_VMODE_YWRAP) {
- if (par->xoffset || par->yoffset < 0 || par->yoffset >= par->vyres)
+ if (par->xoffset || par->yoffset < 0 ||
+ par->yoffset >= par->vyres)
par->xoffset = par->yoffset = 0;
} else {
- if (par->xoffset < 0 || par->xoffset > upx(16<<maxfmode, par->vxres-par->xres) ||
- par->yoffset < 0 || par->yoffset > par->vyres-par->yres)
+ if (par->xoffset < 0 ||
+ par->xoffset > upx(16 << maxfmode, par->vxres - par->xres) ||
+ par->yoffset < 0 || par->yoffset > par->vyres - par->yres)
par->xoffset = par->yoffset = 0;
}
} else
@@ -2919,7 +2936,7 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
*/
static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
+ struct amifb_par *par)
{
u_short clk_shift, line_shift;
@@ -2942,7 +2959,7 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
var->red.msb_right = 0;
var->red.length = par->bpp;
if (par->bplcon0 & BPC0_HAM)
- var->red.length -= 2;
+ var->red.length -= 2;
var->blue = var->green = var->red;
var->transp.offset = 0;
var->transp.length = 0;
@@ -2967,10 +2984,10 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
var->vmode = FB_VMODE_NONINTERLACED;
if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) {
- var->hsync_len = (par->hsstop-par->hsstrt)>>clk_shift;
+ var->hsync_len = (par->hsstop - par->hsstrt)>>clk_shift;
var->right_margin = par->hsstrt>>clk_shift;
var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
- var->vsync_len = (par->vsstop-par->vsstrt)>>line_shift;
+ var->vsync_len = (par->vsstop - par->vsstrt)>>line_shift;
var->lower_margin = par->vsstrt>>line_shift;
var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len;
var->sync = 0;
@@ -2988,7 +3005,7 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
var->vsync_len = 4>>line_shift;
var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len;
var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres -
- var->lower_margin - var->vsync_len;
+ var->lower_margin - var->vsync_len;
}
if (par->bplcon0 & BPC0_ERSY)
@@ -3035,14 +3052,14 @@ static int ami_update_par(void)
clk_shift = par->clk_shift;
if (!(par->vmode & FB_VMODE_SMOOTH_XPAN))
- par->xoffset = upx(16<<maxfmode, par->xoffset);
+ par->xoffset = upx(16 << maxfmode, par->xoffset);
- fconst = 16<<maxfmode<<clk_shift;
- vshift = modx(16<<maxfmode, par->xoffset);
- fstrt = par->diwstrt_h - (vshift<<clk_shift) - 4;
- fsize = (par->xres+vshift)<<clk_shift;
+ fconst = 16 << maxfmode << clk_shift;
+ vshift = modx(16 << maxfmode, par->xoffset);
+ fstrt = par->diwstrt_h - (vshift << clk_shift) - 4;
+ fsize = (par->xres + vshift) << clk_shift;
shift = modx(fconst, fstrt);
- move = downx(2<<maxfmode, div8(par->xoffset));
+ move = downx(2 << maxfmode, div8(par->xoffset));
if (maxfmode + clk_shift > 1) {
fstrt = downx(fconst, fstrt) - 64;
fsize = upx(fconst, fsize);
@@ -3056,7 +3073,7 @@ static int ami_update_par(void)
fstop += min_fstrt - fstrt;
fstrt = min_fstrt;
}
- move = move - div8((mod-fstrt)>>clk_shift);
+ move = move - div8((mod - fstrt)>>clk_shift);
}
mod = par->next_line - div8(fsize>>clk_shift);
par->ddfstrt = fstrt;
@@ -3071,11 +3088,14 @@ static int ami_update_par(void)
par->bpl1mod = par->bpl2mod;
if (par->yoffset) {
- par->bplpt0 = fb_info.fix.smem_start + par->next_line*par->yoffset + move;
+ par->bplpt0 = fb_info.fix.smem_start +
+ par->next_line * par->yoffset + move;
if (par->vmode & FB_VMODE_YWRAP) {
- if (par->yoffset > par->vyres-par->yres) {
+ if (par->yoffset > par->vyres - par->yres) {
par->bplpt0wrap = fb_info.fix.smem_start + move;
- if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v+par->vyres-par->yoffset))
+ if (par->bplcon0 & BPC0_LACE &&
+ mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
par->bplpt0wrap += par->next_line;
}
}
@@ -3096,7 +3116,7 @@ static int ami_update_par(void)
*/
static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
+ u_int transp, struct fb_info *info)
{
if (IS_AGA) {
if (regno > 255)
@@ -3130,10 +3150,13 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
if (IS_AGA) {
u_short bplcon3 = currentpar.bplcon3;
VBlankOff();
- custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000);
- custom.color[regno&31] = rgb2hw8_high(red, green, blue);
- custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000) | BPC3_LOCT;
- custom.color[regno&31] = rgb2hw8_low(red, green, blue);
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
+ custom.color[regno & 31] = rgb2hw8_high(red, green,
+ blue);
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000) |
+ BPC3_LOCT;
+ custom.color[regno & 31] = rgb2hw8_low(red, green,
+ blue);
custom.bplcon3 = bplcon3;
VBlankOn();
} else
@@ -3146,11 +3169,11 @@ static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
mask = 0x3333;
color = rgb2hw2(red, green, blue);
VBlankOff();
- for (i = regno+12; i >= (int)regno; i -= 4)
+ for (i = regno + 12; i >= (int)regno; i -= 4)
custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<=2; color >>= 2;
- regno = down16(regno)+mul4(mod4(regno));
- for (i = regno+3; i >= (int)regno; i--)
+ mask <<= 2; color >>= 2;
+ regno = down16(regno) + mul4(mod4(regno));
+ for (i = regno + 3; i >= (int)regno; i--)
custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
VBlankOn();
} else
@@ -3243,30 +3266,30 @@ static void ami_do_blank(void)
red = green = blue = 0;
if (!IS_OCS && do_blank > 1) {
switch (do_blank) {
- case FB_BLANK_VSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.vsstrt = vsstrt2hw(par->vtotal+4);
- custom.vsstop = vsstop2hw(par->vtotal+4);
- break;
- case FB_BLANK_HSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->htotal+16);
- custom.hsstop = hsstop2hw(par->htotal+16);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstrt2hw(par->vsstop);
- break;
- case FB_BLANK_POWERDOWN:
- custom.hsstrt = hsstrt2hw(par->htotal+16);
- custom.hsstop = hsstop2hw(par->htotal+16);
- custom.vsstrt = vsstrt2hw(par->vtotal+4);
- custom.vsstop = vsstop2hw(par->vtotal+4);
- break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstrt2hw(par->vsstop);
+ break;
+ case FB_BLANK_POWERDOWN:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
}
if (!(par->beamcon0 & BMC0_VARBEAMEN)) {
custom.htotal = htotal2hw(par->htotal);
custom.vtotal = vtotal2hw(par->vtotal);
custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
}
}
} else {
@@ -3300,7 +3323,7 @@ static void ami_do_blank(void)
color = rgb2hw2(red, green, blue);
for (i = 12; i >= 0; i -= 4)
custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<=2; color >>= 2;
+ mask <<= 2; color >>= 2;
for (i = 3; i >= 0; i--)
custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
} else
@@ -3334,32 +3357,32 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
short height, width, bits, words;
int size, alloc;
- size = par->crsr.height*par->crsr.width;
- alloc = var->height*var->width;
+ size = par->crsr.height * par->crsr.width;
+ alloc = var->height * var->width;
var->height = par->crsr.height;
var->width = par->crsr.width;
var->xspot = par->crsr.spot_x;
var->yspot = par->crsr.spot_y;
- if (size > var->height*var->width)
+ if (size > var->height * var->width)
return -ENAMETOOLONG;
if (!access_ok(VERIFY_WRITE, data, size))
return -EFAULT;
- delta = 1<<par->crsr.fmode;
- lspr = lofsprite + (delta<<1);
+ delta = 1 << par->crsr.fmode;
+ lspr = lofsprite + (delta << 1);
if (par->bplcon0 & BPC0_LACE)
- sspr = shfsprite + (delta<<1);
+ sspr = shfsprite + (delta << 1);
else
sspr = NULL;
- for (height = (short)var->height-1; height >= 0; height--) {
+ for (height = (short)var->height - 1; height >= 0; height--) {
bits = 0; words = delta; datawords = 0;
- for (width = (short)var->width-1; width >= 0; width--) {
+ for (width = (short)var->width - 1; width >= 0; width--) {
if (bits = 0) {
bits = 16; --words;
#ifdef __mc68000__
asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0"
: "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta));
#else
- datawords = (*(lspr+delta) << 16) | (*lspr++);
+ datawords = (*(lspr + delta) << 16) | (*lspr++);
#endif
}
--bits;
@@ -3422,26 +3445,26 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
return -EINVAL;
if (!var->height)
return -EINVAL;
- if (!access_ok(VERIFY_READ, data, var->width*var->height))
+ if (!access_ok(VERIFY_READ, data, var->width * var->height))
return -EFAULT;
- delta = 1<<fmode;
+ delta = 1 << fmode;
lofsprite = shfsprite = (u_short *)spritememory;
- lspr = lofsprite + (delta<<1);
+ lspr = lofsprite + (delta << 1);
if (par->bplcon0 & BPC0_LACE) {
- if (((var->height+4)<<fmode<<2) > SPRITEMEMSIZE)
+ if (((var->height + 4) << fmode << 2) > SPRITEMEMSIZE)
return -EINVAL;
- memset(lspr, 0, (var->height+4)<<fmode<<2);
- shfsprite += ((var->height+5)&-2)<<fmode;
- sspr = shfsprite + (delta<<1);
+ memset(lspr, 0, (var->height + 4) << fmode << 2);
+ shfsprite += ((var->height + 5)&-2) << fmode;
+ sspr = shfsprite + (delta << 1);
} else {
- if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE)
+ if (((var->height + 2) << fmode << 2) > SPRITEMEMSIZE)
return -EINVAL;
- memset(lspr, 0, (var->height+2)<<fmode<<2);
+ memset(lspr, 0, (var->height + 2) << fmode << 2);
sspr = NULL;
}
- for (height = (short)var->height-1; height >= 0; height--) {
+ for (height = (short)var->height - 1; height >= 0; height--) {
bits = 16; words = delta; datawords = 0;
- for (width = (short)var->width-1; width >= 0; width--) {
+ for (width = (short)var->width - 1; width >= 0; width--) {
unsigned long tdata = 0;
get_user(tdata, data);
data++;
@@ -3454,7 +3477,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
#else
datawords = ((datawords << 1) & 0xfffefffe);
datawords |= tdata & 1;
- datawords |= (tdata & 2) << (16-1);
+ datawords |= (tdata & 2) << (16 - 1);
#endif
if (--bits = 0) {
bits = 16; --words;
@@ -3462,7 +3485,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
: "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta));
#else
- *(lspr+delta) = (u_short) (datawords >> 16);
+ *(lspr + delta) = (u_short) (datawords >> 16);
*lspr++ = (u_short) (datawords & 0xffff);
#endif
}
@@ -3475,7 +3498,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
"swap %2 ; lslw %4,%2 ; movew %2,%0@+"
: "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits));
#else
- *(lspr+delta) = (u_short) (datawords >> (16+bits));
+ *(lspr + delta) = (u_short) (datawords >> (16 + bits));
*lspr++ = (u_short) ((datawords & 0x0000ffff) >> bits);
#endif
}
@@ -3484,7 +3507,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *
asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+"
: "=a" (lspr) : "0" (lspr), "d" (delta) : "d0");
#else
- *(lspr+delta) = 0;
+ *(lspr + delta) = 0;
*lspr++ = 0;
#endif
}
@@ -3546,8 +3569,8 @@ static void ami_set_sprite(void)
cops = copdisplay.list[currentcop][0];
copl = copdisplay.list[currentcop][1];
ps = pl = ZTWO_PADDR(dummysprite);
- mx = par->crsr.crsr_x-par->crsr.spot_x;
- my = par->crsr.crsr_y-par->crsr.spot_y;
+ mx = par->crsr.crsr_x - par->crsr.spot_x;
+ my = par->crsr.crsr_y - par->crsr.spot_y;
if (!(par->vmode & FB_VMODE_YWRAP)) {
mx -= par->xoffset;
my -= par->yoffset;
@@ -3556,24 +3579,24 @@ static void ami_set_sprite(void)
mx > -(short)par->crsr.width && mx < par->xres &&
my > -(short)par->crsr.height && my < par->yres) {
pl = ZTWO_PADDR(lofsprite);
- hs = par->diwstrt_h + (mx<<par->clk_shift) - 4;
- vs = par->diwstrt_v + (my<<par->line_shift);
- ve = vs + (par->crsr.height<<par->line_shift);
+ hs = par->diwstrt_h + (mx << par->clk_shift) - 4;
+ vs = par->diwstrt_v + (my << par->line_shift);
+ ve = vs + (par->crsr.height << par->line_shift);
if (par->bplcon0 & BPC0_LACE) {
ps = ZTWO_PADDR(shfsprite);
lofsprite[0] = spr2hw_pos(vs, hs);
- shfsprite[0] = spr2hw_pos(vs+1, hs);
+ shfsprite[0] = spr2hw_pos(vs + 1, hs);
if (mod2(vs)) {
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
- shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve+1);
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
pt = pl; pl = ps; ps = pt;
} else {
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve+1);
- shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve);
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);
}
} else {
lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0);
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
}
}
copl[cop_spr0ptrh].w[1] = highw(pl);
@@ -3624,7 +3647,7 @@ static void ami_reinit_copper(void)
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);
+ copdisplay.wait->l = CWAIT(32, par->diwstrt_v - 4);
}
/*
@@ -3654,20 +3677,20 @@ static void ami_build_copper(void)
(cops++)->l = CMOVE(0, sprpt[0]);
(cops++)->l = CMOVE2(0, sprpt[0]);
- (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v+1), diwstrt);
- (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v+1), diwstop);
+ (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v + 1), diwstrt);
+ (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v + 1), diwstop);
(cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
(cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
if (!IS_OCS) {
- (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v+1,
- par->diwstop_h, par->diwstop_v+1), diwhigh);
+ (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v + 1,
+ par->diwstop_h, par->diwstop_v + 1), diwhigh);
(cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
+ par->diwstop_h, par->diwstop_v), diwhigh);
#if 0
if (par->beamcon0 & BMC0_VARBEAMEN) {
(copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt+1), vbstrt);
- (copl++)->l = CMOVE(vbstop2hw(par->vbstop+1), vbstop);
+ (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt + 1), vbstrt);
+ (copl++)->l = CMOVE(vbstop2hw(par->vbstop + 1), vbstop);
(cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
(cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
(cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
@@ -3686,7 +3709,7 @@ static void ami_build_copper(void)
(copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
if (!IS_OCS) {
(copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
+ par->diwstop_h, par->diwstop_v), diwhigh);
#if 0
if (par->beamcon0 & BMC0_VARBEAMEN) {
(copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
@@ -3717,23 +3740,23 @@ static void ami_rebuild_copper(void)
u_long p;
if (IS_AGA && maxfmode + par->clk_shift = 0)
- h_end1 = par->diwstrt_h-64;
+ h_end1 = par->diwstrt_h - 64;
else
- h_end1 = par->htotal-32;
- h_end2 = par->ddfstop+64;
+ h_end1 = par->htotal - 32;
+ h_end2 = par->ddfstop + 64;
ami_set_sprite();
copl = copdisplay.rebuild[1];
p = par->bplpt0;
if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres-par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres-par->yres) {
+ if ((par->vyres - par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres) {
for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
(copl++)->l = CMOVE(highw(p), bplpt[i]);
(copl++)->l = CMOVE2(loww(p), bplpt[i]);
}
- line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 1;
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 1;
while (line >= 512) {
(copl++)->l = CWAIT(h_end1, 510);
line -= 512;
@@ -3744,7 +3767,8 @@ static void ami_rebuild_copper(void)
(copl++)->l = CWAIT(h_end2, line);
p = par->bplpt0wrap;
}
- } else p = par->bplpt0wrap;
+ } else
+ p = par->bplpt0wrap;
}
for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
(copl++)->l = CMOVE(highw(p), bplpt[i]);
@@ -3760,13 +3784,13 @@ static void ami_rebuild_copper(void)
else
p += par->next_line;
if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres-par->yoffset) != 1 || mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres-par->yres+1) {
+ if ((par->vyres - par->yoffset) != 1 || mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres + 1) {
for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
(cops++)->l = CMOVE(highw(p), bplpt[i]);
(cops++)->l = CMOVE2(loww(p), bplpt[i]);
}
- line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 2;
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 2;
while (line >= 512) {
(cops++)->l = CWAIT(h_end1, 510);
line -= 512;
@@ -3776,12 +3800,14 @@ static void ami_rebuild_copper(void)
else
(cops++)->l = CWAIT(h_end2, line);
p = par->bplpt0wrap;
- if (mod2(par->diwstrt_v+par->vyres-par->yoffset))
+ if (mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
p -= par->next_line;
else
p += par->next_line;
}
- } else p = par->bplpt0wrap - par->next_line;
+ } else
+ p = par->bplpt0wrap - par->next_line;
}
for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
(cops++)->l = CMOVE(highw(p), bplpt[i]);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Timur Tabi @ 2011-11-21 18:37 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
Bruno Prémont wrote:
> Exactly, thats why I would prefer to see all that initialization moved
> out of registrer_framebuffer() into a init_framebuffer().
I'm okay with that, but I'm not crazy about it.
>
> For simplicity any driver that uses framebuffer_alloc() should not need
> to additionally call init_framebuffer() - framebuffer_alloc() should
> call it just before returning.
My patch does that.
> All those drivers that don't call framebuffer_alloc() would then have to
> call init_framebuffer().
Well, that would then mean that it's easier to move initialization *into* register_framebuffer().
> I think register_framebuffer() is a bit too late to do the initialisation
> of mutexes and other class state because driver cannot use the same code
> for HW setup before registration and after registration as at least the lock
> is in undefined state.
How many drivers actually do that? The only thing that framebuffer_alloc() initializes in fb_info is the 'device' field, which is just a parameter passed into framebuffer_alloc(), so the driver already knows what that value is. I can't find any examples of a driver doing what you're talking about.
It should be easy to modify any driver to stop using the fields of fb_info before register_framebuffer() is called. In fact, I would say it's bad programming to use the fb_info object before the framebuffer is registered.
> In pseudo-code my though would be:
>
>
> // driver using their own memory allocation
>
> struct driver_data {
> ...
> struct fb_info fb;
> ...
> }
>
> int driver_init() {
> struct driver_data *data;
> ...
> memset(&data->fb, 0, sizeof(data->fb));
> init_framebuffer(&data->fb);
> // fill in driver's settings for fb
> ...
> register_framebuffer(&data->fb);
> ...
> }
>
> // driver using alloc_framebuffer()
>
> struct driver_data {
> ...
> struct fb_info *fb;
> ...
> }
>
> int driver_init() {
> struct driver_data *data;
> ...
> data->fb = alloc_framebuffer(0); // this implicitly calls init_framebuffer();
> // fill in driver's settings for fb
> ...
> register_framebuffer(&data->fb);
> ...
> }
This is pretty much what my patch does. But the more I think about it, the more I'm in favor of moving all initialization into register_framebuffer().
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH] fb: split out framebuffer initialization from
From: Bruno Prémont @ 2011-11-21 17:43 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
On Mon, 21 November 2011 Timur Tabi wrote:
> Bruno Prémont wrote:
>
> > Wouldn't it even make sense to move some more of the initialization of fb_info
> > out of fb registration into this new init funtion? (I'm thinking about initializing
> > mutexes and the like)
>
> I was thinking the opposite. See my reply to Florian's message.
Well, in there you don't mention a reason to put it in
register_framebuffer() rather than collect initialization into
a new function for exactly that task.
> > This way fb_info could be used before being registered. Registration would then
> > be reduced to makeing the framebuffer visible to userspace and listed in
> > registered_fb[].
> >
> > This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> > would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> > of which is currently being done by framebuffer_alloc() and the rest by
> > do_register_framebuffer()!).
>
> I think the problem is that it's unclear what the difference is between
> framebuffer_alloc() and register_framebuffer(). The problem is that
> register_framebuffer() also initializes the fb_info structure. So some
> initialization is done in framebuffer_alloc(), some is done in register_framebuffer(),
> and some is done by the driver. Not only that, but drivers that don't call
> framebuffer_alloc() can't really know what needs to be initialized before
> calling register_framebuffer().
>
> Why is fb_info->lock initialized in register_framebuffer(), but
> fb_info->bl_curve_mutex is initialized in framebuffer_alloc()?
> They're both mutexes.
Exactly, thats why I would prefer to see all that initialization moved
out of registrer_framebuffer() into a init_framebuffer().
For simplicity any driver that uses framebuffer_alloc() should not need
to additionally call init_framebuffer() - framebuffer_alloc() should
call it just before returning.
All those drivers that don't call framebuffer_alloc() would then have to
call init_framebuffer().
I think register_framebuffer() is a bit too late to do the initialisation
of mutexes and other class state because driver cannot use the same code
for HW setup before registration and after registration as at least the lock
is in undefined state.
In pseudo-code my though would be:
// driver using their own memory allocation
struct driver_data {
...
struct fb_info fb;
...
}
int driver_init() {
struct driver_data *data;
...
memset(&data->fb, 0, sizeof(data->fb));
init_framebuffer(&data->fb);
// fill in driver's settings for fb
...
register_framebuffer(&data->fb);
...
}
// driver using alloc_framebuffer()
struct driver_data {
...
struct fb_info *fb;
...
}
int driver_init() {
struct driver_data *data;
...
data->fb = alloc_framebuffer(0); // this implicitly calls init_framebuffer();
// fill in driver's settings for fb
...
register_framebuffer(&data->fb);
...
}
Bruno
^ permalink raw reply
* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Timur Tabi @ 2011-11-21 16:28 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
Bruno Prémont wrote:
> Wouldn't it even make sense to move some more of the initialization of fb_info
> out of fb registration into this new init funtion? (I'm thinking about initializing
> mutexes and the like)
I was thinking the opposite. See my reply to Florian's message.
> This way fb_info could be used before being registered. Registration would then
> be reduced to makeing the framebuffer visible to userspace and listed in
> registered_fb[].
>
> This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> of which is currently being done by framebuffer_alloc() and the rest by
> do_register_framebuffer()!).
I think the problem is that it's unclear what the difference is between framebuffer_alloc() and register_framebuffer(). The problem is that register_framebuffer() also initializes the fb_info structure. So some initialization is done in framebuffer_alloc(), some is done in register_framebuffer(), and some is done by the driver. Not only that, but drivers that don't call framebuffer_alloc() can't really know what needs to be initialized before calling register_framebuffer().
Why is fb_info->lock initialized in register_framebuffer(), but fb_info->bl_curve_mutex is initialized in framebuffer_alloc()? They're both mutexes.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Timur Tabi @ 2011-11-21 16:22 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
Florian Tobias Schandinat wrote:
>> Any comments on this patch? If you're okay with the change, I want to take
>> advantage of it in my framebuffer driver.
>
> Of course you want, otherwise I'd be wondering why you are sending this patch
> at all.
I frequently have to ping maintainers on patches that I've posted. I've lost count how many times I've been told, "Oh sorry, I forgot all about your patch".
> But I don't see any advantages of your approach. Instead of pointers to fb_info
> with this patch you could embed fb_info directly in your data structure but that
> is barely a difference for a programmer I'd think. You'd still have to call your
> new functions on init/exit so the amount of function calls needed is the same
> with or without the patch (I could see an advantage if alloc and release were
> pure memory allocations). Or is this all about handling the case when fb_alloc
> fails?
It's all about reducing the number of kmalloc calls. Here's an example of what my per-device data structure looks like:
struct fsl_diu_data {
dma_addr_t phys;
struct fb_info fsl_diu_info[NUM_AOIS]; <-----
struct mfb_info mfb[NUM_AOIS];
struct device_attribute dev_attr;
unsigned int irq;
int fb_enabled;
enum fsl_diu_monitor_port monitor_port;
struct diu __iomem *diu_reg;
spinlock_t reg_lock;
u8 dummy_aoi[4 * 4 * 4];
struct diu_ad dummy_ad __aligned(8);
struct diu_ad ad[NUM_AOIS] __aligned(8);
u8 gamma[256 * 3] __aligned(32);
u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
} __aligned(32);
So this way, I have all of the memory I need allocated in one spot. I know need to allocate one block of memory.
> Historically some drivers don't even call alloc but have their own fb_info and
> call only register.
That's exactly the same thing I want to do. Do these drivers also initialize info->device and info->bl_curve_mutex by themselves? How would they know if the fb_info structure got new members that also need to be initialized?
Perhaps we need to move the fb_info initialization code from framebuffer_alloc() into register_framebuffer()?
> I do not want to add yet another way of doing framebuffer
> initialization unless you can clearly show its benefits.
I think the problem is that we already have two ways that framebuffers are initialized.
What do you think about this:
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 67afa9c..ba47a38 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -57,12 +57,6 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
if (size)
info->par = p + fb_info_size;
- info->device = dev;
-
-#ifdef CONFIG_FB_BACKLIGHT
- mutex_init(&info->bl_curve_mutex);
-#endif
-
return info;
#undef PADDING
#undef BYTES_PER_LONG
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ad93629..ea35bf8 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1591,6 +1591,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
mutex_init(&fb_info->lock);
mutex_init(&fb_info->mm_lock);
+ fb_info->device = dev;
+
+#ifdef CONFIG_FB_BACKLIGHT
+ mutex_init(&fb_info->bl_curve_mutex);
+#endif
+
fb_info->dev = device_create(fb_class, fb_info->device,
MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
if (IS_ERR(fb_info->dev)) {
There are a few instances where drivers use info->device after calling framebuffer_alloc() but before calling register_framebuffer(). These drivers will need to be fixed. But otherwise, I think this is a good idea.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply related
* [PATCH] viafb: correct sync polarity for OLPC DCON
From: Daniel Drake @ 2011-11-21 15:05 UTC (permalink / raw)
To: linux-fbdev
While the OLPC display appears to be able to handle either positive
or negative sync, the Display Controller only recognises positive sync.
This brings viafb (for XO-1.5) in line with lxfb (for XO-1) and
fixes a recent regression where the XO-1.5 DCON could no longer be
frozen. Thanks to Florian Tobias Schandinat for helping identify
the fix.
Test case: from a vt,
echo 1 > /sys/devices/platform/dcon/freeze
should cause the current screen contents to freeze, rather than garbage being
displayed.
Signed-off-by: Daniel Drake <dsd@laptop.org>
---
drivers/video/via/share.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 69d882c..c01c1c1 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -559,8 +559,8 @@
#define M1200X720_R60_VSP POSITIVE
/* 1200x900@60 Sync Polarity (DCON) */
-#define M1200X900_R60_HSP NEGATIVE
-#define M1200X900_R60_VSP NEGATIVE
+#define M1200X900_R60_HSP POSITIVE
+#define M1200X900_R60_VSP POSITIVE
/* 1280x600@60 Sync Polarity (GTF Mode) */
#define M1280x600_R60_HSP NEGATIVE
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH 0/15] fbdev: sh_mipi_dsi: care un-explained register settings
From: Magnus Damm @ 2011-11-21 10:34 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <874nydc3vz.wl%kuninori.morimoto.gx@renesas.com>
Hi Florian,
On Sat, Nov 12, 2011 at 12:37 AM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> Hi Guennadi, Magnus,
>
> On 11/09/2011 04:32 AM, kuninori.morimoto.gx@renesas.com wrote:
>> Dear Florian, Paul
>>
>> These are sh_mipi_dsi update patches.
>>
>> Kuninori Morimoto (15):
>> fbdev: sh_mobile_lcdcfb: fixup LDHAJR :: HSYNPAJ needs mask
>> fbdev: sh_mipi_dsi: tidyup dsip_clk
>> fbdev: sh_mipi_dsi: typo fix of SH_MIPI_DSI_HBPBM
>> fbdev: sh_mipi_dsi: tidyup VMCTR2 parameter expression
>> fbdev: sh_mipi_dsi: add SH_MIPI_DSI_HFPBM flag
>> fbdev: sh_mipi_dsi: add SH_MIPI_DSI_BL2E flag
>> fbdev: sh_mipi_dsi: add lane control support
>> fbdev: sh_mipi_dsi: add sync_pulses/sync_events/burst mode
>> fbdev: sh_mipi_dsi: add VMLEN1/VMLEN2 calculation
>> fbdev: sh_mipi_dsi: add set_dot_clock() for each platform
>> fbdev: sh_mipi_dsi: add HSxxCLK support
>> fbdev: sh_mipi_dsi: sh_mipi has pdata instead of dev
>> fbdev: sh_mipi_dsi: fixup setup timing of sh_mipi_setup()
>> fbdev: sh_mipi_dsi: fixup setup timing of SYSCONF
>> fbdev: sh_mipi_dsi: fixup setup timing DSICTRL
>
> can you have a look at these patches?
> After a quick glance they look okay to me, but as this is all about hardware
> (which I don't know) I'd be happier if someone more qualified could have a look
> at it.
They all look fine to me. Please add:
Acked-by: Magnus Damm <damm@opensource.se>
Thanks for your help,
/ magnus
^ permalink raw reply
* [PATCH] video: Fix return value of fb_notifier_call_chain
From: Joonyoung Shim @ 2011-11-21 6:55 UTC (permalink / raw)
To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1321855411-13730-1-git-send-email-jy0922.shim@samsung.com>
The return value of blocking_notifier_call_chain isn't errno value, it
is just notify return value. The ret of fb_notifier_call_chain should is
restored to error value from notify return value using
notifier_to_errno().
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
---
drivers/video/fb_notify.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
index 74c2da5..49a64a3 100644
--- a/drivers/video/fb_notify.c
+++ b/drivers/video/fb_notify.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
*/
int fb_notifier_call_chain(unsigned long val, void *v)
{
- return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+ int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
+
+ return notifier_to_errno(ret);
}
EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
--
1.7.5.4
^ permalink raw reply related
* [PATCH] video: Fix return value of fb_notifier_call_chain
From: Joonyoung Shim @ 2011-11-21 6:03 UTC (permalink / raw)
To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel
The return value of blocking_notifier_call_chain isn't errno value, it
is just notify return value. The ret of fb_notifier_call_chain should is
restored to error value from notify return value using
notifier_to_errno().
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
---
drivers/video/fb_notify.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
index 74c2da5..49a64a3 100644
--- a/drivers/video/fb_notify.c
+++ b/drivers/video/fb_notify.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
*/
int fb_notifier_call_chain(unsigned long val, void *v)
{
- return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+ int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
+
+ return notifier_to_errno(ret);
}
EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH v3 1/3] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-11-20 10:55 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-media, magnus.damm
In-Reply-To: <4EC85F41.50100@gmx.de>
Hi Florian,
On Sunday 20 November 2011 03:00:33 Florian Tobias Schandinat wrote:
> Hi Laurent,
>
> On 08/31/2011 11:18 AM, Laurent Pinchart wrote:
> > This API will be used to support YUV frame buffer formats in a standard
> > way.
>
> looks like the union is causing problems. With this patch applied I get
> errors like this:
>
> CC [M] drivers/auxdisplay/cfag12864bfb.o
> drivers/auxdisplay/cfag12864bfb.c:57: error: unknown field ‘red’ specified
> in initializer
*ouch*
gcc < 4.6 chokes on anonymous unions initializers :-/
[snip]
> > @@ -246,12 +251,23 @@ struct fb_var_screeninfo {
> >
> > __u32 yoffset; /* resolution */
> >
> > __u32 bits_per_pixel; /* guess what */
> >
> > - __u32 grayscale; /* != 0 Graylevels instead of colors */
> >
> > - struct fb_bitfield red; /* bitfield in fb mem if true color, */
> > - struct fb_bitfield green; /* else only length is significant */
> > - struct fb_bitfield blue;
> > - struct fb_bitfield transp; /* transparency */
> > + union {
> > + struct { /* Legacy format API */
> > + __u32 grayscale; /* 0 = color, 1 = grayscale */
> > + /* bitfields in fb mem if true color, else only */
> > + /* length is significant */
> > + struct fb_bitfield red;
> > + struct fb_bitfield green;
> > + struct fb_bitfield blue;
> > + struct fb_bitfield transp; /* transparency */
> > + };
> > + struct { /* FOURCC-based format API */
> > + __u32 fourcc; /* FOURCC format */
> > + __u32 colorspace;
> > + __u32 reserved[11];
> > + } fourcc;
> > + };
We can't name the union, otherwise this will change the userspace API.
We could "fix" the problem on the kernel side with
#ifdef __KERNEL__
} color;
#else
};
#endif
That's quite hackish though... What's your opinion ?
It would also not handle userspace code that initializes an fb_var_screeninfo
structure with named initializers, but that shouldn't happen, as application
should read fb_var_screeninfo , modify it and write it back.
> >
> > __u32 nonstd; /* != 0 Non standard pixel format */
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: Recent viafb changes break OLPC DCON freeze
From: Florian Tobias Schandinat @ 2011-11-20 2:16 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <CAMLZHHQHZL9zZMsQgvXBi6MoG9_TXWqPN5D19sqeKSjsoV3unA@mail.gmail.com>
Hi Daniel,
On 11/18/2011 04:09 PM, Daniel Drake wrote:
> On Thu, Nov 17, 2011 at 8:14 PM, Florian Tobias Schandinat
> <FlorianSchandinat@gmx.de> wrote:
>> As you mentioned it, I had a look at this driver. It looks like viafb does it
>> (polarity) just the other way around than geode. So it might be wort a try to
>> change in
>>
>> drivers/video/via/share.h:
>> /* 1200x900@60 Sync Polarity (DCON) */
>> #define M1200X900_R60_HSP NEGATIVE
>> #define M1200X900_R60_VSP NEGATIVE
>>
>> to
>>
>> /* 1200x900@60 Sync Polarity (DCON) */
>> #define M1200X900_R60_HSP POSITIVE
>> #define M1200X900_R60_VSP POSITIVE
>
> That fixes the problem - thanks! Let me know if you'd like me to make
> a patch with that change (I can do so on Monday).
Yes, I'd appreciate it. Then I could queue this patch for 3.2, you might also
consider adding a "Cc: stable@kernel.org" to it so previous releases also get
fixed up.
> It may still be worth you looking at the diagnosis - in particular I
> think I may have found something that may clean up some of the
> uncertainty in commit 32fab7bc
True. Well I already know that it was required for some reason to get the
output, so I merged my branch with the fix before I merged the one with the
problematic patch, to make regression testing easier. So now we know the display
wiring on OLPC better than the driver did some releases ago, though I'd be
happier if I'd find a generic way to figure these display wiring out...
Thanks,
Florian Tobias Schandinat
>
> Thanks
> Daniel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v3 1/3] fbdev: Add FOURCC-based format configuration API
From: Florian Tobias Schandinat @ 2011-11-20 2:00 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linux-fbdev, linux-media, magnus.damm
In-Reply-To: <1314789501-824-2-git-send-email-laurent.pinchart@ideasonboard.com>
Hi Laurent,
On 08/31/2011 11:18 AM, Laurent Pinchart wrote:
> This API will be used to support YUV frame buffer formats in a standard
> way.
looks like the union is causing problems. With this patch applied I get errors
like this:
CC [M] drivers/auxdisplay/cfag12864bfb.o
drivers/auxdisplay/cfag12864bfb.c:57: error: unknown field ‘red’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:57: warning: missing braces around initializer
drivers/auxdisplay/cfag12864bfb.c:57: warning: (near initialization for
‘cfag12864bfb_var.<anonymous>.<anonymous>’)
drivers/auxdisplay/cfag12864bfb.c:58: error: unknown field ‘green’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: braces around scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:58: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:58: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:59: error: unknown field ‘blue’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: braces around scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
drivers/auxdisplay/cfag12864bfb.c:59: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
drivers/auxdisplay/cfag12864bfb.c:59: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
make[2]: *** [drivers/auxdisplay/cfag12864bfb.o] Error 1
Any idea?
Best regards,
Florian Tobias Schandinat
>
> Last but not least, create a much needed fbdev API documentation and
> document the format setting APIs.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> Documentation/fb/api.txt | 317 ++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/fb.h | 28 +++-
> 2 files changed, 339 insertions(+), 6 deletions(-)
> create mode 100644 Documentation/fb/api.txt
>
> diff --git a/Documentation/fb/api.txt b/Documentation/fb/api.txt
> new file mode 100644
> index 0000000..d842534
> --- /dev/null
> +++ b/Documentation/fb/api.txt
> @@ -0,0 +1,317 @@
> + The Frame Buffer Device API
> + ---------------------------
> +
> +Last revised: June 21, 2011
> +
> +
> +0. Introduction
> +---------------
> +
> +This document describes the frame buffer API used by applications to interact
> +with frame buffer devices. In-kernel APIs between device drivers and the frame
> +buffer core are not described.
> +
> +Due to a lack of documentation in the original frame buffer API, drivers
> +behaviours differ in subtle (and not so subtle) ways. This document describes
> +the recommended API implementation, but applications should be prepared to
> +deal with different behaviours.
> +
> +
> +1. Capabilities
> +---------------
> +
> +Device and driver capabilities are reported in the fixed screen information
> +capabilities field.
> +
> +struct fb_fix_screeninfo {
> + ...
> + __u16 capabilities; /* see FB_CAP_* */
> + ...
> +};
> +
> +Application should use those capabilities to find out what features they can
> +expect from the device and driver.
> +
> +- FB_CAP_FOURCC
> +
> +The driver supports the four character code (FOURCC) based format setting API.
> +When supported, formats are configured using a FOURCC instead of manually
> +specifying color components layout.
> +
> +
> +2. Types and visuals
> +--------------------
> +
> +Pixels are stored in memory in hardware-dependent formats. Applications need
> +to be aware of the pixel storage format in order to write image data to the
> +frame buffer memory in the format expected by the hardware.
> +
> +Formats are described by frame buffer types and visuals. Some visuals require
> +additional information, which are stored in the variable screen information
> +bits_per_pixel, grayscale, fourcc, red, green, blue and transp fields.
> +
> +Visuals describe how color information is encoded and assembled to create
> +macropixels. Types describe how macropixels are stored in memory. The following
> +types and visuals are supported.
> +
> +- FB_TYPE_PACKED_PIXELS
> +
> +Macropixels are stored contiguously in a single plane. If the number of bits
> +per macropixel is not a multiple of 8, whether macropixels are padded to the
> +next multiple of 8 bits or packed together into bytes depends on the visual.
> +
> +Padding at end of lines may be present and is then reported through the fixed
> +screen information line_length field.
> +
> +- FB_TYPE_PLANES
> +
> +Macropixels are split across multiple planes. The number of planes is equal to
> +the number of bits per macropixel, with plane i'th storing i'th bit from all
> +macropixels.
> +
> +Planes are located contiguously in memory.
> +
> +- FB_TYPE_INTERLEAVED_PLANES
> +
> +Macropixels are split across multiple planes. The number of planes is equal to
> +the number of bits per macropixel, with plane i'th storing i'th bit from all
> +macropixels.
> +
> +Planes are interleaved in memory. The interleave factor, defined as the
> +distance in bytes between the beginning of two consecutive interleaved blocks
> +belonging to different planes, is stored in the fixed screen information
> +type_aux field.
> +
> +- FB_TYPE_FOURCC
> +
> +Macropixels are stored in memory as described by the format FOURCC identifier
> +stored in the variable screen information fourcc field.
> +
> +- FB_VISUAL_MONO01
> +
> +Pixels are black or white and stored on a number of bits (typically one)
> +specified by the variable screen information bpp field.
> +
> +Black pixels are represented by all bits set to 1 and white pixels by all bits
> +set to 0. When the number of bits per pixel is smaller than 8, several pixels
> +are packed together in a byte.
> +
> +FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
> +
> +- FB_VISUAL_MONO10
> +
> +Pixels are black or white and stored on a number of bits (typically one)
> +specified by the variable screen information bpp field.
> +
> +Black pixels are represented by all bits set to 0 and white pixels by all bits
> +set to 1. When the number of bits per pixel is smaller than 8, several pixels
> +are packed together in a byte.
> +
> +FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
> +
> +- FB_VISUAL_TRUECOLOR
> +
> +Pixels are broken into red, green and blue components, and each component
> +indexes a read-only lookup table for the corresponding value. Lookup tables
> +are device-dependent, and provide linear or non-linear ramps.
> +
> +Each component is stored in a macropixel according to the variable screen
> +information red, green, blue and transp fields.
> +
> +- FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR
> +
> +Pixel values are encoded as indices into a colormap that stores red, green and
> +blue components. The colormap is read-only for FB_VISUAL_STATIC_PSEUDOCOLOR
> +and read-write for FB_VISUAL_PSEUDOCOLOR.
> +
> +Each pixel value is stored in the number of bits reported by the variable
> +screen information bits_per_pixel field.
> +
> +- FB_VISUAL_DIRECTCOLOR
> +
> +Pixels are broken into red, green and blue components, and each component
> +indexes a programmable lookup table for the corresponding value.
> +
> +Each component is stored in a macropixel according to the variable screen
> +information red, green, blue and transp fields.
> +
> +- FB_VISUAL_FOURCC
> +
> +Pixels are encoded and interpreted as described by the format FOURCC
> +identifier stored in the variable screen information fourcc field.
> +
> +
> +3. Screen information
> +---------------------
> +
> +Screen information are queried by applications using the FBIOGET_FSCREENINFO
> +and FBIOGET_VSCREENINFO ioctls. Those ioctls take a pointer to a
> +fb_fix_screeninfo and fb_var_screeninfo structure respectively.
> +
> +struct fb_fix_screeninfo stores device independent unchangeable information
> +about the frame buffer device and the current format. Those information can't
> +be directly modified by applications, but can be changed by the driver when an
> +application modifies the format.
> +
> +struct fb_fix_screeninfo {
> + char id[16]; /* identification string eg "TT Builtin" */
> + unsigned long smem_start; /* Start of frame buffer mem */
> + /* (physical address) */
> + __u32 smem_len; /* Length of frame buffer mem */
> + __u32 type; /* see FB_TYPE_* */
> + __u32 type_aux; /* Interleave for interleaved Planes */
> + __u32 visual; /* see FB_VISUAL_* */
> + __u16 xpanstep; /* zero if no hardware panning */
> + __u16 ypanstep; /* zero if no hardware panning */
> + __u16 ywrapstep; /* zero if no hardware ywrap */
> + __u32 line_length; /* length of a line in bytes */
> + unsigned long mmio_start; /* Start of Memory Mapped I/O */
> + /* (physical address) */
> + __u32 mmio_len; /* Length of Memory Mapped I/O */
> + __u32 accel; /* Indicate to driver which */
> + /* specific chip/card we have */
> + __u16 capabilities; /* see FB_CAP_* */
> + __u16 reserved[2]; /* Reserved for future compatibility */
> +};
> +
> +struct fb_var_screeninfo stores device independent changeable information
> +about a frame buffer device, its current format and video mode, as well as
> +other miscellaneous parameters.
> +
> +struct fb_var_screeninfo {
> + __u32 xres; /* visible resolution */
> + __u32 yres;
> + __u32 xres_virtual; /* virtual resolution */
> + __u32 yres_virtual;
> + __u32 xoffset; /* offset from virtual to visible */
> + __u32 yoffset; /* resolution */
> +
> + __u32 bits_per_pixel; /* guess what */
> + union {
> + struct { /* Legacy format API */
> + __u32 grayscale; /* 0 = color, 1 = grayscale */
> + /* bitfields in fb mem if true color, else only */
> + /* length is significant */
> + struct fb_bitfield red;
> + struct fb_bitfield green;
> + struct fb_bitfield blue;
> + struct fb_bitfield transp; /* transparency */
> + };
> + struct { /* FOURCC-based format API */
> + __u32 fourcc; /* FOURCC format */
> + __u32 colorspace;
> + __u32 reserved[11];
> + } fourcc;
> + };
> +
> + __u32 nonstd; /* != 0 Non standard pixel format */
> +
> + __u32 activate; /* see FB_ACTIVATE_* */
> +
> + __u32 height; /* height of picture in mm */
> + __u32 width; /* width of picture in mm */
> +
> + __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
> +
> + /* Timing: All values in pixclocks, except pixclock (of course) */
> + __u32 pixclock; /* pixel clock in ps (pico seconds) */
> + __u32 left_margin; /* time from sync to picture */
> + __u32 right_margin; /* time from picture to sync */
> + __u32 upper_margin; /* time from sync to picture */
> + __u32 lower_margin;
> + __u32 hsync_len; /* length of horizontal sync */
> + __u32 vsync_len; /* length of vertical sync */
> + __u32 sync; /* see FB_SYNC_* */
> + __u32 vmode; /* see FB_VMODE_* */
> + __u32 rotate; /* angle we rotate counter clockwise */
> + __u32 reserved[5]; /* Reserved for future compatibility */
> +};
> +
> +To modify variable information, applications call the FBIOPUT_VSCREENINFO
> +ioctl with a pointer to a fb_var_screeninfo structure. If the call is
> +successful, the driver will update the fixed screen information accordingly.
> +
> +Instead of filling the complete fb_var_screeninfo structure manually,
> +applications should call the FBIOGET_VSCREENINFO ioctl and modify only the
> +fields they care about.
> +
> +
> +4. Format configuration
> +-----------------------
> +
> +Frame buffer devices offer two ways to configure the frame buffer format: the
> +legacy API and the FOURCC-based API.
> +
> +
> +The legacy API has been the only frame buffer format configuration API for a
> +long time and is thus widely used by application. It is the recommended API
> +for applications when using RGB and grayscale formats, as well as legacy
> +non-standard formats.
> +
> +To select a format, applications set the fb_var_screeninfo bits_per_pixel field
> +to the desired frame buffer depth. Values up to 8 will usually map to
> +monochrome, grayscale or pseudocolor visuals, although this is not required.
> +
> +- For grayscale formats, applications set the grayscale field to one. The red,
> + blue, green and transp fields must be set to 0 by applications and ignored by
> + drivers. Drivers must fill the red, blue and green offsets to 0 and lengths
> + to the bits_per_pixel value.
> +
> +- For pseudocolor formats, applications set the grayscale field to zero. The
> + red, blue, green and transp fields must be set to 0 by applications and
> + ignored by drivers. Drivers must fill the red, blue and green offsets to 0
> + and lengths to the bits_per_pixel value.
> +
> +- For truecolor and directcolor formats, applications set the grayscale field
> + to zero, and the red, blue, green and transp fields to describe the layout of
> + color components in memory.
> +
> +struct fb_bitfield {
> + __u32 offset; /* beginning of bitfield */
> + __u32 length; /* length of bitfield */
> + __u32 msb_right; /* != 0 : Most significant bit is */
> + /* right */
> +};
> +
> + Pixel values are bits_per_pixel wide and are split in non-overlapping red,
> + green, blue and alpha (transparency) components. Location and size of each
> + component in the pixel value are described by the fb_bitfield offset and
> + length fields. Offset are computed from the right.
> +
> + Pixels are always stored in an integer number of bytes. If the number of
> + bits per pixel is not a multiple of 8, pixel values are padded to the next
> + multiple of 8 bits.
> +
> +Upon successful format configuration, drivers update the fb_fix_screeninfo
> +type, visual and line_length fields depending on the selected format.
> +
> +
> +The FOURCC-based API replaces format descriptions by four character codes
> +(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
> +without explicitly describing it. This is the only API that supports YUV
> +formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
> +and grayscale formats.
> +
> +Drivers that support the FOURCC-based API report this capability by setting
> +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
> +
> +FOURCC definitions are located in the linux/videodev2.h header. However, and
> +despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
> +and don't require usage of the V4L2 subsystem. FOURCC documentation is
> +available in Documentation/DocBook/v4l/pixfmt.xml.
> +
> +To select a format, applications set the fourcc.fourcc field to the desired
> +FOURCC. For YUV formats, they should also select the appropriate colorspace by
> +setting the fourcc.colorspace field to one of the colorspaces listed in
> +linux/videodev2.h and documented in Documentation/DocBook/v4l/colorspaces.xml.
> +
> +For forward compatibility reasons applications must zero the fourcc reserved
> +fields by zeroing the whole fourcc structure before filling it. The reserved
> +fields must be ignored by drivers. Values other than 0 may get a meaning in
> +future extensions. Note that the grayscale, red, green, blue and transp field
> +share memory with the fourcc field. Application must thus not touch those
> +fields when using the FOURCC-based API.
> +
> +Upon successful format configuration, drivers update the fb_fix_screeninfo
> +type, visual and line_length fields depending on the selected format. The type
> +and visual fields are set to FB_TYPE_FOURCC and FB_VISUAL_FOURCC respectively.
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index 1d6836c..98b23e3 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -45,6 +45,7 @@
> #define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
> #define FB_TYPE_TEXT 3 /* Text/attributes */
> #define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
> +#define FB_TYPE_FOURCC 5 /* Type identified by a V4L2 FOURCC */
>
> #define FB_AUX_TEXT_MDA 0 /* Monochrome text */
> #define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
> @@ -69,6 +70,7 @@
> #define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
> #define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
> #define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
> +#define FB_VISUAL_FOURCC 6 /* Visual identified by a V4L2 FOURCC */
>
> #define FB_ACCEL_NONE 0 /* no hardware accelerator */
> #define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
> @@ -154,6 +156,8 @@
>
> #define FB_ACCEL_PUV3_UNIGFX 0xa0 /* PKUnity-v3 Unigfx */
>
> +#define FB_CAP_FOURCC 1 /* Device supports FOURCC-based formats */
> +
> struct fb_fix_screeninfo {
> char id[16]; /* identification string eg "TT Builtin" */
> unsigned long smem_start; /* Start of frame buffer mem */
> @@ -171,7 +175,8 @@ struct fb_fix_screeninfo {
> __u32 mmio_len; /* Length of Memory Mapped I/O */
> __u32 accel; /* Indicate to driver which */
> /* specific chip/card we have */
> - __u16 reserved[3]; /* Reserved for future compatibility */
> + __u16 capabilities; /* see FB_CAP_* */
> + __u16 reserved[2]; /* Reserved for future compatibility */
> };
>
> /* Interpretation of offset for color fields: All offsets are from the right,
> @@ -246,12 +251,23 @@ struct fb_var_screeninfo {
> __u32 yoffset; /* resolution */
>
> __u32 bits_per_pixel; /* guess what */
> - __u32 grayscale; /* != 0 Graylevels instead of colors */
>
> - struct fb_bitfield red; /* bitfield in fb mem if true color, */
> - struct fb_bitfield green; /* else only length is significant */
> - struct fb_bitfield blue;
> - struct fb_bitfield transp; /* transparency */
> + union {
> + struct { /* Legacy format API */
> + __u32 grayscale; /* 0 = color, 1 = grayscale */
> + /* bitfields in fb mem if true color, else only */
> + /* length is significant */
> + struct fb_bitfield red;
> + struct fb_bitfield green;
> + struct fb_bitfield blue;
> + struct fb_bitfield transp; /* transparency */
> + };
> + struct { /* FOURCC-based format API */
> + __u32 fourcc; /* FOURCC format */
> + __u32 colorspace;
> + __u32 reserved[11];
> + } fourcc;
> + };
>
> __u32 nonstd; /* != 0 Non standard pixel format */
>
^ permalink raw reply
* Re: [PATCH 5/5] Drivers: video: riva: riva_hw: fixed a brace coding
From: Florian Tobias Schandinat @ 2011-11-20 1:50 UTC (permalink / raw)
To: Zac Storer; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1321591537-8475-1-git-send-email-zac.3.14159@gmail.com>
On 11/18/2011 04:45 AM, Zac Storer wrote:
> Fixed a brace coding style issue.
*sigh* You are fixing coding style, but I still get lots of warnings for the
single line you are changing. IF you are fixing coding style, at least do it
right. Or do you really expect me to be happy if you send me 3 patches that all
touch the same line?
Really, if you want to fix it, at least fix it in a way that checkpatch.pl does
no longer complain about your patch, at least regarding coding style issues. And
for such patches I think a per file patch or similar would be appropriate.
Regards,
Florian Tobias Schandinat
>
> Signed-off-by: Zac Storer <zac.3.14159@gmail.com>
> ---
> drivers/video/riva/riva_hw.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
> index 78fdbf5..c4b8a6f 100644
> --- a/drivers/video/riva/riva_hw.c
> +++ b/drivers/video/riva/riva_hw.c
> @@ -994,7 +994,7 @@ static void nv10CalcArbitration
> clwm = clwm_mt;
> */
> /* Finally, a heuristic check when width = 64 bits */
> - if(width = 1){
> + if(width = 1) {
> nvclk_fill = nvclk_freq * 8;
> if(crtc_drain_rate * 100 >= nvclk_fill * 102)
> clwm = 0xfff; /*Large number to fail */
^ permalink raw reply
* Re: [PATCH] video:da8xx-fb: Add 24bpp LCD configuration support
From: Florian Tobias Schandinat @ 2011-11-20 0:41 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321358479-20390-1-git-send-email-prakash.pm@ti.com>
On 11/15/2011 12:01 PM, Manjunathappa, Prakash wrote:
> LCD controller on am335x supports 24bpp raster configuration
> in addition to ones on da850. LCDC also supports 24bpp in unpacked
> format having ARGB:8888 32bpp format data in DDR, but it doesn't
> interpret Alpha component of the data.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
> drivers/video/da8xx-fb.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 56 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 55f91d9..e111971 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -82,6 +82,8 @@
> #define LCD_V2_LIDD_CLK_EN BIT(1)
> #define LCD_V2_CORE_CLK_EN BIT(0)
> #define LCD_V2_LPP_B10 26
> +#define LCD_V2_TFT_24BPP_MODE BIT(25)
> +#define LCD_V2_TFT_24BPP_UNPACK BIT(26)
>
> /* LCD Raster Timing 2 Register */
> #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
> @@ -151,7 +153,7 @@ struct da8xx_fb_par {
> unsigned int dma_end;
> struct clk *lcdc_clk;
> int irq;
> - unsigned short pseudo_palette[16];
> + unsigned short pseudo_palette[32];
This looks wrong, include/linux/fb.h says:
"void *pseudo_palette; /* Fake palette of 16 colors */"
This will probably also simplify the code below to write to the pseudo palette.
But I think you have to increase the data type of the palette, maybe to u32?
Best regards,
Florian Tobias Schandinat
> unsigned int palette_sz;
> unsigned int pxl_clk;
> int blank;
> @@ -458,6 +460,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
> {
> u32 reg;
>
> + if ((bpp > 16) && (lcd_revision = LCD_VERSION_1))
> + return -EINVAL;
> +
> /* Set the Panel Width */
> /* Pixels per line = (PPL + 1)*16 */
> if (lcd_revision = LCD_VERSION_1) {
> @@ -501,6 +506,13 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
> reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
> if (raster_order)
> reg |= LCD_RASTER_ORDER;
> +
> + if (bpp = 24)
> + reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE);
> + else if (bpp = 32)
> + reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE
> + | LCD_V2_TFT_24BPP_UNPACK);
> +
> lcdc_write(reg, LCD_RASTER_CTRL_REG);
>
> switch (bpp) {
> @@ -508,6 +520,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
> case 2:
> case 4:
> case 16:
> + case 24:
> + case 32:
> par->palette_sz = 16 * 2;
> break;
>
> @@ -537,6 +551,9 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
> if (info->fix.visual = FB_VISUAL_DIRECTCOLOR)
> return 1;
>
> + if ((info->var.bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
> + return 1;
> +
> if (info->var.bits_per_pixel = 8) {
> red >>= 4;
> green >>= 8;
> @@ -566,6 +583,23 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
> update_hw = 1;
> palette[0] = 0x4000;
> }
> + } else if (((info->var.bits_per_pixel = 32) && regno < 32) ||
> + ((info->var.bits_per_pixel = 24) && regno < 24)) {
> + red >>= (24 - info->var.red.length);
> + red <<= info->var.red.offset;
> +
> + green >>= (24 - info->var.green.length);
> + green <<= info->var.green.offset;
> +
> + blue >>= (24 - info->var.blue.length);
> + blue <<= info->var.blue.offset;
> +
> + par->pseudo_palette[regno] = red | green | blue;
> +
> + if (palette[0] != 0x4000) {
> + update_hw = 1;
> + palette[0] = 0x4000;
> + }
> }
>
> /* Update the palette in the h/w as needed. */
> @@ -777,6 +811,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
> {
> int err = 0;
>
> + if ((var->bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
> + return -EINVAL;
> +
> switch (var->bits_per_pixel) {
> case 1:
> case 8:
> @@ -809,6 +846,24 @@ static int fb_check_var(struct fb_var_screeninfo *var,
> var->transp.offset = 0;
> var->transp.length = 0;
> break;
> + case 24:
> + var->red.offset = 16;
> + var->red.length = 8;
> + var->green.offset = 8;
> + var->green.length = 8;
> + var->blue.offset = 0;
> + var->blue.length = 8;
> + break;
> + case 32:
> + var->transp.offset = 24;
> + var->transp.length = 8;
> + var->red.offset = 16;
> + var->red.length = 8;
> + var->green.offset = 8;
> + var->green.length = 8;
> + var->blue.offset = 0;
> + var->blue.length = 8;
> + break;
> default:
> err = -EINVAL;
> }
^ permalink raw reply
* Re: [PATCH] fb: split out framebuffer initialization from
From: Bruno Prémont @ 2011-11-19 12:35 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
Hi Florian,
On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> On 11/19/2011 11:47 AM, Bruno Prémont wrote:
> > On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> >> On 11/17/2011 08:19 PM, Timur Tabi wrote:
> >>> Timur Tabi wrote:
> >>>> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
> >>>> the initialization of a user-allocated fb_info object.
> >>>>
> >>>> framebuffer_alloc() allows for appending a private data structure when it
> >>>> allocates the fb_info object. However, a driver that registers multiple
> >>>> framebuffers for one device may also need another private data structure
> >>>> for the device itself. framebuffer_init() allows such drivers to store
> >>>> the fb_info objects in the device-specific private data structure,
> >>>> thereby simplifying memory allocation.
> >>>>
> >>>> Signed-off-by: Timur Tabi <timur@freescale.com>
> >>>
> >>> Florian,
> >>>
> >>> Any comments on this patch? If you're okay with the change, I want to take
> >>> advantage of it in my framebuffer driver.
> >>
> >> Of course you want, otherwise I'd be wondering why you are sending this patch
> >> at all.
> >>
> >> But I don't see any advantages of your approach. Instead of pointers to fb_info
> >> with this patch you could embed fb_info directly in your data structure but that
> >> is barely a difference for a programmer I'd think. You'd still have to call your
> >> new functions on init/exit so the amount of function calls needed is the same
> >> with or without the patch (I could see an advantage if alloc and release were
> >> pure memory allocations). Or is this all about handling the case when fb_alloc
> >> fails?
> >> Historically some drivers don't even call alloc but have their own fb_info and
> >> call only register. I do not want to add yet another way of doing framebuffer
> >> initialization unless you can clearly show its benefits.
> >
> > Wouldn't it even make sense to move some more of the initialization of fb_info
> > out of fb registration into this new init funtion? (I'm thinking about initializing
> > mutexes and the like)
>
> This would require someone going through all framebuffers and change them to use
> the new fb_init function if they don't use fb_alloc. I'd accept this patch as an
> improvement iff someone would do this. Than the number of variation of doing
> framebuffer initialization would remain the same. Of course the same should be
> done for fb_cleanup.
I agree, though (in a first step) alloc_framebuffer() could call init_framebuffer()
by itself (same goes for cleanup on release) so that only those doing the memory
allocation manually have to be changed (though I'm wondering if those are not already
wrong with regard to fb_info.bl_curve_mutex which is being initialized in
alloc_framebuffer() - but then again they will not use backlight).
I might give it a try once I'm no more busy with system administration.
Bruno
> > This way fb_info could be used before being registered. Registration would then
> > be reduced to makeing the framebuffer visible to userspace and listed in
> > registered_fb[].
> >
> > This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> > would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> > of which is currently being done by framebuffer_alloc() and the rest by
> > do_register_framebuffer()!).
^ permalink raw reply
* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Florian Tobias Schandinat @ 2011-11-19 12:08 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>
Hi Bruno,
On 11/19/2011 11:47 AM, Bruno Prémont wrote:
> Hi Florian, Timur,
>
> On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
>> On 11/17/2011 08:19 PM, Timur Tabi wrote:
>>> Timur Tabi wrote:
>>>> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
>>>> the initialization of a user-allocated fb_info object.
>>>>
>>>> framebuffer_alloc() allows for appending a private data structure when it
>>>> allocates the fb_info object. However, a driver that registers multiple
>>>> framebuffers for one device may also need another private data structure
>>>> for the device itself. framebuffer_init() allows such drivers to store
>>>> the fb_info objects in the device-specific private data structure,
>>>> thereby simplifying memory allocation.
>>>>
>>>> Signed-off-by: Timur Tabi <timur@freescale.com>
>>>
>>> Florian,
>>>
>>> Any comments on this patch? If you're okay with the change, I want to take
>>> advantage of it in my framebuffer driver.
>>
>> Of course you want, otherwise I'd be wondering why you are sending this patch
>> at all.
>>
>> But I don't see any advantages of your approach. Instead of pointers to fb_info
>> with this patch you could embed fb_info directly in your data structure but that
>> is barely a difference for a programmer I'd think. You'd still have to call your
>> new functions on init/exit so the amount of function calls needed is the same
>> with or without the patch (I could see an advantage if alloc and release were
>> pure memory allocations). Or is this all about handling the case when fb_alloc
>> fails?
>> Historically some drivers don't even call alloc but have their own fb_info and
>> call only register. I do not want to add yet another way of doing framebuffer
>> initialization unless you can clearly show its benefits.
>
> Wouldn't it even make sense to move some more of the initialization of fb_info
> out of fb registration into this new init funtion? (I'm thinking about initializing
> mutexes and the like)
This would require someone going through all framebuffers and change them to use
the new fb_init function if they don't use fb_alloc. I'd accept this patch as an
improvement iff someone would do this. Than the number of variation of doing
framebuffer initialization would remain the same. Of course the same should be
done for fb_cleanup.
Best regards,
Florian Tobias Schandinat
> This way fb_info could be used before being registered. Registration would then
> be reduced to makeing the framebuffer visible to userspace and listed in
> registered_fb[].
>
> This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> of which is currently being done by framebuffer_alloc() and the rest by
> do_register_framebuffer()!).
>
> Bruno
>
>> Best regards,
>>
>> Florian Tobias Schandinat
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox