drm/nvc0-: support NOUVEAU_GETPARAM_GRAPH_UNITS
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 27 Mar 2013 21:16:54 +0000 (22:16 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 26 Apr 2013 05:37:41 +0000 (15:37 +1000)
Signed-off-by: Christoph Bumiller <e0425955@student.tuwien.ac.at>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
drivers/gpu/drm/nouveau/core/include/engine/graph.h
drivers/gpu/drm/nouveau/nouveau_abi16.c

index 17049d5c723d15e4ca382c3345c9e9186d4ba7e6..193a5de1b48287e05c732c28ddc066b8e4e5048a 100644 (file)
@@ -46,6 +46,14 @@ struct nv40_graph_chan {
        struct nouveau_graph_chan base;
 };
 
+static u64
+nv40_graph_units(struct nouveau_graph *graph)
+{
+       struct nv40_graph_priv *priv = (void *)graph;
+
+       return nv_rd32(priv, 0x1540);
+}
+
 /*******************************************************************************
  * Graphics object classes
  ******************************************************************************/
@@ -359,6 +367,8 @@ nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        else
                nv_engine(priv)->sclass = nv40_graph_sclass;
        nv_engine(priv)->tile_prog = nv40_graph_tile_prog;
+
+       priv->base.units = nv40_graph_units;
        return 0;
 }
 
index f2b1a7a124f2f58ac43a7c94e2b55a3d41546cff..1ac36110ca19d6e2e72005061720fb90442016c8 100644 (file)
@@ -48,6 +48,14 @@ struct nv50_graph_chan {
        struct nouveau_graph_chan base;
 };
 
+static u64
+nv50_graph_units(struct nouveau_graph *graph)
+{
+       struct nv50_graph_priv *priv = (void *)graph;
+
+       return nv_rd32(priv, 0x1540);
+}
+
 /*******************************************************************************
  * Graphics object classes
  ******************************************************************************/
@@ -819,6 +827,8 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        nv_subdev(priv)->intr = nv50_graph_intr;
        nv_engine(priv)->cclass = &nv50_graph_cclass;
 
+       priv->base.units = nv50_graph_units;
+
        switch (nv_device(priv)->chipset) {
        case 0x50:
                nv_engine(priv)->sclass = nv50_graph_sclass;
index 0de0dd724afff9643125a0ed2bf11e74e231353b..5ce49412e48283b716d33aa5901b2ce7bd859f5b 100644 (file)
@@ -60,6 +60,19 @@ nvc8_graph_sclass[] = {
        {}
 };
 
+u64
+nvc0_graph_units(struct nouveau_graph *graph)
+{
+       struct nvc0_graph_priv *priv = (void *)graph;
+       u64 cfg;
+
+       cfg  = (u32)priv->gpc_nr;
+       cfg |= (u32)priv->tpc_total << 8;
+       cfg |= (u64)priv->rop_nr << 32;
+
+       return cfg;
+}
+
 /*******************************************************************************
  * PGRAPH context
  ******************************************************************************/
@@ -529,6 +542,8 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        nv_subdev(priv)->intr = nvc0_graph_intr;
        nv_engine(priv)->cclass = &nvc0_graph_cclass;
 
+       priv->base.units = nvc0_graph_units;
+
        if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
                nv_info(priv, "using external firmware\n");
                if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
index a1e78de46456b446e0a0261bf92e3f474c949ad6..af033dc244406845c471085472f26885b8f64c6a 100644 (file)
@@ -169,4 +169,6 @@ int  nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
                             struct nouveau_object **);
 void nvc0_graph_context_dtor(struct nouveau_object *);
 
+u64 nvc0_graph_units(struct nouveau_graph *);
+
 #endif
index 4857f913efddd3226c9a8d9362031c337bcefbdf..4b45afb624610d03a8af0659c00b5561fa9b55ef 100644 (file)
@@ -217,6 +217,8 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        nv_engine(priv)->cclass = &nve0_graph_cclass;
        nv_engine(priv)->sclass = nve0_graph_sclass;
 
+       priv->base.units = nvc0_graph_units;
+
        if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
                nv_info(priv, "using external firmware\n");
                if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
index 6943b40d081740e58ac27753092a7665046af2c7..5d392439f2acfaf9b612212694a92cb2569b33da 100644 (file)
@@ -26,6 +26,10 @@ struct nouveau_graph_chan {
 
 struct nouveau_graph {
        struct nouveau_engine base;
+
+       /* Returns chipset-specific counts of units packed into an u64.
+        */
+       u64 (*units)(struct nouveau_graph *);
 };
 
 static inline struct nouveau_graph *
index 5eb3e0da7c6eb1eb213e527021668ddd96bccaa1..1c4c6c9161ac6a675a1ffb3b9af9469669aa5d31 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/fb.h>
 #include <subdev/timer.h>
 #include <subdev/instmem.h>
+#include <engine/graph.h>
 
 #include "nouveau_drm.h"
 #include "nouveau_dma.h"
@@ -168,6 +169,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_device *device = nv_device(drm->device);
        struct nouveau_timer *ptimer = nouveau_timer(device);
+       struct nouveau_graph *graph = (void *)nouveau_engine(device, NVDEV_ENGINE_GR);
        struct drm_nouveau_getparam *getparam = data;
 
        switch (getparam->param) {
@@ -208,14 +210,8 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
                getparam->value = 1;
                break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
-               /* NV40 and NV50 versions are quite different, but register
-                * address is the same. User is supposed to know the card
-                * family anyway... */
-               if (device->chipset >= 0x40) {
-                       getparam->value = nv_rd32(device, 0x001540);
-                       break;
-               }
-               /* FALLTHRU */
+               getparam->value = graph->units ? graph->units(graph) : 0;
+               break;
        default:
                nv_debug(device, "unknown parameter %lld\n", getparam->param);
                return -EINVAL;