Commit 85fa8aa4 authored by James Simmons's avatar James Simmons

Ported Mach64 and NVIDIA driver to final api. A bunch of improvements and bug fixes.

parent 4a20b66c
...@@ -233,33 +233,6 @@ config FB_ATARI ...@@ -233,33 +233,6 @@ config FB_ATARI
This is the frame buffer device driver for the builtin graphics This is the frame buffer device driver for the builtin graphics
chipset found in Ataris. chipset found in Ataris.
config FB_ATY
tristate "ATI Mach64 display support" if PCI
depends on FB
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
The driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called atyfb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY
prompt "ATI Mach64 display support"
depends on FB && (SPARC64 && PCI && FB_PCI || ATARI)
config FB_ATY_GX
bool "Mach64 GX support" if PCI
depends on FB_ATY
default y if ATARI
help
Say Y here to support use of the ATI Mach64 Graphics Expression
board (or other boards based on the Mach64 GX chipset) as a
framebuffer device. The ATI product support page for these boards
is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
config FB_OF config FB_OF
bool "Open Firmware frame buffer device support" bool "Open Firmware frame buffer device support"
depends on FB && PPC && ALL_PPC depends on FB && PPC && ALL_PPC
...@@ -649,16 +622,6 @@ config FB_MATROX_MULTIHEAD ...@@ -649,16 +622,6 @@ config FB_MATROX_MULTIHEAD
There is no need for enabling 'Matrox multihead support' if you have There is no need for enabling 'Matrox multihead support' if you have
only one Matrox card in the box. only one Matrox card in the box.
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
default y if SPARC64 && FB_PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
framebuffer device. The ATI product support page for these boards
is at <http://support.ati.com/products/pc/mach64/>.
config FB_RADEON config FB_RADEON
tristate "ATI Radeon display support" tristate "ATI Radeon display support"
depends on FB && PCI depends on FB && PCI
...@@ -682,6 +645,39 @@ config FB_ATY128 ...@@ -682,6 +645,39 @@ config FB_ATY128
module will be called aty128fb.o. If you want to compile it as a module will be called aty128fb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY
tristate "ATI Mach64 display support" if PCI || ATARI
depends on FB
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
The driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called atyfb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
default y if SPARC64 && FB_PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
framebuffer device. The ATI product support page for these boards
is at <http://support.ati.com/products/pc/mach64/>.
config FB_ATY_GX
bool "Mach64 GX support" if PCI
depends on FB_ATY
default y if ATARI
help
Say Y here to support use of the ATI Mach64 Graphics Expression
board (or other boards based on the Mach64 GX chipset) as a
framebuffer device. The ATI product support page for these boards
is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
config FB_SIS config FB_SIS
tristate "SIS acceleration" tristate "SIS acceleration"
depends on FB && PCI depends on FB && PCI
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <video/fbcon.h>
/* /*
* Elements of the hardware specific atyfb_par structure * Elements of the hardware specific atyfb_par structure
*/ */
...@@ -59,19 +57,9 @@ union aty_pll { ...@@ -59,19 +57,9 @@ union aty_pll {
*/ */
struct aty_cursor { struct aty_cursor {
int enable;
int on;
int vbl_cnt;
int blink_rate;
u32 offset;
struct {
u16 x, y;
} pos, hot, size;
u32 color[2];
u8 bits[8][64]; u8 bits[8][64];
u8 mask[8][64]; u8 mask[8][64];
u8 *ram; u8 *ram;
struct timer_list *timer;
}; };
struct atyfb_par { struct atyfb_par {
...@@ -93,8 +81,6 @@ struct atyfb_par { ...@@ -93,8 +81,6 @@ struct atyfb_par {
u8 blitter_may_be_busy; u8 blitter_may_be_busy;
#ifdef __sparc__ #ifdef __sparc__
struct pci_mmap_map *mmap_map; struct pci_mmap_map *mmap_map;
int consolecnt;
int vtconsole;
u8 mmaped; u8 mmaped;
int open; int open;
#endif #endif
...@@ -251,11 +237,9 @@ extern void aty_calc_pll_ct(const struct fb_info *info, ...@@ -251,11 +237,9 @@ extern void aty_calc_pll_ct(const struct fb_info *info,
*/ */
extern struct aty_cursor *aty_init_cursor(struct fb_info *info); extern struct aty_cursor *aty_init_cursor(struct fb_info *info);
extern void atyfb_cursor(struct display *p, int mode, int x, int y); extern int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
extern void aty_set_cursor_color(struct fb_info *info); extern void aty_set_cursor_color(struct fb_info *info);
extern void aty_set_cursor_shape(struct fb_info *info); extern void aty_set_cursor_shape(struct fb_info *info);
extern int atyfb_set_font(struct display *d, int width, int height);
/* /*
* Hardware acceleration * Hardware acceleration
......
...@@ -208,10 +208,11 @@ static struct fb_ops atyfb_ops = { ...@@ -208,10 +208,11 @@ static struct fb_ops atyfb_ops = {
.fb_fillrect = atyfb_fillrect, .fb_fillrect = atyfb_fillrect,
.fb_copyarea = atyfb_copyarea, .fb_copyarea = atyfb_copyarea,
.fb_imageblit = atyfb_imageblit, .fb_imageblit = atyfb_imageblit,
.fb_cursor = cfb_cursor,
#ifdef __sparc__ #ifdef __sparc__
.fb_mmap = atyfb_mmap, .fb_mmap = atyfb_mmap,
#endif #endif
.fb_rasterimg = atyfb_rasterimg, .fb_sync = atyfb_sync,
}; };
static char curblink __initdata = 1; static char curblink __initdata = 1;
...@@ -681,13 +682,6 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -681,13 +682,6 @@ static int aty_crtc_to_var(const struct crtc *crtc,
(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
(c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.offset = 0;
var->blue.msb_right = 0;
var->transp.offset = 0;
var->transp.length = 0;
var->transp.msb_right = 0;
switch (pix_width) { switch (pix_width) {
#if 0 #if 0
case CRTC_PIX_WIDTH_4BPP: case CRTC_PIX_WIDTH_4BPP:
...@@ -696,7 +690,10 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -696,7 +690,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8; var->red.length = 8;
var->green.offset = 0; var->green.offset = 0;
var->green.length = 8; var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8; var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
#endif #endif
case CRTC_PIX_WIDTH_8BPP: case CRTC_PIX_WIDTH_8BPP:
...@@ -705,7 +702,10 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -705,7 +702,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8; var->red.length = 8;
var->green.offset = 0; var->green.offset = 0;
var->green.length = 8; var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8; var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */ case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
bpp = 16; bpp = 16;
...@@ -713,7 +713,10 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -713,7 +713,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 5; var->red.length = 5;
var->green.offset = 5; var->green.offset = 5;
var->green.length = 5; var->green.length = 5;
var->blue.offset = 0;
var->blue.length = 5; var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
#if 0 #if 0
case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */ case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
...@@ -722,7 +725,10 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -722,7 +725,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 5; var->red.length = 5;
var->green.offset = 5; var->green.offset = 5;
var->green.length = 6; var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 5; var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
#endif #endif
case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */ case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
...@@ -731,7 +737,10 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -731,7 +737,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8; var->red.length = 8;
var->green.offset = 8; var->green.offset = 8;
var->green.length = 8; var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8; var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */ case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
bpp = 32; bpp = 32;
...@@ -739,6 +748,7 @@ static int aty_crtc_to_var(const struct crtc *crtc, ...@@ -739,6 +748,7 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8; var->red.length = 8;
var->green.offset = 8; var->green.offset = 8;
var->green.length = 8; var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8; var->blue.length = 8;
var->transp.offset = 24; var->transp.offset = 24;
var->transp.length = 8; var->transp.length = 8;
...@@ -848,7 +858,8 @@ static int atyfb_set_par(struct fb_info *info) ...@@ -848,7 +858,8 @@ static int atyfb_set_par(struct fb_info *info)
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
btext_update_display(info->fix.smem_start, btext_update_display(info->fix.smem_start,
(((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8, (((par->crtc.h_tot_disp >> 16) & 0xff) +
1) * 8,
((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1, ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
info->var.bits_per_pixel, info->var.bits_per_pixel,
par->crtc.vxres * info->var.bits_per_pixel / 8); par->crtc.vxres * info->var.bits_per_pixel / 8);
...@@ -882,13 +893,14 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var, ...@@ -882,13 +893,14 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
{ {
int err; int err;
memset(var, 0, sizeof(struct fb_var_screeninfo));
if ((err = aty_crtc_to_var(&par->crtc, var))) if ((err = aty_crtc_to_var(&par->crtc, var)))
return err; return err;
var->pixclock = par->pll_ops->pll_to_var(info, &par->pll); var->pixclock = par->pll_ops->pll_to_var(info, &par->pll);
var->height = -1; var->height = -1;
var->width = -1; var->width = -1;
var->nonstd = 0;
return 0; return 0;
} }
...@@ -920,9 +932,6 @@ static int atyfb_open(struct fb_info *info, int user) ...@@ -920,9 +932,6 @@ static int atyfb_open(struct fb_info *info, int user)
if (user) { if (user) {
par->open++; par->open++;
par->mmaped = 0; par->mmaped = 0;
par->vtconsole = -1;
} else {
par->consolecnt++;
} }
#endif #endif
return (0); return (0);
...@@ -949,9 +958,6 @@ static int atyfb_release(struct fb_info *info, int user) ...@@ -949,9 +958,6 @@ static int atyfb_release(struct fb_info *info, int user)
int was_mmaped = par->mmaped; int was_mmaped = par->mmaped;
par->mmaped = 0; par->mmaped = 0;
if (par->vtconsole != -1)
vt_cons[par->vtconsole]->vc_mode = KD_TEXT;
par->vtconsole = -1;
if (was_mmaped) { if (was_mmaped) {
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
...@@ -981,8 +987,6 @@ static int atyfb_release(struct fb_info *info, int user) ...@@ -981,8 +987,6 @@ static int atyfb_release(struct fb_info *info, int user)
gen_set_var(&var, -1, info); gen_set_var(&var, -1, info);
} }
} }
} else {
par->consolecnt--;
} }
#endif #endif
return (0); return (0);
...@@ -1204,18 +1208,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file, ...@@ -1204,18 +1208,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
vma->vm_flags |= VM_IO; vma->vm_flags |= VM_IO;
if (!par->mmaped) { if (!par->mmaped)
int lastconsole = 0;
if (info->display_fg)
lastconsole = info->display_fg->vc_num;
par->mmaped = 1; par->mmaped = 1;
if (par->consolecnt
&& fb_display[lastconsole].fb_info == info) {
par->vtconsole = lastconsole;
vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
}
}
return 0; return 0;
} }
...@@ -1418,15 +1412,15 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par) ...@@ -1418,15 +1412,15 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
{ {
struct fb_info *info; struct fb_info *info;
struct atyfb_par *par; struct atyfb_par *par = (struct atyfb_par *) info->fb.par;
int result; int result;
result = PBOOK_SLEEP_OK; result = PBOOK_SLEEP_OK;
for (info = first_display; info != NULL; info = par->next) { for (info = first_display; info != NULL; info = par->next) {
struct fb_fix_screeninfo fix;
int nb; int nb;
par = (struct atyfb_par *) info->par;
nb = fb_display[fg_console].var.yres * info->fix.line_length; nb = fb_display[fg_console].var.yres * info->fix.line_length;
switch (when) { switch (when) {
...@@ -1445,7 +1439,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) ...@@ -1445,7 +1439,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
if (par->blitter_may_be_busy) if (par->blitter_may_be_busy)
wait_for_idle(par); wait_for_idle(par);
/* Stop accel engine (stop bus mastering) */ /* Stop accel engine (stop bus mastering) */
if (info->var.accel_flags & FB_ACCELF_TEXT) if (par->accel_flags & FB_ACCELF_TEXT)
aty_reset_engine(par); aty_reset_engine(par);
/* Backup fb content */ /* Backup fb content */
...@@ -1931,15 +1925,8 @@ static int __init aty_init(struct fb_info *info, const char *name) ...@@ -1931,15 +1925,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
#endif #endif
#ifdef CONFIG_FB_ATY_CT #ifdef CONFIG_FB_ATY_CT
if (curblink && M64_HAS(INTEGRATED)) { if (curblink && M64_HAS(INTEGRATED))
par->cursor = aty_init_cursor(info); par->cursor = aty_init_cursor(info);
if (par->cursor) {
/*
disp->dispsw.cursor = atyfb_cursor;
disp->dispsw.set_font = atyfb_set_font;
*/
}
}
#endif /* CONFIG_FB_ATY_CT */ #endif /* CONFIG_FB_ATY_CT */
info->var = var; info->var = var;
...@@ -1992,17 +1979,23 @@ int __init atyfb_init(void) ...@@ -1992,17 +1979,23 @@ int __init atyfb_init(void)
continue; continue;
info = info =
kmalloc(sizeof(struct fb_info) + kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
sizeof(struct atyfb_par), GFP_ATOMIC);
if (!info) { if (!info) {
printk printk
("atyfb_init: can't alloc fb_info\n"); ("atyfb_init: can't alloc fb_info\n");
return -ENXIO; return -ENXIO;
} }
memset(info, 0, sizeof(struct fb_info) + memset(info, 0, sizeof(struct fb_info));
sizeof(struct atyfb_par));
default_par = (struct atyfb_par *) (info + 1); default_par =
kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
if (!default_par) {
printk
("atyfb_init: can't alloc atyfb_par\n");
kfree(info);
return -ENXIO;
}
memset(default_par, 0, sizeof(struct atyfb_par));
info->fix = atyfb_fix; info->fix = atyfb_fix;
info->par = default_par; info->par = default_par;
...@@ -2337,6 +2330,7 @@ int __init atyfb_init(void) ...@@ -2337,6 +2330,7 @@ int __init atyfb_init(void)
if (first_display == NULL) if (first_display == NULL)
pmu_register_sleep_notifier pmu_register_sleep_notifier
(&aty_sleep_notifier); (&aty_sleep_notifier);
/* FIXME info->next = first_display; */
default_par->next = first_display; default_par->next = first_display;
#endif #endif
} }
...@@ -2374,7 +2368,7 @@ int __init atyfb_init(void) ...@@ -2374,7 +2368,7 @@ int __init atyfb_init(void)
info->fix.smem_start = info->screen_base; /* Fake! */ info->fix.smem_start = info->screen_base; /* Fake! */
default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num], default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
0x10000) + 0xFC00ul; 0x10000) + 0xFC00ul;
info->fix.mmio_start = default_par->ati_regbase; /* Fake! */ info->fix.mmio_start = par->ati_regbase; /* Fake! */
aty_st_le32(CLOCK_CNTL, 0x12345678, default_par); aty_st_le32(CLOCK_CNTL, 0x12345678, default_par);
clock_r = aty_ld_le32(CLOCK_CNTL, default_par); clock_r = aty_ld_le32(CLOCK_CNTL, default_par);
...@@ -2633,16 +2627,12 @@ void cleanup_module(void) ...@@ -2633,16 +2627,12 @@ void cleanup_module(void)
if (info->screen_base) if (info->screen_base)
iounmap((void *) info->screen_base); iounmap((void *) info->screen_base);
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
if (par->cursor && par->cursor->ram) if (info->cursor && info->cursor->ram)
iounmap(par->cursor->ram); iounmap(info->cursor->ram);
#endif #endif
#endif #endif
if (info->cursor)
if (par->cursor) { kfree(info->cursor);
if (par->cursor->timer)
kfree(par->cursor->timer);
kfree(par->cursor);
}
#ifdef __sparc__ #ifdef __sparc__
if (par->mmap_map) if (par->mmap_map)
kfree(par->mmap_map); kfree(par->mmap_map);
......
...@@ -19,11 +19,6 @@ ...@@ -19,11 +19,6 @@
#include <video/mach64.h> #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
#define DEFAULT_CURSOR_BLINK_RATE (20)
#define CURSOR_DRAW_DELAY (2)
/* /*
* Hardware Cursor support. * Hardware Cursor support.
*/ */
...@@ -49,50 +44,48 @@ void aty_set_cursor_color(struct fb_info *info) ...@@ -49,50 +44,48 @@ void aty_set_cursor_color(struct fb_info *info)
const u8 *red = cursor_color_map; const u8 *red = cursor_color_map;
const u8 *green = cursor_color_map; const u8 *green = cursor_color_map;
const u8 *blue = cursor_color_map; const u8 *blue = cursor_color_map;
int i; u32 fg_color, bg_color;
if (!c) if (!c)
return; return;
#ifdef __sparc__ #ifdef __sparc__
if (par->mmaped && (!info->display_fg if (par->mmaped)
|| info->display_fg->vc_num ==
par->vtconsole))
return; return;
#endif #endif
fg_color = (u32) red[0] << 24;
fg_color |= (u32) green[0] << 16;
fg_color |= (u32) blue[0] << 8;
fg_color |= (u32) pixel[0];
for (i = 0; i < 2; i++) { bg_color = (u32) red[1] << 24;
c->color[i] = (u32) red[i] << 24; bg_color |= (u32) green[1] << 16;
c->color[i] |= (u32) green[i] << 16; bg_color |= (u32) blue[1] << 8;
c->color[i] |= (u32) blue[i] << 8; bg_color |= (u32) pixel[1];
c->color[i] |= (u32) pixel[i];
}
wait_for_fifo(2, par); wait_for_fifo(2, par);
aty_st_le32(CUR_CLR0, c->color[0], par); aty_st_le32(CUR_CLR0, fg_color, par);
aty_st_le32(CUR_CLR1, c->color[1], par); aty_st_le32(CUR_CLR1, bg_color, par);
} }
void aty_set_cursor_shape(struct fb_info *info) void aty_set_cursor_shape(struct fb_info *info)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor; struct aty_cursor *c = par->cursor;
u8 *ram, m, b; u8 *ram, m, b;
int x, y; int x, y;
if (!c) if (!c)
return; return;
#ifdef __sparc__ #ifdef __sparc__
if (par->mmaped && (!info->display_fg if (par->mmaped)
|| info->display_fg->vc_num ==
par->vtconsole))
return; return;
#endif #endif
ram = c->ram; ram = c->ram;
for (y = 0; y < c->size.y; y++) { for (y = 0; y < cursor->image.height; y++) {
for (x = 0; x < c->size.x >> 2; x++) { for (x = 0; x < cursor->image.width >> 2; x++) {
m = c->mask[x][y]; m = c->mask[x][y];
b = c->bits[x][y]; b = c->bits[x][y];
fb_writeb(cursor_mask_lookup[m >> 4] | fb_writeb(cursor_mask_lookup[m >> 4] |
...@@ -106,12 +99,13 @@ void aty_set_cursor_shape(struct fb_info *info) ...@@ -106,12 +99,13 @@ void aty_set_cursor_shape(struct fb_info *info)
fb_writeb(0xaa, ram++); fb_writeb(0xaa, ram++);
} }
} }
fb_memset(ram, 0xaa, (64 - c->size.y) * 16); fb_memset(ram, 0xaa, (64 - cursor->image.height) * 16);
} }
static void aty_set_cursor(struct fb_info *info, int on) static void aty_set_cursor(struct fb_info *info)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor; struct aty_cursor *c = par->cursor;
u16 xoff, yoff; u16 xoff, yoff;
int x, y; int x, y;
...@@ -120,14 +114,12 @@ static void aty_set_cursor(struct fb_info *info, int on) ...@@ -120,14 +114,12 @@ static void aty_set_cursor(struct fb_info *info, int on)
return; return;
#ifdef __sparc__ #ifdef __sparc__
if (par->mmaped && (!info->display_fg if (par->mmaped)
|| info->display_fg->vc_num ==
par->vtconsole))
return; return;
#endif #endif
if (on) { if (cursor->enable) {
x = c->pos.x - c->hot.x - info->var.xoffset; x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
if (x < 0) { if (x < 0) {
xoff = -x; xoff = -x;
x = 0; x = 0;
...@@ -135,7 +127,7 @@ static void aty_set_cursor(struct fb_info *info, int on) ...@@ -135,7 +127,7 @@ static void aty_set_cursor(struct fb_info *info, int on)
xoff = 0; xoff = 0;
} }
y = c->pos.y - c->hot.y - info->var.yoffset; y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
if (y < 0) { if (y < 0) {
yoff = -y; yoff = -y;
y = 0; y = 0;
...@@ -144,10 +136,10 @@ static void aty_set_cursor(struct fb_info *info, int on) ...@@ -144,10 +136,10 @@ static void aty_set_cursor(struct fb_info *info, int on)
} }
wait_for_fifo(4, par); wait_for_fifo(4, par);
aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1), aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1),
par); par);
aty_st_le32(CUR_HORZ_VERT_OFF, aty_st_le32(CUR_HORZ_VERT_OFF,
((u32) (64 - c->size.y + yoff) << 16) | xoff, ((u32) (64 - cursor->image.height + yoff) << 16) | xoff,
par); par);
aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par); aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
...@@ -162,70 +154,25 @@ static void aty_set_cursor(struct fb_info *info, int on) ...@@ -162,70 +154,25 @@ static void aty_set_cursor(struct fb_info *info, int on)
wait_for_idle(par); wait_for_idle(par);
} }
static void aty_cursor_timer_handler(unsigned long dev_addr) int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{ {
struct fb_info *info = (struct fb_info *) dev_addr;
struct atyfb_par *par = (struct atyfb_par *) info->par;
if (!par->cursor)
return;
if (!par->cursor->enable)
goto out;
if (par->cursor->vbl_cnt && --par->cursor->vbl_cnt == 0) {
par->cursor->on ^= 1;
aty_set_cursor(info, par->cursor->on);
par->cursor->vbl_cnt = par->cursor->blink_rate;
}
out:
par->cursor->timer->expires = jiffies + (HZ / 50);
add_timer(par->cursor->timer);
}
void atyfb_cursor(struct display *p, int mode, int x, int y)
{
struct fb_info *info = p->fb_info;
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
struct aty_cursor *c = par->cursor; struct aty_cursor *c = par->cursor;
if (!c) if (!c)
return; return -1;
#ifdef __sparc__ #ifdef __sparc__
if (par->mmaped && (!info->display_fg if (par->mmaped)
|| info->display_fg->vc_num ==
par->vtconsole))
return; return;
#endif #endif
x *= fontwidth(p); aty_set_cursor(info);
y *= fontheight(p); cursor->image.dx = info->cursor.image.dx;
if (c->pos.x == x && c->pos.y == y cursor->image.dy = info->cursor.image.dy;
&& (mode == CM_ERASE) == !c->enable)
return;
c->enable = 0; aty_set_cursor(info);
if (c->on) return 0;
aty_set_cursor(info, 0);
c->pos.x = x;
c->pos.y = y;
switch (mode) {
case CM_ERASE:
c->on = 0;
break;
case CM_DRAW:
case CM_MOVE:
if (c->on)
aty_set_cursor(info, 1);
else
c->vbl_cnt = CURSOR_DRAW_DELAY;
c->enable = 1;
break;
}
} }
struct aty_cursor *__init aty_init_cursor(struct fb_info *info) struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
...@@ -238,47 +185,31 @@ struct aty_cursor *__init aty_init_cursor(struct fb_info *info) ...@@ -238,47 +185,31 @@ struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
return 0; return 0;
memset(cursor, 0, sizeof(*cursor)); memset(cursor, 0, sizeof(*cursor));
cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
if (!cursor->timer) {
kfree(cursor);
return 0;
}
memset(cursor->timer, 0, sizeof(*cursor->timer));
cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
info->fix.smem_len -= PAGE_SIZE; info->fix.smem_len -= PAGE_SIZE;
cursor->offset = info->fix.smem_len;
#ifdef __sparc__ #ifdef __sparc__
addr = (unsigned long) info->screen_base - 0x800000 + cursor->offset; addr = info->screen_base - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) addr; cursor->ram = (u8 *) addr;
#else #else
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
addr = info->fix.smem_start - 0x800000 + cursor->offset; addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) ioremap(addr, 1024); cursor->ram = (u8 *) ioremap(addr, 1024);
#else #else
addr = (unsigned long) info->screen_base + cursor->offset; addr = (unsigned long) info->screen_base + info->fix.smem_len;
cursor->ram = (u8 *) addr; cursor->ram = (u8 *) addr;
#endif #endif
#endif #endif
if (!cursor->ram) { if (!cursor->ram) {
kfree(cursor); kfree(cursor);
return NULL; return NULL;
} }
init_timer(cursor->timer);
cursor->timer->expires = jiffies + (HZ / 50);
cursor->timer->data = (unsigned long) info;
cursor->timer->function = aty_cursor_timer_handler;
add_timer(cursor->timer);
return cursor; return cursor;
} }
int atyfb_set_font(struct display *d, int width, int height) int atyfb_set_font(struct fb_info *info, int width, int height)
{ {
struct fb_info *info = d->fb_info;
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor; struct aty_cursor *c = par->cursor;
int i, j; int i, j;
...@@ -288,10 +219,10 @@ int atyfb_set_font(struct display *d, int width, int height) ...@@ -288,10 +219,10 @@ int atyfb_set_font(struct display *d, int width, int height)
height = 16; height = 16;
} }
c->hot.x = 0; cursor->hot.x = 0;
c->hot.y = 0; cursor->hot.y = 0;
c->size.x = width; cursor->image.width = width;
c->size.y = height; cursor->image.height = height;
memset(c->bits, 0xff, sizeof(c->bits)); memset(c->bits, 0xff, sizeof(c->bits));
memset(c->mask, 0, sizeof(c->mask)); memset(c->mask, 0, sizeof(c->mask));
......
This diff is collapsed.
...@@ -118,12 +118,6 @@ config FBCON_ADVANCED ...@@ -118,12 +118,6 @@ config FBCON_ADVANCED
If unsure, say N. If unsure, say N.
config FBCON_ACCEL
tristate "Hardware acceleration support" if FBCON_ADVANCED
depends on FRAMEBUFFER_CONSOLE
default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && FB_ATY128!=y && !FB_MAC && FB_RIVA!=y && FB_HGA!=y && !FB_OF && FB_SGIVW!=y && FB_VGA16!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m || FB_HGA=m || FB_ATY128=m)
default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_ATY128=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y || FB_HGA=y || FB_VGA16)
config FBCON_AFB config FBCON_AFB
tristate "Amiga bitplanes support" if FBCON_ADVANCED tristate "Amiga bitplanes support" if FBCON_ADVANCED
depends on FRAMEBUFFER_CONSOLE depends on FRAMEBUFFER_CONSOLE
......
...@@ -27,7 +27,7 @@ obj-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o ...@@ -27,7 +27,7 @@ obj-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
obj-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o obj-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
obj-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o obj-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o fonts.o obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o fonts.o fbcon-accel.o
# Generic Low Level Drivers # Generic Low Level Drivers
...@@ -37,7 +37,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o ...@@ -37,7 +37,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
# Files generated that shall be removed upon make clean # Files generated that shall be removed upon make clean
clean-files := promcon_tbl.c clean-files := promcon_tbl.c
......
...@@ -464,13 +464,14 @@ static void vgaHWRestore(const struct fb_info *info, ...@@ -464,13 +464,14 @@ static void vgaHWRestore(const struct fb_info *info,
/* /*
* Hardware Acceleration for Neo2200+ * Hardware Acceleration for Neo2200+
*/ */
static inline void neo2200_sync(struct fb_info *info) static inline int neo2200_sync(struct fb_info *info)
{ {
struct neofb_par *par = (struct neofb_par *) info->par; struct neofb_par *par = (struct neofb_par *) info->par;
int waitcycles; int waitcycles;
while (par->neo2200->bltStat & 1) while (par->neo2200->bltStat & 1)
waitcycles++; waitcycles++;
return 0;
} }
static inline void neo2200_wait_fifo(struct fb_info *info, static inline void neo2200_wait_fifo(struct fb_info *info,
......
This diff is collapsed.
...@@ -74,6 +74,7 @@ typedef unsigned int U032; ...@@ -74,6 +74,7 @@ typedef unsigned int U032;
#define NV_ARCH_03 0x03 #define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04 #define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10 #define NV_ARCH_10 0x10
#define NV_ARCH_20 0x20
/***************************************************************************\ /***************************************************************************\
* * * *
* FIFO registers. * * FIFO registers. *
......
...@@ -4,10 +4,6 @@ ...@@ -4,10 +4,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <video/fbcon.h> #include <video/fbcon.h>
#include <video/fbcon-cfb4.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#include "riva_hw.h" #include "riva_hw.h"
/* GGI compatibility macros */ /* GGI compatibility macros */
...@@ -27,56 +23,16 @@ struct riva_regs { ...@@ -27,56 +23,16 @@ struct riva_regs {
RIVA_HW_STATE ext; RIVA_HW_STATE ext;
}; };
typedef struct { struct riva_par {
unsigned char red, green, blue, transp;
} riva_cfb8_cmap_t;
struct rivafb_info;
struct rivafb_info {
struct fb_info info; /* kernel framebuffer info */
RIVA_HW_INST riva; /* interface to riva_hw.c */ RIVA_HW_INST riva; /* interface to riva_hw.c */
const char *drvr_name; /* Riva hardware board type */
unsigned long ctrl_base_phys; /* physical control register base addr */
unsigned long fb_base_phys; /* physical framebuffer base addr */
caddr_t ctrl_base; /* virtual control register base addr */ caddr_t ctrl_base; /* virtual control register base addr */
caddr_t fb_base; /* virtual framebuffer base addr */
unsigned ram_amount; /* amount of RAM on card, in bytes */
unsigned dclk_max; /* max DCLK */ unsigned dclk_max; /* max DCLK */
struct riva_regs initial_state; /* initial startup video mode */ struct riva_regs initial_state; /* initial startup video mode */
struct riva_regs current_state; struct riva_regs current_state;
struct display disp;
int currcon;
struct display *currcon_display;
struct rivafb_info *next;
struct pci_dev *pd; /* pointer to board's pci info */
unsigned base0_region_size; /* size of control register region */
unsigned base1_region_size; /* size of framebuffer region */
struct riva_cursor *cursor; struct riva_cursor *cursor;
struct display_switch dispsw;
riva_cfb8_cmap_t palette[256]; /* VGA DAC palette cache */
#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
union {
#ifdef FBCON_HAS_CFB16
u_int16_t cfb16[16];
#endif
#ifdef FBCON_HAS_CFB32
u_int32_t cfb32[16];
#endif
} con_cmap;
#endif /* FBCON_HAS_CFB16 | FBCON_HAS_CFB32 */
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr; struct { int vram; int vram_valid; } mtrr;
#endif #endif
......
...@@ -23,15 +23,16 @@ ...@@ -23,15 +23,16 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
#define INCLUDE_TIMING_TABLE_DATA #define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE regs #define DBE_REG_BASE default_par.regs
#include <video/sgivw.h> #include <asm/sgi-vwdbe.h>
struct sgivw_par { struct sgivw_par {
asregs *regs; struct asregs *regs;
u32 cmap_fifo; u32 cmap_fifo;
u_long timing_num; u_long timing_num;
}; };
...@@ -44,11 +45,12 @@ struct sgivw_par { ...@@ -44,11 +45,12 @@ struct sgivw_par {
*/ */
/* set by arch/i386/kernel/setup.c */ /* set by arch/i386/kernel/setup.c */
u_long sgivwfb_mem_phys; extern unsigned long sgivwfb_mem_phys;
u_long sgivwfb_mem_size; extern unsigned long sgivwfb_mem_size;
static struct fb_info fb_info;
static struct sgivw_par default_par; static struct sgivw_par default_par;
static u32 pseudo_palette[17];
static struct fb_info fb_info;
static int ypan = 0; static int ypan = 0;
static int ywrap = 0; static int ywrap = 0;
...@@ -58,7 +60,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = { ...@@ -58,7 +60,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
.visual = FB_VISUAL_PSEUDOCOLOR, .visual = FB_VISUAL_PSEUDOCOLOR,
.mmio_start = DBE_REG_PHYS, .mmio_start = DBE_REG_PHYS,
.mmio_len = DBE_REG_SIZE, .mmio_len = DBE_REG_SIZE,
.accel_flags = FB_ACCEL_NONE .accel = FB_ACCEL_NONE
}; };
static struct fb_var_screeninfo sgivwfb_var __initdata = { static struct fb_var_screeninfo sgivwfb_var __initdata = {
...@@ -152,8 +154,8 @@ static unsigned long bytes_per_pixel(int bpp) ...@@ -152,8 +154,8 @@ static unsigned long bytes_per_pixel(int bpp)
static void dbe_TurnOffDma(void) static void dbe_TurnOffDma(void)
{ {
int i;
unsigned int readVal; unsigned int readVal;
int i;
// Check to see if things are already turned off: // Check to see if things are already turned off:
// 1) Check to see if dbe is not using the internal dotclock. // 1) Check to see if dbe is not using the internal dotclock.
...@@ -219,7 +221,7 @@ static void dbe_TurnOffDma(void) ...@@ -219,7 +221,7 @@ static void dbe_TurnOffDma(void)
static int sgivwfb_check_var(struct fb_var_screeninfo *var, static int sgivwfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info) struct fb_info *info)
{ {
int err, activate = var->activate; struct sgivw_par *par = (struct sgivw_par *)info->par;
struct dbe_timing_info *timing; struct dbe_timing_info *timing;
u_long line_length; u_long line_length;
u_long min_mode; u_long min_mode;
...@@ -362,7 +364,7 @@ static int sgivwfb_set_par(struct fb_info *info) ...@@ -362,7 +364,7 @@ static int sgivwfb_set_par(struct fb_info *info)
u32 readVal, outputVal; u32 readVal, outputVal;
int wholeTilesX, maxPixelsPerTileX; int wholeTilesX, maxPixelsPerTileX;
int frmWrite1, frmWrite2, frmWrite3b; int frmWrite1, frmWrite2, frmWrite3b;
dbe_timing_info_t *currentTiming; /* Current Video Timing */ struct dbe_timing_info_t *currentTiming; /* Current Video Timing */
int xpmax, ypmax; // Monitor resolution int xpmax, ypmax; // Monitor resolution
int bytesPerPixel; // Bytes per pixel int bytesPerPixel; // Bytes per pixel
...@@ -698,11 +700,16 @@ int __init sgivwfb_init(void) ...@@ -698,11 +700,16 @@ int __init sgivwfb_init(void)
printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n", printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
sgivwfb_mem_phys, sgivwfb_mem_size / 1024); sgivwfb_mem_phys, sgivwfb_mem_size / 1024);
default_par.regs = (asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE); if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
goto fail_request_mem_region;
}
default_par.regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
if (!default_par.regs) { if (!default_par.regs) {
printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n"); printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs; goto fail_ioremap_regs;
} }
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size, mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
MTRR_TYPE_WRCOMB, 1); MTRR_TYPE_WRCOMB, 1);
...@@ -722,8 +729,7 @@ int __init sgivwfb_init(void) ...@@ -722,8 +729,7 @@ int __init sgivwfb_init(void)
fb_info.flags = FBINFO_FLAG_DEFAULT; fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.screen_base = fb_info.screen_base =
ioremap_nocache((unsigned long) sgivwfb_mem_phys, fb_info.screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
sgivwfb_mem_size);
if (!fb_info.screen_base) { if (!fb_info.screen_base) {
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n"); printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
goto fail_ioremap_fbmem; goto fail_ioremap_fbmem;
...@@ -732,15 +738,11 @@ int __init sgivwfb_init(void) ...@@ -732,15 +738,11 @@ int __init sgivwfb_init(void)
fb_alloc_cmap(&fb_info.cmap, 256, 0); fb_alloc_cmap(&fb_info.cmap, 256, 0);
if (register_framebuffer(&fb_info) < 0) { if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
"sgivwfb: couldn't register framebuffer\n");
goto fail_register_framebuffer; goto fail_register_framebuffer;
} }
printk(KERN_INFO printk(KERN_INFO "fb%d: SGI BDE frame buffer device, using %ldK of video memory\n", minor(fb_info.node, sgivwfb_mem_size >> 10);
"fb%d: Virtual frame buffer device, using %ldK of video memory\n",
minor(fb_info.node), sgivwfb_mem_size >> 10);
return 0; return 0;
fail_register_framebuffer: fail_register_framebuffer:
......
...@@ -165,6 +165,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf ...@@ -165,6 +165,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area); static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image); static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image);
static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
static struct fb_ops tdfxfb_ops = { static struct fb_ops tdfxfb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -176,6 +177,7 @@ static struct fb_ops tdfxfb_ops = { ...@@ -176,6 +177,7 @@ static struct fb_ops tdfxfb_ops = {
.fb_fillrect = tdfxfb_fillrect, .fb_fillrect = tdfxfb_fillrect,
.fb_copyarea = tdfxfb_copyarea, .fb_copyarea = tdfxfb_copyarea,
.fb_imageblit = tdfxfb_imageblit, .fb_imageblit = tdfxfb_imageblit,
.fb_sync = banshee_wait_idle,
.fb_cursor = cfb_cursor, .fb_cursor = cfb_cursor,
}; };
...@@ -183,7 +185,7 @@ static struct fb_ops tdfxfb_ops = { ...@@ -183,7 +185,7 @@ static struct fb_ops tdfxfb_ops = {
* do_xxx: Hardware-specific functions * do_xxx: Hardware-specific functions
*/ */
static u32 do_calc_pll(int freq, int *freq_out); static u32 do_calc_pll(int freq, int *freq_out);
static void do_write_regs(struct tdfx_par *par, struct banshee_reg *reg); static void do_write_regs(struct fb_info *info, struct banshee_reg *reg);
static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short); static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
/* /*
...@@ -316,8 +318,9 @@ static inline void banshee_make_room(struct tdfx_par *par, int size) ...@@ -316,8 +318,9 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
while((tdfx_inl(par, STATUS) & 0x1f) < size); while((tdfx_inl(par, STATUS) & 0x1f) < size);
} }
static inline void banshee_wait_idle(struct tdfx_par *par) static inline void banshee_wait_idle(struct fb_info *info)
{ {
struct tdfx_par *par = (struct tdfx_par *) info->par;
int i = 0; int i = 0;
banshee_make_room(par, 1); banshee_make_room(par, 1);
...@@ -368,11 +371,12 @@ static u32 do_calc_pll(int freq, int* freq_out) ...@@ -368,11 +371,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
return (n << 8) | (m << 2) | k; return (n << 8) | (m << 2) | k;
} }
static void do_write_regs(struct tdfx_par *par, struct banshee_reg* reg) static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
{ {
struct tdfx_par *par = (struct tdfx_par *) info->par;
int i; int i;
banshee_wait_idle(par); banshee_wait_idle(info);
tdfx_outl(par, MISCINIT1, tdfx_inl(par, MISCINIT1) | 0x01); tdfx_outl(par, MISCINIT1, tdfx_inl(par, MISCINIT1) | 0x01);
...@@ -429,7 +433,7 @@ static void do_write_regs(struct tdfx_par *par, struct banshee_reg* reg) ...@@ -429,7 +433,7 @@ static void do_write_regs(struct tdfx_par *par, struct banshee_reg* reg)
tdfx_outl(par, CLIP1MAX, 0x0fff0fff); tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
tdfx_outl(par, SRCXY, 0); tdfx_outl(par, SRCXY, 0);
banshee_wait_idle(par); banshee_wait_idle(info);
} }
static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
...@@ -885,7 +889,7 @@ static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) ...@@ -885,7 +889,7 @@ static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16)); tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16));
banshee_wait_idle(par); banshee_wait_idle(info);
} }
/* /*
...@@ -920,7 +924,7 @@ static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area) ...@@ -920,7 +924,7 @@ static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
tdfx_outl(par, DSTSIZE, area->width | (area->height << 16)); tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
tdfx_outl(par, DSTXY, area->dx | (area->dy << 16)); tdfx_outl(par, DSTXY, area->dx | (area->dy << 16));
tdfx_outl(par, LAUNCH_2D, area->sx | (area->sy << 16)); tdfx_outl(par, LAUNCH_2D, area->sx | (area->sy << 16));
banshee_wait_idle(par); banshee_wait_idle(info);
} }
static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap) static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
...@@ -939,8 +943,8 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap) ...@@ -939,8 +943,8 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
tdfx_outl(par, COLORBACK, pixmap->bg_color); tdfx_outl(par, COLORBACK, pixmap->bg_color);
srcfmt = 0x400000; srcfmt = 0x400000;
} else { } else {
banshee_make_room(par, 6 + ((size + 3) >> 2)); //banshee_make_room(par, 6 + ((size + 3) >> 2));
srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000; //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
} }
tdfx_outl(par, SRCXY, 0); tdfx_outl(par, SRCXY, 0);
...@@ -964,7 +968,144 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap) ...@@ -964,7 +968,144 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break; case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break;
case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break; case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
} }
banshee_wait_idle(par); banshee_wait_idle(info);
}
static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct tdfx_par *par = (struct tdfx_par *) info->par;
unsigned long flags;
/*
* If the cursor is not be changed this means either we want the
* current cursor state (if enable is set) or we want to query what
* we can do with the cursor (if enable is not set)
*/
if (!cursor->set) return 0;
/* Too large of a cursor :-( */
if (cursor->image.width > 64 || cursor->image.height > 64)
return -ENXIO;
/*
* If we are going to be changing things we should disable
* the cursor first
*/
if (info->cursor.enable) {
spin_lock_irqsave(&par->DAClock, flags);
info->cursor.enable = 0;
del_timer(&(par->hwcursor.timer));
tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
spin_unlock_irqrestore(&par->DAClock, flags);
}
/* Disable the Cursor */
if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable)
return 0;
/* fix cursor color - XFree86 forgets to restore it properly */
if (cursor->set && FB_CUR_SETCMAP) {
struct fb_cmap cmap = cursor->image.cmap;
unsigned long bg_color, fg_color;
cmap.len = 2;/* Voodoo 3+ only support 2 color cursors*/
fg_color = ((cmap.red[cmap.start] << 16) |
(cmap.green[cmap.start] << 8) |
(cmap.blue[cmap.start]));
bg_color = ((cmap.red[cmap.start+1] << 16) |
(cmap.green[cmap.start+1] << 8) |
(cmap.blue[cmap.start+1]));
fb_copy_cmap(&cmap, &info->cursor.image.cmap, 0);
spin_lock_irqsave(&par->DAClock, flags);
banshee_make_room(par, 2);
tdfx_outl(par, HWCURC0, bg_color);
tdfx_outl(par, HWCURC1, fg_color);
spin_unlock_irqrestore(&par->DAClock, flags);
}
if (cursor->set && FB_CUR_SETPOS) {
int x, y;
x = cursor->image.dx;
y = cursor->image.dy;
y -= info->var.yoffset;
info->cursor.image.dx = x;
info->cursor.image.dy = y;
x += 63;
y += 63;
spin_lock_irqsave(&par->DAClock, flags);
banshee_make_room(par, 1);
tdfx_outl(par, HWCURLOC, (y << 16) + x);
spin_unlock_irqrestore(&par->DAClock, flags);
}
/* Not supported so we fake it */
if (cursor->set && FB_CUR_SETHOT) {
info->cursor.hot.x = cursor->hot.x;
info->cursor.hot.y = cursor->hot.y;
}
if (cursor->set && FB_CUR_SETSHAPE) {
/*
* Voodoo 3 and above cards use 2 monochrome cursor patterns.
* The reason is so the card can fetch 8 words at a time
* and are stored on chip for use for the next 8 scanlines.
* This reduces the number of times for access to draw the
* cursor for each screen refresh.
* Each pattern is a bitmap of 64 bit wide and 64 bit high
* (total of 8192 bits or 1024 Kbytes). The two patterns are
* stored in such a way that pattern 0 always resides in the
* lower half (least significant 64 bits) of a 128 bit word
* and pattern 1 the upper half. If you examine the data of
* the cursor image the graphics card uses then from the
* begining you see line one of pattern 0, line one of
* pattern 1, line two of pattern 0, line two of pattern 1,
* etc etc. The linear stride for the cursor is always 16 bytes
* (128 bits) which is the maximum cursor width times two for
* the two monochrome patterns.
*/
u8 *cursorbase = (u8 *) info->cursor.image.data;
char *bitmap = cursor->image.data;
char *mask = cursor->mask;
int i, j, k, h = 0;
for (i = 0; i < 64; i++) {
if (i < cursor->image.height) {
j = (cursor->image.width + 7) >> 3;
k = 8 - j;
for (;j > 0; j--) {
/* Pattern 0. Copy the cursor bitmap to it */
fb_writeb(*bitmap, cursorbase + h);
bitmap++;
/* Pattern 1. Copy the cursor mask to it */
fb_writeb(*mask, cursorbase + h + 8);
mask++;
h++;
}
for (;k > 0; k--) {
fb_writeb(0, cursorbase + h);
fb_writeb(~0, cursorbase + h + 8);
h++;
}
} else {
fb_writel(0, cursorbase + h);
fb_writel(0, cursorbase + h + 4);
fb_writel(~0, cursorbase + h + 8);
fb_writel(~0, cursorbase + h + 12);
h += 16;
}
}
}
/* Turn the cursor on */
cursor->enable = 1;
info->cursor = *cursor;
mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
spin_lock_irqsave(&par->DAClock, flags);
banshee_make_room(par, 1);
tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
spin_unlock_irqrestore(&par->DAClock, flags);
return 0;
} }
/** /**
...@@ -988,14 +1129,15 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -988,14 +1129,15 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
return err; return err;
} }
info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) + size = sizeof(struct fb_info)+sizeof(struct tdfx_par)+16*sizeof(u32);
sizeof(u32) * 16, GFP_KERNEL);
info = kmalloc(size, GFP_KERNEL);
if (!info) return -ENOMEM; if (!info) return -ENOMEM;
memset(info, 0, sizeof(info) + sizeof(struct display) + sizeof(u32) * 16); memset(info, 0, size);
default_par = kmalloc(sizeof(struct tdfx_par), GFP_KERNEL); default_par = (struct tdfx_par *) (info + 1);
/* Configure the default fb_fix_screeninfo first */ /* Configure the default fb_fix_screeninfo first */
switch (pdev->device) { switch (pdev->device) {
...@@ -1078,7 +1220,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1078,7 +1220,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
info->fbops = &tdfxfb_ops; info->fbops = &tdfxfb_ops;
info->fix = tdfx_fix; info->fix = tdfx_fix;
info->par = default_par; info->par = default_par;
info->pseudo_palette = (void *)(info + 1); info->pseudo_palette = (void *)(default_par + 1);
info->flags = FBINFO_FLAG_DEFAULT; info->flags = FBINFO_FLAG_DEFAULT;
if (!mode_option) if (!mode_option)
......
...@@ -368,7 +368,7 @@ struct fb_ops { ...@@ -368,7 +368,7 @@ struct fb_ops {
/* perform polling on fb device */ /* perform polling on fb device */
int (*fb_poll)(struct fb_info *info, poll_table *wait); int (*fb_poll)(struct fb_info *info, poll_table *wait);
/* wait for blit idle, optional */ /* wait for blit idle, optional */
void (*fb_sync)(struct fb_info *info); int (*fb_sync)(struct fb_info *info);
/* perform fb specific ioctl (optional) */ /* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg, struct fb_info *info); unsigned long arg, struct fb_info *info);
......
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