Commit bb4d29df authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs

drm/nouveau/clk: support for non-BIOS pstates

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: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2cfd22f4
...@@ -115,8 +115,9 @@ struct nouveau_clocks { ...@@ -115,8 +115,9 @@ struct nouveau_clocks {
int mdiv; int mdiv;
}; };
#define nouveau_clock_create(p,e,o,i,r,d) \ #define nouveau_clock_create(p,e,o,i,r,s,n,d) \
nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d) nouveau_clock_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d), \
(void **)d)
#define nouveau_clock_destroy(p) ({ \ #define nouveau_clock_destroy(p) ({ \
struct nouveau_clock *clk = (p); \ struct nouveau_clock *clk = (p); \
_nouveau_clock_dtor(nv_object(clk)); \ _nouveau_clock_dtor(nv_object(clk)); \
...@@ -132,7 +133,8 @@ struct nouveau_clocks { ...@@ -132,7 +133,8 @@ struct nouveau_clocks {
int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *, int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, 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 *); void _nouveau_clock_dtor(struct nouveau_object *);
int _nouveau_clock_init(struct nouveau_object *); int _nouveau_clock_init(struct nouveau_object *);
int _nouveau_clock_fini(struct nouveau_object *, bool); int _nouveau_clock_fini(struct nouveau_object *, bool);
......
...@@ -534,6 +534,7 @@ nouveau_clock_create_(struct nouveau_object *parent, ...@@ -534,6 +534,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
struct nouveau_object *engine, struct nouveau_object *engine,
struct nouveau_oclass *oclass, struct nouveau_oclass *oclass,
struct nouveau_clocks *clocks, struct nouveau_clocks *clocks,
struct nouveau_pstate *pstates, int nb_pstates,
bool allow_reclock, bool allow_reclock,
int length, void **object) int length, void **object)
{ {
...@@ -557,10 +558,17 @@ nouveau_clock_create_(struct nouveau_object *parent, ...@@ -557,10 +558,17 @@ nouveau_clock_create_(struct nouveau_object *parent,
init_waitqueue_head(&clk->wait); init_waitqueue_head(&clk->wait);
atomic_set(&clk->waiting, 0); atomic_set(&clk->waiting, 0);
/* If no pstates are provided, try and fetch them from the BIOS */
if (!pstates) {
idx = 0; idx = 0;
do { do {
ret = nouveau_pstate_new(clk, idx++); ret = nouveau_pstate_new(clk, idx++);
} while (ret == 0); } 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; clk->allow_reclock = allow_reclock;
......
...@@ -82,8 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -82,8 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_clock_priv *priv; struct nv04_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false, ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, NULL, 0,
&priv); false, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -213,8 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -213,8 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv40_clock_priv *priv; struct nv40_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true, ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, NULL, 0,
&priv); true, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, pclass->domains, ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
false, &priv); NULL, 0, false, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -302,8 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -302,8 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nva3_clock_priv *priv; struct nva3_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false, ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, NULL, 0,
&priv); false, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -421,8 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -421,8 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvaa_clock_priv *priv; struct nvaa_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true, ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, NULL,
&priv); 0, true, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -437,8 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -437,8 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvc0_clock_priv *priv; struct nvc0_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false, ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, NULL, 0,
&priv); false, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
...@@ -475,8 +475,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -475,8 +475,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nve0_clock_priv *priv; struct nve0_clock_priv *priv;
int ret; int ret;
ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true, ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, NULL, 0,
&priv); true, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment