drm/nouveau: Fix fbcon on mixed pre-NV50 + NV50 multicard.

We used single shared fbops struct and patched it at fb init time with
pointers to the right variant. On mixed multicard, this meant that
it was either sending NV50-style commands to all cards, or NV04-style
commands to all cards.

Signed-off-by: Marcin Kościelnicki <koriakin@0x04.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Marcin Kościelnicki 2010-01-27 14:03:18 +00:00 committed by Ben Skeggs
parent 7dad9ef6d9
commit 126b544056
4 changed files with 42 additions and 12 deletions

View File

@ -107,6 +107,34 @@ static struct fb_ops nouveau_fbcon_ops = {
.fb_setcmap = drm_fb_helper_setcmap, .fb_setcmap = drm_fb_helper_setcmap,
}; };
static struct fb_ops nv04_fbcon_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcolreg = drm_fb_helper_setcolreg,
.fb_fillrect = nv04_fbcon_fillrect,
.fb_copyarea = nv04_fbcon_copyarea,
.fb_imageblit = nv04_fbcon_imageblit,
.fb_sync = nouveau_fbcon_sync,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
};
static struct fb_ops nv50_fbcon_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcolreg = drm_fb_helper_setcolreg,
.fb_fillrect = nv50_fbcon_fillrect,
.fb_copyarea = nv50_fbcon_copyarea,
.fb_imageblit = nv50_fbcon_imageblit,
.fb_sync = nouveau_fbcon_sync,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
};
static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno) u16 blue, int regno)
{ {
@ -324,9 +352,11 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
switch (dev_priv->card_type) { switch (dev_priv->card_type) {
case NV_50: case NV_50:
nv50_fbcon_accel_init(info); nv50_fbcon_accel_init(info);
info->fbops = &nv50_fbcon_ops;
break; break;
default: default:
nv04_fbcon_accel_init(info); nv04_fbcon_accel_init(info);
info->fbops = &nv04_fbcon_ops;
break; break;
}; };
} }

View File

@ -40,7 +40,13 @@ int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb);
void nouveau_fbcon_restore(void); void nouveau_fbcon_restore(void);
void nouveau_fbcon_zfill(struct drm_device *dev); void nouveau_fbcon_zfill(struct drm_device *dev);
void nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
void nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
void nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv04_fbcon_accel_init(struct fb_info *info); int nv04_fbcon_accel_init(struct fb_info *info);
void nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
void nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
void nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv50_fbcon_accel_init(struct fb_info *info); int nv50_fbcon_accel_init(struct fb_info *info);
void nouveau_fbcon_gpu_lockup(struct fb_info *info); void nouveau_fbcon_gpu_lockup(struct fb_info *info);

View File

@ -27,7 +27,7 @@
#include "nouveau_dma.h" #include "nouveau_dma.h"
#include "nouveau_fbcon.h" #include "nouveau_fbcon.h"
static void void
nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -54,7 +54,7 @@ nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
FIRE_RING(chan); FIRE_RING(chan);
} }
static void void
nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -88,7 +88,7 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
FIRE_RING(chan); FIRE_RING(chan);
} }
static void void
nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -307,9 +307,6 @@ nv04_fbcon_accel_init(struct fb_info *info)
FIRE_RING(chan); FIRE_RING(chan);
info->fbops->fb_fillrect = nv04_fbcon_fillrect;
info->fbops->fb_copyarea = nv04_fbcon_copyarea;
info->fbops->fb_imageblit = nv04_fbcon_imageblit;
return 0; return 0;
} }

View File

@ -3,7 +3,7 @@
#include "nouveau_dma.h" #include "nouveau_dma.h"
#include "nouveau_fbcon.h" #include "nouveau_fbcon.h"
static void void
nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -46,7 +46,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
FIRE_RING(chan); FIRE_RING(chan);
} }
static void void
nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -81,7 +81,7 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
FIRE_RING(chan); FIRE_RING(chan);
} }
static void void
nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
struct nouveau_fbcon_par *par = info->par; struct nouveau_fbcon_par *par = info->par;
@ -262,9 +262,6 @@ nv50_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
dev_priv->vm_vram_base); dev_priv->vm_vram_base);
info->fbops->fb_fillrect = nv50_fbcon_fillrect;
info->fbops->fb_copyarea = nv50_fbcon_copyarea;
info->fbops->fb_imageblit = nv50_fbcon_imageblit;
return 0; return 0;
} }