Commit c0138240 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds

[PATCH] M68k update (part 7)

Atari frame buffer device updates
  - Move static function definition before usage
  - Fix breakage caused by recent fbdev changes
  - Make some setup parameter parsing separate routines (strsep() must be able
    to modify the passed pointers)
  - On Atari the ATI Mach64 registers are memory mapped, but it's not on
    the PCI bus, so we cannot use writel() and friends.
  - Kill warnings by protecting unused data with the appropriate #ifdef
  - On Atari the ATI Mach64 registers are memory mapped, but it's not on the
    PCI bus, so we cannot use writel() and friends.
  - Fix assignment of addresses for Atari
parent cff1a4f5
......@@ -2593,6 +2593,35 @@ atafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return -EINVAL;
}
/* (un)blank/poweroff
* 0 = unblank
* 1 = blank
* 2 = suspend vsync
* 3 = suspend hsync
* 4 = off
*/
static int
atafb_blank(int blank, struct fb_info *info)
{
unsigned short black[16];
struct fb_cmap cmap;
if (fbhw->blank && !fbhw->blank(blank))
return 1;
if (blank) {
memset(black, 0, 16*sizeof(unsigned short));
cmap.red=black;
cmap.green=black;
cmap.blue=black;
cmap.transp=NULL;
cmap.start=0;
cmap.len=16;
fb_set_cmap(&cmap, 1, info);
}
else
do_install_cmap(info->currcon, info);
return 0;
}
static struct fb_ops atafb_ops = {
owner: THIS_MODULE,
fb_get_fix: atafb_get_fix,
......@@ -2660,35 +2689,6 @@ atafb_switch(int con, struct fb_info *info)
return 0;
}
/* (un)blank/poweroff
* 0 = unblank
* 1 = blank
* 2 = suspend vsync
* 3 = suspend hsync
* 4 = off
*/
static int
atafb_blank(int blank, struct fb_info *info)
{
unsigned short black[16];
struct fb_cmap cmap;
if (fbhw->blank && !fbhw->blank(blank))
return 1;
if (blank) {
memset(black, 0, 16*sizeof(unsigned short));
cmap.red=black;
cmap.green=black;
cmap.blue=black;
cmap.transp=NULL;
cmap.start=0;
cmap.len=16;
fb_set_cmap(&cmap, 1, info);
}
else
do_install_cmap(info->currcon, info);
return 0;
}
int __init atafb_init(void)
{
int pad;
......@@ -2702,21 +2702,21 @@ int __init atafb_init(void)
#ifdef ATAFB_EXT
if (external_addr) {
fbhw = &ext_switch;
fb_info.fb_setcolreg = &ext_setcolreg;
atafb_ops.fb_setcolreg = &ext_setcolreg;
break;
}
#endif
#ifdef ATAFB_TT
if (ATARIHW_PRESENT(TT_SHIFTER)) {
fbhw = &tt_switch;
fb_info.fb_setcolreg = &tt_setcolreg;
atafb_ops.fb_setcolreg = &tt_setcolreg;
break;
}
#endif
#ifdef ATAFB_FALCON
if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
fbhw = &falcon_switch;
fb_info.fb_setcolreg = &falcon_setcolreg;
atafb_ops.fb_setcolreg = &falcon_setcolreg;
request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO,
"framebuffer/modeswitch", falcon_vbl_switcher);
break;
......@@ -2726,11 +2726,11 @@ int __init atafb_init(void)
if (ATARIHW_PRESENT(STND_SHIFTER) ||
ATARIHW_PRESENT(EXTD_SHIFTER)) {
fbhw = &st_switch;
fb_info.fb_setcolreg = &stste_setcolreg;
atafb_ops.fb_setcolreg = &stste_setcolreg;
break;
}
fbhw = &st_switch;
fb_info.fb_setcolreg = &stste_setcolreg;
atafb_ops.fb_setcolreg = &stste_setcolreg;
printk("Cannot determine video hardware; defaulting to ST(e)\n");
#else /* ATAFB_STE */
/* no default driver included */
......@@ -2824,103 +2824,10 @@ int __init atafb_init(void)
return 0;
}
int __init atafb_setup( char *options )
{
char *this_opt;
int temp;
char ext_str[80], int_str[100];
char mcap_spec[80];
char user_mode[80];
ext_str[0] =
int_str[0] =
mcap_spec[0] =
user_mode[0] =
fb_info.fontname[0] = '\0';
if (!options || !*options)
return 0;
while ((this_opt = strsep(options, ",")) != NULL) {
if (!*this_opt) continue;
if ((temp=get_video_mode(this_opt)))
default_par=temp;
else if (! strcmp(this_opt, "inverse"))
inverse=1;
else if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
else if (! strncmp(this_opt, "hwscroll_",9)) {
hwscroll=simple_strtoul(this_opt+9, NULL, 10);
if (hwscroll < 0)
hwscroll = 0;
if (hwscroll > 200)
hwscroll = 200;
}
#ifdef ATAFB_EXT
else if (!strcmp(this_opt,"mv300")) {
external_bitspercol = 8;
external_card_type = IS_MV300;
}
else if (!strncmp(this_opt,"external:",9))
strcpy(ext_str, this_opt+9);
#endif
else if (!strncmp(this_opt,"internal:",9))
strcpy(int_str, this_opt+9);
#ifdef ATAFB_FALCON
else if (!strncmp(this_opt, "eclock:", 7)) {
fext.f = simple_strtoul(this_opt+7, NULL, 10);
/* external pixelclock in kHz --> ps */
fext.t = 1000000000/fext.f;
fext.f *= 1000;
}
else if (!strncmp(this_opt, "monitorcap:", 11))
strcpy(mcap_spec, this_opt+11);
#endif
else if (!strcmp(this_opt, "keep"))
DontCalcRes = 1;
else if (!strncmp(this_opt, "R", 1))
strcpy(user_mode, this_opt+1);
}
if (*int_str) {
/* Format to config extended internal video hardware like OverScan:
"internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
Explanation:
<xres>: x-resolution
<yres>: y-resolution
The following are only needed if you have an overscan which
needs a black border:
<xres_max>: max. length of a line in pixels your OverScan hardware would allow
<yres_max>: max. number of lines your OverScan hardware would allow
<offset>: Offset from physical beginning to visible beginning
of screen in bytes
*/
int xres;
char *p;
if (!(p = strsep(&int_str, ";")) || !*p) goto int_invalid;
xres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&int_str, ";")) || !*p) goto int_invalid;
sttt_xres=xres;
tt_yres=st_yres=simple_strtoul(p, NULL, 10);
if ((p=strsep(&int_str, ";")) && *p) {
sttt_xres_virtual=simple_strtoul(p, NULL, 10);
}
if ((p=strsep(&int_str, ";")) && *p) {
sttt_yres_virtual=simple_strtoul(p, NULL, 0);
}
if ((p=strsep(&int_str, ";")) && *p) {
ovsc_offset=simple_strtoul(p, NULL, 0);
}
if (ovsc_offset || (sttt_yres_virtual != st_yres))
use_hwscroll=0;
int_invalid:
;
}
#ifdef ATAFB_EXT
if (*ext_str) {
static void __init atafb_setup_ext(char *spec)
{
int xres, xres_virtual, yres, depth, planes;
unsigned long addr, len;
char *p;
......@@ -2935,20 +2842,27 @@ int __init atafb_setup( char *options )
*
* Even xres_virtual is available, we neither support panning nor hw-scrolling!
*/
if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
xres_virtual = xres = simple_strtoul(p, NULL, 10);
if (xres <= 0) goto ext_invalid;
if (xres <= 0)
return;
if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
yres = simple_strtoul(p, NULL, 10);
if (yres <= 0) goto ext_invalid;
if (yres <= 0)
return;
if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
depth = simple_strtoul(p, NULL, 10);
if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
depth != 16 && depth != 24) goto ext_invalid;
depth != 16 && depth != 24)
return;
if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
if (*p == 'i')
planes = FB_TYPE_INTERLEAVED_PLANES;
else if (*p == 'p')
......@@ -2958,37 +2872,38 @@ int __init atafb_setup( char *options )
else if (*p == 't')
planes = -1; /* true color */
else
goto ext_invalid;
return;
if (!(p = strsep(&ext_str, ";")) || !*p) goto ext_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
addr = simple_strtoul(p, NULL, 0);
if (!(p = strsep(&ext_str, ";")) || !*p)
if (!(p = strsep(&spec, ";")) || !*p)
len = xres*yres*depth/8;
else
len = simple_strtoul(p, NULL, 0);
if ((p = strsep(&ext_str, ";")) && *p) {
if ((p = strsep(&spec, ";")) && *p) {
external_vgaiobase=simple_strtoul(p, NULL, 0);
}
if ((p = strsep(&ext_str, ";")) && *p) {
if ((p = strsep(&spec, ";")) && *p) {
external_bitspercol = simple_strtoul(p, NULL, 0);
if (external_bitspercol > 8)
external_bitspercol = 8;
else if (external_bitspercol < 1)
external_bitspercol = 1;
}
if ((p = strsep(&ext_str, ";")) && *p) {
if ((p = strsep(&spec, ";")) && *p) {
if (!strcmp(p, "vga"))
external_card_type = IS_VGA;
if (!strcmp(p, "mv300"))
external_card_type = IS_MV300;
}
if ((p = strsep(&ext_str, ";")) && *p) {
if ((p = strsep(&spec, ";")) && *p) {
xres_virtual = simple_strtoul(p, NULL, 10);
if (xres_virtual < xres)
xres_virtual = xres;
......@@ -3003,7 +2918,7 @@ int __init atafb_setup( char *options )
external_pmode = planes;
external_addr = (void *)addr;
external_len = len;
if (external_card_type == IS_MV300)
switch (external_depth) {
case 1:
......@@ -3016,14 +2931,52 @@ int __init atafb_setup( char *options )
MV300_reg = MV300_reg_8bit;
break;
}
ext_invalid:
;
}
}
#endif /* ATAFB_EXT */
static void __init atafb_setup_int(char *spec)
{
/* Format to config extended internal video hardware like OverScan:
"internal:<xres>;<yres>;<xres_max>;<yres_max>;<offset>"
Explanation:
<xres>: x-resolution
<yres>: y-resolution
The following are only needed if you have an overscan which
needs a black border:
<xres_max>: max. length of a line in pixels your OverScan hardware would allow
<yres_max>: max. number of lines your OverScan hardware would allow
<offset>: Offset from physical beginning to visible beginning
of screen in bytes
*/
int xres;
char *p;
if (!(p = strsep(&spec, ";")) || !*p)
return;
xres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&spec, ";")) || !*p)
return;
sttt_xres=xres;
tt_yres=st_yres=simple_strtoul(p, NULL, 10);
if ((p=strsep(&spec, ";")) && *p) {
sttt_xres_virtual=simple_strtoul(p, NULL, 10);
}
if ((p=strsep(&spec, ";")) && *p) {
sttt_yres_virtual=simple_strtoul(p, NULL, 0);
}
if ((p=strsep(&spec, ";")) && *p) {
ovsc_offset=simple_strtoul(p, NULL, 0);
}
if (ovsc_offset || (sttt_yres_virtual != st_yres))
use_hwscroll=0;
}
#ifdef ATAFB_FALCON
if (*mcap_spec) {
static void __init atafb_setup_mcap(char *spec)
{
char *p;
int vmin, vmax, hmin, hmax;
......@@ -3031,51 +2984,110 @@ int __init atafb_setup( char *options )
* <V*> vertical freq. in Hz
* <H*> horizontal freq. in kHz
*/
if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
if (!(p = strsep(&spec, ";")) || !*p)
return;
vmin = simple_strtoul(p, NULL, 10);
if (vmin <= 0) goto cap_invalid;
if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
if (vmin <= 0)
return;
if (!(p = strsep(&spec, ";")) || !*p)
return;
vmax = simple_strtoul(p, NULL, 10);
if (vmax <= 0 || vmax <= vmin) goto cap_invalid;
if (!(p = strsep(&mcap_spec, ";")) || !*p) goto cap_invalid;
if (vmax <= 0 || vmax <= vmin)
return;
if (!(p = strsep(&spec, ";")) || !*p)
return;
hmin = 1000 * simple_strtoul(p, NULL, 10);
if (hmin <= 0) goto cap_invalid;
if (!(p = strsep(&mcap_spec, "")) || !*p) goto cap_invalid;
if (hmin <= 0)
return;
if (!(p = strsep(&spec, "")) || !*p)
return;
hmax = 1000 * simple_strtoul(p, NULL, 10);
if (hmax <= 0 || hmax <= hmin) goto cap_invalid;
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;
cap_invalid:
;
}
#endif
}
#endif /* ATAFB_FALCON */
if (*user_mode) {
/* Format of user defined video mode is: <xres>;<yres>;<depth>
*/
char *p;
int xres, yres, depth, temp;
if (!(p = strsep(&user_mode, ";")) || !*p) goto user_invalid;
xres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&user_mode, ";")) || !*p) goto user_invalid;
yres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&user_mode, "")) || !*p) goto user_invalid;
depth = simple_strtoul(p, NULL, 10);
if ((temp=get_video_mode("user0"))) {
default_par=temp;
atafb_predefined[default_par-1].xres = xres;
atafb_predefined[default_par-1].yres = yres;
atafb_predefined[default_par-1].bits_per_pixel = depth;
}
user_invalid:
;
static void __init atafb_setup_user(char *spec)
{
/* Format of user defined video mode is: <xres>;<yres>;<depth>
*/
char *p;
int xres, yres, depth, temp;
if (!(p = strsep(&spec, ";")) || !*p)
return;
xres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&spec, ";")) || !*p)
return;
yres = simple_strtoul(p, NULL, 10);
if (!(p = strsep(&spec, "")) || !*p)
return;
depth = simple_strtoul(p, NULL, 10);
if ((temp=get_video_mode("user0"))) {
default_par=temp;
atafb_predefined[default_par-1].xres = xres;
atafb_predefined[default_par-1].yres = yres;
atafb_predefined[default_par-1].bits_per_pixel = depth;
}
return 0;
}
int __init atafb_setup( char *options )
{
char *this_opt;
int temp;
fb_info.fontname[0] = '\0';
if (!options || !*options)
return 0;
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt) continue;
if ((temp=get_video_mode(this_opt)))
default_par=temp;
else if (! strcmp(this_opt, "inverse"))
inverse=1;
else if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
else if (! strncmp(this_opt, "hwscroll_",9)) {
hwscroll=simple_strtoul(this_opt+9, NULL, 10);
if (hwscroll < 0)
hwscroll = 0;
if (hwscroll > 200)
hwscroll = 200;
}
#ifdef ATAFB_EXT
else if (!strcmp(this_opt,"mv300")) {
external_bitspercol = 8;
external_card_type = IS_MV300;
}
else if (!strncmp(this_opt,"external:",9))
atafb_setup_ext(this_opt+9);
#endif
else if (!strncmp(this_opt,"internal:",9))
atafb_setup_int(this_opt+9);
#ifdef ATAFB_FALCON
else if (!strncmp(this_opt, "eclock:", 7)) {
fext.f = simple_strtoul(this_opt+7, NULL, 10);
/* external pixelclock in kHz --> ps */
fext.t = 1000000000/fext.f;
fext.f *= 1000;
}
else if (!strncmp(this_opt, "monitorcap:", 11))
atafb_setup_mcap(this_opt+11);
#endif
else if (!strcmp(this_opt, "keep"))
DontCalcRes = 1;
else if (!strncmp(this_opt, "R", 1))
atafb_setup_user(this_opt+1);
}
return 0;
}
#ifdef MODULE
......
......@@ -174,10 +174,10 @@ static inline u32 aty_ld_le32(int regindex,
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if (regindex >= 0x400)
regindex -= 0x800;
regindex -= 0x800;
#if defined(__mc68000__)
return le32_to_cpu(*((volatile u32 *)(info->ati_regbase+regindex)));
#ifdef CONFIG_ATARI
return in_le32((volatile u32 *)(info->ati_regbase+regindex));
#else
return readl (info->ati_regbase + regindex);
#endif
......@@ -188,10 +188,10 @@ static inline void aty_st_le32(int regindex, u32 val,
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if (regindex >= 0x400)
regindex -= 0x800;
regindex -= 0x800;
#if defined(__mc68000__)
*((volatile u32 *)(info->ati_regbase+regindex)) = cpu_to_le32(val);
#ifdef CONFIG_ATARI
out_le32 (info->ati_regbase+regindex, val);
#else
writel (val, info->ati_regbase + regindex);
#endif
......@@ -202,9 +202,13 @@ static inline u8 aty_ld_8(int regindex,
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if (regindex >= 0x400)
regindex -= 0x800;
regindex -= 0x800;
#ifdef CONFIG_ATARI
return in_8 (info->ati_regbase + regindex);
#else
return readb (info->ati_regbase + regindex);
#endif
}
static inline void aty_st_8(int regindex, u8 val,
......@@ -212,9 +216,13 @@ static inline void aty_st_8(int regindex, u8 val,
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if (regindex >= 0x400)
regindex -= 0x800;
regindex -= 0x800;
#ifdef CONFIG_ATARI
out_8 (info->ati_regbase + regindex, val);
#else
writeb (val, info->ati_regbase + regindex);
#endif
}
static inline u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
......
......@@ -270,8 +270,11 @@ static unsigned long phys_size[FB_MAX] __initdata = { 0, };
static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
#endif
#ifdef CONFIG_FB_ATY_GX
static char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";
static char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
static char m64n_ct[] __initdata = "mach64CT (ATI264CT)";
static char m64n_et[] __initdata = "mach64ET (ATI264ET)";
static char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";
......@@ -294,6 +297,7 @@ static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
#endif /* CONFIG_FB_ATY_CT */
static struct {
......@@ -357,12 +361,16 @@ static struct {
};
static char ram_dram[] __initdata = "DRAM";
#ifdef CONFIG_FB_ATY_GX
static char ram_vram[] __initdata = "VRAM";
#endif /* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
static char ram_edo[] __initdata = "EDO";
static char ram_sdram[] __initdata = "SDRAM";
static char ram_sgram[] __initdata = "SGRAM";
static char ram_wram[] __initdata = "WRAM";
static char ram_off[] __initdata = "OFF";
#endif /* CONFIG_FB_ATY_CT */
static char ram_resv[] __initdata = "RESV";
#ifdef CONFIG_FB_ATY_GX
......@@ -2486,9 +2494,11 @@ int __init atyfb_init(void)
* Map the video memory (physical address given) to somewhere in the
* kernel address space.
*/
info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
info->frame_buffer = (unsigned long)ioremap(phys_vmembase[m64_num],
phys_size[m64_num]);
info->frame_buffer_phys = info->frame_buffer; /* Fake! */
info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
info->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
0x10000)+0xFC00ul;
info->ati_regbase_phys = info->ati_regbase; /* Fake! */
aty_st_le32(CLOCK_CNTL, 0x12345678, info);
......@@ -2748,10 +2758,17 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
aty_st_8(DAC_CNTL, i, info);
aty_st_8(DAC_MASK, 0xff, info);
scale = (M64_HAS(INTEGRATED) && info->current_par.crtc.bpp == 16) ? 3 : 0;
#ifdef CONFIG_ATARI
out_8(&info->aty_cmap_regs->windex, regno << scale);
out_8(&info->aty_cmap_regs->lut, red);
out_8(&info->aty_cmap_regs->lut, green);
out_8(&info->aty_cmap_regs->lut, blue);
#else
writeb(regno << scale, &info->aty_cmap_regs->windex);
writeb(red, &info->aty_cmap_regs->lut);
writeb(green, &info->aty_cmap_regs->lut);
writeb(blue, &info->aty_cmap_regs->lut);
#endif
if (regno < 16)
switch (info->current_par.crtc.bpp) {
#ifdef FBCON_HAS_CFB16
......
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