Marcin KoĆcielnicki
2010-Jan-27 14:03 UTC
[Nouveau] [PATCH] 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 at 0x04.net> --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 30 ++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_fbcon.h | 6 ++++++ drivers/gpu/drm/nouveau/nv04_fbcon.c | 9 +++------ drivers/gpu/drm/nouveau/nv50_fbcon.c | 9 +++------ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index eddadac..ea879a2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -107,6 +107,34 @@ static struct fb_ops nouveau_fbcon_ops = { .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, u16 blue, int regno) { @@ -324,9 +352,11 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, switch (dev_priv->card_type) { case NV_50: nv50_fbcon_accel_init(info); + info->fbops = &nv50_fbcon_ops; break; default: nv04_fbcon_accel_init(info); + info->fbops = &nv04_fbcon_ops; break; }; } diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 462e0b8..f9c34e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -40,7 +40,13 @@ int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb); void nouveau_fbcon_restore(void); 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); +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); void nouveau_fbcon_gpu_lockup(struct fb_info *info); diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index d910873..fd01caa 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -27,7 +27,7 @@ #include "nouveau_dma.h" #include "nouveau_fbcon.h" -static void +void nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) { 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); } -static void +void nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { 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); } -static void +void nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) { struct nouveau_fbcon_par *par = info->par; @@ -307,9 +307,6 @@ nv04_fbcon_accel_init(struct fb_info *info) 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; } diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index e4f279e..0f57cdf 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -3,7 +3,7 @@ #include "nouveau_dma.h" #include "nouveau_fbcon.h" -static void +void nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { 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); } -static void +void nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) { 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); } -static void +void nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) { 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 + 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; } -- 1.6.5.6
Ben Skeggs
2010-Feb-04 11:48 UTC
[Nouveau] [PATCH] drm/nouveau: Fix fbcon on mixed pre-NV50 + NV50 multicard.
On Wed, 2010-01-27 at 14:03 +0000, Marcin Ko?cielnicki wrote:> 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.Good catch :) Pushed.> > Signed-off-by: Marcin Ko?cielnicki <koriakin at 0x04.net> > --- > drivers/gpu/drm/nouveau/nouveau_fbcon.c | 30 ++++++++++++++++++++++++++++++ > drivers/gpu/drm/nouveau/nouveau_fbcon.h | 6 ++++++ > drivers/gpu/drm/nouveau/nv04_fbcon.c | 9 +++------ > drivers/gpu/drm/nouveau/nv50_fbcon.c | 9 +++------ > 4 files changed, 42 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c > index eddadac..ea879a2 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c > +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c > @@ -107,6 +107,34 @@ static struct fb_ops nouveau_fbcon_ops = { > .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, > u16 blue, int regno) > { > @@ -324,9 +352,11 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, > switch (dev_priv->card_type) { > case NV_50: > nv50_fbcon_accel_init(info); > + info->fbops = &nv50_fbcon_ops; > break; > default: > nv04_fbcon_accel_init(info); > + info->fbops = &nv04_fbcon_ops; > break; > }; > } > diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h > index 462e0b8..f9c34e1 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h > +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h > @@ -40,7 +40,13 @@ int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb); > void nouveau_fbcon_restore(void); > 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); > +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); > > void nouveau_fbcon_gpu_lockup(struct fb_info *info); > diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c > index d910873..fd01caa 100644 > --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c > +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c > @@ -27,7 +27,7 @@ > #include "nouveau_dma.h" > #include "nouveau_fbcon.h" > > -static void > +void > nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) > { > 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); > } > > -static void > +void > nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) > { > 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); > } > > -static void > +void > nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) > { > struct nouveau_fbcon_par *par = info->par; > @@ -307,9 +307,6 @@ nv04_fbcon_accel_init(struct fb_info *info) > > 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; > } > > diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c > index e4f279e..0f57cdf 100644 > --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c > +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c > @@ -3,7 +3,7 @@ > #include "nouveau_dma.h" > #include "nouveau_fbcon.h" > > -static void > +void > nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) > { > 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); > } > > -static void > +void > nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) > { > 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); > } > > -static void > +void > nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) > { > 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 + > 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; > } >