drm/nv50-nvc0: precalculate some fb state when creating them
authorBen Skeggs <bskeggs@redhat.com>
Wed, 9 Feb 2011 01:57:45 +0000 (11:57 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 24 Feb 2011 20:45:08 +0000 (06:45 +1000)
Just a cleanup, to avoid duplicating parts of nv50_crtc.c's code in
the page flipping routines.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_fb.h
drivers/gpu/drm/nouveau/nv50_crtc.c

index 505c6bf..3a30d82 100644 (file)
@@ -32,6 +32,7 @@
 #include "nouveau_hw.h"
 #include "nouveau_crtc.h"
 #include "nouveau_dma.h"
+#include "nv50_display.h"
 
 static void
 nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
 };
 
 int
-nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
-                        struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo)
+nouveau_framebuffer_init(struct drm_device *dev,
+                        struct nouveau_framebuffer *nv_fb,
+                        struct drm_mode_fb_cmd *mode_cmd,
+                        struct nouveau_bo *nvbo)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct drm_framebuffer *fb = &nv_fb->base;
        int ret;
 
-       ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs);
+       ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
        if (ret) {
                return ret;
        }
 
-       drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd);
-       nouveau_fb->nvbo = nvbo;
+       drm_helper_mode_fill_fb_struct(fb, mode_cmd);
+       nv_fb->nvbo = nvbo;
+
+       if (dev_priv->card_type >= NV_50) {
+               u32 tile_flags = nouveau_bo_tile_layout(nvbo);
+               if (tile_flags == 0x7a00 ||
+                   tile_flags == 0xfe00)
+                       nv_fb->r_dma = NvEvoFB32;
+               else
+               if (tile_flags == 0x7000)
+                       nv_fb->r_dma = NvEvoFB16;
+               else
+                       nv_fb->r_dma = NvEvoVRAM_LP;
+
+               switch (fb->depth) {
+               case  8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break;
+               case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break;
+               case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break;
+               case 24:
+               case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
+               case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
+               default:
+                        NV_ERROR(dev, "unknown depth %d\n", fb->depth);
+                        return -EINVAL;
+               }
+
+               if (dev_priv->chipset == 0x50)
+                       nv_fb->r_format |= (tile_flags << 8);
+
+               if (!tile_flags)
+                       nv_fb->r_pitch = 0x00100000 | fb->pitch;
+               else {
+                       u32 mode = nvbo->tile_mode;
+                       if (dev_priv->card_type >= NV_C0)
+                               mode >>= 4;
+                       nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode;
+               }
+       }
+
        return 0;
 }
 
index d432134..a3a88ad 100644 (file)
@@ -30,6 +30,9 @@
 struct nouveau_framebuffer {
        struct drm_framebuffer base;
        struct nouveau_bo *nvbo;
+       u32 r_dma;
+       u32 r_format;
+       u32 r_pitch;
 };
 
 static inline struct nouveau_framebuffer *
index a94aff5..308af1d 100644 (file)
@@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
        struct nouveau_channel *evo = nv50_display(dev)->master;
        struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
        struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
-       int ret, format;
+       int ret;
 
        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 
@@ -548,28 +548,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
                }
        }
 
-       switch (drm_fb->depth) {
-       case  8:
-               format = NV50_EVO_CRTC_FB_DEPTH_8;
-               break;
-       case 15:
-               format = NV50_EVO_CRTC_FB_DEPTH_15;
-               break;
-       case 16:
-               format = NV50_EVO_CRTC_FB_DEPTH_16;
-               break;
-       case 24:
-       case 32:
-               format = NV50_EVO_CRTC_FB_DEPTH_24;
-               break;
-       case 30:
-               format = NV50_EVO_CRTC_FB_DEPTH_30;
-               break;
-       default:
-                NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth);
-                return -EINVAL;
-       }
-
        nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
        nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
        nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
                        return ret;
 
                BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
-               if (nv_crtc->fb.tile_flags == 0x7a00 ||
-                   nv_crtc->fb.tile_flags == 0xfe00)
-                       OUT_RING(evo, NvEvoFB32);
-               else
-               if (nv_crtc->fb.tile_flags == 0x7000)
-                       OUT_RING(evo, NvEvoFB16);
-               else
-                       OUT_RING(evo, NvEvoVRAM_LP);
+               OUT_RING  (evo, fb->r_dma);
        }
 
        ret = RING_SPACE(evo, 12);
@@ -594,30 +565,20 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
                return ret;
 
        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
-       OUT_RING(evo, nv_crtc->fb.offset >> 8);
-       OUT_RING(evo, 0);
-       OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width);
-       if (!nv_crtc->fb.tile_flags) {
-               OUT_RING(evo, drm_fb->pitch | (1 << 20));
-       } else {
-               u32 tile_mode = fb->nvbo->tile_mode;
-               if (dev_priv->card_type >= NV_C0)
-                       tile_mode >>= 4;
-               OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode);
-       }
-       if (dev_priv->chipset == 0x50)
-               OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
-       else
-               OUT_RING(evo, format);
+       OUT_RING  (evo, nv_crtc->fb.offset >> 8);
+       OUT_RING  (evo, 0);
+       OUT_RING  (evo, (drm_fb->height << 16) | drm_fb->width);
+       OUT_RING  (evo, fb->r_pitch);
+       OUT_RING  (evo, fb->r_format);
 
        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
-       OUT_RING(evo, fb->base.depth == 8 ?
-                NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
+       OUT_RING  (evo, fb->base.depth == 8 ?
+                  NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
 
        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
-       OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
+       OUT_RING  (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
-       OUT_RING(evo, (y << 16) | x);
+       OUT_RING  (evo, (y << 16) | x);
 
        if (nv_crtc->lut.depth != fb->base.depth) {
                nv_crtc->lut.depth = fb->base.depth;