Commit fafa93c5 authored by James Simmons's avatar James Simmons

Ported SA1100 framebuffer over to new fbdev api.

parent 02f18c68
...@@ -245,11 +245,11 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -245,11 +245,11 @@ if [ "$CONFIG_FB" = "y" ]; then
define_tristate CONFIG_FBCON_MFB m define_tristate CONFIG_FBCON_MFB m
fi fi
fi fi
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then if [ "$CONFIG_FB_ACORN" = "y" ]; then
define_tristate CONFIG_FBCON_CFB2 y define_tristate CONFIG_FBCON_CFB2 y
define_tristate CONFIG_FBCON_CFB4 y define_tristate CONFIG_FBCON_CFB4 y
else else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_SA1100" = "m" ]; then if [ "$CONFIG_FB_ACORN" = "m" ]; then
define_tristate CONFIG_FBCON_CFB2 m define_tristate CONFIG_FBCON_CFB2 m
define_tristate CONFIG_FBCON_CFB4 m define_tristate CONFIG_FBCON_CFB4 m
fi fi
...@@ -265,8 +265,8 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -265,8 +265,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \ "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_RADEON" = "y" ]; then "$CONFIG_FB_SGIVW" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y define_tristate CONFIG_FBCON_CFB8 y
else else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
...@@ -280,8 +280,8 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -280,8 +280,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_SA1100" = "m" -o \ "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_RADEON" = "m" ]; then "$CONFIG_FB_SGIVW" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m define_tristate CONFIG_FBCON_CFB8 m
fi fi
fi fi
...@@ -294,8 +294,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -294,8 +294,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_PM3" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \ "$CONFIG_FB_PM3" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
"$CONFIG_FB_CYBER2000" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y define_tristate CONFIG_FBCON_CFB16 y
else else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
...@@ -307,8 +306,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -307,8 +306,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \ "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_SA1100" = "m" -o \ "$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
"$CONFIG_FB_CYBER2000" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m define_tristate CONFIG_FBCON_CFB16 m
fi fi
fi fi
...@@ -359,7 +357,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -359,7 +357,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \ "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
"$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_RIVA" = "y" ]; then "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then
define_tristate CONFIG_FBCON_ACCEL y define_tristate CONFIG_FBCON_ACCEL y
else else
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \ if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
......
...@@ -94,7 +94,7 @@ obj-$(CONFIG_FB_ATY) += aty/ ...@@ -94,7 +94,7 @@ obj-$(CONFIG_FB_ATY) += aty/
obj-$(CONFIG_FB_SUN3) += sun3fb.o obj-$(CONFIG_FB_SUN3) += sun3fb.o
obj-$(CONFIG_FB_BWTWO) += bwtwofb.o obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
obj-$(CONFIG_FB_HGA) += hgafb.o obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o obj-$(CONFIG_FB_SA1100) += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VIRTUAL) += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_VIRTUAL) += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_E1355) += epson1355fb.o obj-$(CONFIG_FB_E1355) += epson1355fb.o
......
...@@ -661,7 +661,7 @@ static struct sa1100fb_mach_info xp860_info __initdata = { ...@@ -661,7 +661,7 @@ static struct sa1100fb_mach_info xp860_info __initdata = {
static struct sa1100fb_mach_info * __init static struct sa1100fb_mach_info * __init
sa1100fb_get_machine_info(struct sa1100fb_info *fbi) sa1100fb_get_machine_info(struct sa1100_par *par)
{ {
struct sa1100fb_mach_info *inf = NULL; struct sa1100fb_mach_info *inf = NULL;
...@@ -683,7 +683,7 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi) ...@@ -683,7 +683,7 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
#ifdef CONFIG_SA1100_H3XXX #ifdef CONFIG_SA1100_H3XXX
if (machine_is_h3600()) { if (machine_is_h3600()) {
inf = &h3600_info; inf = &h3600_info;
fbi->rgb[RGB_16] = &h3600_rgb_16; par->rgb[RGB_16] = &h3600_rgb_16;
} }
if (machine_is_h3100()) { if (machine_is_h3100()) {
inf = &h3100_info; inf = &h3100_info;
...@@ -705,7 +705,7 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi) ...@@ -705,7 +705,7 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
#ifdef CONFIG_SA1100_FREEBIRD #ifdef CONFIG_SA1100_FREEBIRD
if (machine_is_freebird()) { if (machine_is_freebird()) {
inf = &freebird_info; inf = &freebird_info;
fbi->rgb[RGB_16] = &freebird_rgb16; par->rgb[RGB_16] = &freebird_rgb16;
} }
#endif #endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT #ifdef CONFIG_SA1100_GRAPHICSCLIENT
...@@ -758,10 +758,10 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi) ...@@ -758,10 +758,10 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
if (machine_is_stork()) { if (machine_is_stork()) {
#if STORK_TFT #if STORK_TFT
inf = &stork_tft_info; inf = &stork_tft_info;
fbi->rgb[RGB_16] = &stork_tft_rgb_16; par->rgb[RGB_16] = &stork_tft_rgb_16;
#else #else
inf = &stork_dstn_info; inf = &stork_dstn_info;
fbi->rgb[RGB_16] = &stork_dstn_rgb_16; par->rgb[RGB_16] = &stork_dstn_rgb_16;
#endif #endif
} }
#endif #endif
...@@ -773,10 +773,10 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi) ...@@ -773,10 +773,10 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
return inf; return inf;
} }
static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *); static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct fb_info *);
static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state); static void set_ctrlr_state(struct sa1100_par *par, u_int state);
static inline void sa1100fb_schedule_task(struct sa1100fb_info *fbi, u_int state) static inline void sa1100fb_schedule_task(struct sa1100_par *par, u_int state)
{ {
unsigned long flags; unsigned long flags;
...@@ -789,43 +789,18 @@ static inline void sa1100fb_schedule_task(struct sa1100fb_info *fbi, u_int state ...@@ -789,43 +789,18 @@ static inline void sa1100fb_schedule_task(struct sa1100fb_info *fbi, u_int state
* 2. When we are blanking, but immediately unblank before we have * 2. When we are blanking, but immediately unblank before we have
* blanked. We do the "REENABLE" thing here as well, just to be sure. * blanked. We do the "REENABLE" thing here as well, just to be sure.
*/ */
if (fbi->task_state == C_ENABLE && state == C_REENABLE) if (par->task_state == C_ENABLE && state == C_REENABLE)
state = (u_int) -1; state = (u_int) -1;
if (fbi->task_state == C_DISABLE && state == C_ENABLE) if (par->task_state == C_DISABLE && state == C_ENABLE)
state = C_REENABLE; state = C_REENABLE;
if (state != (u_int)-1) { if (state != (u_int)-1) {
fbi->task_state = state; par->task_state = state;
schedule_task(&fbi->task); schedule_task(&par->task);
} }
local_irq_restore(flags); local_irq_restore(flags);
} }
/*
* Get the VAR structure pointer for the specified console
*/
static inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con)
{
return (con == info->currcon || con == -1) ? &info->var : &fb_display[con].var;
}
/*
* Get the DISPLAY structure pointer for the specified console
*/
static inline struct display *get_con_display(struct fb_info *info, int con)
{
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
return (con < 0) ? fbi->fb.disp : &fb_display[con];
}
/*
* Get the CMAP pointer for the specified console
*/
static inline struct fb_cmap *get_con_cmap(struct fb_info *info, int con)
{
return (con == info->currcon || con == -1) ? &info->cmap : &fb_display[con].cmap;
}
static inline u_int static inline u_int
chan_to_field(u_int chan, struct fb_bitfield *bf) chan_to_field(u_int chan, struct fb_bitfield *bf)
{ {
...@@ -838,19 +813,13 @@ chan_to_field(u_int chan, struct fb_bitfield *bf) ...@@ -838,19 +813,13 @@ chan_to_field(u_int chan, struct fb_bitfield *bf)
* Convert bits-per-pixel to a hardware palette PBS value. * Convert bits-per-pixel to a hardware palette PBS value.
*/ */
static inline u_int static inline u_int
palette_pbs(struct fb_var_screeninfo *var) palette_pbs(int bpp)
{ {
int ret = 0; int ret = 0;
switch (var->bits_per_pixel) { switch (bpp) {
#ifdef FBCON_HAS_CFB4
case 4: ret = 0 << 12; break; case 4: ret = 0 << 12; break;
#endif
#ifdef FBCON_HAS_CFB8
case 8: ret = 1 << 12; break; case 8: ret = 1 << 12; break;
#endif
#ifdef FBCON_HAS_CFB16
case 16: ret = 2 << 12; break; case 16: ret = 2 << 12; break;
#endif
} }
return ret; return ret;
} }
...@@ -859,18 +828,18 @@ static int ...@@ -859,18 +828,18 @@ static int
sa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, sa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
u_int trans, struct fb_info *info) u_int trans, struct fb_info *info)
{ {
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; struct sa1100_par *par = (struct sa1100_par *) info->par;
u_int val, ret = 1; u_int val, ret = 1;
if (regno < fbi->palette_size) { if (regno < par->palette_size) {
val = ((red >> 4) & 0xf00); val = ((red >> 4) & 0xf00);
val |= ((green >> 8) & 0x0f0); val |= ((green >> 8) & 0x0f0);
val |= ((blue >> 12) & 0x00f); val |= ((blue >> 12) & 0x00f);
if (regno == 0) if (regno == 0)
val |= palette_pbs(&fbi->fb.var); val |= palette_pbs(info->var.bits_per_pixel);
fbi->palette_cpu[regno] = val; par->palette_cpu[regno] = val;
ret = 0; ret = 0;
} }
return ret; return ret;
...@@ -880,8 +849,6 @@ static int ...@@ -880,8 +849,6 @@ static int
sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int trans, struct fb_info *info) u_int trans, struct fb_info *info)
{ {
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
struct display *disp = get_con_display(info, info->currcon);
u_int val; u_int val;
int ret = 1; int ret = 1;
...@@ -890,33 +857,34 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -890,33 +857,34 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* rather than the register number. The register number * rather than the register number. The register number
* is what you poke into the framebuffer to produce the * is what you poke into the framebuffer to produce the
* colour you requested. * colour you requested.
*/ *
if (disp->inverse) { if (inverse) {
red = 0xffff - red; red = 0xffff - red;
green = 0xffff - green; green = 0xffff - green;
blue = 0xffff - blue; blue = 0xffff - blue;
} }
*/
/* /*
* If greyscale is true, then we convert the RGB value * If greyscale is true, then we convert the RGB value
* to greyscale no mater what visual we are using. * to greyscale no mater what visual we are using.
*/ */
if (fbi->fb.var.grayscale) if (info->var.grayscale)
red = green = blue = (19595 * red + 38470 * green + red = green = blue = (19595 * red + 38470 * green +
7471 * blue) >> 16; 7471 * blue) >> 16;
switch (fbi->fb.disp->visual) { switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR: case FB_VISUAL_TRUECOLOR:
/* /*
* 12 or 16-bit True Colour. We encode the RGB value * 12 or 16-bit True Colour. We encode the RGB value
* according to the RGB bitfield information. * according to the RGB bitfield information.
*/ */
if (regno < 16) { if (regno < 16) {
u16 *pal = fbi->fb.pseudo_palette; u16 *pal = info->pseudo_palette;
val = chan_to_field(red, &fbi->fb.var.red); val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &fbi->fb.var.green); val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &fbi->fb.var.blue); val |= chan_to_field(blue, &info->var.blue);
pal[regno] = val; pal[regno] = val;
ret = 0; ret = 0;
...@@ -963,19 +931,20 @@ sa1100fb_display_dma_period(struct fb_var_screeninfo *var) ...@@ -963,19 +931,20 @@ sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
* bitfields, horizontal timing, vertical timing. * bitfields, horizontal timing, vertical timing.
*/ */
static int static int
sa1100fb_validate_var(struct fb_var_screeninfo *var, sa1100fb_check_var(struct fb_var_screeninfo *var,
struct sa1100fb_info *fbi) struct fb_info *info)
{ {
int ret = -EINVAL; struct sa1100_par *par = (struct sa1100_par *) info->par;
int rgbidx = RGB_16, ret = -EINVAL;
if (var->xres < MIN_XRES) if (var->xres < MIN_XRES)
var->xres = MIN_XRES; var->xres = MIN_XRES;
if (var->yres < MIN_YRES) if (var->yres < MIN_YRES)
var->yres = MIN_YRES; var->yres = MIN_YRES;
if (var->xres > fbi->max_xres) if (var->xres > par->max_xres)
var->xres = fbi->max_xres; var->xres = par->max_xres;
if (var->yres > fbi->max_yres) if (var->yres > par->max_yres)
var->yres = fbi->max_yres; var->yres = par->max_yres;
var->xres_virtual = var->xres_virtual =
var->xres_virtual < var->xres ? var->xres : var->xres_virtual; var->xres_virtual < var->xres ? var->xres : var->xres_virtual;
var->yres_virtual = var->yres_virtual =
...@@ -983,23 +952,22 @@ sa1100fb_validate_var(struct fb_var_screeninfo *var, ...@@ -983,23 +952,22 @@ sa1100fb_validate_var(struct fb_var_screeninfo *var,
DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB4 case 4: rgbidx = RGB_8; ret = 0; break;
case 4: ret = 0; break; case 8: rgbidx = RGB_8; ret = 0; break;
#endif case 16: rgbidx = RGB_16; ret = 0; break;
#ifdef FBCON_HAS_CFB8
case 8: ret = 0; break;
#endif
#ifdef FBCON_HAS_CFB16
case 16: ret = 0; break;
#endif
default: default:
break; break;
} }
var->red = par->rgb[rgbidx]->red;
var->green = par->rgb[rgbidx]->green;
var->blue = par->rgb[rgbidx]->blue;
var->transp = par->rgb[rgbidx]->transp;
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n",
sa1100fb_display_dma_period(var), sa1100fb_display_dma_period(var),
cpufreq_get(smp_processor_id())); cpufreq_get());
#endif #endif
return ret; return ret;
...@@ -1026,24 +994,26 @@ static inline void sa1100fb_set_truecolor(u_int is_true_color) ...@@ -1026,24 +994,26 @@ static inline void sa1100fb_set_truecolor(u_int is_true_color)
} }
} }
static void static int
sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi) sa1100fb_set_par(struct fb_info *info)
{ {
struct sa1100_par *par = (struct sa1100_par *) info->par;
u_long palette_mem_size; u_long palette_mem_size;
fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; par->bpp = info->var.bits_per_pixel;
par->palette_size = par->bpp == 8 ? 256 : 16;
palette_mem_size = fbi->palette_size * sizeof(u16); palette_mem_size = par->palette_size * sizeof(u16);
DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); par->palette_cpu = (u16 *)(par->map_cpu + PAGE_SIZE - palette_mem_size);
fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; par->palette_dma = par->map_dma + PAGE_SIZE - palette_mem_size;
fb_set_cmap(&fbi->fb.cmap, 1, &fbi->fb); fb_set_cmap(&info->cmap, 1, info);
/* Set board control register to handle new color depth */ /* Set board control register to handle new color depth */
sa1100fb_set_truecolor(var->bits_per_pixel >= 16); sa1100fb_set_truecolor(info->var.bits_per_pixel >= 16);
#ifdef CONFIG_SA1100_OMNIMETER #ifdef CONFIG_SA1100_OMNIMETER
#error Do we have to do this here? We already do it at init time. #error Do we have to do this here? We already do it at init time.
...@@ -1051,210 +1021,31 @@ sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi) ...@@ -1051,210 +1021,31 @@ sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi)
SetLCDContrast(DefaultLCDContrast); SetLCDContrast(DefaultLCDContrast);
#endif #endif
sa1100fb_activate_var(var, fbi); sa1100fb_activate_var(&info->var, info);
fbi->palette_cpu[0] = (fbi->palette_cpu[0] &
0xcfff) | palette_pbs(var);
}
/*
* sa1100fb_set_var():
* Set the user defined part of the display for the specified console
*/
static int
sa1100fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
struct fb_var_screeninfo *dvar = get_con_var(&fbi->fb, con);
struct display *display = get_con_display(&fbi->fb, con);
int err, chgvar = 0, rgbidx;
DPRINTK("set_var\n");
/*
* Decode var contents into a par structure, adjusting any
* out of range values.
*/
err = sa1100fb_validate_var(var, fbi);
if (err)
return err;
if (var->activate & FB_ACTIVATE_TEST)
return 0;
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
return -EINVAL;
if (dvar->xres != var->xres)
chgvar = 1;
if (dvar->yres != var->yres)
chgvar = 1;
if (dvar->xres_virtual != var->xres_virtual)
chgvar = 1;
if (dvar->yres_virtual != var->yres_virtual)
chgvar = 1;
if (dvar->bits_per_pixel != var->bits_per_pixel)
chgvar = 1;
if (con < 0)
chgvar = 0;
switch (var->bits_per_pixel) { par->palette_cpu[0] = (par->palette_cpu[0] &
#ifdef FBCON_HAS_CFB4 0xcfff) | palette_pbs(info->var.bits_per_pixel);
switch (info->var.bits_per_pixel) {
case 4: case 4:
if (fbi->cmap_static) if (par->cmap_static)
display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR; info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
else else
display->visual = FB_VISUAL_PSEUDOCOLOR; info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
display->line_length = var->xres / 2; info->fix.line_length = info->var.xres / 2;
display->dispsw = &fbcon_cfb4;
rgbidx = RGB_8;
break; break;
#endif
#ifdef FBCON_HAS_CFB8
case 8: case 8:
if (fbi->cmap_static) if (par->cmap_static)
display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR; info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
else else
display->visual = FB_VISUAL_PSEUDOCOLOR; info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
display->line_length = var->xres; info->fix.line_length = info->var.xres;
display->dispsw = &fbcon_cfb8;
rgbidx = RGB_8;
break; break;
#endif
#ifdef FBCON_HAS_CFB16
case 16: case 16:
display->visual = FB_VISUAL_TRUECOLOR; info->fix.visual = FB_VISUAL_TRUECOLOR;
display->line_length = var->xres * 2; info->fix.line_length = info->var.xres * 2;
display->dispsw = &fbcon_cfb16;
display->dispsw_data = fbi->fb.pseudo_palette;
rgbidx = RGB_16;
break;
#endif
default:
rgbidx = 0;
display->dispsw = &fbcon_dummy;
break; break;
} }
display->next_line = display->line_length;
display->type = fbi->fb.fix.type;
display->type_aux = fbi->fb.fix.type_aux;
display->ypanstep = fbi->fb.fix.ypanstep;
display->ywrapstep = fbi->fb.fix.ywrapstep;
display->can_soft_blank = 1;
display->inverse = fbi->cmap_inverse;
*dvar = *var;
dvar->activate &= ~FB_ACTIVATE_ALL;
/*
* Copy the RGB parameters for this display
* from the machine specific parameters.
*/
dvar->red = fbi->rgb[rgbidx]->red;
dvar->green = fbi->rgb[rgbidx]->green;
dvar->blue = fbi->rgb[rgbidx]->blue;
dvar->transp = fbi->rgb[rgbidx]->transp;
DPRINTK("RGBT length = %d:%d:%d:%d\n",
dvar->red.length, dvar->green.length, dvar->blue.length,
dvar->transp.length);
DPRINTK("RGBT offset = %d:%d:%d:%d\n",
dvar->red.offset, dvar->green.offset, dvar->blue.offset,
dvar->transp.offset);
/*
* Update the old var. The fbcon drivers still use this.
* Once they are using fbi->fb.var, this can be dropped.
*/
display->var = *dvar;
/*
* If we are setting all the virtual consoles, also set the
* defaults used to create new consoles.
*/
if (var->activate & FB_ACTIVATE_ALL)
fbi->fb.disp->var = *dvar;
/*
* If the console has changed and the console has defined
* a changevar function, call that function.
*/
if (chgvar && info && fbi->fb.changevar)
fbi->fb.changevar(con);
/* If the current console is selected, activate the new var. */
if (con != fbi->fb.currcon)
return 0;
sa1100fb_hw_set_var(dvar, fbi);
return 0;
}
static int
__do_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
struct fb_cmap *dcmap = get_con_cmap(info, con);
int err = 0;
if (con == -1)
con = info->currcon;
/* no colormap allocated? (we always have "this" colour map allocated) */
if (con >= 0)
err = fb_alloc_cmap(&fb_display[con].cmap, fbi->palette_size, 0);
if (!err && con == info->currcon)
err = fb_set_cmap(cmap, kspc, info);
if (!err)
fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
return err;
}
static int
sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
struct display *disp = get_con_display(info, con);
if (disp->visual == FB_VISUAL_TRUECOLOR ||
disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
return -EINVAL;
return __do_set_cmap(cmap, kspc, con, info);
}
static int
sa1100fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
struct display *display = get_con_display(info, con);
*fix = info->fix;
fix->line_length = display->line_length;
fix->visual = display->visual;
return 0;
}
static int
sa1100fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
*var = *get_con_var(info, con);
return 0;
}
static int
sa1100fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
{
struct fb_cmap *dcmap = get_con_cmap(info, con);
fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2);
return 0; return 0;
} }
...@@ -1295,21 +1086,21 @@ sa1100fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) ...@@ -1295,21 +1086,21 @@ sa1100fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
*/ */
static int sa1100fb_blank(int blank, struct fb_info *info) static int sa1100fb_blank(int blank, struct fb_info *info)
{ {
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; struct sa1100_par *par = (struct sa1100_par *) info->par;
int i; int i;
DPRINTK("sa1100fb_blank: blank=%d info->modename=%s\n", blank, DPRINTK("sa1100fb_blank: blank=%d fix.id=%s\n", blank,
fbi->fb.modename); info->fix.id);
switch (blank) { switch (blank) {
case VESA_POWERDOWN: case VESA_POWERDOWN:
case VESA_VSYNC_SUSPEND: case VESA_VSYNC_SUSPEND:
case VESA_HSYNC_SUSPEND: case VESA_HSYNC_SUSPEND:
if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR || if (info->disp->visual == FB_VISUAL_PSEUDOCOLOR ||
fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR) info->disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
for (i = 0; i < fbi->palette_size; i++) for (i = 0; i < par->palette_size; i++)
sa1100fb_setpalettereg(i, 0, 0, 0, 0, info); sa1100fb_setpalettereg(i, 0, 0, 0, 0, info);
sa1100fb_schedule_task(fbi, C_DISABLE); sa1100fb_schedule_task(par, C_DISABLE);
if (sa1100fb_blank_helper) if (sa1100fb_blank_helper)
sa1100fb_blank_helper(blank); sa1100fb_blank_helper(blank);
break; break;
...@@ -1317,83 +1108,30 @@ static int sa1100fb_blank(int blank, struct fb_info *info) ...@@ -1317,83 +1108,30 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
case VESA_NO_BLANKING: case VESA_NO_BLANKING:
if (sa1100fb_blank_helper) if (sa1100fb_blank_helper)
sa1100fb_blank_helper(blank); sa1100fb_blank_helper(blank);
if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR || if (info->disp->visual == FB_VISUAL_PSEUDOCOLOR ||
fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR) info->disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
fb_set_cmap(&fbi->fb.cmap, 1, info); fb_set_cmap(&info->cmap, 1, info);
sa1100fb_schedule_task(fbi, C_ENABLE); sa1100fb_schedule_task(par, C_ENABLE);
} }
return 0; return 0;
} }
static struct fb_ops sa1100fb_ops = { static struct fb_ops sa1100fb_ops = {
owner: THIS_MODULE, owner: THIS_MODULE,
fb_get_fix: sa1100fb_get_fix, fb_get_fix: gen_get_fix,
fb_get_var: sa1100fb_get_var, fb_get_var: gen_get_var,
fb_set_var: sa1100fb_set_var, fb_set_var: gen_set_var,
fb_get_cmap: sa1100fb_get_cmap, fb_get_cmap: gen_get_cmap,
fb_set_cmap: sa1100fb_set_cmap, fb_set_cmap: gen_set_cmap,
fb_check_var: sa1100fb_check_var,
fb_set_par: sa1100fb_set_par,
fb_setcolreg: sa1100fb_setcolreg, fb_setcolreg: sa1100fb_setcolreg,
fb_blank: sa1100fb_blank, fb_blank: sa1100fb_blank,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
}; };
/*
* sa1100fb_switch():
* Change to the specified console. Palette and video mode
* are changed to the console's stored parameters.
*
* Uh oh, this can be called from a tasklet (IRQ)
*/
static int sa1100fb_switch(int con, struct fb_info *info)
{
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
struct display *disp;
struct fb_cmap *cmap;
DPRINTK("con=%d info->modename=%s\n", con, fbi->fb.modename);
if (con == info->currcon)
return 0;
if (info->currcon >= 0) {
disp = fb_display + info->currcon;
/*
* Save the old colormap and video mode.
*/
disp->var = fbi->fb.var;
if (disp->cmap.len)
fb_copy_cmap(&fbi->fb.cmap, &disp->cmap, 0);
}
info->currcon = con;
disp = fb_display + con;
/*
* Make sure that our colourmap contains 256 entries.
*/
fb_alloc_cmap(&fbi->fb.cmap, 256, 0);
if (disp->cmap.len)
cmap = &disp->cmap;
else
cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
fb_copy_cmap(cmap, &fbi->fb.cmap, 0);
fbi->fb.var = disp->var;
fbi->fb.var.activate = FB_ACTIVATE_NOW;
sa1100fb_set_var(&fbi->fb.var, con, info);
return 0;
}
static int sa1100fb_updatevar(int con, struct fb_info *info)
{
DPRINTK("entered\n");
return 0;
}
/* /*
* Calculate the PCD value from the clock rate (in picoseconds). * Calculate the PCD value from the clock rate (in picoseconds).
* We take account of the PPCR clock setting. * We take account of the PPCR clock setting.
...@@ -1403,7 +1141,7 @@ static inline int get_pcd(unsigned int pixclock) ...@@ -1403,7 +1141,7 @@ static inline int get_pcd(unsigned int pixclock)
unsigned int pcd; unsigned int pcd;
if (pixclock) { if (pixclock) {
pcd = cpufreq_get(0) / 100; pcd = cpufreq_get() / 100;
pcd *= pixclock; pcd *= pixclock;
pcd /= 10000000; pcd /= 10000000;
pcd += 1; /* make up for integer math truncations */ pcd += 1; /* make up for integer math truncations */
...@@ -1433,8 +1171,9 @@ static inline int get_pcd(unsigned int pixclock) ...@@ -1433,8 +1171,9 @@ static inline int get_pcd(unsigned int pixclock)
* Configures LCD Controller based on entries in var parameter. Settings are * Configures LCD Controller based on entries in var parameter. Settings are
* only written to the controller if changes were made. * only written to the controller if changes were made.
*/ */
static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi) static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
{ {
struct sa1100_par *par = (struct sa1100_par *) info->par;
struct sa1100fb_lcd_reg new_regs; struct sa1100fb_lcd_reg new_regs;
u_int half_screen_size, yres, pcd = get_pcd(var->pixclock); u_int half_screen_size, yres, pcd = get_pcd(var->pixclock);
u_long flags; u_long flags;
...@@ -1451,31 +1190,31 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -1451,31 +1190,31 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
#if DEBUG_VAR #if DEBUG_VAR
if (var->xres < 16 || var->xres > 1024) if (var->xres < 16 || var->xres > 1024)
printk(KERN_ERR "%s: invalid xres %d\n", printk(KERN_ERR "%s: invalid xres %d\n",
fbi->fb.fix.id, var->xres); info->fix.id, var->xres);
if (var->hsync_len < 1 || var->hsync_len > 64) if (var->hsync_len < 1 || var->hsync_len > 64)
printk(KERN_ERR "%s: invalid hsync_len %d\n", printk(KERN_ERR "%s: invalid hsync_len %d\n",
fbi->fb.fix.id, var->hsync_len); info->fix.id, var->hsync_len);
if (var->left_margin < 1 || var->left_margin > 255) if (var->left_margin < 1 || var->left_margin > 255)
printk(KERN_ERR "%s: invalid left_margin %d\n", printk(KERN_ERR "%s: invalid left_margin %d\n",
fbi->fb.fix.id, var->left_margin); info->fix.id, var->left_margin);
if (var->right_margin < 1 || var->right_margin > 255) if (var->right_margin < 1 || var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n", printk(KERN_ERR "%s: invalid right_margin %d\n",
fbi->fb.fix.id, var->right_margin); info->fix.id, var->right_margin);
if (var->yres < 1 || var->yres > 1024) if (var->yres < 1 || var->yres > 1024)
printk(KERN_ERR "%s: invalid yres %d\n", printk(KERN_ERR "%s: invalid yres %d\n",
fbi->fb.fix.id, var->yres); info->fix.id, var->yres);
if (var->vsync_len < 1 || var->vsync_len > 64) if (var->vsync_len < 1 || var->vsync_len > 64)
printk(KERN_ERR "%s: invalid vsync_len %d\n", printk(KERN_ERR "%s: invalid vsync_len %d\n",
fbi->fb.fix.id, var->vsync_len); info->fix.id, var->vsync_len);
if (var->upper_margin < 0 || var->upper_margin > 255) if (var->upper_margin < 0 || var->upper_margin > 255)
printk(KERN_ERR "%s: invalid upper_margin %d\n", printk(KERN_ERR "%s: invalid upper_margin %d\n",
fbi->fb.fix.id, var->upper_margin); info->fix.id, var->upper_margin);
if (var->lower_margin < 0 || var->lower_margin > 255) if (var->lower_margin < 0 || var->lower_margin > 255)
printk(KERN_ERR "%s: invalid lower_margin %d\n", printk(KERN_ERR "%s: invalid lower_margin %d\n",
fbi->fb.fix.id, var->lower_margin); info->fix.id, var->lower_margin);
#endif #endif
new_regs.lccr0 = fbi->lccr0 | new_regs.lccr0 = par->lccr0 |
LCCR0_LEN | LCCR0_LDM | LCCR0_BAM | LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0); LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
...@@ -1490,7 +1229,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -1490,7 +1229,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
* the YRES parameter. * the YRES parameter.
*/ */
yres = var->yres; yres = var->yres;
if (fbi->lccr0 & LCCR0_Dual) if (par->lccr0 & LCCR0_Dual)
yres /= 2; yres /= 2;
new_regs.lccr2 = new_regs.lccr2 =
...@@ -1499,7 +1238,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -1499,7 +1238,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
LCCR2_BegFrmDel(var->upper_margin) + LCCR2_BegFrmDel(var->upper_margin) +
LCCR2_EndFrmDel(var->lower_margin); LCCR2_EndFrmDel(var->lower_margin);
new_regs.lccr3 = fbi->lccr3 | new_regs.lccr3 = par->lccr3 |
(var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
(var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL) | (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL) |
LCCR3_ACBsCntOff; LCCR3_ACBsCntOff;
...@@ -1517,23 +1256,23 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -1517,23 +1256,23 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
/* Update shadow copy atomically */ /* Update shadow copy atomically */
local_irq_save(flags); local_irq_save(flags);
fbi->dbar1 = fbi->palette_dma; par->dbar1 = par->palette_dma;
fbi->dbar2 = fbi->screen_dma + half_screen_size; par->dbar2 = par->screen_dma + half_screen_size;
fbi->reg_lccr0 = new_regs.lccr0; par->reg_lccr0 = new_regs.lccr0;
fbi->reg_lccr1 = new_regs.lccr1; par->reg_lccr1 = new_regs.lccr1;
fbi->reg_lccr2 = new_regs.lccr2; par->reg_lccr2 = new_regs.lccr2;
fbi->reg_lccr3 = new_regs.lccr3; par->reg_lccr3 = new_regs.lccr3;
local_irq_restore(flags); local_irq_restore(flags);
/* /*
* Only update the registers if the controller is enabled * Only update the registers if the controller is enabled
* and something has changed. * and something has changed.
*/ */
if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || if ((LCCR0 != par->reg_lccr0) || (LCCR1 != par->reg_lccr1) ||
(LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || (LCCR2 != par->reg_lccr2) || (LCCR3 != par->reg_lccr3) ||
(DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2)) (DBAR1 != par->dbar1) || (DBAR2 != par->dbar2))
sa1100fb_schedule_task(fbi, C_REENABLE); sa1100fb_schedule_task(par, C_REENABLE);
return 0; return 0;
} }
...@@ -1550,7 +1289,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -1550,7 +1289,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
* Also, I'm expecting that the backlight stuff should * Also, I'm expecting that the backlight stuff should
* be handled differently. * be handled differently.
*/ */
static inline void sa1100fb_backlight_on(struct sa1100fb_info *fbi) static inline void sa1100fb_backlight_on(struct sa1100_par *par)
{ {
DPRINTK("backlight on\n"); DPRINTK("backlight on\n");
...@@ -1563,7 +1302,7 @@ static inline void sa1100fb_backlight_on(struct sa1100fb_info *fbi) ...@@ -1563,7 +1302,7 @@ static inline void sa1100fb_backlight_on(struct sa1100fb_info *fbi)
* Also, I'm expecting that the backlight stuff should * Also, I'm expecting that the backlight stuff should
* be handled differently. * be handled differently.
*/ */
static inline void sa1100fb_backlight_off(struct sa1100fb_info *fbi) static inline void sa1100fb_backlight_off(struct sa1100_par *par)
{ {
DPRINTK("backlight off\n"); DPRINTK("backlight off\n");
...@@ -1571,7 +1310,7 @@ static inline void sa1100fb_backlight_off(struct sa1100fb_info *fbi) ...@@ -1571,7 +1310,7 @@ static inline void sa1100fb_backlight_off(struct sa1100fb_info *fbi)
sa1100fb_backlight_power(0); sa1100fb_backlight_power(0);
} }
static inline void sa1100fb_power_up_lcd(struct sa1100fb_info *fbi) static inline void sa1100fb_power_up_lcd(struct sa1100_par *par)
{ {
DPRINTK("LCD power on\n"); DPRINTK("LCD power on\n");
...@@ -1586,7 +1325,7 @@ static inline void sa1100fb_power_up_lcd(struct sa1100fb_info *fbi) ...@@ -1586,7 +1325,7 @@ static inline void sa1100fb_power_up_lcd(struct sa1100fb_info *fbi)
#endif #endif
} }
static inline void sa1100fb_power_down_lcd(struct sa1100fb_info *fbi) static inline void sa1100fb_power_down_lcd(struct sa1100_par *par)
{ {
DPRINTK("LCD power off\n"); DPRINTK("LCD power off\n");
...@@ -1601,7 +1340,7 @@ static inline void sa1100fb_power_down_lcd(struct sa1100fb_info *fbi) ...@@ -1601,7 +1340,7 @@ static inline void sa1100fb_power_down_lcd(struct sa1100fb_info *fbi)
#endif #endif
} }
static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) static void sa1100fb_setup_gpio(struct sa1100_par *par)
{ {
u_int mask = 0; u_int mask = 0;
...@@ -1617,12 +1356,12 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) ...@@ -1617,12 +1356,12 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
* clear LDD15 to 12 for 4 or 8bpp modes with active * clear LDD15 to 12 for 4 or 8bpp modes with active
* panels. * panels.
*/ */
if ((fbi->reg_lccr0 & LCCR0_CMS) == LCCR0_Color && if ((par->reg_lccr0 & LCCR0_CMS) == LCCR0_Color &&
(fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) { (par->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) != 0) {
mask = GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; mask = GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
if (fbi->fb.var.bits_per_pixel > 8 || if (par->bpp > 8 ||
(fbi->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) == LCCR0_Dual) (par->reg_lccr0 & (LCCR0_Dual|LCCR0_Act)) == LCCR0_Dual)
mask |= GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12; mask |= GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12;
} }
...@@ -1666,23 +1405,23 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) ...@@ -1666,23 +1405,23 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
} }
} }
static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) static void sa1100fb_enable_controller(struct sa1100_par *par)
{ {
DPRINTK("Enabling LCD controller\n"); DPRINTK("Enabling LCD controller\n");
/* /*
* Make sure the mode bits are present in the first palette entry * Make sure the mode bits are present in the first palette entry
*/ */
fbi->palette_cpu[0] &= 0xcfff; par->palette_cpu[0] &= 0xcfff;
fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); par->palette_cpu[0] |= palette_pbs(par->bpp);
/* Sequence from 11.7.10 */ /* Sequence from 11.7.10 */
LCCR3 = fbi->reg_lccr3; LCCR3 = par->reg_lccr3;
LCCR2 = fbi->reg_lccr2; LCCR2 = par->reg_lccr2;
LCCR1 = fbi->reg_lccr1; LCCR1 = par->reg_lccr1;
LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN; LCCR0 = par->reg_lccr0 & ~LCCR0_LEN;
DBAR1 = fbi->dbar1; DBAR1 = par->dbar1;
DBAR2 = fbi->dbar2; DBAR2 = par->dbar2;
LCCR0 |= LCCR0_LEN; LCCR0 |= LCCR0_LEN;
#ifdef CONFIG_SA1100_GRAPHICSCLIENT #ifdef CONFIG_SA1100_GRAPHICSCLIENT
...@@ -1708,7 +1447,7 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) ...@@ -1708,7 +1447,7 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
DPRINTK("LCCR3 = 0x%08x\n", LCCR3); DPRINTK("LCCR3 = 0x%08x\n", LCCR3);
} }
static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) static void sa1100fb_disable_controller(struct sa1100_par *par)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -1742,7 +1481,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) ...@@ -1742,7 +1481,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
GPCR |= SHANNON_GPIO_DISP_EN; GPCR |= SHANNON_GPIO_DISP_EN;
} }
add_wait_queue(&fbi->ctrlr_wait, &wait); add_wait_queue(&par->ctrlr_wait, &wait);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
LCSR = 0xffffffff; /* Clear LCD Status Register */ LCSR = 0xffffffff; /* Clear LCD Status Register */
...@@ -1751,7 +1490,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) ...@@ -1751,7 +1490,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
schedule_timeout(20 * HZ / 1000); schedule_timeout(20 * HZ / 1000);
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
remove_wait_queue(&fbi->ctrlr_wait, &wait); remove_wait_queue(&par->ctrlr_wait, &wait);
} }
/* /*
...@@ -1759,12 +1498,12 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) ...@@ -1759,12 +1498,12 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
*/ */
static void sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs) static void sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct sa1100fb_info *fbi = dev_id; struct sa1100_par *par = dev_id;
unsigned int lcsr = LCSR; unsigned int lcsr = LCSR;
if (lcsr & LCSR_LDD) { if (lcsr & LCSR_LDD) {
LCCR0 |= LCCR0_LDM; LCCR0 |= LCCR0_LDM;
wake_up(&fbi->ctrlr_wait); wake_up(&par->ctrlr_wait);
} }
LCSR = lcsr; LCSR = lcsr;
...@@ -1775,13 +1514,13 @@ static void sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1775,13 +1514,13 @@ static void sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
* sleep when disabling the LCD controller, or if we get two contending * sleep when disabling the LCD controller, or if we get two contending
* processes trying to alter state. * processes trying to alter state.
*/ */
static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) static void set_ctrlr_state(struct sa1100_par *par, u_int state)
{ {
u_int old_state; u_int old_state;
down(&fbi->ctrlr_sem); down(&par->ctrlr_sem);
old_state = fbi->state; old_state = par->state;
switch (state) { switch (state) {
case C_DISABLE_CLKCHANGE: case C_DISABLE_CLKCHANGE:
...@@ -1790,8 +1529,8 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1790,8 +1529,8 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* controller is already disabled, then do nothing. * controller is already disabled, then do nothing.
*/ */
if (old_state != C_DISABLE && old_state != C_DISABLE_PM) { if (old_state != C_DISABLE && old_state != C_DISABLE_PM) {
fbi->state = state; par->state = state;
sa1100fb_disable_controller(fbi); sa1100fb_disable_controller(par);
} }
break; break;
...@@ -1801,12 +1540,12 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1801,12 +1540,12 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* Disable controller * Disable controller
*/ */
if (old_state != C_DISABLE) { if (old_state != C_DISABLE) {
fbi->state = state; par->state = state;
sa1100fb_backlight_off(fbi); sa1100fb_backlight_off(par);
if (old_state != C_DISABLE_CLKCHANGE) if (old_state != C_DISABLE_CLKCHANGE)
sa1100fb_disable_controller(fbi); sa1100fb_disable_controller(par);
sa1100fb_power_down_lcd(fbi); sa1100fb_power_down_lcd(par);
} }
break; break;
...@@ -1816,8 +1555,8 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1816,8 +1555,8 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* do this if we were disabled for the clock change. * do this if we were disabled for the clock change.
*/ */
if (old_state == C_DISABLE_CLKCHANGE) { if (old_state == C_DISABLE_CLKCHANGE) {
fbi->state = C_ENABLE; par->state = C_ENABLE;
sa1100fb_enable_controller(fbi); sa1100fb_enable_controller(par);
} }
break; break;
...@@ -1828,9 +1567,9 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1828,9 +1567,9 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* registers. * registers.
*/ */
if (old_state == C_ENABLE) { if (old_state == C_ENABLE) {
sa1100fb_disable_controller(fbi); sa1100fb_disable_controller(par);
sa1100fb_setup_gpio(fbi); sa1100fb_setup_gpio(par);
sa1100fb_enable_controller(fbi); sa1100fb_enable_controller(par);
} }
break; break;
...@@ -1850,15 +1589,15 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1850,15 +1589,15 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
* turn on the backlight. * turn on the backlight.
*/ */
if (old_state != C_ENABLE) { if (old_state != C_ENABLE) {
fbi->state = C_ENABLE; par->state = C_ENABLE;
sa1100fb_setup_gpio(fbi); sa1100fb_setup_gpio(par);
sa1100fb_power_up_lcd(fbi); sa1100fb_power_up_lcd(par);
sa1100fb_enable_controller(fbi); sa1100fb_enable_controller(par);
sa1100fb_backlight_on(fbi); sa1100fb_backlight_on(par);
} }
break; break;
} }
up(&fbi->ctrlr_sem); up(&par->ctrlr_sem);
} }
/* /*
...@@ -1867,10 +1606,12 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state) ...@@ -1867,10 +1606,12 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
*/ */
static void sa1100fb_task(void *dummy) static void sa1100fb_task(void *dummy)
{ {
struct sa1100fb_info *fbi = dummy; struct fb_info *info = dummy;
u_int state = xchg(&fbi->task_state, -1); struct sa1100_par *par = (struct sa1100_par *) info->par;
set_ctrlr_state(fbi, state); u_int state = xchg(&par->task_state, -1);
set_ctrlr_state(par, state);
} }
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
...@@ -1879,7 +1620,7 @@ static void sa1100fb_task(void *dummy) ...@@ -1879,7 +1620,7 @@ static void sa1100fb_task(void *dummy)
* This, together with the SDRAM bandwidth defines the slowest CPU * This, together with the SDRAM bandwidth defines the slowest CPU
* frequency that can be selected. * frequency that can be selected.
*/ */
static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) static unsigned int sa1100fb_min_dma_period(struct fb_info *info)
{ {
unsigned int min_period = (unsigned int)-1; unsigned int min_period = (unsigned int)-1;
int i; int i;
...@@ -1890,13 +1631,13 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) ...@@ -1890,13 +1631,13 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)
/* /*
* Do we own this display? * Do we own this display?
*/ */
if (fb_display[i].fb_info != &fbi->fb) if (fb_display[i].fb_info != info)
continue; continue;
/* /*
* Ok, calculate its DMA period * Ok, calculate its DMA period
*/ */
period = sa1100fb_display_dma_period(get_con_var(&fbi->fb, i)); period = sa1100fb_display_dma_period(&info->var);
if (period < min_period) if (period < min_period)
min_period = period; min_period = period;
} }
...@@ -1913,26 +1654,27 @@ static int ...@@ -1913,26 +1654,27 @@ static int
sa1100fb_clkchg_notifier(struct notifier_block *nb, unsigned long val, sa1100fb_clkchg_notifier(struct notifier_block *nb, unsigned long val,
void *data) void *data)
{ {
struct sa1100fb_info *fbi = TO_INF(nb, clockchg); struct fb_info *info = TO_INF(nb, clockchg);
struct cpufreq_minmax *mm = data; struct sa1100_par *par = (struct sa1100_par *) info->par;
struct cpufreq_freqs *mm = data;
u_int pcd; u_int pcd;
switch (val) { switch (val) {
case CPUFREQ_MINMAX: case CPUFREQ_MINMAX:
printk(KERN_DEBUG "min dma period: %d ps, old clock %d kHz, " printk(KERN_DEBUG "min dma period: %d ps, old clock %d kHz, "
"new clock %d kHz\n", sa1100fb_min_dma_period(fbi), "new clock %d kHz\n", sa1100fb_min_dma_period(info),
mm->cur_freq, mm->new_freq); mm->cur, mm->new);
/* todo: fill in min/max values */ /* todo: fill in min/max values */
break; break;
case CPUFREQ_PRECHANGE: case CPUFREQ_PRECHANGE:
set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); set_ctrlr_state(par, C_DISABLE_CLKCHANGE);
break; break;
case CPUFREQ_POSTCHANGE: case CPUFREQ_POSTCHANGE:
pcd = get_pcd(fbi->fb.var.pixclock); pcd = get_pcd(info->var.pixclock);
fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); par->reg_lccr3 = (par->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); set_ctrlr_state(par, C_ENABLE_CLKCHANGE);
break; break;
} }
return 0; return 0;
...@@ -1947,7 +1689,7 @@ sa1100fb_clkchg_notifier(struct notifier_block *nb, unsigned long val, ...@@ -1947,7 +1689,7 @@ sa1100fb_clkchg_notifier(struct notifier_block *nb, unsigned long val,
static int static int
sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
{ {
struct sa1100fb_info *fbi = pm_dev->data; struct sa1100_par *par = pm_dev->data;
DPRINTK("pm_callback: %d\n", req); DPRINTK("pm_callback: %d\n", req);
...@@ -1956,10 +1698,10 @@ sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) ...@@ -1956,10 +1698,10 @@ sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
if (state == 0) { if (state == 0) {
/* Enter D0. */ /* Enter D0. */
set_ctrlr_state(fbi, C_ENABLE_PM); set_ctrlr_state(par, C_ENABLE_PM);
} else { } else {
/* Enter D1-D3. Disable the LCD controller. */ /* Enter D1-D3. Disable the LCD controller. */
set_ctrlr_state(fbi, C_DISABLE_PM); set_ctrlr_state(par, C_DISABLE_PM);
} }
} }
DPRINTK("done\n"); DPRINTK("done\n");
...@@ -1975,133 +1717,142 @@ sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) ...@@ -1975,133 +1717,142 @@ sa1100fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
* cache. Once this area is remapped, all virtual memory * cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region. * access to the video memory should occur at the new region.
*/ */
static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) static int __init sa1100fb_map_video_memory(struct fb_info *info)
{ {
struct sa1100_par *par= (struct sa1100_par *) info->par;
/* /*
* We reserve one page for the palette, plus the size * We reserve one page for the palette, plus the size
* of the framebuffer. * of the framebuffer.
*/ */
fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE); par->map_size = PAGE_ALIGN(info->fix.smem_len + PAGE_SIZE);
fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size, par->map_cpu = consistent_alloc(GFP_KERNEL, par->map_size,
&fbi->map_dma); &par->map_dma);
if (fbi->map_cpu) { if (par->map_cpu) {
fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE; info->screen_base = par->map_cpu + PAGE_SIZE;
fbi->screen_dma = fbi->map_dma + PAGE_SIZE; par->screen_dma = par->map_dma + PAGE_SIZE;
fbi->fb.fix.smem_start = fbi->screen_dma; info->fix.smem_start = par->screen_dma;
} }
return fbi->map_cpu ? 0 : -ENOMEM; return par->map_cpu ? 0 : -ENOMEM;
} }
/* Fake monspecs to fill in fbinfo structure */ /* Fake monspecs to fill in infonfo structure */
static struct fb_monspecs monspecs __initdata = { static struct fb_monspecs monspecs __initdata = {
30000, 70000, 50, 65, 0 /* Generic */ 30000, 70000, 50, 65, 0 /* Generic */
}; };
static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void) static struct fb_info * __init sa1100fb_init_fbinfo(void)
{ {
struct sa1100fb_mach_info *inf; struct sa1100fb_mach_info *inf;
struct sa1100fb_info *fbi; struct fb_info *info;
struct sa1100_par *par;
fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(struct display) + info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
sizeof(u16) * 16, GFP_KERNEL); sizeof(u16) * 16, GFP_KERNEL);
if (!fbi) if (!info)
return NULL; return NULL;
memset(fbi, 0, sizeof(struct sa1100fb_info) + sizeof(struct display)); memset(info, 0, sizeof(struct fb_info) + sizeof(struct display));
fbi->fb.currcon = -1; par = kmalloc(sizeof(struct sa1100_par), GFP_KERNEL);
memset(par, 0, sizeof(struct sa1100_par));
strcpy(fbi->fb.fix.id, SA1100_NAME);
info->currcon = -1;
fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
fbi->fb.fix.type_aux = 0; strcpy(info->fix.id, SA1100_NAME);
fbi->fb.fix.xpanstep = 0;
fbi->fb.fix.ypanstep = 0; info->fix.type = FB_TYPE_PACKED_PIXELS;
fbi->fb.fix.ywrapstep = 0; info->fix.type_aux = 0;
fbi->fb.fix.accel = FB_ACCEL_NONE; info->fix.xpanstep = 0;
info->fix.ypanstep = 0;
fbi->fb.var.nonstd = 0; info->fix.ywrapstep = 0;
fbi->fb.var.activate = FB_ACTIVATE_NOW; info->fix.accel = FB_ACCEL_NONE;
fbi->fb.var.height = -1;
fbi->fb.var.width = -1; info->var.nonstd = 0;
fbi->fb.var.accel_flags = 0; info->var.activate = FB_ACTIVATE_NOW;
fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; info->var.height = -1;
info->var.width = -1;
strcpy(fbi->fb.modename, SA1100_NAME); info->var.accel_flags = 0;
strcpy(fbi->fb.fontname, "Acorn8x8"); info->var.vmode = FB_VMODE_NONINTERLACED;
fbi->fb.fbops = &sa1100fb_ops; strcpy(info->modename, info->fix.id);
fbi->fb.changevar = NULL; strcpy(info->fontname, "Acorn8x8");
fbi->fb.switch_con = sa1100fb_switch;
fbi->fb.updatevar = sa1100fb_updatevar; info->fbops = &sa1100fb_ops;
fbi->fb.flags = FBINFO_FLAG_DEFAULT; info->changevar = NULL;
fbi->fb.node = NODEV; info->switch_con = gen_switch;
fbi->fb.monspecs = monspecs; info->updatevar = gen_update_var;
fbi->fb.currcon = -1; info->flags = FBINFO_FLAG_DEFAULT;
fbi->fb.disp = (struct display *)(fbi + 1); info->node = NODEV;
fbi->fb.pseudo_palette = (void *)(fbi->fb.disp + 1); info->monspecs = monspecs;
info->currcon = -1;
fbi->rgb[RGB_8] = &rgb_8; info->disp = (struct display *)(info + 1);
fbi->rgb[RGB_16] = &def_rgb_16; info->pseudo_palette = (void *)(info->disp + 1);
info->par = par;
inf = sa1100fb_get_machine_info(fbi);
par->rgb[RGB_8] = &rgb_8;
fbi->max_xres = inf->xres; par->rgb[RGB_16] = &def_rgb_16;
fbi->fb.var.xres = inf->xres;
fbi->fb.var.xres_virtual = inf->xres; inf = sa1100fb_get_machine_info(par);
fbi->max_yres = inf->yres;
fbi->fb.var.yres = inf->yres; par->max_xres = inf->xres;
fbi->fb.var.yres_virtual = inf->yres; info->var.xres = inf->xres;
fbi->max_bpp = inf->bpp; info->var.xres_virtual = inf->xres;
fbi->fb.var.bits_per_pixel = inf->bpp; par->max_yres = inf->yres;
fbi->fb.var.pixclock = inf->pixclock; info->var.yres = inf->yres;
fbi->fb.var.hsync_len = inf->hsync_len; info->var.yres_virtual = inf->yres;
fbi->fb.var.left_margin = inf->left_margin; par->max_bpp = inf->bpp;
fbi->fb.var.right_margin = inf->right_margin; info->var.bits_per_pixel = inf->bpp;
fbi->fb.var.vsync_len = inf->vsync_len; info->var.pixclock = inf->pixclock;
fbi->fb.var.upper_margin = inf->upper_margin; info->var.hsync_len = inf->hsync_len;
fbi->fb.var.lower_margin = inf->lower_margin; info->var.left_margin = inf->left_margin;
fbi->fb.var.sync = inf->sync; info->var.right_margin = inf->right_margin;
fbi->fb.var.grayscale = inf->cmap_greyscale; info->var.vsync_len = inf->vsync_len;
fbi->cmap_inverse = inf->cmap_inverse; info->var.upper_margin = inf->upper_margin;
fbi->cmap_static = inf->cmap_static; info->var.lower_margin = inf->lower_margin;
fbi->lccr0 = inf->lccr0; info->var.sync = inf->sync;
fbi->lccr3 = inf->lccr3; info->var.grayscale = inf->cmap_greyscale;
fbi->state = C_DISABLE; par->cmap_inverse = inf->cmap_inverse;
fbi->task_state = (u_char)-1; par->cmap_static = inf->cmap_static;
fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * par->lccr0 = inf->lccr0;
fbi->max_bpp / 8; par->lccr3 = inf->lccr3;
par->state = C_DISABLE;
init_waitqueue_head(&fbi->ctrlr_wait); par->task_state = (u_char)-1;
INIT_TQUEUE(&fbi->task, sa1100fb_task, fbi); info->fix.smem_len = par->max_xres * par->max_yres *
init_MUTEX(&fbi->ctrlr_sem); par->max_bpp / 8;
return fbi; init_waitqueue_head(&par->ctrlr_wait);
INIT_TQUEUE(&par->task, sa1100fb_task, info);
init_MUTEX(&par->ctrlr_sem);
fb_alloc_cmap(&info->cmap, 256, 0);
return info;
} }
int __init sa1100fb_init(void) int __init sa1100fb_init(void)
{ {
struct sa1100fb_info *fbi; struct fb_info *info;
struct sa1100_par *par;
int ret; int ret;
if (!request_mem_region(0xb0100000, 0x10000, "LCD")) if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
return -EBUSY; return -EBUSY;
fbi = sa1100fb_init_fbinfo(); info = sa1100fb_init_fbinfo();
ret = -ENOMEM; ret = -ENOMEM;
if (!fbi) if (!info)
goto failed; goto failed;
/* Initialize video memory */ /* Initialize video memory */
ret = sa1100fb_map_video_memory(fbi); ret = sa1100fb_map_video_memory(info);
if (ret) if (ret)
goto failed; goto failed;
ret = request_irq(IRQ_LCD, sa1100fb_handle_irq, SA_INTERRUPT, ret = request_irq(IRQ_LCD, sa1100fb_handle_irq, SA_INTERRUPT,
"LCD", fbi); "LCD", info->par);
if (ret) { if (ret) {
printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
goto failed; goto failed;
...@@ -2122,30 +1873,32 @@ int __init sa1100fb_init(void) ...@@ -2122,30 +1873,32 @@ int __init sa1100fb_init(void)
} }
#endif #endif
sa1100fb_set_var(&fbi->fb.var, -1, &fbi->fb); gen_set_var(&info->var, -1, info);
ret = register_framebuffer(&fbi->fb); ret = register_framebuffer(info);
if (ret < 0) if (ret < 0)
goto failed; goto failed;
par = info->par;
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* /*
* Note that the console registers this as well, but we want to * Note that the console registers this as well, but we want to
* power down the display prior to sleeping. * power down the display prior to sleeping.
*/ */
fbi->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, sa1100fb_pm_callback); par->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, sa1100fb_pm_callback);
if (fbi->pm) if (par->pm)
fbi->pm->data = fbi; par->pm->data = par;
#endif #endif
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
fbi->clockchg.notifier_call = sa1100fb_clkchg_notifier; info->clockchg.notifier_call = sa1100fb_clkchg_notifier;
cpufreq_register_notifier(&fbi->clockchg); cpufreq_register_notifier(&info->clockchg);
#endif #endif
/* /*
* Ok, now enable the LCD controller * Ok, now enable the LCD controller
*/ */
set_ctrlr_state(fbi, C_ENABLE); set_ctrlr_state(par, C_ENABLE);
/* This driver cannot be unloaded at the moment */ /* This driver cannot be unloaded at the moment */
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
...@@ -2153,8 +1906,8 @@ int __init sa1100fb_init(void) ...@@ -2153,8 +1906,8 @@ int __init sa1100fb_init(void)
return 0; return 0;
failed: failed:
if (fbi) if (info)
kfree(fbi); kfree(info);
release_mem_region(0xb0100000, 0x10000); release_mem_region(0xb0100000, 0x10000);
return ret; return ret;
} }
......
...@@ -61,13 +61,13 @@ struct sa1100fb_lcd_reg { ...@@ -61,13 +61,13 @@ struct sa1100fb_lcd_reg {
#define RGB_16 (1) #define RGB_16 (1)
#define NR_RGB 2 #define NR_RGB 2
struct sa1100fb_info { struct sa1100_par {
struct fb_info fb;
struct sa1100fb_rgb *rgb[NR_RGB]; struct sa1100fb_rgb *rgb[NR_RGB];
u_int max_bpp;
u_int max_xres; u_int max_xres;
u_int max_yres; u_int max_yres;
u_int max_bpp;
u_int bpp;
/* /*
* These are the addresses we mapped * These are the addresses we mapped
...@@ -86,12 +86,13 @@ struct sa1100fb_info { ...@@ -86,12 +86,13 @@ struct sa1100fb_info {
dma_addr_t dbar1; dma_addr_t dbar1;
dma_addr_t dbar2; dma_addr_t dbar2;
u_int lccr0;
u_int lccr3;
u_int cmap_inverse:1, u_int cmap_inverse:1,
cmap_static:1, cmap_static:1,
unused:30; unused:30;
u_int lccr0;
u_int lccr3;
u_int reg_lccr0; u_int reg_lccr0;
u_int reg_lccr1; u_int reg_lccr1;
u_int reg_lccr2; u_int reg_lccr2;
...@@ -102,18 +103,14 @@ struct sa1100fb_info { ...@@ -102,18 +103,14 @@ struct sa1100fb_info {
struct semaphore ctrlr_sem; struct semaphore ctrlr_sem;
wait_queue_head_t ctrlr_wait; wait_queue_head_t ctrlr_wait;
struct tq_struct task; struct tq_struct task;
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct pm_dev *pm; struct pm_dev *pm;
#endif #endif
#ifdef CONFIG_CPU_FREQ
struct notifier_block clockchg;
#endif
}; };
#define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member))) #define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))
#define TO_INF(ptr,member) __type_entry(ptr,struct sa1100fb_info,member) #define TO_INF(ptr,member) __type_entry(ptr, struct fb_info, member)
#define SA1100_PALETTE_MODE_VAL(bpp) (((bpp) & 0x018) << 9) #define SA1100_PALETTE_MODE_VAL(bpp) (((bpp) & 0x018) << 9)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment