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));                                   \
 
 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);
 
                      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)
 {
        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;
 
 
        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;
 
        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;
 
        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;
 
        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;
 
        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;
 
        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;
 
        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;