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
This is the frame buffer device driver for the builtin graphics
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
bool "Open Firmware frame buffer device support"
depends on FB && PPC && ALL_PPC
......@@ -649,16 +622,6 @@ config FB_MATROX_MULTIHEAD
There is no need for enabling 'Matrox multihead support' if you have
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
tristate "ATI Radeon display support"
depends on FB && PCI
......@@ -682,6 +645,39 @@ config FB_ATY128
module will be called aty128fb.o. If you want to compile it as a
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
tristate "SIS acceleration"
depends on FB && PCI
......
......@@ -3,8 +3,6 @@
*/
#include <linux/config.h>
#include <video/fbcon.h>
/*
* Elements of the hardware specific atyfb_par structure
*/
......@@ -59,19 +57,9 @@ union aty_pll {
*/
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 mask[8][64];
u8 *ram;
struct timer_list *timer;
};
struct atyfb_par {
......@@ -93,8 +81,6 @@ struct atyfb_par {
u8 blitter_may_be_busy;
#ifdef __sparc__
struct pci_mmap_map *mmap_map;
int consolecnt;
int vtconsole;
u8 mmaped;
int open;
#endif
......@@ -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 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_shape(struct fb_info *info);
extern int atyfb_set_font(struct display *d, int width, int height);
/*
* Hardware acceleration
......
......@@ -208,10 +208,11 @@ static struct fb_ops atyfb_ops = {
.fb_fillrect = atyfb_fillrect,
.fb_copyarea = atyfb_copyarea,
.fb_imageblit = atyfb_imageblit,
.fb_cursor = cfb_cursor,
#ifdef __sparc__
.fb_mmap = atyfb_mmap,
#endif
.fb_rasterimg = atyfb_rasterimg,
.fb_sync = atyfb_sync,
};
static char curblink __initdata = 1;
......@@ -681,13 +682,6 @@ static int aty_crtc_to_var(const struct crtc *crtc,
(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
(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) {
#if 0
case CRTC_PIX_WIDTH_4BPP:
......@@ -696,7 +690,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
#endif
case CRTC_PIX_WIDTH_8BPP:
......@@ -705,7 +702,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
bpp = 16;
......@@ -713,7 +713,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 5;
var->green.offset = 5;
var->green.length = 5;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break;
#if 0
case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
......@@ -722,7 +725,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 5;
var->green.offset = 5;
var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break;
#endif
case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
......@@ -731,7 +737,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
bpp = 32;
......@@ -739,6 +748,7 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8;
......@@ -848,7 +858,8 @@ static int atyfb_set_par(struct fb_info *info)
#ifdef CONFIG_BOOTX_TEXT
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,
info->var.bits_per_pixel,
par->crtc.vxres * info->var.bits_per_pixel / 8);
......@@ -882,13 +893,14 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
{
int err;
memset(var, 0, sizeof(struct fb_var_screeninfo));
if ((err = aty_crtc_to_var(&par->crtc, var)))
return err;
var->pixclock = par->pll_ops->pll_to_var(info, &par->pll);
var->height = -1;
var->width = -1;
var->nonstd = 0;
return 0;
}
......@@ -920,9 +932,6 @@ static int atyfb_open(struct fb_info *info, int user)
if (user) {
par->open++;
par->mmaped = 0;
par->vtconsole = -1;
} else {
par->consolecnt++;
}
#endif
return (0);
......@@ -949,9 +958,6 @@ static int atyfb_release(struct fb_info *info, int user)
int was_mmaped = par->mmaped;
par->mmaped = 0;
if (par->vtconsole != -1)
vt_cons[par->vtconsole]->vc_mode = KD_TEXT;
par->vtconsole = -1;
if (was_mmaped) {
struct fb_var_screeninfo var;
......@@ -981,9 +987,7 @@ static int atyfb_release(struct fb_info *info, int user)
gen_set_var(&var, -1, info);
}
}
} else {
par->consolecnt--;
}
}
#endif
return (0);
}
......@@ -1204,18 +1208,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
vma->vm_flags |= VM_IO;
if (!par->mmaped) {
int lastconsole = 0;
if (info->display_fg)
lastconsole = info->display_fg->vc_num;
if (!par->mmaped)
par->mmaped = 1;
if (par->consolecnt
&& fb_display[lastconsole].fb_info == info) {
par->vtconsole = lastconsole;
vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
}
}
return 0;
}
......@@ -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)
{
struct fb_info *info;
struct atyfb_par *par;
struct atyfb_par *par = (struct atyfb_par *) info->fb.par;
int result;
result = PBOOK_SLEEP_OK;
for (info = first_display; info != NULL; info = par->next) {
struct fb_fix_screeninfo fix;
int nb;
par = (struct atyfb_par *) info->par;
nb = fb_display[fg_console].var.yres * info->fix.line_length;
switch (when) {
......@@ -1445,7 +1439,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
if (par->blitter_may_be_busy)
wait_for_idle(par);
/* 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);
/* Backup fb content */
......@@ -1931,15 +1925,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
#endif
#ifdef CONFIG_FB_ATY_CT
if (curblink && M64_HAS(INTEGRATED)) {
if (curblink && M64_HAS(INTEGRATED))
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 */
info->var = var;
......@@ -1992,17 +1979,23 @@ int __init atyfb_init(void)
continue;
info =
kmalloc(sizeof(struct fb_info) +
sizeof(struct atyfb_par), GFP_ATOMIC);
kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
if (!info) {
printk
("atyfb_init: can't alloc fb_info\n");
return -ENXIO;
}
memset(info, 0, sizeof(struct fb_info) +
sizeof(struct atyfb_par));
memset(info, 0, sizeof(struct fb_info));
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->par = default_par;
......@@ -2337,6 +2330,7 @@ int __init atyfb_init(void)
if (first_display == NULL)
pmu_register_sleep_notifier
(&aty_sleep_notifier);
/* FIXME info->next = first_display; */
default_par->next = first_display;
#endif
}
......@@ -2363,7 +2357,7 @@ int __init atyfb_init(void)
return -ENOMEM;
}
memset(info, 0, sizeof(struct fb_info));
info->fix = atyfb_fix;
info->fix = atyfb_fix;
/*
* Map the video memory (physical address given) to somewhere in the
......@@ -2374,7 +2368,7 @@ int __init atyfb_init(void)
info->fix.smem_start = info->screen_base; /* Fake! */
default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
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);
clock_r = aty_ld_le32(CLOCK_CNTL, default_par);
......@@ -2633,16 +2627,12 @@ void cleanup_module(void)
if (info->screen_base)
iounmap((void *) info->screen_base);
#ifdef __BIG_ENDIAN
if (par->cursor && par->cursor->ram)
iounmap(par->cursor->ram);
if (info->cursor && info->cursor->ram)
iounmap(info->cursor->ram);
#endif
#endif
if (par->cursor) {
if (par->cursor->timer)
kfree(par->cursor->timer);
kfree(par->cursor);
}
if (info->cursor)
kfree(info->cursor);
#ifdef __sparc__
if (par->mmap_map)
kfree(par->mmap_map);
......
......@@ -19,11 +19,6 @@
#include <video/mach64.h>
#include "atyfb.h"
#define DEFAULT_CURSOR_BLINK_RATE (20)
#define CURSOR_DRAW_DELAY (2)
/*
* Hardware Cursor support.
*/
......@@ -49,50 +44,48 @@ void aty_set_cursor_color(struct fb_info *info)
const u8 *red = cursor_color_map;
const u8 *green = cursor_color_map;
const u8 *blue = cursor_color_map;
int i;
u32 fg_color, bg_color;
if (!c)
return;
#ifdef __sparc__
if (par->mmaped && (!info->display_fg
|| info->display_fg->vc_num ==
par->vtconsole))
if (par->mmaped)
return;
#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++) {
c->color[i] = (u32) red[i] << 24;
c->color[i] |= (u32) green[i] << 16;
c->color[i] |= (u32) blue[i] << 8;
c->color[i] |= (u32) pixel[i];
}
bg_color = (u32) red[1] << 24;
bg_color |= (u32) green[1] << 16;
bg_color |= (u32) blue[1] << 8;
bg_color |= (u32) pixel[1];
wait_for_fifo(2, par);
aty_st_le32(CUR_CLR0, c->color[0], par);
aty_st_le32(CUR_CLR1, c->color[1], par);
aty_st_le32(CUR_CLR0, fg_color, par);
aty_st_le32(CUR_CLR1, bg_color, par);
}
void aty_set_cursor_shape(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u8 *ram, m, b;
int x, y;
if (!c)
return;
#ifdef __sparc__
if (par->mmaped && (!info->display_fg
|| info->display_fg->vc_num ==
par->vtconsole))
if (par->mmaped)
return;
#endif
ram = c->ram;
for (y = 0; y < c->size.y; y++) {
for (x = 0; x < c->size.x >> 2; x++) {
for (y = 0; y < cursor->image.height; y++) {
for (x = 0; x < cursor->image.width >> 2; x++) {
m = c->mask[x][y];
b = c->bits[x][y];
fb_writeb(cursor_mask_lookup[m >> 4] |
......@@ -106,12 +99,13 @@ void aty_set_cursor_shape(struct fb_info *info)
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 fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u16 xoff, yoff;
int x, y;
......@@ -120,14 +114,12 @@ static void aty_set_cursor(struct fb_info *info, int on)
return;
#ifdef __sparc__
if (par->mmaped && (!info->display_fg
|| info->display_fg->vc_num ==
par->vtconsole))
if (par->mmaped)
return;
#endif
if (on) {
x = c->pos.x - c->hot.x - info->var.xoffset;
if (cursor->enable) {
x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
if (x < 0) {
xoff = -x;
x = 0;
......@@ -135,7 +127,7 @@ static void aty_set_cursor(struct fb_info *info, int on)
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) {
yoff = -y;
y = 0;
......@@ -144,10 +136,10 @@ static void aty_set_cursor(struct fb_info *info, int on)
}
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);
aty_st_le32(CUR_HORZ_VERT_OFF,
((u32) (64 - c->size.y + yoff) << 16) | xoff,
((u32) (64 - cursor->image.height + yoff) << 16) | xoff,
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)
......@@ -162,70 +154,25 @@ static void aty_set_cursor(struct fb_info *info, int on)
wait_for_idle(par);
}
static void aty_cursor_timer_handler(unsigned long dev_addr)
{
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)
int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct fb_info *info = p->fb_info;
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct aty_cursor *c = par->cursor;
if (!c)
return;
return -1;
#ifdef __sparc__
if (par->mmaped && (!info->display_fg
|| info->display_fg->vc_num ==
par->vtconsole))
if (par->mmaped)
return;
#endif
x *= fontwidth(p);
y *= fontheight(p);
if (c->pos.x == x && c->pos.y == y
&& (mode == CM_ERASE) == !c->enable)
return;
aty_set_cursor(info);
cursor->image.dx = info->cursor.image.dx;
cursor->image.dy = info->cursor.image.dy;
c->enable = 0;
if (c->on)
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;
}
aty_set_cursor(info);
return 0;
}
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;
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;
cursor->offset = info->fix.smem_len;
#ifdef __sparc__
addr = (unsigned long) info->screen_base - 0x800000 + cursor->offset;
addr = info->screen_base - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) addr;
#else
#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);
#else
addr = (unsigned long) info->screen_base + cursor->offset;
addr = (unsigned long) info->screen_base + info->fix.smem_len;
cursor->ram = (u8 *) addr;
#endif
#endif
if (!cursor->ram) {
kfree(cursor);
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;
}
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 fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
int i, j;
......@@ -288,10 +219,10 @@ int atyfb_set_font(struct display *d, int width, int height)
height = 16;
}
c->hot.x = 0;
c->hot.y = 0;
c->size.x = width;
c->size.y = height;
cursor->hot.x = 0;
cursor->hot.y = 0;
cursor->image.width = width;
cursor->image.height = height;
memset(c->bits, 0xff, sizeof(c->bits));
memset(c->mask, 0, sizeof(c->mask));
......
This diff is collapsed.
......@@ -118,12 +118,6 @@ config FBCON_ADVANCED
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
tristate "Amiga bitplanes support" if FBCON_ADVANCED
depends on FRAMEBUFFER_CONSOLE
......
......@@ -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_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
......@@ -37,7 +37,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
# Files generated that shall be removed upon make clean
clean-files := promcon_tbl.c
......
......@@ -464,13 +464,14 @@ static void vgaHWRestore(const struct fb_info *info,
/*
* 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;
int waitcycles;
while (par->neo2200->bltStat & 1)
waitcycles++;
return 0;
}
static inline void neo2200_wait_fifo(struct fb_info *info,
......
This diff is collapsed.
......@@ -74,6 +74,7 @@ typedef unsigned int U032;
#define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
#define NV_ARCH_20 0x20
/***************************************************************************\
* *
* FIFO registers. *
......
......@@ -4,10 +4,6 @@
#include <linux/config.h>
#include <linux/fb.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"
/* GGI compatibility macros */
......@@ -27,56 +23,16 @@ struct riva_regs {
RIVA_HW_STATE ext;
};
typedef struct {
unsigned char red, green, blue, transp;
} riva_cfb8_cmap_t;
struct rivafb_info;
struct rivafb_info {
struct fb_info info; /* kernel framebuffer info */
struct riva_par {
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 fb_base; /* virtual framebuffer base addr */
unsigned ram_amount; /* amount of RAM on card, in bytes */
unsigned dclk_max; /* max DCLK */
struct riva_regs initial_state; /* initial startup video mode */
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 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
struct { int vram; int vram_valid; } mtrr;
#endif
......
......@@ -23,15 +23,16 @@
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE regs
#include <video/sgivw.h>
#define DBE_REG_BASE default_par.regs
#include <asm/sgi-vwdbe.h>
struct sgivw_par {
asregs *regs;
struct asregs *regs;
u32 cmap_fifo;
u_long timing_num;
};
......@@ -44,11 +45,12 @@ struct sgivw_par {
*/
/* set by arch/i386/kernel/setup.c */
u_long sgivwfb_mem_phys;
u_long sgivwfb_mem_size;
extern unsigned long sgivwfb_mem_phys;
extern unsigned long sgivwfb_mem_size;
static struct fb_info fb_info;
static struct sgivw_par default_par;
static u32 pseudo_palette[17];
static struct fb_info fb_info;
static int ypan = 0;
static int ywrap = 0;
......@@ -58,7 +60,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
.visual = FB_VISUAL_PSEUDOCOLOR,
.mmio_start = DBE_REG_PHYS,
.mmio_len = DBE_REG_SIZE,
.accel_flags = FB_ACCEL_NONE
.accel = FB_ACCEL_NONE
};
static struct fb_var_screeninfo sgivwfb_var __initdata = {
......@@ -152,8 +154,8 @@ static unsigned long bytes_per_pixel(int bpp)
static void dbe_TurnOffDma(void)
{
int i;
unsigned int readVal;
int i;
// Check to see if things are already turned off:
// 1) Check to see if dbe is not using the internal dotclock.
......@@ -219,7 +221,7 @@ static void dbe_TurnOffDma(void)
static int sgivwfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int err, activate = var->activate;
struct sgivw_par *par = (struct sgivw_par *)info->par;
struct dbe_timing_info *timing;
u_long line_length;
u_long min_mode;
......@@ -362,7 +364,7 @@ static int sgivwfb_set_par(struct fb_info *info)
u32 readVal, outputVal;
int wholeTilesX, maxPixelsPerTileX;
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 bytesPerPixel; // Bytes per pixel
......@@ -698,11 +700,16 @@ int __init sgivwfb_init(void)
printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
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) {
printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs;
}
#ifdef CONFIG_MTRR
mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
MTRR_TYPE_WRCOMB, 1);
......@@ -722,8 +729,7 @@ int __init sgivwfb_init(void)
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.screen_base =
ioremap_nocache((unsigned long) sgivwfb_mem_phys,
sgivwfb_mem_size);
fb_info.screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
if (!fb_info.screen_base) {
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
goto fail_ioremap_fbmem;
......@@ -732,15 +738,11 @@ int __init sgivwfb_init(void)
fb_alloc_cmap(&fb_info.cmap, 256, 0);
if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR
"sgivwfb: couldn't register framebuffer\n");
printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
goto fail_register_framebuffer;
}
printk(KERN_INFO
"fb%d: Virtual frame buffer device, using %ldK of video memory\n",
minor(fb_info.node), sgivwfb_mem_size >> 10);
printk(KERN_INFO "fb%d: SGI BDE frame buffer device, using %ldK of video memory\n", minor(fb_info.node, sgivwfb_mem_size >> 10);
return 0;
fail_register_framebuffer:
......
......@@ -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_copyarea(struct fb_info *info, struct fb_copyarea *area);
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 = {
.owner = THIS_MODULE,
......@@ -176,6 +177,7 @@ static struct fb_ops tdfxfb_ops = {
.fb_fillrect = tdfxfb_fillrect,
.fb_copyarea = tdfxfb_copyarea,
.fb_imageblit = tdfxfb_imageblit,
.fb_sync = banshee_wait_idle,
.fb_cursor = cfb_cursor,
};
......@@ -183,7 +185,7 @@ static struct fb_ops tdfxfb_ops = {
* do_xxx: Hardware-specific functions
*/
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);
/*
......@@ -316,8 +318,9 @@ static inline void banshee_make_room(struct tdfx_par *par, int 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;
banshee_make_room(par, 1);
......@@ -368,11 +371,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
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;
banshee_wait_idle(par);
banshee_wait_idle(info);
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)
tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
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)
......@@ -753,7 +757,7 @@ static int tdfxfb_set_par(struct fb_info *info)
reg.miscinit0 &= ~(1 << 31);
break;
}
#endif
#endif
do_write_regs(par, &reg);
/* Now change fb_fix_screeninfo according to changes in par */
......@@ -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, DSTSIZE, rect->width | (rect->height << 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)
tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
tdfx_outl(par, DSTXY, area->dx | (area->dy << 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)
......@@ -939,8 +943,8 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
tdfx_outl(par, COLORBACK, pixmap->bg_color);
srcfmt = 0x400000;
} else {
banshee_make_room(par, 6 + ((size + 3) >> 2));
srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
//banshee_make_room(par, 6 + ((size + 3) >> 2));
//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
}
tdfx_outl(par, SRCXY, 0);
......@@ -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 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,
return err;
}
info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
sizeof(u32) * 16, GFP_KERNEL);
size = sizeof(struct fb_info)+sizeof(struct tdfx_par)+16*sizeof(u32);
info = kmalloc(size, GFP_KERNEL);
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 */
switch (pdev->device) {
......@@ -1078,7 +1220,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
info->fbops = &tdfxfb_ops;
info->fix = tdfx_fix;
info->par = default_par;
info->pseudo_palette = (void *)(info + 1);
info->pseudo_palette = (void *)(default_par + 1);
info->flags = FBINFO_FLAG_DEFAULT;
if (!mode_option)
......
......@@ -368,7 +368,7 @@ struct fb_ops {
/* perform polling on fb device */
int (*fb_poll)(struct fb_info *info, poll_table *wait);
/* wait for blit idle, optional */
void (*fb_sync)(struct fb_info *info);
int (*fb_sync)(struct fb_info *info);
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
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