drm/gk20a: support for reclocking
v2 cover drm/gk20a: support for reclocking
Second version of the gk20a clock patches. I have tried to keep the therm and volt devices mandatory in the clock driver, but unfortunately they are too tied to bios to allow this, at least for the moment. Consequently this version is mostly a port of the first version to Ben's tree.
Ben, please let me know what I have done wrong in terms of integration to your tree, as the main purpose of writing patches against it instead of the kernel is to make your life easier. :)
Alexandre Courbot (3):
clk: make therm and volt devices optional
clk: support for non-BIOS pstates
gk20a: reclocking support
drm/Kbuild | 1 + drm/core/os.h | 1 + drm/core/subdev/clock/gk20a.c | 1 + drm/core/subdev/fb/ramgk20a.h | 1 + drm/core/subdev/instmem/gk20a.c | 1 + lib/core/os.h | 10 + nvkm/engine/device/nve0.c | 1 + nvkm/include/subdev/clock.h | 9 +- nvkm/subdev/clock/Makefile.am | 1 + nvkm/subdev/clock/base.c | 52 ++-- nvkm/subdev/clock/gk20a.c | 665 ++++++++++++++++++++++++++++++++++++++++ nvkm/subdev/clock/nv04.c | 4 +- nvkm/subdev/clock/nv40.c | 4 +- nvkm/subdev/clock/nv50.c | 2 +- nvkm/subdev/clock/nva3.c | 4 +- nvkm/subdev/clock/nvaa.c | 4 +- nvkm/subdev/clock/nvc0.c | 4 +- nvkm/subdev/clock/nve0.c | 4 +- 18 files changed, 735 insertions(+), 34 deletions(-) create mode 120000 drm/core/subdev/clock/gk20a.c create mode 120000 drm/core/subdev/fb/ramgk20a.h create mode 120000 drm/core/subdev/instmem/gk20a.c create mode 100644 nvkm/subdev/clock/gk20a.c
Signature · 1 line
2.0.2
A message that is not in the archive (sent off-list or not yet received): 1406367701-9155-1-git-send-email-gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
PATCH v2 1/3 clk: make therm and volt devices optional
From: Alexandre Courbot <[email protected]>
Allow the clock subsystem to operate even if voltage and thermal devices are not set for the device (for people with watercooling! ;))
--- nvkm/subdev/clock/base.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-)
nvkm/subdev/clock/base.c +22 -14
@@ -90,16 +90,20 @@ nouveau_cstate_prog(struct nouveau_clock *clk, cstate = &pstate->base; } - ret =nouveau_therm_cstate (ptherm, pstate->fanspeed,+1 ); -if (ret && ret != -ENODEV ) { -nv_error (clk,"failed to raise fan speed: %d\n" , ret); -return ret; +if (ptherm) { + ret =nouveau_therm_cstate (ptherm, pstate->fanspeed,+1 ); +if (ret && ret != -ENODEV ) { +nv_error (clk,"failed to raise fan speed: %d\n" , ret); +return ret; + } } - ret = volt->set_id (volt, cstate->voltage,+1 ); -if (ret && ret != -ENODEV ) { -nv_error (clk,"failed to raise voltage: %d\n" , ret); -return ret; +if (volt) { + ret = volt->set_id (volt, cstate->voltage,+1 ); +if (ret && ret != -ENODEV ) { +nv_error (clk,"failed to raise voltage: %d\n" , ret); +return ret; + } } ret = clk->calc (clk, cstate);
@@ -108,13 +112,17 @@ nouveau_cstate_prog(struct nouveau_clock *clk, clk->tidy (clk); } - ret = volt->set_id (volt, cstate->voltage,-1 ); -if (ret && ret != -ENODEV ) -nv_error (clk,"failed to lower voltage: %d\n" , ret); +if (volt) { + ret = volt->set_id (volt, cstate->voltage,-1 ); +if (ret && ret != -ENODEV ) +nv_error (clk,"failed to lower voltage: %d\n" , ret); + } - ret =nouveau_therm_cstate (ptherm, pstate->fanspeed,-1 ); -if (ret && ret != -ENODEV ) -nv_error (clk,"failed to lower fan speed: %d\n" , ret); +if (ptherm) { + ret =nouveau_therm_cstate (ptherm, pstate->fanspeed,-1 ); +if (ret && ret != -ENODEV ) +nv_error (clk,"failed to lower fan speed: %d\n" , ret); + }return 0 ; }
Signature · 1 line
2.0.2
PATCH v2 2/3 clk: support for non-BIOS pstates
In reply to a message not in the archiveFrom: Alexandre Courbot <[email protected]>
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.
--- nvkm/include/subdev/clock.h | 8 +++++--- nvkm/subdev/clock/base.c | 16 ++++++++++++---- nvkm/subdev/clock/nv04.c | 4 ++-- nvkm/subdev/clock/nv40.c | 4 ++-- nvkm/subdev/clock/nv50.c | 2 +- nvkm/subdev/clock/nva3.c | 4 ++-- nvkm/subdev/clock/nvaa.c | 4 ++-- nvkm/subdev/clock/nvc0.c | 4 ++-- nvkm/subdev/clock/nve0.c | 4 ++-- 9 files changed, 30 insertions(+), 20 deletions(-)
nvkm/include/subdev/clock.h +5 -3
@@ -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 );
nvkm/subdev/clock/base.c +12 -4
@@ -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;
nvkm/subdev/clock/nv04.c +2 -2
@@ -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;
nvkm/subdev/clock/nv40.c +2 -2
@@ -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;
nvkm/subdev/clock/nv50.c +1 -1
@@ -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;
nvkm/subdev/clock/nva3.c +2 -2
@@ -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;
nvkm/subdev/clock/nvaa.c +2 -2
@@ -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;
nvkm/subdev/clock/nvc0.c +2 -2
@@ -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;
nvkm/subdev/clock/nve0.c +2 -2
@@ -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;
Signature · 1 line
2.0.2
PATCH v2 3/3 gk20a: reclocking support
In reply to a message not in the archiveFrom: Alexandre Courbot <[email protected]>
Add support for reclocking on GK20A, using a statically-defined pstates table. The algorithms for calculating the coefficients and setting the clocks are directly taken from the ChromeOS kernel.
--- drm/Kbuild | 1 + drm/core/os.h | 1 + drm/core/subdev/clock/gk20a.c | 1 + drm/core/subdev/fb/ramgk20a.h | 1 + drm/core/subdev/instmem/gk20a.c | 1 + lib/core/os.h | 10 + nvkm/engine/device/nve0.c | 1 + nvkm/include/subdev/clock.h | 1 + nvkm/subdev/clock/Makefile.am | 1 + nvkm/subdev/clock/gk20a.c | 665 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 683 insertions(+) create mode 120000 drm/core/subdev/clock/gk20a.c create mode 120000 drm/core/subdev/fb/ramgk20a.h create mode 120000 drm/core/subdev/instmem/gk20a.c create mode 100644 nvkm/subdev/clock/gk20a.c
drm/Kbuild +1 -0
@@ -65,6 +65,7 @@ nouveau-y += core/subdev/clock/nva3.o nouveau-y += core/subdev/clock/nvaa.o nouveau-y += core/subdev/clock/nvc0.o nouveau-y += core/subdev/clock/nve0.o +nouveau-y += core/subdev/clock/gk20a.o nouveau-y += core/subdev/clock/pllnv04.o nouveau-y += core/subdev/clock/pllnva3.o nouveau-y += core/subdev/devinit/base.o
drm/core/os.h +1 -0
@@ -22,6 +22,7 @@#include <linux/log2.h> #include <linux/pm_runtime.h> #include <linux/power_supply.h> +#include <linux/clk.h> #include <asm/unaligned.h>
drm/core/subdev/clock/gk20a.c new file +1 -0
@@ -0,0 +1 @@ +../../../../nvkm/subdev/clock/gk20a.c
drm/core/subdev/fb/ramgk20a.h new file +1 -0
@@ -0,0 +1 @@ +../../../../nvkm/subdev/fb/ramgk20a.h
drm/core/subdev/instmem/gk20a.c new file +1 -0
@@ -0,0 +1 @@ +../../../../nvkm/subdev/instmem/gk20a.c
lib/core/os.h +10 -0
@@ -1098,4 +1098,14 @@ struct notifier_block {#undef __BIG_ENDIAN#endif +struct nouveau_platform_gpu { +void *clk; +}; + +struct nouveau_platform_device { +struct nouveau_platform_gpu *gpu; +}; + +#define nv_device_to_platform (x) NULL +#endif
nvkm/engine/device/nve0.c +1 -0
@@ -158,6 +158,7 @@ nve0_identify(struct nouveau_device *device)break ;case 0xea : device->cname ="GK20A" ; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &gk20a_clock_oclass; device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
nvkm/include/subdev/clock.h +1 -0
@@ -147,6 +147,7 @@ extern struct nouveau_oclass *nvaa_clock_oclass;extern struct nouveau_oclass nva3_clock_oclass;extern struct nouveau_oclass nvc0_clock_oclass;extern struct nouveau_oclass nve0_clock_oclass; +extern struct nouveau_oclass gk20a_clock_oclass;int nv04_clock_pll_set (struct nouveau_clock *,u32 type,u32 freq); int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
nvkm/subdev/clock/Makefile.am +1 -0
@@ -9,6 +9,7 @@ libclock_la_SOURCES = base.c \ nvaa.c \ nvc0.c \ nve0.c \ + gk20a.c \ pllnv04.c \ pllnva3.c
nvkm/subdev/clock/gk20a.c new file +665 -0
665 lines not on this page · raw message
Signature · 1 line
2.0.2
Ben Skeggs
AppliedQuoted 4 lines · Alexandre Courbot
Second version of the gk20a clock patches. I have tried to keep the therm and volt devices mandatory in the clock driver, but unfortunately they are too tied to bios to allow this, at least for the moment. Consequently this version is mostly a port of the first version to Ben's tree.
I've merged the series, thanks Alex.
Quoted 4 lines
Ben, please let me know what I have done wrong in terms of integration to your tree, as the main purpose of writing patches against it instead of the kernel is to make your life easier. :)
I honestly don't mind at all if you completely ignore the non-DRM build and leave it to me to fix up. I personally use the userspace build quite a lot for dev/testing, but don't at all expect others to, or to maintain it. But thank you for bothering :)
In any case, it was *almost* (clk_get_rate() was missing) fine. I left a patch in the tree of what I changed, and I'll squash it before it goes to -staging.
Thanks again,
Ben.
Quoted 37 lines
Alexandre Courbot (3):
clk: make therm and volt devices optional
clk: support for non-BIOS pstates
gk20a: reclocking supportdrm/Kbuild | 1 + drm/core/os.h | 1 + drm/core/subdev/clock/gk20a.c | 1 + drm/core/subdev/fb/ramgk20a.h | 1 + drm/core/subdev/instmem/gk20a.c | 1 + lib/core/os.h | 10 + nvkm/engine/device/nve0.c | 1 + nvkm/include/subdev/clock.h | 9 +- nvkm/subdev/clock/Makefile.am | 1 + nvkm/subdev/clock/base.c | 52 ++-- nvkm/subdev/clock/gk20a.c | 665 ++++++++++++++++++++++++++++++++++++++++ nvkm/subdev/clock/nv04.c | 4 +- nvkm/subdev/clock/nv40.c | 4 +- nvkm/subdev/clock/nv50.c | 2 +- nvkm/subdev/clock/nva3.c | 4 +- nvkm/subdev/clock/nvaa.c | 4 +- nvkm/subdev/clock/nvc0.c | 4 +- nvkm/subdev/clock/nve0.c | 4 +- 18 files changed, 735 insertions(+), 34 deletions(-) create mode 120000 drm/core/subdev/clock/gk20a.c create mode 120000 drm/core/subdev/fb/ramgk20a.h create mode 120000 drm/core/subdev/instmem/gk20a.c create mode 100644 nvkm/subdev/clock/gk20a.c--
2.0.2_______________________________________________
Nouveau mailing list [email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): CACAvsv7mLcaWmZsaQz95GBktxcCf22Nkh9y+UyeHTcY78TPY2w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 6 lines · Ben Skeggs
Quoted 4 lines · Alexandre Courbot
Second version of the gk20a clock patches. I have tried to keep the therm and volt devices mandatory in the clock driver, but unfortunately they are too tied to bios to allow this, at least for the moment. Consequently this version is mostly a port of the first version to Ben's tree.
I've merged the series, thanks Alex.
Great, thanks to you!
Quoted 5 lines
Quoted 5 lines
Ben, please let me know what I have done wrong in terms of integration to your tree, as the main purpose of writing patches against it instead of the kernel is to make your life easier. :)
Quoted 8 lines
I honestly don't mind at all if you completely ignore the non-DRM build and leave it to me to fix up. I personally use the userspace build quite a lot for dev/testing, but don't at all expect others to, or to maintain it. But thank you for bothering :)
In any case, it was *almost* (
clk_get_rate()was missing) fine. I left a patch in the tree of what I changed, and I'll squash it before it goes to -staging.
Oh I see. I probably omitted to do a test build after committing some last changes - sorry about that.
Thanks again,
Alex.