drm/nouveau/clk: support for non-BIOS pstates
authorAlexandre Courbot <acourbot@nvidia.com>
Sat, 26 Jul 2014 09:41:40 +0000 (18:41 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Sat, 9 Aug 2014 19:12:47 +0000 (05:12 +1000)
Make nouveau_clock_create() take new two optional arguments: an array
of pstates and its size. When these are specified,
nouveau_clock_create() will use the provided pstates instead of
probing them using the BIOS.

This is useful for platforms which do not provide a BIOS, like Tegra.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/clock.h
drivers/gpu/drm/nouveau/core/subdev/clock/base.c
drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c

index 9f37c096c34db9372d91ababc29ef4af16f97857..a7581478e4ea6b2428f7e3831dde25655119451f 100644 (file)
@@ -115,8 +115,9 @@ struct nouveau_clocks {
        int mdiv;
 };
 
-#define nouveau_clock_create(p,e,o,i,r,d)                                      \
-       nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d)
+#define nouveau_clock_create(p,e,o,i,r,s,n,d)                                  \
+       nouveau_clock_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d),  \
+                             (void **)d)
 #define nouveau_clock_destroy(p) ({                                            \
        struct nouveau_clock *clk = (p);                                       \
        _nouveau_clock_dtor(nv_object(clk));                                   \
@@ -132,7 +133,8 @@ struct nouveau_clocks {
 
 int  nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
                           struct nouveau_oclass *,
-                          struct nouveau_clocks *, bool, int, void **);
+                          struct nouveau_clocks *, struct nouveau_pstate *,
+                          int, bool, int, void **);
 void _nouveau_clock_dtor(struct nouveau_object *);
 int  _nouveau_clock_init(struct nouveau_object *);
 int  _nouveau_clock_fini(struct nouveau_object *, bool);
index 508639d0f08859ea16eb536379db7b6b7e0192c2..d3f70d892d54fc44b5d96fe1d3f5f4156de8aca9 100644 (file)
@@ -534,6 +534,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
                      struct nouveau_object *engine,
                      struct nouveau_oclass *oclass,
                      struct nouveau_clocks *clocks,
+                     struct nouveau_pstate *pstates, int nb_pstates,
                      bool allow_reclock,
                      int length, void **object)
 {
@@ -557,10 +558,17 @@ nouveau_clock_create_(struct nouveau_object *parent,
        init_waitqueue_head(&clk->wait);
        atomic_set(&clk->waiting, 0);
 
-       idx = 0;
-       do {
-               ret = nouveau_pstate_new(clk, idx++);
-       } while (ret == 0);
+       /* If no pstates are provided, try and fetch them from the BIOS */
+       if (!pstates) {
+               idx = 0;
+               do {
+                       ret = nouveau_pstate_new(clk, idx++);
+               } while (ret == 0);
+       } else {
+               for (idx = 0; idx < nb_pstates; idx++)
+                       list_add_tail(&pstates[idx].head, &clk->states);
+               clk->state_nr = nb_pstates;
+       }
 
        clk->allow_reclock = allow_reclock;
 
index eb2d4425a49e45e87fe49983fda2fe48c69adf88..4c48232686be884810e6887fd34e7f1c9fa4d234 100644 (file)
@@ -82,8 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nv04_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, NULL, 0,
+                                  false, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index 8a9e168397912f3d040846f548e5852ed1ca6c61..08368fe970299eea180e2258dacd9e576180795b 100644 (file)
@@ -213,8 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nv40_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, NULL, 0,
+                                  true, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index 8c132772ba9ea526a5cd2f9339ace5e6a22fd299..5070ebc260f8d8cd9bc6493c93e1ed97a8c0603c 100644 (file)
@@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
-                                  false, &priv);
+                                  NULL, 0, false, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index 9fb58354a80bd12d3be11866bff5078c23f55494..087012b189569ee8cf21e1d2f02327023093f25d 100644 (file)
@@ -302,8 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nva3_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, NULL, 0,
+                                  false, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index 6a65fc9e9663a2187c4826efa4ddbb8e31400211..74e19731b1b7db97fc942a70d6e7289a25083a93 100644 (file)
@@ -421,8 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nvaa_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, NULL,
+                                  0, true, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index dbf8517f54da906fc4ad634950217977565092f8..1234abaab2dbe15309e192cf6d8ed24de2a0a6ae 100644 (file)
@@ -437,8 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nvc0_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, NULL, 0,
+                                  false, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
index 0e62a324014404f0dc4e4f30c84f7c370c614585..7eccad57512ee55fcf3764549b6deb5b80a851e0 100644 (file)
@@ -475,8 +475,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        struct nve0_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true,
-                                  &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, NULL, 0,
+                                  true, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;