* [PATCH][RIVAFB]: Updates to rivafb driver
@ 2004-06-15 20:06 Antonino A. Daplas
2004-06-15 22:17 ` David Eger
0 siblings, 1 reply; 14+ messages in thread
From: Antonino A. Daplas @ 2004-06-15 20:06 UTC (permalink / raw)
To: James Simmons; +Cc: Andrew Morton, Linux Fbdev development list
Hi,
The patch updates rivafb to the following:
1. Fixed cursor corruption and simplified cursor code.
2. Maximized var->yres_virtual on initial mode setting. Scrolling, therefore, defaults
to y-panning which is significantly faster.
3. Restricted var->xres_virtual and var->yres_virtual to 0x7fff (hardware limitation?).
Otherwise, var->yres_virtual > 0x7fff + panning will hang the GPU.
4. Added I2C/DDC support. This feature enables independent mode setup to rivafb.
'stty rows n cols n' should now work correctly. This is a configurable option.
5. Various/minor fixes to drawing code.
Diff is against linux-2.6.6. Test hardware - GeForce 2 MX.
Tony
Signed-off-by: Antonino Daplas <adaplas@pol.net>
diff -Naur linux-2.6.6-orig/drivers/video/Kconfig linux-2.6.6-new/drivers/video/Kconfig
--- linux-2.6.6-orig/drivers/video/Kconfig 2004-06-15 04:58:39.000000000 +0000
+++ linux-2.6.6-new/drivers/video/Kconfig 2004-06-15 19:32:13.000000000 +0000
@@ -405,6 +405,11 @@
To compile this driver as a module, choose M here: the
module will be called rivafb.
+config FB_RIVA_I2C
+ bool "Enable DDC Support"
+ depends on FB_RIVA && I2C
+ help
+
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI
diff -Naur linux-2.6.6-orig/drivers/video/riva/Makefile linux-2.6.6-new/drivers/video/riva/Makefile
--- linux-2.6.6-orig/drivers/video/riva/Makefile 2004-05-10 02:31:59.000000000 +0000
+++ linux-2.6.6-new/drivers/video/riva/Makefile 2004-06-15 19:51:56.794341848 +0000
@@ -2,6 +2,10 @@
# Makefile for the Riva framebuffer driver
#
-obj-$(CONFIG_FB_RIVA) += rivafb.o
+obj-$(CONFIG_FB_RIVA) += rivafb.o
-rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+
+ifdef CONFIG_FB_RIVA_I2C
+ rivafb-objs += rivafb-i2c.o
+endif
diff -Naur linux-2.6.6-orig/drivers/video/riva/fbdev.c linux-2.6.6-new/drivers/video/riva/fbdev.c
--- linux-2.6.6-orig/drivers/video/riva/fbdev.c 2004-05-10 02:32:54.000000000 +0000
+++ linux-2.6.6-new/drivers/video/riva/fbdev.c 2004-06-15 19:31:33.000000000 +0000
@@ -296,9 +296,8 @@
static int nomtrr __initdata = 0;
#endif
-#ifndef MODULE
static char *mode_option __initdata = NULL;
-#endif
+static int strictmode = 0;
static struct fb_fix_screeninfo rivafb_fix = {
.id = "nVidia",
@@ -493,54 +492,35 @@
* rivafb_cursor()
*/
static void rivafb_load_cursor_image(struct riva_par *par, u8 *data,
- u8 *mask, u16 bg, u16 fg, u32 w, u32 h)
+ u16 bg, u16 fg, u32 w, u32 h)
{
int i, j, k = 0;
- u32 b, m, tmp;
+ u32 *dat, b, m, tmp;
+ dat = (u32 *) data;
for (i = 0; i < h; i++) {
- b = *((u32 *)data);
- b = (u32)((u32 *)b + 1);
- m = *((u32 *)mask);
- m = (u32)((u32 *)m + 1);
+ b = dat[i];
reverse_order(&b);
-
for (j = 0; j < w/2; j++) {
tmp = 0;
#if defined (__BIG_ENDIAN)
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
b <<= 1;
m <<= 1;
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & (1 << 31)) ? fg : bg;
b <<= 1;
m <<= 1;
#else
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & 1) ? fg : bg;
b >>= 1;
m >>= 1;
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & 1) ? fg << 16 : bg << 16;
b >>= 1;
m >>= 1;
#endif
- writel(tmp, par->riva.CURSOR + k++);
+ writel(tmp, &par->riva.CURSOR[k++]);
}
k += (MAX_CURS - w)/2;
}
@@ -833,6 +813,24 @@
rivafb_blank(0, info);
}
+static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+{
+ var->xres = var->xres_virtual = modedb->xres;
+ var->yres = modedb->yres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = modedb->pixclock;
+ var->left_margin = modedb->left_margin;
+ var->right_margin = modedb->right_margin;
+ var->upper_margin = modedb->upper_margin;
+ var->lower_margin = modedb->lower_margin;
+ var->hsync_len = modedb->hsync_len;
+ var->vsync_len = modedb->vsync_len;
+ var->sync = modedb->sync;
+ var->vmode = modedb->vmode;
+}
+
/**
* rivafb_do_maximize -
* @info: pointer to fb_info object containing info for current riva board
@@ -872,7 +870,7 @@
"using maximum available virtual resolution\n");
for (i = 0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- info->fix.smem_len / 2)
+ info->fix.smem_len)
break;
}
if (modes[i].xres == -1) {
@@ -927,35 +925,47 @@
"virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
return -EINVAL;
}
+ if (var->xres_virtual > 0x7fff)
+ var->xres_virtual = 0x7fff;
+ if (var->yres_virtual > 0x7fff)
+ var->yres_virtual = 0x7fff;
return 0;
}
+static void
+riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(par->riva, Patt, 4);
+ par->riva.Patt->Color0 = clr0;
+ par->riva.Patt->Color1 = clr1;
+ par->riva.Patt->Monochrome[0] = pat0;
+ par->riva.Patt->Monochrome[1] = pat1;
+}
+
/* acceleration routines */
inline void wait_for_idle(struct riva_par *par)
{
while (par->riva.Busy(&par->riva));
}
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct riva_par *par)
-{
- RIVA_FIFO_FREE(par->riva, Patt, 5);
- par->riva.Patt->Shape = 0;
- par->riva.Patt->Color0 = 0xffffffff;
- par->riva.Patt->Color1 = 0xffffffff;
- par->riva.Patt->Monochrome[0] = 0xffffffff;
- par->riva.Patt->Monochrome[1] = 0xffffffff;
-
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC;
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+riva_set_rop_solid(struct riva_par *par, int rop)
+{
+ riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ RIVA_FIFO_FREE(par->riva, Rop, 1);
+ par->riva.Rop->Rop3 = rop;
+
}
void riva_setup_accel(struct riva_par *par)
{
RIVA_FIFO_FREE(par->riva, Clip, 2);
par->riva.Clip->TopLeft = 0x0;
- par->riva.Clip->WidthHeight = 0x80008000;
- riva_setup_ROP(par);
+ par->riva.Clip->WidthHeight = 0x7fff7fff;
+ riva_set_rop_solid(par, 0xcc);
wait_for_idle(par);
}
@@ -1043,7 +1053,9 @@
static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
+ struct fb_monspecs *specs = &info->monspecs;
int nom, den; /* translating from pixels->bytes */
+ int mode_valid = 0;
switch (var->bits_per_pixel) {
case 1 ... 8:
@@ -1094,6 +1106,73 @@
return -EINVAL;
}
+ if (!strictmode) {
+ if (!fb_validate_mode(var, info))
+ mode_valid = 1;
+ }
+
+ /* find best mode from modedb */
+ if (!mode_valid && specs->modedb_len) {
+ int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
+
+ best_refresh = best = best_x = best_y = 0;
+ diff_x = diff_y = -1;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (var->xres <= specs->modedb[i].xres &&
+ !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].xres - var->xres < diff_x) {
+ best_x = specs->modedb[i].xres;
+ diff_x = best_x - var->xres;
+ }
+ if (!diff_x) break;
+ }
+
+ if (diff_x != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ var->yres <= specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].yres-var->yres < diff_y) {
+ best_y = specs->modedb[i].yres;
+ diff_y = best_y - var->yres;
+ }
+ if (!diff_y) break;
+ }
+ }
+
+ if (diff_y != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ best_y == specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].refresh > best_refresh) {
+ best_refresh=specs->modedb[i].refresh;
+ best = i;
+ }
+ }
+ }
+
+ if (best_refresh) {
+ riva_update_var(var, &specs->modedb[best]);
+ mode_valid = 1;
+ }
+ }
+
+ /* calculate modeline if supported by monitor */
+ if (!mode_valid && info->monspecs.gtf) {
+ if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ mode_valid = 1;
+ }
+ if (!mode_valid && info->monspecs.modedb_len)
+ return -EINVAL;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual <= var->yres)
+ var->yres_virtual = -1;
if (rivafb_do_maximize(info, var, nom, den) < 0)
return -EINVAL;
@@ -1329,8 +1408,7 @@
break;
}
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = rop;
+ riva_set_rop_solid(par, rop);
RIVA_FIFO_FREE(par->riva, Bitmap, 1);
par->riva.Bitmap->Color1A = color;
@@ -1338,10 +1416,12 @@
RIVA_FIFO_FREE(par->riva, Bitmap, 2);
par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
(rect->dx << 16) | rect->dy;
+ mb();
par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
(rect->width << 16) | rect->height;
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC; // back to COPY
+ mb();
+ riva_set_rop_solid(par, 0xcc);
+
}
/**
@@ -1362,8 +1442,9 @@
RIVA_FIFO_FREE(par->riva, Blt, 3);
par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx;
par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx;
+ mb();
par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
- wait_for_idle(par);
+ mb();
}
static inline void convert_bgcolor_16(u32 *col)
@@ -1372,6 +1453,7 @@
| ((*col & 0x000003E0) << 6)
| ((*col & 0x0000001F) << 3)
| 0xFF000000;
+ mb();
}
/**
@@ -1478,7 +1560,6 @@
{
struct riva_par *par = (struct riva_par *) info->par;
u8 data[MAX_CURS * MAX_CURS/8];
- u8 mask[MAX_CURS * MAX_CURS/8];
u16 fg, bg;
int i;
@@ -1508,7 +1589,7 @@
info->cursor.image.fg_color = cursor->image.fg_color;
}
- if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
u32 bg_idx = info->cursor.image.bg_color;
u32 fg_idx = info->cursor.image.fg_color;
u32 s_pitch = (info->cursor.image.width+7) >> 3;
@@ -1517,34 +1598,35 @@
u8 *msk = (u8 *) info->cursor.mask;
u8 src[64];
+ info->cursor.image.data = cursor->image.data;
switch (info->cursor.rop) {
case ROP_XOR:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
- src[i] = dat[i] ^ msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] ^ msk[i];
break;
case ROP_COPY:
default:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-
- src[i] = dat[i] & msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] & msk[i];
break;
}
- fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src, s_pitch, info->cursor.image.height);
-
- fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
+ fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
+ s_pitch, info->cursor.image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
((info->cmap.green[fg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
par->riva.LockUnlock(&par->riva, 0);
- rivafb_load_cursor_image(par, data, mask, bg, fg,
+ rivafb_load_cursor_image(par, data, bg, fg,
info->cursor.image.width,
info->cursor.image.height);
}
@@ -1586,24 +1668,14 @@
static int __devinit riva_set_fbinfo(struct fb_info *info)
{
- struct riva_par *par = (struct riva_par *) info->par;
unsigned int cmap_len;
info->flags = FBINFO_FLAG_DEFAULT;
info->var = rivafb_default_var;
- info->fix = rivafb_fix;
- info->fbops = &riva_fb_ops;
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
info->pseudo_palette = pseudo_palette;
-#ifndef MODULE
- if (mode_option)
- fb_find_mode(&info->var, info, mode_option,
- NULL, 0, NULL, 8);
-#endif
- if (par->use_default_var)
- /* We will use the modified default var */
- info->var = rivafb_default_var;
-
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
@@ -1611,7 +1683,8 @@
info->pixmap.buf_align = 4;
info->pixmap.scan_align = 4;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
- return 0;
+ info->var.yres_virtual = -1;
+ return (rivafb_check_var(&info->var, info));
}
#ifdef CONFIG_PPC_OF
@@ -1632,77 +1705,35 @@
}
#endif /* CONFIG_PPC_OF */
-static int riva_dfp_parse_EDID(struct riva_par *par)
+static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- unsigned char *block = par->EDID;
-
- if (!block)
- return 0;
-
- /* jump to detailed timing block section */
- block += 54;
+ struct fb_monspecs *specs = &info->monspecs;
+ struct fb_videomode modedb;
- par->clock = (block[0] + (block[1] << 8));
- par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
- par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
- par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
- par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
- par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
- par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
- par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
- par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
- par->interlaced = ((block[17] & 0x80) >> 7);
- par->synct = ((block[17] & 0x18) >> 3);
- par->misc = ((block[17] & 0x06) >> 1);
- par->hAct_high = par->vAct_high = 0;
- if (par->synct == 3) {
- if (par->misc & 2)
- par->hAct_high = 1;
- if (par->misc & 1)
- par->vAct_high = 1;
+ /* respect mode options */
+ if (mode_option) {
+ fb_find_mode(var, info, mode_option,
+ specs->modedb, specs->modedb_len,
+ NULL, 8);
+ } else if (specs->modedb != NULL) {
+ /* get preferred timing */
+ if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
+ int i;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+ modedb = specs->modedb[i];
+ break;
+ }
+ }
+ } else {
+ /* otherwise, get first mode in database */
+ modedb = specs->modedb[0];
+ }
+ var->bits_per_pixel = 8;
+ riva_update_var(var, &modedb);
}
-
- printk(KERN_INFO PFX
- "detected DFP panel size from EDID: %dx%d\n",
- par->panel_xres, par->panel_yres);
- par->got_dfpinfo = 1;
- return 1;
-}
-
-static void riva_update_default_var(struct fb_info *info)
-{
- struct fb_var_screeninfo *var = &rivafb_default_var;
- struct riva_par *par = (struct riva_par *) info->par;
-
- var->xres = par->panel_xres;
- var->yres = par->panel_yres;
- var->xres_virtual = par->panel_xres;
- var->yres_virtual = par->panel_yres;
- var->xoffset = var->yoffset = 0;
- var->bits_per_pixel = 8;
- var->pixclock = 100000000 / par->clock;
- var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
- var->right_margin = par->hOver_plus;
- var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
- var->lower_margin = par->vOver_plus;
- var->hsync_len = par->hSync_width;
- var->vsync_len = par->vSync_width;
- var->sync = 0;
-
- if (par->synct == 3) {
- if (par->hAct_high)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (par->vAct_high)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- }
-
- var->vmode = 0;
- if (par->interlaced)
- var->vmode |= FB_VMODE_INTERLACED;
-
var->accel_flags |= FB_ACCELF_TEXT;
-
- par->use_default_var = 1;
}
@@ -1713,19 +1744,27 @@
printk("rivafb: could not retrieve EDID from OF\n");
#else
/* XXX use other methods later */
+#ifdef CONFIG_FB_RIVA_I2C
+ struct riva_par *par = (struct riva_par *) info->par;
+
+ riva_create_i2c_busses(par);
+ riva_probe_i2c_connector(par, 1, &par->EDID);
+ riva_delete_i2c_busses(par);
+#endif
#endif
}
-static void riva_get_dfpinfo(struct fb_info *info)
+static void riva_get_edidinfo(struct fb_info *info)
{
+ struct fb_var_screeninfo *var = &rivafb_default_var;
struct riva_par *par = (struct riva_par *) info->par;
- if (riva_dfp_parse_EDID(par))
- riva_update_default_var(info);
+ fb_edid_to_monspecs(par->EDID, &info->monspecs);
+ riva_update_default_var(var, info);
/* if user specified flatpanel, we respect that */
- if (par->got_dfpinfo == 1)
+ if (info->monspecs.input & FB_DISP_DDI)
par->FlatPanel = 1;
}
@@ -1755,6 +1794,7 @@
memset(info, 0, sizeof(struct fb_info));
memset(default_par, 0, sizeof(struct riva_par));
+ default_par->pdev = pd;
info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
@@ -1802,10 +1842,6 @@
info->par = default_par;
- riva_get_EDID(info, pd);
-
- riva_get_dfpinfo(info);
-
switch (default_par->riva.Architecture) {
case NV_ARCH_03:
/* Riva128's PRAMIN is in the "framebuffer" space
@@ -1870,6 +1906,11 @@
}
#endif /* CONFIG_MTRR */
+ info->fbops = &riva_fb_ops;
+ info->fix = rivafb_fix;
+ riva_get_EDID(info, pd);
+ riva_get_edidinfo(info);
+
if (riva_set_fbinfo(info) < 0) {
printk(KERN_ERR PFX "error setting initial video mode\n");
goto err_out_iounmap_fb;
@@ -1978,6 +2019,8 @@
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
#endif
+ } else if (!strncmp(this_opt, "strictmode", 10)) {
+ strictmode = 1;
} else
mode_option = this_opt;
}
@@ -2026,6 +2069,8 @@
#ifdef CONFIG_MTRR
MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM(strictmode, "i");
+MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
#endif
#endif /* MODULE */
diff -Naur linux-2.6.6-orig/drivers/video/riva/rivafb-i2c.c linux-2.6.6-new/drivers/video/riva/rivafb-i2c.c
--- linux-2.6.6-orig/drivers/video/riva/rivafb-i2c.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.6-new/drivers/video/riva/rivafb-i2c.c 2004-06-15 19:31:33.000000000 +0000
@@ -0,0 +1,209 @@
+/*
+ * linux/drivers/video/riva/fbdev-i2c.c - nVidia i2c
+ *
+ * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
+ *
+ * Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
+ *
+ * Based on radeonfb-i2c.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+
+#include <asm/io.h>
+
+#include "rivafb.h"
+#include "../edid.h"
+
+#define RIVA_DDC 0x50
+
+static void riva_gpio_setscl(void* data, int state)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
+
+ if (state)
+ val |= 0x20;
+ else
+ val &= ~0x20;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
+}
+
+static void riva_gpio_setsda(void* data, int state)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
+
+ if (state)
+ val |= 0x10;
+ else
+ val &= ~0x10;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
+}
+
+static int riva_gpio_getscl(void* data)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val = 0;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
+ if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04)
+ val = 1;
+
+ val = VGA_RD08(par->riva.PCIO, 0x3d5);
+
+ return val;
+}
+
+static int riva_gpio_getsda(void* data)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val = 0;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
+ if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x08)
+ val = 1;
+
+ return val;
+}
+
+#define I2C_ALGO_RIVA 0x0e0000
+static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
+{
+ int rc;
+
+ strcpy(chan->adapter.name, name);
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.id = I2C_ALGO_RIVA;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = &chan->par->pdev->dev;
+ chan->algo.setsda = riva_gpio_setsda;
+ chan->algo.setscl = riva_gpio_setscl;
+ chan->algo.getsda = riva_gpio_getsda;
+ chan->algo.getscl = riva_gpio_getscl;
+ chan->algo.udelay = 40;
+ chan->algo.timeout = 20;
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ /* Raise SCL and SDA */
+ riva_gpio_setsda(chan, 1);
+ riva_gpio_setscl(chan, 1);
+ udelay(20);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ dev_dbg(&chan->par->pdev->dev, "I2C bus %s registered.\n", name);
+ else
+ dev_warn(&chan->par->pdev->dev, "Failed to register I2C bus %s.\n", name);
+ return rc;
+}
+
+void riva_create_i2c_busses(struct riva_par *par)
+{
+ par->chan[0].par = par;
+ par->chan[1].par = par;
+ par->chan[2].par = par;
+
+ switch (par->riva.Architecture) {
+#if 0 /* no support yet for other nVidia chipsets */
+ par->chan[2].ddc_base = 0x50;
+ riva_setup_i2c_bus(&par->chan[2], "BUS2");
+#endif
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ case NV_ARCH_04:
+ par->chan[1].ddc_base = 0x36;
+ riva_setup_i2c_bus(&par->chan[1], "BUS1");
+ case NV_ARCH_03:
+ par->chan[0].ddc_base = 0x3e;
+ riva_setup_i2c_bus(&par->chan[0], "BUS0");
+ }
+}
+
+void riva_delete_i2c_busses(struct riva_par *par)
+{
+ if (par->chan[0].par)
+ i2c_bit_del_bus(&par->chan[0].adapter);
+ par->chan[0].par = NULL;
+
+ if (par->chan[1].par)
+ i2c_bit_del_bus(&par->chan[1].adapter);
+ par->chan[1].par = NULL;
+
+}
+
+static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
+{
+ u8 start = 0x0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = RIVA_DDC,
+ .len = 1,
+ .buf = &start,
+ }, {
+ .addr = RIVA_DDC,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ },
+ };
+ u8 *buf;
+
+ buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!buf) {
+ dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
+ return NULL;
+ }
+ msgs[1].buf = buf;
+
+ if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
+ return buf;
+ dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
+ kfree(buf);
+ return NULL;
+}
+
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
+{
+ u8 *edid = NULL;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ /* Do the real work */
+ edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
+ if (edid)
+ break;
+ }
+ if (out_edid)
+ *out_edid = edid;
+ if (!edid)
+ return 1;
+
+ return 0;
+}
+
diff -Naur linux-2.6.6-orig/drivers/video/riva/rivafb.h linux-2.6.6-new/drivers/video/riva/rivafb.h
--- linux-2.6.6-orig/drivers/video/riva/rivafb.h 2004-05-10 02:32:27.000000000 +0000
+++ linux-2.6.6-new/drivers/video/riva/rivafb.h 2004-06-15 19:31:35.000000000 +0000
@@ -4,6 +4,10 @@
#include <linux/config.h>
#include <linux/fb.h>
#include <video/vga.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
#include "riva_hw.h"
/* GGI compatibility macros */
@@ -12,6 +16,12 @@
#define NUM_GRC_REGS 0x09
#define NUM_ATC_REGS 0x15
+/* I2C */
+#define DDC_SCL_READ_MASK (1 << 2)
+#define DDC_SCL_WRITE_MASK (1 << 5)
+#define DDC_SDA_READ_MASK (1 << 3)
+#define DDC_SDA_WRITE_MASK (1 << 4)
+
/* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
* From KGI originally. */
struct riva_regs {
@@ -23,6 +33,15 @@
RIVA_HW_STATE ext;
};
+struct riva_par;
+
+struct riva_i2c_chan {
+ struct riva_par *par;
+ unsigned long ddc_base;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
struct riva_par {
RIVA_HW_INST riva; /* interface to riva_hw.c */
@@ -36,26 +55,22 @@
u32 cursor_data[32 * 32/4];
int cursor_reset;
unsigned char *EDID;
-
- int panel_xres, panel_yres;
- int hOver_plus, hSync_width, hblank;
- int vOver_plus, vSync_width, vblank;
- int hAct_high, vAct_high, interlaced;
- int synct, misc, clock;
-
- int use_default_var;
- int got_dfpinfo;
unsigned int Chipset;
int forceCRTC;
Bool SecondCRTC;
int FlatPanel;
+ struct pci_dev *pdev;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
+ struct riva_i2c_chan chan[3];
};
void riva_common_setup(struct riva_par *);
unsigned long riva_get_memlen(struct riva_par *);
unsigned long riva_get_maxdclk(struct riva_par *);
+void riva_delete_i2c_busses(struct riva_par *par);
+void riva_create_i2c_busses(struct riva_par *par);
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid);
#endif /* __RIVAFB_H */
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-15 20:06 [PATCH][RIVAFB]: Updates to rivafb driver Antonino A. Daplas
@ 2004-06-15 22:17 ` David Eger
2004-06-15 22:18 ` jsimmons
2004-06-16 2:44 ` Antonino A. Daplas
0 siblings, 2 replies; 14+ messages in thread
From: David Eger @ 2004-06-15 22:17 UTC (permalink / raw)
To: adaplas; +Cc: James Simmons, Andrew Morton, Linux Fbdev development list
hey tony,
your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
-dte
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-15 22:17 ` David Eger
@ 2004-06-15 22:18 ` jsimmons
2004-06-16 2:44 ` Antonino A. Daplas
1 sibling, 0 replies; 14+ messages in thread
From: jsimmons @ 2004-06-15 22:18 UTC (permalink / raw)
To: David Eger; +Cc: adaplas, Andrew Morton, Linux Fbdev development list
I wil give it a try tonight. I'm working on the riva driver as well. I got
a oops in the i2c code. This is from the code in the fbdev-2.5 BK branch.
On Tue, 15 Jun 2004, David Eger wrote:
>
> hey tony,
>
> your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
> applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
>
> -dte
>
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-15 22:17 ` David Eger
2004-06-15 22:18 ` jsimmons
@ 2004-06-16 2:44 ` Antonino A. Daplas
2004-06-16 5:53 ` Antonino A. Daplas
1 sibling, 1 reply; 14+ messages in thread
From: Antonino A. Daplas @ 2004-06-16 2:44 UTC (permalink / raw)
To: David Eger; +Cc: James Simmons, Andrew Morton, Linux Fbdev development list
On Wednesday 16 June 2004 06:17, David Eger wrote:
> hey tony,
>
> your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
> applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
>
Ok. Patch against 2.6.7-rc3-mm2.
Note I haven't added the hardware acceleration capability support yet,
so scrolling is still slow.
Secondly, stty seems not to work anymore, though I'm sure
the driver can do mode setup independently if with DDC. I'll look into
this later.
Tony
Signed-off-by: Antonino Daplas <adaplas@pol.net>
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/Kconfig linux-2.6.6-rc3-mm2/drivers/video/Kconfig
--- linux-2.6.6-rc3-mm2-orig/drivers/video/Kconfig 2004-06-16 01:17:54.000000000 +0000
+++ linux-2.6.6-rc3-mm2/drivers/video/Kconfig 2004-06-16 01:20:45.314626384 +0000
@@ -432,6 +432,11 @@
To compile this driver as a module, choose M here: the
module will be called rivafb.
+config FB_RIVA_I2C
+ bool "Enable DDC Support"
+ depends on FB_RIVA && I2C
+ help
+
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/riva/Makefile linux-2.6.6-rc3-mm2/drivers/video/riva/Makefile
--- linux-2.6.6-rc3-mm2-orig/drivers/video/riva/Makefile 2004-05-10 02:31:59.000000000 +0000
+++ linux-2.6.6-rc3-mm2/drivers/video/riva/Makefile 2004-06-16 01:20:45.315626232 +0000
@@ -2,6 +2,10 @@
# Makefile for the Riva framebuffer driver
#
-obj-$(CONFIG_FB_RIVA) += rivafb.o
+obj-$(CONFIG_FB_RIVA) += rivafb.o
-rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+
+ifdef CONFIG_FB_RIVA_I2C
+ rivafb-objs += rivafb-i2c.o
+endif
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/riva/fbdev.c linux-2.6.6-rc3-mm2/drivers/video/riva/fbdev.c
--- linux-2.6.6-rc3-mm2-orig/drivers/video/riva/fbdev.c 2004-06-16 01:17:54.000000000 +0000
+++ linux-2.6.6-rc3-mm2/drivers/video/riva/fbdev.c 2004-06-16 01:23:31.099423264 +0000
@@ -296,9 +296,8 @@
static int nomtrr __initdata = 0;
#endif
-#ifndef MODULE
static char *mode_option __initdata = NULL;
-#endif
+static int strictmode = 0;
static struct fb_fix_screeninfo rivafb_fix = {
.id = "nVidia",
@@ -493,54 +492,30 @@
* rivafb_cursor()
*/
static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
- u8 *mask8, u16 bg, u16 fg, u32 w, u32 h)
+ u16 bg, u16 fg, u32 w, u32 h)
{
int i, j, k = 0;
- u32 b, m, tmp;
+ u32 b, tmp;
u32 *data = (u32 *)data8;
- u32 *mask = (u32 *)mask8;
for (i = 0; i < h; i++) {
b = *data++;
- m = *mask++;
reverse_order(&b);
for (j = 0; j < w/2; j++) {
tmp = 0;
#if defined (__BIG_ENDIAN)
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
b <<= 1;
- m <<= 1;
-
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & (1 << 31)) ? fg : bg;
b <<= 1;
- m <<= 1;
#else
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & 1) ? fg : bg;
b >>= 1;
- m >>= 1;
-
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & 1) ? fg << 16 : bg << 16;
b >>= 1;
- m >>= 1;
#endif
- writel(tmp, par->riva.CURSOR + k++);
+ writel(tmp, &par->riva.CURSOR[k++]);
}
k += (MAX_CURS - w)/2;
}
@@ -833,6 +808,24 @@
rivafb_blank(0, info);
}
+static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+{
+ var->xres = var->xres_virtual = modedb->xres;
+ var->yres = modedb->yres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = modedb->pixclock;
+ var->left_margin = modedb->left_margin;
+ var->right_margin = modedb->right_margin;
+ var->upper_margin = modedb->upper_margin;
+ var->lower_margin = modedb->lower_margin;
+ var->hsync_len = modedb->hsync_len;
+ var->vsync_len = modedb->vsync_len;
+ var->sync = modedb->sync;
+ var->vmode = modedb->vmode;
+}
+
/**
* rivafb_do_maximize -
* @info: pointer to fb_info object containing info for current riva board
@@ -872,7 +865,7 @@
"using maximum available virtual resolution\n");
for (i = 0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- info->fix.smem_len / 2)
+ info->fix.smem_len)
break;
}
if (modes[i].xres == -1) {
@@ -927,35 +920,47 @@
"virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
return -EINVAL;
}
+ if (var->xres_virtual > 0x7fff)
+ var->xres_virtual = 0x7fff;
+ if (var->yres_virtual > 0x7fff)
+ var->yres_virtual = 0x7fff;
return 0;
}
+static void
+riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(par->riva, Patt, 4);
+ par->riva.Patt->Color0 = clr0;
+ par->riva.Patt->Color1 = clr1;
+ par->riva.Patt->Monochrome[0] = pat0;
+ par->riva.Patt->Monochrome[1] = pat1;
+}
+
/* acceleration routines */
inline void wait_for_idle(struct riva_par *par)
{
while (par->riva.Busy(&par->riva));
}
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct riva_par *par)
-{
- RIVA_FIFO_FREE(par->riva, Patt, 5);
- par->riva.Patt->Shape = 0;
- par->riva.Patt->Color0 = 0xffffffff;
- par->riva.Patt->Color1 = 0xffffffff;
- par->riva.Patt->Monochrome[0] = 0xffffffff;
- par->riva.Patt->Monochrome[1] = 0xffffffff;
-
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC;
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+riva_set_rop_solid(struct riva_par *par, int rop)
+{
+ riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ RIVA_FIFO_FREE(par->riva, Rop, 1);
+ par->riva.Rop->Rop3 = rop;
+
}
void riva_setup_accel(struct riva_par *par)
{
RIVA_FIFO_FREE(par->riva, Clip, 2);
par->riva.Clip->TopLeft = 0x0;
- par->riva.Clip->WidthHeight = 0x80008000;
- riva_setup_ROP(par);
+ par->riva.Clip->WidthHeight = 0x7fff7fff;
+ riva_set_rop_solid(par, 0xcc);
wait_for_idle(par);
}
@@ -1043,7 +1048,9 @@
static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
+ struct fb_monspecs *specs = &info->monspecs;
int nom, den; /* translating from pixels->bytes */
+ int mode_valid = 0;
switch (var->bits_per_pixel) {
case 1 ... 8:
@@ -1094,6 +1101,73 @@
return -EINVAL;
}
+ if (!strictmode) {
+ if (!fb_validate_mode(var, info))
+ mode_valid = 1;
+ }
+
+ /* find best mode from modedb */
+ if (!mode_valid && specs->modedb_len) {
+ int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
+
+ best_refresh = best = best_x = best_y = 0;
+ diff_x = diff_y = -1;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (var->xres <= specs->modedb[i].xres &&
+ !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].xres - var->xres < diff_x) {
+ best_x = specs->modedb[i].xres;
+ diff_x = best_x - var->xres;
+ }
+ if (!diff_x) break;
+ }
+
+ if (diff_x != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ var->yres <= specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].yres-var->yres < diff_y) {
+ best_y = specs->modedb[i].yres;
+ diff_y = best_y - var->yres;
+ }
+ if (!diff_y) break;
+ }
+ }
+
+ if (diff_y != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ best_y == specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].refresh > best_refresh) {
+ best_refresh=specs->modedb[i].refresh;
+ best = i;
+ }
+ }
+ }
+
+ if (best_refresh) {
+ riva_update_var(var, &specs->modedb[best]);
+ mode_valid = 1;
+ }
+ }
+
+ /* calculate modeline if supported by monitor */
+ if (!mode_valid && info->monspecs.gtf) {
+ if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ mode_valid = 1;
+ }
+ if (!mode_valid && info->monspecs.modedb_len)
+ return -EINVAL;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual <= var->yres)
+ var->yres_virtual = -1;
if (rivafb_do_maximize(info, var, nom, den) < 0)
return -EINVAL;
@@ -1329,8 +1403,7 @@
break;
}
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = rop;
+ riva_set_rop_solid(par, rop);
RIVA_FIFO_FREE(par->riva, Bitmap, 1);
par->riva.Bitmap->Color1A = color;
@@ -1338,10 +1411,12 @@
RIVA_FIFO_FREE(par->riva, Bitmap, 2);
par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
(rect->dx << 16) | rect->dy;
+ mb();
par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
(rect->width << 16) | rect->height;
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC; // back to COPY
+ mb();
+ riva_set_rop_solid(par, 0xcc);
+
}
/**
@@ -1362,8 +1437,9 @@
RIVA_FIFO_FREE(par->riva, Blt, 3);
par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx;
par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx;
+ mb();
par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
- wait_for_idle(par);
+ mb();
}
static inline void convert_bgcolor_16(u32 *col)
@@ -1372,6 +1448,7 @@
| ((*col & 0x000003E0) << 6)
| ((*col & 0x0000001F) << 3)
| 0xFF000000;
+ mb();
}
/**
@@ -1478,7 +1555,6 @@
{
struct riva_par *par = (struct riva_par *) info->par;
u8 data[MAX_CURS * MAX_CURS/8];
- u8 mask[MAX_CURS * MAX_CURS/8];
u16 fg, bg;
int i;
@@ -1508,7 +1584,7 @@
info->cursor.image.fg_color = cursor->image.fg_color;
}
- if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
u32 bg_idx = info->cursor.image.bg_color;
u32 fg_idx = info->cursor.image.fg_color;
u32 s_pitch = (info->cursor.image.width+7) >> 3;
@@ -1517,34 +1593,35 @@
u8 *msk = (u8 *) info->cursor.mask;
u8 src[64];
+ info->cursor.image.data = cursor->image.data;
switch (info->cursor.rop) {
case ROP_XOR:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
- src[i] = dat[i] ^ msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] ^ msk[i];
break;
case ROP_COPY:
default:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-
- src[i] = dat[i] & msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] & msk[i];
break;
}
- fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src, s_pitch, info->cursor.image.height);
-
- fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
+ fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
+ s_pitch, info->cursor.image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
((info->cmap.green[fg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
par->riva.LockUnlock(&par->riva, 0);
- rivafb_load_cursor_image(par, data, mask, bg, fg,
+ rivafb_load_cursor_image(par, data, bg, fg,
info->cursor.image.width,
info->cursor.image.height);
}
@@ -1586,24 +1663,14 @@
static int __devinit riva_set_fbinfo(struct fb_info *info)
{
- struct riva_par *par = (struct riva_par *) info->par;
unsigned int cmap_len;
info->flags = FBINFO_FLAG_DEFAULT;
info->var = rivafb_default_var;
- info->fix = rivafb_fix;
- info->fbops = &riva_fb_ops;
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
info->pseudo_palette = pseudo_palette;
-#ifndef MODULE
- if (mode_option)
- fb_find_mode(&info->var, info, mode_option,
- NULL, 0, NULL, 8);
-#endif
- if (par->use_default_var)
- /* We will use the modified default var */
- info->var = rivafb_default_var;
-
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
@@ -1611,7 +1678,8 @@
info->pixmap.buf_align = 4;
info->pixmap.scan_align = 4;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
- return 0;
+ info->var.yres_virtual = -1;
+ return (rivafb_check_var(&info->var, info));
}
#ifdef CONFIG_PPC_OF
@@ -1645,77 +1713,35 @@
}
#endif /* CONFIG_PPC_OF */
-static int riva_dfp_parse_EDID(struct riva_par *par)
+static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- unsigned char *block = par->EDID;
-
- if (!block)
- return 0;
-
- /* jump to detailed timing block section */
- block += 54;
+ struct fb_monspecs *specs = &info->monspecs;
+ struct fb_videomode modedb;
- par->clock = (block[0] + (block[1] << 8));
- par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
- par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
- par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
- par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
- par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
- par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
- par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
- par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
- par->interlaced = ((block[17] & 0x80) >> 7);
- par->synct = ((block[17] & 0x18) >> 3);
- par->misc = ((block[17] & 0x06) >> 1);
- par->hAct_high = par->vAct_high = 0;
- if (par->synct == 3) {
- if (par->misc & 2)
- par->hAct_high = 1;
- if (par->misc & 1)
- par->vAct_high = 1;
+ /* respect mode options */
+ if (mode_option) {
+ fb_find_mode(var, info, mode_option,
+ specs->modedb, specs->modedb_len,
+ NULL, 8);
+ } else if (specs->modedb != NULL) {
+ /* get preferred timing */
+ if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
+ int i;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+ modedb = specs->modedb[i];
+ break;
+ }
+ }
+ } else {
+ /* otherwise, get first mode in database */
+ modedb = specs->modedb[0];
+ }
+ var->bits_per_pixel = 8;
+ riva_update_var(var, &modedb);
}
-
- printk(KERN_INFO PFX
- "detected DFP panel size from EDID: %dx%d\n",
- par->panel_xres, par->panel_yres);
- par->got_dfpinfo = 1;
- return 1;
-}
-
-static void riva_update_default_var(struct fb_info *info)
-{
- struct fb_var_screeninfo *var = &rivafb_default_var;
- struct riva_par *par = (struct riva_par *) info->par;
-
- var->xres = par->panel_xres;
- var->yres = par->panel_yres;
- var->xres_virtual = par->panel_xres;
- var->yres_virtual = par->panel_yres;
- var->xoffset = var->yoffset = 0;
- var->bits_per_pixel = 8;
- var->pixclock = 100000000 / par->clock;
- var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
- var->right_margin = par->hOver_plus;
- var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
- var->lower_margin = par->vOver_plus;
- var->hsync_len = par->hSync_width;
- var->vsync_len = par->vSync_width;
- var->sync = 0;
-
- if (par->synct == 3) {
- if (par->hAct_high)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (par->vAct_high)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- }
-
- var->vmode = 0;
- if (par->interlaced)
- var->vmode |= FB_VMODE_INTERLACED;
-
var->accel_flags |= FB_ACCELF_TEXT;
-
- par->use_default_var = 1;
}
@@ -1726,19 +1752,27 @@
printk("rivafb: could not retrieve EDID from OF\n");
#else
/* XXX use other methods later */
+#ifdef CONFIG_FB_RIVA_I2C
+ struct riva_par *par = (struct riva_par *) info->par;
+
+ riva_create_i2c_busses(par);
+ riva_probe_i2c_connector(par, 1, &par->EDID);
+ riva_delete_i2c_busses(par);
+#endif
#endif
}
-static void riva_get_dfpinfo(struct fb_info *info)
+static void riva_get_edidinfo(struct fb_info *info)
{
+ struct fb_var_screeninfo *var = &rivafb_default_var;
struct riva_par *par = (struct riva_par *) info->par;
- if (riva_dfp_parse_EDID(par))
- riva_update_default_var(info);
+ fb_edid_to_monspecs(par->EDID, &info->monspecs);
+ riva_update_default_var(var, info);
/* if user specified flatpanel, we respect that */
- if (par->got_dfpinfo == 1)
+ if (info->monspecs.input & FB_DISP_DDI)
par->FlatPanel = 1;
}
@@ -1768,6 +1802,7 @@
memset(info, 0, sizeof(struct fb_info));
memset(default_par, 0, sizeof(struct riva_par));
+ default_par->pdev = pd;
info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
@@ -1815,10 +1850,6 @@
info->par = default_par;
- riva_get_EDID(info, pd);
-
- riva_get_dfpinfo(info);
-
switch (default_par->riva.Architecture) {
case NV_ARCH_03:
/* Riva128's PRAMIN is in the "framebuffer" space
@@ -1883,6 +1914,11 @@
}
#endif /* CONFIG_MTRR */
+ info->fbops = &riva_fb_ops;
+ info->fix = rivafb_fix;
+ riva_get_EDID(info, pd);
+ riva_get_edidinfo(info);
+
if (riva_set_fbinfo(info) < 0) {
printk(KERN_ERR PFX "error setting initial video mode\n");
goto err_out_iounmap_fb;
@@ -1991,6 +2027,8 @@
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
#endif
+ } else if (!strncmp(this_opt, "strictmode", 10)) {
+ strictmode = 1;
} else
mode_option = this_opt;
}
@@ -2039,6 +2077,8 @@
#ifdef CONFIG_MTRR
MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM(strictmode, "i");
+MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
#endif
#endif /* MODULE */
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/riva/rivafb-i2c.c linux-2.6.6-rc3-mm2/drivers/video/riva/rivafb-i2c.c
--- linux-2.6.6-rc3-mm2-orig/drivers/video/riva/rivafb-i2c.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.6-rc3-mm2/drivers/video/riva/rivafb-i2c.c 2004-06-16 01:20:45.321625320 +0000
@@ -0,0 +1,209 @@
+/*
+ * linux/drivers/video/riva/fbdev-i2c.c - nVidia i2c
+ *
+ * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
+ *
+ * Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
+ *
+ * Based on radeonfb-i2c.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+
+#include <asm/io.h>
+
+#include "rivafb.h"
+#include "../edid.h"
+
+#define RIVA_DDC 0x50
+
+static void riva_gpio_setscl(void* data, int state)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
+
+ if (state)
+ val |= 0x20;
+ else
+ val &= ~0x20;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
+}
+
+static void riva_gpio_setsda(void* data, int state)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
+
+ if (state)
+ val |= 0x10;
+ else
+ val &= ~0x10;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
+ VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
+}
+
+static int riva_gpio_getscl(void* data)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val = 0;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
+ if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04)
+ val = 1;
+
+ val = VGA_RD08(par->riva.PCIO, 0x3d5);
+
+ return val;
+}
+
+static int riva_gpio_getsda(void* data)
+{
+ struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data;
+ struct riva_par *par = chan->par;
+ u32 val = 0;
+
+ VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
+ if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x08)
+ val = 1;
+
+ return val;
+}
+
+#define I2C_ALGO_RIVA 0x0e0000
+static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
+{
+ int rc;
+
+ strcpy(chan->adapter.name, name);
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.id = I2C_ALGO_RIVA;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = &chan->par->pdev->dev;
+ chan->algo.setsda = riva_gpio_setsda;
+ chan->algo.setscl = riva_gpio_setscl;
+ chan->algo.getsda = riva_gpio_getsda;
+ chan->algo.getscl = riva_gpio_getscl;
+ chan->algo.udelay = 40;
+ chan->algo.timeout = 20;
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ /* Raise SCL and SDA */
+ riva_gpio_setsda(chan, 1);
+ riva_gpio_setscl(chan, 1);
+ udelay(20);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ dev_dbg(&chan->par->pdev->dev, "I2C bus %s registered.\n", name);
+ else
+ dev_warn(&chan->par->pdev->dev, "Failed to register I2C bus %s.\n", name);
+ return rc;
+}
+
+void riva_create_i2c_busses(struct riva_par *par)
+{
+ par->chan[0].par = par;
+ par->chan[1].par = par;
+ par->chan[2].par = par;
+
+ switch (par->riva.Architecture) {
+#if 0 /* no support yet for other nVidia chipsets */
+ par->chan[2].ddc_base = 0x50;
+ riva_setup_i2c_bus(&par->chan[2], "BUS2");
+#endif
+ case NV_ARCH_10:
+ case NV_ARCH_20:
+ case NV_ARCH_04:
+ par->chan[1].ddc_base = 0x36;
+ riva_setup_i2c_bus(&par->chan[1], "BUS1");
+ case NV_ARCH_03:
+ par->chan[0].ddc_base = 0x3e;
+ riva_setup_i2c_bus(&par->chan[0], "BUS0");
+ }
+}
+
+void riva_delete_i2c_busses(struct riva_par *par)
+{
+ if (par->chan[0].par)
+ i2c_bit_del_bus(&par->chan[0].adapter);
+ par->chan[0].par = NULL;
+
+ if (par->chan[1].par)
+ i2c_bit_del_bus(&par->chan[1].adapter);
+ par->chan[1].par = NULL;
+
+}
+
+static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
+{
+ u8 start = 0x0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = RIVA_DDC,
+ .len = 1,
+ .buf = &start,
+ }, {
+ .addr = RIVA_DDC,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ },
+ };
+ u8 *buf;
+
+ buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!buf) {
+ dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
+ return NULL;
+ }
+ msgs[1].buf = buf;
+
+ if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
+ return buf;
+ dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
+ kfree(buf);
+ return NULL;
+}
+
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
+{
+ u8 *edid = NULL;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ /* Do the real work */
+ edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
+ if (edid)
+ break;
+ }
+ if (out_edid)
+ *out_edid = edid;
+ if (!edid)
+ return 1;
+
+ return 0;
+}
+
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/riva/rivafb.h linux-2.6.6-rc3-mm2/drivers/video/riva/rivafb.h
--- linux-2.6.6-rc3-mm2-orig/drivers/video/riva/rivafb.h 2004-05-10 02:32:27.000000000 +0000
+++ linux-2.6.6-rc3-mm2/drivers/video/riva/rivafb.h 2004-06-16 01:20:45.322625168 +0000
@@ -4,6 +4,10 @@
#include <linux/config.h>
#include <linux/fb.h>
#include <video/vga.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
#include "riva_hw.h"
/* GGI compatibility macros */
@@ -12,6 +16,12 @@
#define NUM_GRC_REGS 0x09
#define NUM_ATC_REGS 0x15
+/* I2C */
+#define DDC_SCL_READ_MASK (1 << 2)
+#define DDC_SCL_WRITE_MASK (1 << 5)
+#define DDC_SDA_READ_MASK (1 << 3)
+#define DDC_SDA_WRITE_MASK (1 << 4)
+
/* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
* From KGI originally. */
struct riva_regs {
@@ -23,6 +33,15 @@
RIVA_HW_STATE ext;
};
+struct riva_par;
+
+struct riva_i2c_chan {
+ struct riva_par *par;
+ unsigned long ddc_base;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
struct riva_par {
RIVA_HW_INST riva; /* interface to riva_hw.c */
@@ -36,26 +55,22 @@
u32 cursor_data[32 * 32/4];
int cursor_reset;
unsigned char *EDID;
-
- int panel_xres, panel_yres;
- int hOver_plus, hSync_width, hblank;
- int vOver_plus, vSync_width, vblank;
- int hAct_high, vAct_high, interlaced;
- int synct, misc, clock;
-
- int use_default_var;
- int got_dfpinfo;
unsigned int Chipset;
int forceCRTC;
Bool SecondCRTC;
int FlatPanel;
+ struct pci_dev *pdev;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
+ struct riva_i2c_chan chan[3];
};
void riva_common_setup(struct riva_par *);
unsigned long riva_get_memlen(struct riva_par *);
unsigned long riva_get_maxdclk(struct riva_par *);
+void riva_delete_i2c_busses(struct riva_par *par);
+void riva_create_i2c_busses(struct riva_par *par);
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid);
#endif /* __RIVAFB_H */
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 2:44 ` Antonino A. Daplas
@ 2004-06-16 5:53 ` Antonino A. Daplas
2004-06-16 16:47 ` jsimmons
2004-06-16 17:34 ` [PATCH][RIVAFB]: Updates to rivafb driver David Eger
0 siblings, 2 replies; 14+ messages in thread
From: Antonino A. Daplas @ 2004-06-16 5:53 UTC (permalink / raw)
To: David Eger; +Cc: James Simmons, Andrew Morton, Linux Fbdev development list
On Wednesday 16 June 2004 10:44, Antonino A. Daplas wrote:
> On Wednesday 16 June 2004 06:17, David Eger wrote:
> > hey tony,
> >
> > your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
> > applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
>
> Ok. Patch against 2.6.7-rc3-mm2.
>
> Note I haven't added the hardware acceleration capability support yet,
> so scrolling is still slow.
>
> Secondly, stty seems not to work anymore, though I'm sure
> the driver can do mode setup independently if with DDC. I'll look into
> this later.
I believe I know why stty failed. It's because fbcon_resize() inf fbcon.c uses
fb_find_mode(). I have reservations with this method though.
1. Since it uses a mode database, this will completely ignore drivers/hardware
that can do scaling or can use the GTF.
2. Secondly, stty works in a weird manner. For example, fb is in 800x600. I want
to go to 1024x768. In order to do that I issue 'stty cols 128 rows 48'. This will fail
because it will be processed in 2 steps:
1. set at 1024x592 (128x37) <-- fails
2. set at 1024x768(128x48)
Of course, step 1 will fail since 1024x592 is not in the database.
I believe a proper way is to just add another method in info->fb_ops, something like
info->fb_ops->fb_find_mode(struct fb_var_screeninfo*, int xres, int yres) that will
be called by fbcon_resize().
Anyway, a workaround is to add a best-fit algorithm in fb_find_mode(). It will try to return
modes that are bigger but closest to the given mode. fb_find_mode will return 5 in this case.
Note that it currently ignores refresh rates. So, it will now work this way:
1. set at 1024x592(128x37)
fb_find_mode() return 1024x768
2. set at 1024x768(128x48)
fb_find_mode() return 1024x768 (success)
The algo is currently very simple, feel free to modify.
Tony
Signed-off-by: Antonino Daplas <adaplas@pol.net>
1. pass info->monspecs.modedb and info->monspecs.modedb_len to fb_find_mode()
instead of NULL, 0 since its contents are specific to the attached display. Anyway, if
info->monspecs.modedb == NULL, fb_find_mode() will use the default database.
2. Added best fit algo to fb_find_mode().
3. Use snprintf instead of sprintf.
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/console/fbcon.c linux-2.6.6-rc3-mm2-test/drivers/video/console/fbcon.c
--- linux-2.6.6-rc3-mm2-orig/drivers/video/console/fbcon.c 2004-06-16 01:18:35.000000000 +0000
+++ linux-2.6.6-rc3-mm2-test/drivers/video/console/fbcon.c 2004-06-16 05:31:06.594105304 +0000
@@ -1512,9 +1512,10 @@
if (!info->fbops->fb_set_par)
return -EINVAL;
- sprintf(mode, "%dx%d", var.xres, var.yres);
- err = fb_find_mode(&var, info, mode, NULL, 0, NULL,
- info->var.bits_per_pixel);
+ snprintf(mode, 40, "%ix%i", var.xres, var.yres);
+ err = fb_find_mode(&var, info, mode, info->monspecs.modedb,
+ info->monspecs.modedb_len, NULL,
+ info->var.bits_per_pixel);
if (!err || width > var.xres/fw || height > var.yres/fh)
return -EINVAL;
DPRINTK("resize now %ix%i\n", var.xres, var.yres);
diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/modedb.c linux-2.6.6-rc3-mm2-test/drivers/video/modedb.c
--- linux-2.6.6-rc3-mm2-orig/drivers/video/modedb.c 2004-06-16 01:17:54.000000000 +0000
+++ linux-2.6.6-rc3-mm2-test/drivers/video/modedb.c 2004-06-16 05:30:55.409805576 +0000
@@ -490,7 +490,8 @@
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
int yres_specified = 0;
-
+ u32 best = -1, diff = -1;
+
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
case '@':
@@ -529,8 +530,8 @@
}
done:
for (i = refresh_specified; i >= 0; i--) {
- DPRINTK("Trying specified video mode%s\n",
- i ? "" : " (ignoring refresh rate)");
+ DPRINTK("Trying specified video mode%s %ix%i\n",
+ i ? "" : " (ignoring refresh rate)", xres, yres);
for (j = 0; j < dbsize; j++)
if ((name_matches(db[j], name, namelen) ||
(res_specified && res_matches(db[j], xres, yres))) &&
@@ -538,6 +539,22 @@
!fb_try_mode(var, info, &db[j], bpp))
return 2-i;
}
+ DPRINTK("Trying best-fit modes\n");
+ for (i = 0; i < dbsize; i++) {
+ if (xres <= db[i].xres && yres <= db[i].yres) {
+ DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
+ if (!fb_try_mode(var, info, &db[i], bpp)) {
+ if (diff > (db[i].xres - xres) + (db[i].yres - yres)) {
+ diff = (db[i].xres - xres) + (db[i].yres - yres);
+ best = i;
+ }
+ }
+ }
+ }
+ if (best != -1) {
+ fb_try_mode(var, info, &db[best], bpp);
+ return 5;
+ }
}
DPRINTK("Trying default video mode\n");
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 5:53 ` Antonino A. Daplas
@ 2004-06-16 16:47 ` jsimmons
2004-06-16 20:23 ` Andrew Morton
2004-06-16 17:34 ` [PATCH][RIVAFB]: Updates to rivafb driver David Eger
1 sibling, 1 reply; 14+ messages in thread
From: jsimmons @ 2004-06-16 16:47 UTC (permalink / raw)
To: adaplas; +Cc: David Eger, Andrew Morton, Linux Fbdev development list
> I believe I know why stty failed. It's because fbcon_resize() inf fbcon.c uses
> fb_find_mode(). I have reservations with this method though.
>
> 1. Since it uses a mode database, this will completely ignore drivers/hardware
> that can do scaling or can use the GTF.
The mode database is meant to deal with the lowest denominator hardware.
It works in a large number of cases. I plan to expand that functionaly
even more in the near future.
> 2. Secondly, stty works in a weird manner. For example, fb is in 800x600. I want
> to go to 1024x768. In order to do that I issue 'stty cols 128 rows 48'. This will fail
> because it will be processed in 2 steps:
>
> 1. set at 1024x592 (128x37) <-- fails
> 2. set at 1024x768(128x48)
>
> Of course, step 1 will fail since 1024x592 is not in the database.
This is a bug in stty. I sent the patch to the maintainer. We shoudl add
that functionalty to fbset now.
> Anyway, a workaround is to add a best-fit algorithm in fb_find_mode(). It will try to return
> modes that are bigger but closest to the given mode. fb_find_mode will return 5 in this case.
> Note that it currently ignores refresh rates. So, it will now work this way:
>
> 1. set at 1024x592(128x37)
> fb_find_mode() return 1024x768
> 2. set at 1024x768(128x48)
> fb_find_mode() return 1024x768 (success)
>
> The algo is currently very simple, feel free to modify.
Nice. I will apply.
> Tony
>
> Signed-off-by: Antonino Daplas <adaplas@pol.net>
>
> 1. pass info->monspecs.modedb and info->monspecs.modedb_len to fb_find_mode()
> instead of NULL, 0 since its contents are specific to the attached display. Anyway, if
> info->monspecs.modedb == NULL, fb_find_mode() will use the default database.
>
> 2. Added best fit algo to fb_find_mode().
>
> 3. Use snprintf instead of sprintf.
>
> diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/console/fbcon.c linux-2.6.6-rc3-mm2-test/drivers/video/console/fbcon.c
> --- linux-2.6.6-rc3-mm2-orig/drivers/video/console/fbcon.c 2004-06-16 01:18:35.000000000 +0000
> +++ linux-2.6.6-rc3-mm2-test/drivers/video/console/fbcon.c 2004-06-16 05:31:06.594105304 +0000
> @@ -1512,9 +1512,10 @@
> if (!info->fbops->fb_set_par)
> return -EINVAL;
>
> - sprintf(mode, "%dx%d", var.xres, var.yres);
> - err = fb_find_mode(&var, info, mode, NULL, 0, NULL,
> - info->var.bits_per_pixel);
> + snprintf(mode, 40, "%ix%i", var.xres, var.yres);
> + err = fb_find_mode(&var, info, mode, info->monspecs.modedb,
> + info->monspecs.modedb_len, NULL,
> + info->var.bits_per_pixel);
> if (!err || width > var.xres/fw || height > var.yres/fh)
> return -EINVAL;
> DPRINTK("resize now %ix%i\n", var.xres, var.yres);
> diff -Naur linux-2.6.6-rc3-mm2-orig/drivers/video/modedb.c linux-2.6.6-rc3-mm2-test/drivers/video/modedb.c
> --- linux-2.6.6-rc3-mm2-orig/drivers/video/modedb.c 2004-06-16 01:17:54.000000000 +0000
> +++ linux-2.6.6-rc3-mm2-test/drivers/video/modedb.c 2004-06-16 05:30:55.409805576 +0000
> @@ -490,7 +490,8 @@
> int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
> unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
> int yres_specified = 0;
> -
> + u32 best = -1, diff = -1;
> +
> for (i = namelen-1; i >= 0; i--) {
> switch (name[i]) {
> case '@':
> @@ -529,8 +530,8 @@
> }
> done:
> for (i = refresh_specified; i >= 0; i--) {
> - DPRINTK("Trying specified video mode%s\n",
> - i ? "" : " (ignoring refresh rate)");
> + DPRINTK("Trying specified video mode%s %ix%i\n",
> + i ? "" : " (ignoring refresh rate)", xres, yres);
> for (j = 0; j < dbsize; j++)
> if ((name_matches(db[j], name, namelen) ||
> (res_specified && res_matches(db[j], xres, yres))) &&
> @@ -538,6 +539,22 @@
> !fb_try_mode(var, info, &db[j], bpp))
> return 2-i;
> }
> + DPRINTK("Trying best-fit modes\n");
> + for (i = 0; i < dbsize; i++) {
> + if (xres <= db[i].xres && yres <= db[i].yres) {
> + DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
> + if (!fb_try_mode(var, info, &db[i], bpp)) {
> + if (diff > (db[i].xres - xres) + (db[i].yres - yres)) {
> + diff = (db[i].xres - xres) + (db[i].yres - yres);
> + best = i;
> + }
> + }
> + }
> + }
> + if (best != -1) {
> + fb_try_mode(var, info, &db[best], bpp);
> + return 5;
> + }
> }
>
> DPRINTK("Trying default video mode\n");
>
>
>
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 5:53 ` Antonino A. Daplas
2004-06-16 16:47 ` jsimmons
@ 2004-06-16 17:34 ` David Eger
2004-06-16 22:29 ` Antonino A. Daplas
1 sibling, 1 reply; 14+ messages in thread
From: David Eger @ 2004-06-16 17:34 UTC (permalink / raw)
To: adaplas; +Cc: James Simmons, Andrew Morton, Linux Fbdev development list
On Wed, Jun 16, 2004 at 01:53:51PM +0800, Antonino A. Daplas wrote:
> > On Wednesday 16 June 2004 06:17, David Eger wrote:
> > > hey tony,
> > >
> > > your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
> > > applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
> >
> > Ok. Patch against 2.6.7-rc3-mm2.
Applying your rivafb and fbmode patches work great on my TNT2.
I get a console with 160 columns and 60 rows :-)
And yes, the capabilities patch makes your driver slow.
But setting the proper flags makes it fast again ;-)
The driver still doesn't play nice with the evil binary nvidia drivers,
but then, that's expected. (It'd be nice if changing from X to a console
didn't *crash my machine* though.)
-dte
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 16:47 ` jsimmons
@ 2004-06-16 20:23 ` Andrew Morton
2004-06-16 22:29 ` Antonino A. Daplas
0 siblings, 1 reply; 14+ messages in thread
From: Andrew Morton @ 2004-06-16 20:23 UTC (permalink / raw)
To: jsimmons; +Cc: adaplas, eger, linux-fbdev-devel
jsimmons@pentafluge.infradead.org wrote:
>
> Nice. I will apply.
And then what will happen?
Patches seem to disappear into the linux-fbdev tree never to be seen again.
What can we do about this?
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 17:34 ` [PATCH][RIVAFB]: Updates to rivafb driver David Eger
@ 2004-06-16 22:29 ` Antonino A. Daplas
2004-06-17 0:16 ` David Eger
0 siblings, 1 reply; 14+ messages in thread
From: Antonino A. Daplas @ 2004-06-16 22:29 UTC (permalink / raw)
To: David Eger, adaplas
Cc: James Simmons, Andrew Morton, Linux Fbdev development list
On Thursday 17 June 2004 01:34, David Eger wrote:
> On Wed, Jun 16, 2004 at 01:53:51PM +0800, Antonino A. Daplas wrote:
> > > On Wednesday 16 June 2004 06:17, David Eger wrote:
> > > > hey tony,
> > > >
> > > > your patch against drivers/video/riva/fbdev.c chokes on hunk 2 when
> > > > applied to 2.6.7-rc3-mm2. resend, and i'll test it on my TNT2 :)
> > >
> > > Ok. Patch against 2.6.7-rc3-mm2.
>
> Applying your rivafb and fbmode patches work great on my TNT2.
> I get a console with 160 columns and 60 rows :-)
That's great.
>
> And yes, the capabilities patch makes your driver slow.
> But setting the proper flags makes it fast again ;-)
Do you mind submitting a patch yourself? It's probably a 1 liner patch, unless
we also modify rivafb to use cfb_* drawing functions depending on
the setting of var->accel_flags.
>
> The driver still doesn't play nice with the evil binary nvidia drivers,
> but then, that's expected. (It'd be nice if changing from X to a console
> didn't *crash my machine* though.)
>
Yeah, even with XOrg/Free86 nv driver, it hangs. Don't really know the exact
solution, probably a complete re-initialization of the hardware when switching from
X. But this will require that fbcon recognizes a switch from X itself which it
currently doesn't (unless I'm mistaken).
Tony
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 20:23 ` Andrew Morton
@ 2004-06-16 22:29 ` Antonino A. Daplas
2004-06-16 22:39 ` Andrew Morton
2004-06-17 18:24 ` [PATCH][RIVAFB] rivafb: fb accel capabilities David Eger
0 siblings, 2 replies; 14+ messages in thread
From: Antonino A. Daplas @ 2004-06-16 22:29 UTC (permalink / raw)
To: Andrew Morton, jsimmons; +Cc: adaplas, eger, linux-fbdev-devel
On Thursday 17 June 2004 04:23, Andrew Morton wrote:
> jsimmons@pentafluge.infradead.org wrote:
> > Nice. I will apply.
>
> And then what will happen?
>
> Patches seem to disappear into the linux-fbdev tree never to be seen again.
> What can we do about this?
>
Andrew,
Can you also apply it (and the rivafb update patch) to your tree? Especially the
best-fit mode patch in -mm2 branch which fixes the broken stty functionality.
I'll also submit corresponding changes to James' fbdev tree (once he releases
a diff against one of the 2.6.x branch -- I don't have BK).
Tony
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 22:29 ` Antonino A. Daplas
@ 2004-06-16 22:39 ` Andrew Morton
2004-06-17 18:24 ` [PATCH][RIVAFB] rivafb: fb accel capabilities David Eger
1 sibling, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2004-06-16 22:39 UTC (permalink / raw)
To: adaplas; +Cc: adaplas, jsimmons, eger, linux-fbdev-devel
"Antonino A. Daplas" <adaplas@hotpop.com> wrote:
>
> Can you also apply it (and the rivafb update patch) to your tree? Especially the
> best-fit mode patch in -mm2 branch which fixes the broken stty functionality.
yup. I have three fbdev patches in -mm so far:
updates-to-rivafb-driver.patch
updates-to-rivafb-driver-2.patch
asiliantfb-init-fix.patch
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-16 22:29 ` Antonino A. Daplas
@ 2004-06-17 0:16 ` David Eger
2004-06-17 16:34 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 14+ messages in thread
From: David Eger @ 2004-06-17 0:16 UTC (permalink / raw)
To: adaplas, benh; +Cc: James Simmons, Andrew Morton, Linux Fbdev development list
On Thu, Jun 17, 2004 at 06:29:09AM +0800, Antonino A. Daplas wrote:
> On Thursday 17 June 2004 01:34, David Eger wrote:
> > And yes, the capabilities patch makes your driver slow.
> > But setting the proper flags makes it fast again ;-)
>
> Do you mind submitting a patch yourself? It's probably a 1 liner patch,
> unless we also modify rivafb to use cfb_* drawing functions depending on
> the setting of var->accel_flags.
I'd be happy to. I'll forward it to Andrew+James tomorrow.
( I'm currently at the GNU/yak café night in Atlanta, away
from my TNT2 testing box )
> > The driver still doesn't play nice with the evil binary nvidia drivers,
> > but then, that's expected. (It'd be nice if changing from X to aa
> > console didn't *crash my machine* though.)
>
> Yeah, even with XOrg/Free86 nv driver, it hangs. Don't really know the
> exact solution, probably a complete re-initialization of the hardware
> when switching from X. But this will require that fbcon recognizes
> a switch from X itself which it currently doesn't (unless I'm mistaken).
Back in February, BenH said he was going to work on a patch for this:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0402.2/0247.html
Hey Ben, what ever became of this? Are there now hooks for this or
something?
-dte
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH][RIVAFB]: Updates to rivafb driver
2004-06-17 0:16 ` David Eger
@ 2004-06-17 16:34 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2004-06-17 16:34 UTC (permalink / raw)
To: David Eger
Cc: adaplas, James Simmons, Andrew Morton,
Linux Fbdev development list
On Wed, 2004-06-16 at 19:16, David Eger wrote:
> > Yeah, even with XOrg/Free86 nv driver, it hangs. Don't really know the
> > exact solution, probably a complete re-initialization of the hardware
> > when switching from X. But this will require that fbcon recognizes
> > a switch from X itself which it currently doesn't (unless I'm mistaken).
>
> Back in February, BenH said he was going to work on a patch for this:
>
> http://www.uwsg.iu.edu/hypermail/linux/kernel/0402.2/0247.html
>
> Hey Ben, what ever became of this? Are there now hooks for this or
> something?
Last time I played with nv & rivafb (a loooong time ago), I found out
the hangs were caused by some weirdness with the manipulation of the
endian flip register and got that working. The problem I've been working
on for restoring console is different, and has to do with forcing a
call to set-par when coming back from KD_GRAPHICS mode. That is already
upstream (though I noticed some X driver still mess with the HW after
the switch back, like the radeon one)
Ben.
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH][RIVAFB] rivafb: fb accel capabilities
2004-06-16 22:29 ` Antonino A. Daplas
2004-06-16 22:39 ` Andrew Morton
@ 2004-06-17 18:24 ` David Eger
1 sibling, 0 replies; 14+ messages in thread
From: David Eger @ 2004-06-17 18:24 UTC (permalink / raw)
To: adaplas; +Cc: Andrew Morton, jsimmons, linux-fbdev-devel
Dear Andrew,
Here's the fb accel capabilities patch for rivafb.
-dte
diff -ru linux-2.6.7-rc3-mm2-wrivafb/drivers/video/riva/fbdev.c linux-2.6.7-rc3-mm2-wrivafb2/drivers/video/riva/fbdev.c
--- linux-2.6.7-rc3-mm2-wrivafb/drivers/video/riva/fbdev.c 2004-06-17 14:08:29.000000000 -0400
+++ linux-2.6.7-rc3-mm2-wrivafb2/drivers/video/riva/fbdev.c 2004-06-16 12:39:11.000000000 -0400
@@ -1665,7 +1665,12 @@
{
unsigned int cmap_len;
- info->flags = FBINFO_FLAG_DEFAULT;
+ info->flags = FBINFO_DEFAULT
+ | FBINFO_HWACCEL_XPAN
+ | FBINFO_HWACCEL_YPAN
+ | FBINFO_HWACCEL_COPYAREA
+ | FBINFO_HWACCEL_FILLRECT
+ | FBINFO_HWACCEL_IMAGEBLIT;
info->var = rivafb_default_var;
info->fix.visual = (info->var.bits_per_pixel == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2004-06-17 18:24 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-15 20:06 [PATCH][RIVAFB]: Updates to rivafb driver Antonino A. Daplas
2004-06-15 22:17 ` David Eger
2004-06-15 22:18 ` jsimmons
2004-06-16 2:44 ` Antonino A. Daplas
2004-06-16 5:53 ` Antonino A. Daplas
2004-06-16 16:47 ` jsimmons
2004-06-16 20:23 ` Andrew Morton
2004-06-16 22:29 ` Antonino A. Daplas
2004-06-16 22:39 ` Andrew Morton
2004-06-17 18:24 ` [PATCH][RIVAFB] rivafb: fb accel capabilities David Eger
2004-06-16 17:34 ` [PATCH][RIVAFB]: Updates to rivafb driver David Eger
2004-06-16 22:29 ` Antonino A. Daplas
2004-06-17 0:16 ` David Eger
2004-06-17 16:34 ` Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).