From e09a8e8b0ae232c74b74df8346ce8af7578858c3 Mon Sep 17 00:00:00 2001 From: Lyude Paul <lyude@redhat.com> Date: Fri, 13 Apr 2018 20:46:23 -0400 Subject: [PATCH] wip: maxwell1 power gating currently saves ??? watts. that's a lot of watts. or not. I don't know! --- .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 33 +-- .../gpu/drm/nouveau/nvkm/engine/gr/gk110.h | 46 ++++ .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 246 +++++++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/fb/gk110.c | 8 +- .../gpu/drm/nouveau/nvkm/subdev/fb/gm107.c | 68 ++++- .../gpu/drm/nouveau/nvkm/subdev/therm/gk104.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/therm/gk104.h | 7 + .../gpu/drm/nouveau/nvkm/subdev/therm/gm107.c | 42 ++- 8 files changed, 428 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.h diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 7cd628c84e075..4a7318c604338 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -23,6 +23,7 @@ */ #include "gf100.h" #include "gk104.h" +#include "gk110.h" #include "ctxgf100.h" #include <subdev/timer.h> @@ -158,26 +159,26 @@ gk110_gr_pack_mmio[] = { {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_sked_0[] = { { 0x407000, 1, 0x00004041 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_gcc_0[] = { { 0x419020, 1, 0x00000042 }, { 0x419038, 1, 0x00000042 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_l1c_0[] = { { 0x419cd4, 2, 0x00004042 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_mp_0[] = { { 0x419fd0, 1, 0x00004043 }, { 0x419fd8, 1, 0x00004049 }, @@ -188,32 +189,32 @@ gk110_clkgate_blcg_init_gpc_mp_0[] = { {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_main_0[] = { { 0x4041f4, 1, 0x00000000 }, { 0x409894, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_unk_0[] = { { 0x406004, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_sked_0[] = { { 0x407004, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_ctxctl_0[] = { { 0x41a894, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_unk_0[] = { { 0x418504, 1, 0x00000000 }, { 0x41860c, 1, 0x00000000 }, @@ -221,31 +222,31 @@ gk110_clkgate_slcg_init_gpc_unk_0[] = { {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_esetup_0[] = { { 0x41882c, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_zcull_0[] = { { 0x418974, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_l1c_0[] = { { 0x419cd8, 2, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_unk_1[] = { { 0x419c74, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_mp_0[] = { { 0x419fd4, 1, 0x00004a4a }, { 0x419fdc, 1, 0x00000014 }, @@ -254,13 +255,13 @@ gk110_clkgate_slcg_init_gpc_mp_0[] = { {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_ppc_0[] = { { 0x41be2c, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_pcounter_0[] = { { 0x1be018, 1, 0x000001ff }, { 0x1bc018, 1, 0x000001ff }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.h new file mode 100644 index 0000000000000..7079a22574b88 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.h @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Lyude Paul <lyude@redhat.com> + */ +#ifndef __GM107_GR_H__ +#define __GM107_GR_H__ + +#include <subdev/therm.h> + +extern const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_sked_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_gcc_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_l1c_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_blcg_init_gpc_mp_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_main_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_unk_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_sked_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_ctxctl_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_unk_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_esetup_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_zcull_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_l1c_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_unk_1[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_mp_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_gpc_ppc_0[]; +extern const struct nvkm_therm_clkgate_init gk110_clkgate_slcg_init_pcounter_0[]; + +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 92e31d3972075..edfec84bd8299 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -23,12 +23,15 @@ */ #include "gf100.h" #include "ctxgf100.h" +#include "gk104.h" +#include "gk110.h" #include <subdev/bios.h> #include <subdev/bios/bit.h> #include <subdev/bios/init.h> #include <subdev/bios/P0260.h> #include <subdev/fb.h> +#include <subdev/therm.h> #include <nvif/class.h> @@ -280,6 +283,247 @@ gm107_gr_pack_mmio[] = { {} }; +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_unk_0[] = { + { 0x406000, 1, 0x00004044 }, + { 0x405860, 1, 0x00004042 }, + { 0x40590c, 1, 0x00004044 }, +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_unk_0[] = { + { 0x418500, 1, 0x00004044 }, + { 0x418608, 1, 0x00004042 }, + { 0x418688, 1, 0x00004042 }, + { 0x418718, 1, 0x00000042 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_unk_1[] = { + { 0x418cf0, 1, 0x00004044 }, + { 0x418d70, 1, 0x00004044 }, + { 0x418f0c, 1, 0x00004044 }, + { 0x418e0c, 1, 0x00004044 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_tex_0[] = { + { 0x419a40, 9, 0x00004042 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_l1c_0[] = { + { 0x419cd4, 2, 0x00000002 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_mp_0[] = { + { 0x419fd0, 1, 0x00000044 }, + { 0x419fd8, 1, 0x00000045 }, + { 0x419fe0, 1, 0x00000044 }, + { 0x419fe8, 1, 0x00000042 }, + { 0x419ff0, 1, 0x00000045 }, + { 0x419ff8, 1, 0x00000002 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_blcg_init_gpc_ppc_0[] = { + { 0x41be28, 1, 0x00000042 }, + { 0x41bfe8, 1, 0x00004044 }, + { 0x41bed0, 1, 0x00004044 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_main_0[] = { + { 0x4041f4, 1, 0x00000002 }, + { 0x409894, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_rstr2d_0[] = { + { 0x4078c4, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_unk_0[] = { + { 0x406004, 1, 0x00000000 }, + { 0x405864, 1, 0x00000000 }, + { 0x405910, 1, 0xfffffff0 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gcc_0[] = { + { 0x408044, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_unk_0[] = { + { 0x418504, 1, 0x0001fffe }, + { 0x41860c, 1, 0x00000000 }, + { 0x41868c, 1, 0x00000000 }, + { 0x41871c, 1, 0x00000000 }, + { 0x418388, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_tpbus_0[] = { + { 0x418bc0, 1, 0x00000004 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_zcull_0[] = { + { 0x418974, 1, 0x00000028 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_tpconf_1[] = { + { 0x418c74, 1, 0xffffffc0 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_unk_1[] = { + { 0x418504, 1, 0x0001fffe }, + { 0x41860c, 1, 0x00000000 }, + { 0x41868c, 1, 0x00000000 }, + { 0x41871c, 1, 0x00000000 }, + { 0x418388, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_gcc_0[] = { + { 0x419024, 1, 0x000001fe }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_ffb_0[] = { + { 0x41889c, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_tex_0[] = { + { 0x419d64, 1, 0x00000000 }, + { 0x419a44, 9, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_poly_0[] = { + { 0x41986c, 1, 0x00001fc4 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_unk_2[] = { + { 0x419c74, 1, 0x0000001e }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_gpc_mp_0[] = { + { 0x419fd4, 3, 0x00000000 }, + { 0x419ff4, 2, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_ppc_0[] = { + { 0x41be2c, 1, 0x04135fc0 }, + { 0x41bfec, 1, 0xfffffff0 }, + { 0x41bed4, 1, 0xfffffffe }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_rop_zrop_0[] = { + { 0x4089ac, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_rop_0[] = { + { 0x408a24, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_clkgate_slcg_init_pcounter_0[] = { + { 0x1be018, 1, 0x000001ff }, + { 0x1bc018, 1, 0x000001ff }, + { 0x1bc218, 1, 0x000001ff }, + { 0x1b8018, 1, 0x000001ff }, + { 0x1b4124, 1, 0x00000001 }, + {} +}; + +static const struct nvkm_therm_clkgate_pack +gm107_clkgate_pack[] = { + { gk104_clkgate_blcg_init_main_0 }, + { gk104_clkgate_blcg_init_rstr2d_0 }, + { gm107_clkgate_blcg_init_unk_0 }, + { gk104_clkgate_blcg_init_gcc_0 }, + { gk110_clkgate_blcg_init_sked_0 }, + { gk104_clkgate_blcg_init_unk_1 }, + { gk104_clkgate_blcg_init_gpc_ctxctl_0 }, + { gm107_clkgate_blcg_init_gpc_unk_0 }, + { gk104_clkgate_blcg_init_gpc_esetup_0 }, + { gk104_clkgate_blcg_init_gpc_tpbus_0 }, + { gk104_clkgate_blcg_init_gpc_zcull_0 }, + { gm107_clkgate_blcg_init_gpc_unk_1 }, + { gk104_clkgate_blcg_init_gpc_gcc_0 }, + { gk104_clkgate_blcg_init_gpc_ffb_0 }, + { gm107_clkgate_blcg_init_gpc_tex_0 }, + { gk104_clkgate_blcg_init_gpc_poly_0 }, + { gm107_clkgate_blcg_init_gpc_l1c_0 }, + { gk104_clkgate_blcg_init_gpc_unk_2 }, + { gm107_clkgate_blcg_init_gpc_mp_0 }, + { gm107_clkgate_blcg_init_gpc_ppc_0 }, + { gk104_clkgate_blcg_init_rop_zrop_0 }, + { gk104_clkgate_blcg_init_rop_0 }, + { gk104_clkgate_blcg_init_rop_crop_0 }, + { gk104_clkgate_blcg_init_pxbar_0 }, + { gm107_clkgate_slcg_init_main_0 }, + { gm107_clkgate_slcg_init_rstr2d_0 }, + { gm107_clkgate_slcg_init_unk_0 }, + { gm107_clkgate_slcg_init_gcc_0 }, + { gk110_clkgate_slcg_init_sked_0 }, + { gk110_clkgate_slcg_init_gpc_ctxctl_0 }, + { gm107_clkgate_slcg_init_gpc_unk_0 }, + { gk110_clkgate_slcg_init_gpc_esetup_0 }, + { gm107_clkgate_slcg_init_gpc_tpbus_0 }, + { gm107_clkgate_slcg_init_gpc_zcull_0 }, + { gm107_clkgate_slcg_init_gpc_tpconf_1 }, + { gm107_clkgate_slcg_init_gpc_unk_1 }, + { gm107_clkgate_slcg_init_gpc_gcc_0 }, + { gm107_clkgate_slcg_init_gpc_ffb_0 }, + { gm107_clkgate_slcg_init_gpc_tex_0 }, + { gm107_clkgate_slcg_init_gpc_poly_0 }, + { gk110_clkgate_slcg_init_gpc_l1c_0 }, + { gm107_clkgate_slcg_init_gpc_unk_2 }, + { gm107_clkgate_slcg_init_gpc_mp_0 }, + { gm107_clkgate_slcg_init_ppc_0 }, + { gm107_clkgate_slcg_init_rop_zrop_0 }, + { gm107_clkgate_slcg_init_rop_0 }, + { gm107_clkgate_slcg_init_pcounter_0 }, + {} +}; + /******************************************************************************* * PGRAPH engine/subdev functions ******************************************************************************/ @@ -419,7 +663,7 @@ gm107_gr = { .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gm107_grctx, - .zbc = &gf100_gr_zbc, + .clkgate_pack = gm107_clkgate_pack, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c index 0d9ad9fa77746..e718cffafeb77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c @@ -32,20 +32,20 @@ * PGRAPH registers for clockgating ******************************************************************************* */ -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_fb_clkgate_slcg_init_bcast_0[] = { { 0x10f280, 1, 0x00000000 }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_fb_clkgate_slcg_init_pxbar_0[] = { { 0x13cafc, 1, 0x0000007e }, { 0x13cbe4, 1, 0x1ffffffe }, {} }; -static const struct nvkm_therm_clkgate_init +const struct nvkm_therm_clkgate_init gk110_fb_clkgate_blcg_init_unk_0[] = { { 0x100d10, 1, 0x0000c242 }, { 0x100d30, 1, 0x0000c242 }, @@ -55,7 +55,7 @@ gk110_fb_clkgate_blcg_init_unk_0[] = { {} }; -static const struct nvkm_therm_clkgate_pack +const struct nvkm_therm_clkgate_pack gk110_fb_clkgate_pack[] = { { gk110_fb_clkgate_slcg_init_bcast_0 }, { gk110_fb_clkgate_slcg_init_pxbar_0 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c index 69c876d5d1c11..361c6a1fef869 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c @@ -1,5 +1,5 @@ /* - * Copyright 2012 Red Hat Inc. + * Copyright 2012-2018 Red Hat Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,10 +20,75 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Ben Skeggs + * Lyude Paul */ #include "gf100.h" +#include "gk104.h" +#include "gk110.h" #include "ram.h" +/* + ******************************************************************************* + * PGRAPH registers for clockgating + ******************************************************************************* + */ +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_slcg_init_unk_0[] = { + { 0x100d14, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_slcg_init_vm_0[] = { + { 0x100c9c, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_slcg_init_bcast_0[] = { + { 0x17e050, 1, 0x00000000 }, + { 0x17e35c, 1, 0x00000000 }, + { 0x10f280, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_slcg_init_pxbar_0[] = { + { 0x13c824, 1, 0x00000000 }, + { 0x13cbe4, 1, 0x00000000 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_blcg_init_main_0[] = { + { 0x10f000, 1, 0x00000043 }, + { 0x17e030, 1, 0x00000044 }, + { 0x17e040, 1, 0x00000044 }, + {} +}; + +static const struct nvkm_therm_clkgate_init +gm107_fb_clkgate_blcg_init_unk_1[] = { + { 0x17e3e0, 1, 0x00000044 }, + { 0x17e3c8, 1, 0x00000044 }, + /* XXX extremely unlikely to be a BLCG/SLCG register */ + /*{ 0x17e278, 1, 0x0007fd60 },*/ + {} +}; + +static const struct nvkm_therm_clkgate_pack +gm107_fb_clkgate_pack[] = { + { gm107_fb_clkgate_slcg_init_unk_0 }, + { gm107_fb_clkgate_slcg_init_vm_0 }, + { gm107_fb_clkgate_slcg_init_bcast_0 }, + { gm107_fb_clkgate_slcg_init_pxbar_0 }, + { gk110_fb_clkgate_blcg_init_unk_0 }, + { gk104_fb_clkgate_blcg_init_vm_0 }, + { gm107_fb_clkgate_blcg_init_main_0 }, + { gm107_fb_clkgate_blcg_init_unk_1 }, + {} +}; + static const struct nvkm_fb_func gm107_fb = { .dtor = gf100_fb_dtor, @@ -33,6 +98,7 @@ gm107_fb = { .intr = gf100_fb_intr, .ram_new = gm107_ram_new, .default_bigpage = 17, + .clkgate_pack = gm107_fb_clkgate_pack, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c index 4e03971d2e3df..efc8a23b55f86 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c @@ -105,7 +105,7 @@ gk104_therm_func = { .clkgate_fini = gk104_clkgate_fini, }; -static int +int gk104_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, int index, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h index 293e7743b19bb..f1de626c35694 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h @@ -45,4 +45,11 @@ struct gk104_therm { extern const struct gk104_clkgate_engine_info gk104_clkgate_engine_info[]; extern const struct gf100_idle_filter gk104_idle_filter; +int gk104_therm_new_(const struct nvkm_therm_func *, + struct nvkm_device *, + int, + const struct gk104_clkgate_engine_info *, + const struct gf100_idle_filter *, + struct nvkm_therm **); + #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c index 86848ece4d897..2ad3b2bf57385 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c @@ -22,6 +22,36 @@ * Authors: Martin Peres */ #include "priv.h" +#include "gk104.h" + +void +gm107_clkgate_enable(struct nvkm_therm *base) +{ + struct gk104_therm *therm = gk104_therm(base); + struct nvkm_device *dev = therm->base.subdev.device; + const struct gk104_clkgate_engine_info *order = therm->clkgate_order; + int i; + + /* Program ENG_MANT, ENG_FILTER */ + for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) { + if (!nvkm_device_subdev(dev, order[i].engine)) + continue; + + nvkm_mask(dev, 0x20200 + order[i].offset, 0xff00, 0x2200); + } + + /* magic */ + nvkm_wr32(dev, 0x020288, therm->idle_filter->fecs); + nvkm_wr32(dev, 0x02028c, therm->idle_filter->hubmmu); + + /* Enable clockgating (ENG_CLK = RUN->AUTO) */ + for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) { + if (!nvkm_device_subdev(dev, order[i].engine)) + continue; + + nvkm_mask(dev, 0x20200 + order[i].offset, 0x00ff, 0x0045); + } +} static int gm107_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable) @@ -54,6 +84,11 @@ gm107_fan_pwm_clock(struct nvkm_therm *therm, int line) return therm->subdev.device->crystal * 1000; } +const struct gf100_idle_filter gm107_idle_filter = { + .fecs = 0x00000000, + .hubmmu = 0x00000000, +}; + static const struct nvkm_therm_func gm107_therm = { .init = gf119_therm_init, @@ -65,11 +100,16 @@ gm107_therm = { .temp_get = g84_temp_get, .fan_sense = gt215_therm_fan_sense, .program_alarms = nvkm_therm_program_alarms_polling, + .clkgate_init = gf100_clkgate_init, + .clkgate_enable = gm107_clkgate_enable, + .clkgate_fini = gk104_clkgate_fini, }; int gm107_therm_new(struct nvkm_device *device, int index, struct nvkm_therm **ptherm) { - return nvkm_therm_new_(&gm107_therm, device, index, ptherm); + return gk104_therm_new_(&gm107_therm, device, index, + gk104_clkgate_engine_info, &gm107_idle_filter, + ptherm); } -- GitLab