]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'drm-kdb-next' into drm-core-next
authorDave Airlie <airlied@redhat.com>
Wed, 6 Oct 2010 02:57:50 +0000 (12:57 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 6 Oct 2010 02:57:50 +0000 (12:57 +1000)
* drm-kdb-next:
  drm/nouveau/kms: Avoid a hang entering KDB with VT accel on.
  radeon, kdb, kms: Save and restore the LUT on atomic KMS enter/exit
  drm, kdb, kms: Add an enter argument to mode_set_base_atomic() API
  drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
  drm/radeon/kms: Implement KDB debug hooks for radeon KMS.

1  2 
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv50_crtc.c

index ef480281afecac641e3d502c46ddb89f822da65f,427f90e17b9d45a37ccb50f98c8c3b373620178f..17f7cf0c11a8f45483c834eb7d69b08d11f3a7a1
@@@ -33,6 -33,7 +33,7 @@@
  #include "nouveau_fb.h"
  #include "nouveau_hw.h"
  #include "nvreg.h"
+ #include "nouveau_fbcon.h"
  
  static int
  nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@@ -109,7 -110,7 +110,7 @@@ static void nv_crtc_calc_state_ext(stru
        struct nouveau_pll_vals *pv = &regp->pllvals;
        struct pll_lims pll_lim;
  
 -      if (get_pll_limits(dev, nv_crtc->index ? VPLL2 : VPLL1, &pll_lim))
 +      if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim))
                return;
  
        /* NM2 == 0 is used to determine single stage mode on two stage plls */
@@@ -718,7 -719,6 +719,7 @@@ static void nv_crtc_destroy(struct drm_
  
        drm_crtc_cleanup(crtc);
  
 +      nouveau_bo_unmap(nv_crtc->cursor.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
        kfree(nv_crtc);
  }
@@@ -769,8 -769,9 +770,9 @@@ nv_crtc_gamma_set(struct drm_crtc *crtc
  }
  
  static int
- nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                       struct drm_framebuffer *old_fb)
+ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
+                          struct drm_framebuffer *passed_fb,
+                          int x, int y, bool atomic)
  {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        int arb_burst, arb_lwm;
        int ret;
  
-       ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
-       if (ret)
-               return ret;
+       /* If atomic, we want to switch to the fb we were passed, so
+        * now we update pointers to do that.  (We don't pin; just
+        * assume we're already pinned and update the base address.)
+        */
+       if (atomic) {
+               drm_fb = passed_fb;
+               fb = nouveau_framebuffer(passed_fb);
+       }
+       else {
+               /* If not atomic, we can go ahead and pin, and unpin the
+                * old fb we were passed.
+                */
+               ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+               if (ret)
+                       return ret;
  
-       if (old_fb) {
-               struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
-               nouveau_bo_unpin(ofb->nvbo);
+               if (passed_fb) {
+                       struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+                       nouveau_bo_unpin(ofb->nvbo);
+               }
        }
  
        nv_crtc->fb.offset = fb->nvbo->bo.offset;
        crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX);
        crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX);
  
 -      if (dev_priv->card_type >= NV_30) {
 +      if (dev_priv->card_type >= NV_20) {
                regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8;
                crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47);
        }
        return 0;
  }
  
+ static int
+ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+                       struct drm_framebuffer *old_fb)
+ {
+       return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
+ }
+ static int
+ nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+                              struct drm_framebuffer *fb,
+                              int x, int y, int enter)
+ {
+       struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+       struct drm_device *dev = dev_priv->dev;
+       if (enter)
+               nouveau_fbcon_save_disable_accel(dev);
+       else
+               nouveau_fbcon_restore_accel(dev);
+       return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
+ }
  static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
                               struct nouveau_bo *dst)
  {
@@@ -963,6 -1000,7 +1001,7 @@@ static const struct drm_crtc_helper_fun
        .mode_fixup = nv_crtc_mode_fixup,
        .mode_set = nv_crtc_mode_set,
        .mode_set_base = nv04_crtc_mode_set_base,
+       .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
        .load_lut = nv_crtc_gamma_load,
  };
  
