Merge branch 'drm-nouveau-fixes' of git://anongit.freedesktop.org/git/nouveau/linux...
authorDave Airlie <airlied@redhat.com>
Mon, 19 Nov 2012 04:03:27 +0000 (14:03 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 22 Nov 2012 03:20:01 +0000 (13:20 +1000)
Some more misc fallout from nouveau rework.

* 'drm-nouveau-fixes' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
  drm/nouveau/bios: fix DCB v1.5 parsing
  drm/nouveau: add missing pll_calc calls
  drm/nouveau: fix crash with noaccel=1
  drm/nv40: allocate ctxprog with kmalloc
  drm/nvc0/disp: fix thinko in vblank regression fix..

drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
drivers/gpu/drm/nouveau/core/include/core/object.h
drivers/gpu/drm/nouveau/core/include/subdev/clock.h
drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
drivers/gpu/drm/nouveau/nouveau_abi16.c

index 05a909a17ceee67590195f0e9c60fd4a10857ed1..15b182c84ce8b74b55f0cb1073c452a410329f6e 100644 (file)
@@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
                if (chan->vblank.crtc != crtc)
                        continue;
 
-               if (nv_device(priv)->chipset == 0x50) {
-                       nv_wr32(priv, 0x001704, chan->vblank.channel);
-                       nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
-                       bar->flush(bar);
-                       nv_wr32(priv, 0x001570, chan->vblank.offset);
-                       nv_wr32(priv, 0x001574, chan->vblank.value);
-               } else {
+               if (nv_device(priv)->chipset >= 0xc0) {
                        nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
                        bar->flush(bar);
                        nv_wr32(priv, 0x06000c,
@@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
                        nv_wr32(priv, 0x060010,
                                lower_32_bits(chan->vblank.offset));
                        nv_wr32(priv, 0x060014, chan->vblank.value);
+               } else {
+                       nv_wr32(priv, 0x001704, chan->vblank.channel);
+                       nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+                       bar->flush(bar);
+                       if (nv_device(priv)->chipset == 0x50) {
+                               nv_wr32(priv, 0x001570, chan->vblank.offset);
+                               nv_wr32(priv, 0x001574, chan->vblank.value);
+                       } else {
+                               nv_wr32(priv, 0x060010, chan->vblank.offset);
+                               nv_wr32(priv, 0x060014, chan->vblank.value);
+                       }
                }
 
                list_del(&chan->vblank.head);
index e45035efb8ca084c37785ffd4a0ca789523d4a2b..7bbb1e1b7a8d1ebbeeb275dd38e27caaa7a1400c 100644 (file)
@@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
                           });
 }
 
-void
+int
 nv40_grctx_init(struct nouveau_device *device, u32 *size)
 {
-       u32 ctxprog[256], i;
+       u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
        struct nouveau_grctx ctx = {
                .device = device,
                .mode = NOUVEAU_GRCTX_PROG,
                .data = ctxprog,
-               .ctxprog_max = ARRAY_SIZE(ctxprog)
+               .ctxprog_max = 256,
        };
 
+       if (!ctxprog)
+               return -ENOMEM;
+
        nv40_grctx_generate(&ctx);
 
        nv_wr32(device, 0x400324, 0);
        for (i = 0; i < ctx.ctxprog_len; i++)
                nv_wr32(device, 0x400328, ctxprog[i]);
        *size = ctx.ctxvals_pos * 4;
+
+       kfree(ctxprog);
+       return 0;
 }
index 425001204a89b6133648d6752fb362159fca4cef..cc6574eeb80e6459166224185a5bd81ce41e9aa4 100644 (file)
@@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object)
                return ret;
 
        /* generate and upload context program */
-       nv40_grctx_init(nv_device(priv), &priv->size);
+       ret = nv40_grctx_init(nv_device(priv), &priv->size);
+       if (ret)
+               return ret;
 
        /* No context present currently */
        nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
index d2ac975afc2e8f46feff64c6be4c16e04faf73b3..7da35a4e7970d1684433f3fd036c60492a5ddb0d 100644 (file)
@@ -15,7 +15,7 @@ nv44_graph_class(void *priv)
        return !(0x0baf & (1 << (device->chipset & 0x0f)));
 }
 
-void nv40_grctx_init(struct nouveau_device *, u32 *size);
+int  nv40_grctx_init(struct nouveau_device *, u32 *size);
 void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
 
 #endif
index 818feabbf4a0969f090f897852fe4476a422b1b6..486f1a9217fd6cd51dc2c5530d455eaa155c86b4 100644 (file)
@@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
        return temp;
 }
 
-static inline bool
-nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
+static inline int
+nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
 {
+       unsigned char c1, c2;
+
        while (len--) {
-               if (nv_ro08(obj, addr++) != *(str++))
-                       return false;
+               c1 = nv_ro08(obj, addr++);
+               c2 = *(str++);
+               if (c1 != c2)
+                       return c1 - c2;
        }
-       return true;
+       return 0;
 }
 
 #endif
index 39e73b91d360a3753dbcc3c210ca1e77f00332ec..41b7a6a76f1981ae3427278bacaf8d2c99edbe09 100644 (file)
@@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
                        int clk, struct nouveau_pll_vals *);
 int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
                        struct nouveau_pll_vals *);
-
+int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
+                       int clk, struct nouveau_pll_vals *);
 
 #endif
index 7d750382a833c33b64fbbf40c98a1d8f936399e2..c511971577490499002426ed04087a517d8e0dab 100644 (file)
@@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
                }
        } else
        if (*ver >= 0x15) {
-               if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
+               if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) {
                        u16 i2c = nv_ro16(bios, dcb + 2);
                        *hdr = 4;
                        *cnt = (i2c - dcb) / 10;
index cc8d7d162d7c348da6770d7404f195e9191d41e1..9068c98b96f64f2f8c0c5a18d478400d09855553 100644 (file)
@@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
        return ret;
 }
 
+int
+nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+                   int clk, struct nouveau_pll_vals *pv)
+{
+       int ret, N, M, P;
+
+       ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+
+       if (ret > 0) {
+               pv->refclk = info->refclk;
+               pv->N1 = N;
+               pv->M1 = M;
+               pv->log2P = P;
+       }
+       return ret;
+}
+
+
 static int
 nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                struct nouveau_oclass *oclass, void *data, u32 size,
@@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                return ret;
 
        priv->base.pll_set = nva3_clock_pll_set;
+       priv->base.pll_calc = nva3_clock_pll_calc;
        return 0;
 }
 
index 5ccce0b17bf3dd209bde225486b41bab55fcdf79..f6962c9b6c36b6f00db2715287dedf1c3adb9f4e 100644 (file)
@@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
                return ret;
 
        priv->base.pll_set = nvc0_clock_pll_set;
+       priv->base.pll_calc = nva3_clock_pll_calc;
        return 0;
 }
 
index cc79c796afee316cd810125b93dd86fbef940d5e..cbf1fc60a38682be197dc1bb1f0f15c8853a06e6 100644 (file)
@@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
 
        if (unlikely(!abi16))
                return -ENOMEM;
+
+       if (!drm->channel)
+               return nouveau_abi16_put(abi16, -ENODEV);
+
        client = nv_client(abi16->client);
 
        if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)