index 3f2fb4ec63ab83db16a1d3a2ad21cfb7c51b0288,727a7a12fed9b5d675748a2bfa7ebef6d3f6dce7..ba91befd373445becacfd9e0a73e8dcc448fe96f
@@@ -104,7 -104,8 +104,7 @@@ nv50_crtc_blank(struct nouveau_crtc *nv
                OUT_RING(evo, nv_crtc->lut.depth == 8 ?
                                NV50_EVO_CRTC_CLUT_MODE_OFF :
                                NV50_EVO_CRTC_CLUT_MODE_ON);
 -              OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.mm_node->start <<
 -                               PAGE_SHIFT) >> 8);
 +              OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.start << PAGE_SHIFT) >> 8);
                if (dev_priv->chipset != 0x50) {
                        BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
                        OUT_RING(evo, NvEvoVRAM);
@@@ -265,10 -266,15 +265,10 @@@ nv50_crtc_set_clock(struct drm_device *
  {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct pll_lims pll;
 -      uint32_t reg, reg1, reg2;
 +      uint32_t reg1, reg2;
        int ret, N1, M1, N2, M2, P;
  
 -      if (dev_priv->chipset < NV_C0)
 -              reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head);
 -      else
 -              reg = 0x614140 + (head * 0x800);
 -
 -      ret = get_pll_limits(dev, reg, &pll);
 +      ret = get_pll_limits(dev, PLL_VPLL0 + head, &pll);
        if (ret)
                return ret;
  
                NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n",
                         pclk, ret, N1, M1, N2, M2, P);
  
 -              reg1 = nv_rd32(dev, reg + 4) & 0xff00ff00;
 -              reg2 = nv_rd32(dev, reg + 8) & 0x8000ff00;
 -              nv_wr32(dev, reg, 0x10000611);
 -              nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1);
 -              nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
 +              reg1 = nv_rd32(dev, pll.reg + 4) & 0xff00ff00;
 +              reg2 = nv_rd32(dev, pll.reg + 8) & 0x8000ff00;
 +              nv_wr32(dev, pll.reg + 0, 0x10000611);
 +              nv_wr32(dev, pll.reg + 4, reg1 | (M1 << 16) | N1);
 +              nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
        } else
        if (dev_priv->chipset < NV_C0) {
                ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
                NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
                         pclk, ret, N1, N2, M1, P);
  
 -              reg1 = nv_rd32(dev, reg + 4) & 0xffc00000;
 -              nv_wr32(dev, reg, 0x50000610);
 -              nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
 -              nv_wr32(dev, reg + 8, N2);
 +              reg1 = nv_rd32(dev, pll.reg + 4) & 0xffc00000;
 +              nv_wr32(dev, pll.reg + 0, 0x50000610);
 +              nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
 +              nv_wr32(dev, pll.reg + 8, N2);
        } else {
                ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
                if (ret <= 0)
                NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
                         pclk, ret, N1, N2, M1, P);
  
 -              nv_mask(dev, reg + 0x0c, 0x00000000, 0x00000100);
 -              nv_wr32(dev, reg + 0x04, (P << 16) | (N1 << 8) | M1);
 -              nv_wr32(dev, reg + 0x10, N2 << 16);
 +              nv_mask(dev, pll.reg + 0x0c, 0x00000000, 0x00000100);
 +              nv_wr32(dev, pll.reg + 0x04, (P << 16) | (N1 << 8) | M1);
 +              nv_wr32(dev, pll.reg + 0x10, N2 << 16);
        }
  
        return 0;
@@@ -332,9 -338,7 +332,9 @@@ nv50_crtc_destroy(struct drm_crtc *crtc
  
        nv50_cursor_fini(nv_crtc);
  
 +      nouveau_bo_unmap(nv_crtc->lut.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
 +      nouveau_bo_unmap(nv_crtc->cursor.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
        kfree(nv_crtc->mode);
        kfree(nv_crtc);
@@@ -487,8 -491,9 +487,9 @@@ nv50_crtc_mode_fixup(struct drm_crtc *c
  }
  
  static int
- nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                          struct drm_framebuffer *old_fb, bool update)
+ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
+                          struct drm_framebuffer *passed_fb,
+                          int x, int y, bool update, bool atomic)
  {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = nv_crtc->base.dev;
  
        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
  
+       /* If atomic, we want to switch to the fb we were passed, so
+        * now we update pointers to do that.  (We don't pin; just
+        * assume we're already pinned and update the base address.)
+        */
+       if (atomic) {
+               drm_fb = passed_fb;
+               fb = nouveau_framebuffer(passed_fb);
+       }
+       else {
+               /* If not atomic, we can go ahead and pin, and unpin the
+                * old fb we were passed.
+                */
+               ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+               if (ret)
+                       return ret;
+               if (passed_fb) {
+                       struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+                       nouveau_bo_unpin(ofb->nvbo);
+               }
+       }
        switch (drm_fb->depth) {
        case  8:
                format = NV50_EVO_CRTC_FB_DEPTH_8;
                 return -EINVAL;
        }
  
-       ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
-       if (ret)
-               return ret;
-       if (old_fb) {
-               struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
-               nouveau_bo_unpin(ofb->nvbo);
-       }
        nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
        nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
        nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@@ -681,14 -699,22 +695,22 @@@ nv50_crtc_mode_set(struct drm_crtc *crt
        nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
        nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
  
-       return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+       return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false);
  }
  
  static int
  nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
                        struct drm_framebuffer *old_fb)
  {
-       return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+       return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false);
+ }
+ static int
+ nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+                              struct drm_framebuffer *fb,
+                              int x, int y, int enter)
+ {
+       return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true);
  }
  
  static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
        .mode_fixup = nv50_crtc_mode_fixup,
        .mode_set = nv50_crtc_mode_set,
        .mode_set_base = nv50_crtc_mode_set_base,
+       .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
        .load_lut = nv50_crtc_lut_load,
  };