On 26/01/18 22:59, Lyude Paul wrote:
> This enables BLCG optimization for kepler1. When using clockgating,
> nvidia's firmware has a set of registers which are initially programmed
> by the vbios with various engine delays and other mysterious settings
> that are safe enough to bring up the GPU. However, the values used by
> the vbios are more power hungry then they need to be, so the nvidia driver

then -> than.

With the comment about not exposing clock gating until patch 2, 3, and 4
have landed addressed, the series is:

Reviewed-by: Martin Peres <martin.pe...@free.fr>

Thanks a lot! I really like how this turned out :)

> writes it's own more optimized set of BLCG settings before enabling
> CG_CTRL. This adds support for programming the optimized BLCG values
> during engine/subdev init, which enables rather significant power
> savings.
> 
> This introduces the nvkm_therm_clkgate_init() helper, which we use to
> program the optimized BLCG settings before enabling clockgating with
> nvkm_therm_clkgate_enable.
> 
> As well, this commit shares a lot more code with Fermi since BLCG is
> mostly the same there as far as we can tell. In the future, it's likely
> we'll reformat the clkgate_packs for kepler1 so that they share a list
> of mmio packs with Fermi.
> 
> Signed-off-by: Lyude Paul <ly...@redhat.com>
> ---
>  .../gpu/drm/nouveau/include/nvkm/subdev/therm.h    |  12 ++
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h     |   1 +
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c     | 207 
> +++++++++++++++++++++
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h     |  55 ++++++
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c     |   6 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c     |  47 +++++
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h     |  35 ++++
>  drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h      |   2 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild   |   1 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c   |  10 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c  |  75 ++++++++
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c  |   1 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c  |   2 +-
>  drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h   |   8 +
>  14 files changed, 461 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
>  create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
> 
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h 
> b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> index 240b19bb4667..9398d9f09339 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
> @@ -46,6 +46,16 @@ enum nvkm_therm_attr_type {
>       NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
>  };
>  
> +struct nvkm_therm_clkgate_init {
> +     u32 addr;
> +     u8  count;
> +     u32 data;
> +};
> +
> +struct nvkm_therm_clkgate_pack {
> +     const struct nvkm_therm_clkgate_init *init;
> +};
> +
>  struct nvkm_therm {
>       const struct nvkm_therm_func *func;
>       struct nvkm_subdev subdev;
> @@ -92,6 +102,8 @@ struct nvkm_therm {
>  int nvkm_therm_temp_get(struct nvkm_therm *);
>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
> +void nvkm_therm_clkgate_init(struct nvkm_therm *,
> +                          const struct nvkm_therm_clkgate_pack *);
>  void nvkm_therm_clkgate_enable(struct nvkm_therm *);
>  void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool);
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h 
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> index d7c2adb9b543..c8ec3fd97155 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> @@ -137,6 +137,7 @@ struct gf100_gr_func {
>       int (*rops)(struct gf100_gr *);
>       int ppc_nr;
>       const struct gf100_grctx_func *grctx;
> +     const struct nvkm_therm_clkgate_pack *clkgate_pack;
>       struct nvkm_sclass sclass[];
>  };
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> index 5e82f94c2245..17cea9c70f7f 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
> @@ -22,6 +22,7 @@
>   * Authors: Ben Skeggs <bske...@redhat.com>
>   */
>  #include "gf100.h"
> +#include "gk104.h"
>  #include "ctxgf100.h"
>  
>  #include <nvif/class.h>
> @@ -173,6 +174,208 @@ gk104_gr_pack_mmio[] = {
>       {}
>  };
>  
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_main_0[] = {
> +     { 0x4041f0, 1, 0x00004046 },
> +     { 0x409890, 1, 0x00000045 },
> +     { 0x4098b0, 1, 0x0000007f },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_rstr2d_0[] = {
> +     { 0x4078c0, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_unk_0[] = {
> +     { 0x406000, 1, 0x00004044 },
> +     { 0x405860, 1, 0x00004042 },
> +     { 0x40590c, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gcc_0[] = {
> +     { 0x408040, 1, 0x00004044 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_sked_0[] = {
> +     { 0x407000, 1, 0x00004044 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_unk_1[] = {
> +     { 0x405bf0, 1, 0x00004044 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_ctxctl_0[] = {
> +     { 0x41a890, 1, 0x00000042 },
> +     { 0x41a8b0, 1, 0x0000007f },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_unk_0[] = {
> +     { 0x418500, 1, 0x00004042 },
> +     { 0x418608, 1, 0x00004042 },
> +     { 0x418688, 1, 0x00004042 },
> +     { 0x418718, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_esetup_0[] = {
> +     { 0x418828, 1, 0x00000044 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_tpbus_0[] = {
> +     { 0x418bbc, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_zcull_0[] = {
> +     { 0x418970, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_tpconf_0[] = {
> +     { 0x418c70, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_unk_1[] = {
> +     { 0x418cf0, 1, 0x00004042 },
> +     { 0x418d70, 1, 0x00004042 },
> +     { 0x418f0c, 1, 0x00004042 },
> +     { 0x418e0c, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_gcc_0[] = {
> +     { 0x419020, 1, 0x00004042 },
> +     { 0x419038, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_ffb_0[] = {
> +     { 0x418898, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_tex_0[] = {
> +     { 0x419a40, 9, 0x00004042 },
> +     { 0x419acc, 1, 0x00004047 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_poly_0[] = {
> +     { 0x419868, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_l1c_0[] = {
> +     { 0x419ccc, 3, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_unk_2[] = {
> +     { 0x419c70, 1, 0x00004045 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_mp_0[] = {
> +     { 0x419fd0, 1, 0x00004043 },
> +     { 0x419fd8, 1, 0x00004049 },
> +     { 0x419fe0, 2, 0x00004042 },
> +     { 0x419ff0, 1, 0x00004046 },
> +     { 0x419ff8, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_gpc_ppc_0[] = {
> +     { 0x41be28, 1, 0x00000042 },
> +     { 0x41bfe8, 1, 0x00004042 },
> +     { 0x41bed0, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_rop_zrop_0[] = {
> +     { 0x408810, 2, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_rop_0[] = {
> +     { 0x408a80, 6, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_rop_crop_0[] = {
> +     { 0x4089a8, 1, 0x00004042 },
> +     { 0x4089b0, 1, 0x00000042 },
> +     { 0x4089b8, 1, 0x00004042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_clkgate_blcg_init_pxbar_0[] = {
> +     { 0x13c820, 1, 0x0001007f },
> +     { 0x13cbe0, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_pack
> +gk104_clkgate_pack[] = {
> +     { gk104_clkgate_blcg_init_main_0 },
> +     { gk104_clkgate_blcg_init_rstr2d_0 },
> +     { gk104_clkgate_blcg_init_unk_0 },
> +     { gk104_clkgate_blcg_init_gcc_0 },
> +     { gk104_clkgate_blcg_init_sked_0 },
> +     { gk104_clkgate_blcg_init_unk_1 },
> +     { gk104_clkgate_blcg_init_gpc_ctxctl_0 },
> +     { gk104_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 },
> +     { gk104_clkgate_blcg_init_gpc_tpconf_0 },
> +     { gk104_clkgate_blcg_init_gpc_unk_1 },
> +     { gk104_clkgate_blcg_init_gpc_gcc_0 },
> +     { gk104_clkgate_blcg_init_gpc_ffb_0 },
> +     { gk104_clkgate_blcg_init_gpc_tex_0 },
> +     { gk104_clkgate_blcg_init_gpc_poly_0 },
> +     { gk104_clkgate_blcg_init_gpc_l1c_0 },
> +     { gk104_clkgate_blcg_init_gpc_unk_2 },
> +     { gk104_clkgate_blcg_init_gpc_mp_0 },
> +     { gk104_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 },
> +     {}
> +};
> +
>  
> /*******************************************************************************
>   * PGRAPH engine/subdev functions
>   
> ******************************************************************************/
> @@ -214,6 +417,9 @@ gk104_gr_init(struct gf100_gr *gr)
>       gr->func->init_gpc_mmu(gr);
>  
>       gf100_gr_mmio(gr, gr->func->mmio);
> +     if (gr->func->clkgate_pack)
> +             nvkm_therm_clkgate_init(gr->base.engine.subdev.device->therm,
> +                                     gr->func->clkgate_pack);
>  
>       nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001);
>  
> @@ -338,6 +544,7 @@ gk104_gr = {
>       .rops = gf100_gr_rops,
>       .ppc_nr = 1,
>       .grctx = &gk104_grctx,
> +     .clkgate_pack = gk104_clkgate_pack,
>       .sclass = {
>               { -1, -1, FERMI_TWOD_A },
>               { -1, -1, KEPLER_INLINE_TO_MEMORY_A },
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h 
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
> new file mode 100644
> index 000000000000..a24c177365d1
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
> @@ -0,0 +1,55 @@
> +/*
> + * 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 <ly...@redhat.com>
> + */
> +#ifndef __GK104_GR_H__
> +#define __GK104_GR_H__
> +
> +#include <subdev/therm.h>
> +
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_main_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_rstr2d_0[];
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_unk_0[];
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gcc_0[];
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_sked_0[];
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_unk_1[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_ctxctl_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_unk_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_esetup_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_tpbus_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_zcull_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_tpconf_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_unk_1[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_gcc_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_ffb_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_tex_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_poly_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_l1c_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_unk_2[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_mp_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_gpc_ppc_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_rop_zrop_0[];
> +extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_rop_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_rop_crop_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_clkgate_blcg_init_pxbar_0[];
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
> index 47d28c279707..cdc4e0a2cc6b 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
> @@ -26,6 +26,7 @@
>  
>  #include <core/memory.h>
>  #include <core/option.h>
> +#include <subdev/therm.h>
>  
>  void
>  gf100_fb_intr(struct nvkm_fb *base)
> @@ -92,6 +93,11 @@ gf100_fb_init(struct nvkm_fb *base)
>  
>       if (fb->r100c10_page)
>               nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8);
> +
> +     if (base->func->clkgate_pack) {
> +             nvkm_therm_clkgate_init(device->therm,
> +                                     base->func->clkgate_pack);
> +     }
>  }
>  
>  void *
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
> index 0a6e8eaad42c..48fd98e08baa 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
> @@ -20,10 +20,56 @@
>   * OTHER DEALINGS IN THE SOFTWARE.
>   *
>   * Authors: Ben Skeggs
> + *          Lyude Paul
>   */
> +#include "gk104.h"
>  #include "gf100.h"
>  #include "ram.h"
>  
> +/*
> + 
> *******************************************************************************
> + * PGRAPH registers for clockgating
> + 
> *******************************************************************************
> + */
> +const struct nvkm_therm_clkgate_init
> +gk104_fb_clkgate_blcg_init_unk_0[] = {
> +     { 0x100d10, 1, 0x0000c244 },
> +     { 0x100d30, 1, 0x0000c242 },
> +     { 0x100d3c, 1, 0x00000242 },
> +     { 0x100d48, 1, 0x00000242 },
> +     { 0x100d1c, 1, 0x00000042 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_fb_clkgate_blcg_init_vm_0[] = {
> +     { 0x100c98, 1, 0x00000242 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_fb_clkgate_blcg_init_main_0[] = {
> +     { 0x10f000, 1, 0x00000042 },
> +     { 0x17e030, 1, 0x00000044 },
> +     { 0x17e040, 1, 0x00000044 },
> +     {}
> +};
> +
> +const struct nvkm_therm_clkgate_init
> +gk104_fb_clkgate_blcg_init_bcast_0[] = {
> +     { 0x17ea60, 4, 0x00000044 },
> +     {}
> +};
> +
> +static const struct nvkm_therm_clkgate_pack
> +gk104_fb_clkgate_pack[] = {
> +     { gk104_fb_clkgate_blcg_init_unk_0 },
> +     { gk104_fb_clkgate_blcg_init_vm_0 },
> +     { gk104_fb_clkgate_blcg_init_main_0 },
> +     { gk104_fb_clkgate_blcg_init_bcast_0 },
> +     {}
> +};
> +
>  static const struct nvkm_fb_func
>  gk104_fb = {
>       .dtor = gf100_fb_dtor,
> @@ -33,6 +79,7 @@ gk104_fb = {
>       .intr = gf100_fb_intr,
>       .ram_new = gk104_ram_new,
>       .default_bigpage = 17,
> +     .clkgate_pack = gk104_fb_clkgate_pack,
>  };
>  
>  int
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
> new file mode 100644
> index 000000000000..b3c78e4ff706
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
> @@ -0,0 +1,35 @@
> +/*
> + * 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
> + */
> +
> +#ifndef __GK104_FB_H__
> +#define __GK104_FB_H__
> +
> +#include <subdev/therm.h>
> +
> +extern const struct nvkm_therm_clkgate_init 
> gk104_fb_clkgate_blcg_init_unk_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_fb_clkgate_blcg_init_vm_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_fb_clkgate_blcg_init_main_0[];
> +extern const struct nvkm_therm_clkgate_init 
> gk104_fb_clkgate_blcg_init_bcast_0[];
> +
> +#endif
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
> index 9351188d5d76..414a423e0e55 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
> @@ -3,6 +3,7 @@
>  #define __NVKM_FB_PRIV_H__
>  #define nvkm_fb(p) container_of((p), struct nvkm_fb, subdev)
>  #include <subdev/fb.h>
> +#include <subdev/therm.h>
>  struct nvkm_bios;
>  
>  struct nvkm_fb_func {
> @@ -27,6 +28,7 @@ struct nvkm_fb_func {
>       int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **);
>  
>       u8 default_bigpage;
> +     const struct nvkm_therm_clkgate_pack *clkgate_pack;
>  };
>  
>  void nvkm_fb_ctor(const struct nvkm_fb_func *, struct nvkm_device *device,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> index 4bac4772d8ed..550702eab0b1 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
> @@ -9,6 +9,7 @@ nvkm-y += nvkm/subdev/therm/nv40.o
>  nvkm-y += nvkm/subdev/therm/nv50.o
>  nvkm-y += nvkm/subdev/therm/g84.o
>  nvkm-y += nvkm/subdev/therm/gt215.o
> +nvkm-y += nvkm/subdev/therm/gf100.o
>  nvkm-y += nvkm/subdev/therm/gf119.o
>  nvkm-y += nvkm/subdev/therm/gk104.o
>  nvkm-y += nvkm/subdev/therm/gm107.o
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> index e4c96e46db8f..bf62303571b3 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
> @@ -391,6 +391,16 @@ nvkm_therm_init(struct nvkm_subdev *subdev)
>       return 0;
>  }
>  
> +void
> +nvkm_therm_clkgate_init(struct nvkm_therm *therm,
> +                     const struct nvkm_therm_clkgate_pack *p)
> +{
> +     if (!therm->func->clkgate_init || !therm->clkgating_enabled)
> +             return;
> +
> +     therm->func->clkgate_init(therm, p);
> +}
> +
>  static void *
>  nvkm_therm_dtor(struct nvkm_subdev *subdev)
>  {
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
> new file mode 100644
> index 000000000000..a0da7f8b7d93
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
> @@ -0,0 +1,75 @@
> +/*
> + * 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
> + */
> +#include <core/device.h>
> +
> +#include "priv.h"
> +
> +#define pack_for_each_init(init, pack, head)                          \
> +     for (pack = head; pack && pack->init; pack++)                 \
> +               for (init = pack->init; init && init->count; init++)
> +void
> +gf100_clkgate_init(struct nvkm_therm *therm,
> +                const struct nvkm_therm_clkgate_pack *p)
> +{
> +     struct nvkm_device *device = therm->subdev.device;
> +     const struct nvkm_therm_clkgate_pack *pack;
> +     const struct nvkm_therm_clkgate_init *init;
> +     u32 next, addr;
> +
> +     pack_for_each_init(init, pack, p) {
> +             next = init->addr + init->count * 8;
> +             addr = init->addr;
> +
> +             nvkm_trace(&therm->subdev, "{ 0x%06x, %d, 0x%08x }\n",
> +                        init->addr, init->count, init->data);
> +             while (addr < next) {
> +                     nvkm_trace(&therm->subdev, "\t0x%06x = 0x%08x\n",
> +                                addr, init->data);
> +                     nvkm_wr32(device, addr, init->data);
> +                     addr += 8;
> +             }
> +     }
> +}
> +
> +static const struct nvkm_therm_func
> +gf100_therm_func = {
> +     .init = gt215_therm_init,
> +     .fini = g84_therm_fini,
> +     .pwm_ctrl = nv50_fan_pwm_ctrl,
> +     .pwm_get = nv50_fan_pwm_get,
> +     .pwm_set = nv50_fan_pwm_set,
> +     .pwm_clock = nv50_fan_pwm_clock,
> +     .temp_get = g84_temp_get,
> +     .fan_sense = gt215_therm_fan_sense,
> +     .program_alarms = nvkm_therm_program_alarms_polling,
> +     /* TODO: Fermi clockgating isn't understood fully yet, so we leave it
> +      * disabled here */
> +};
> +
> +int
> +gf100_therm_new(struct nvkm_device *device, int index,
> +             struct nvkm_therm **ptherm)
> +{
> +     return nvkm_therm_new_(&gf100_therm_func, device, index, ptherm);
> +}
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c
> index 79806a757893..4e03971d2e3d 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c
> @@ -100,6 +100,7 @@ gk104_therm_func = {
>       .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 = gk104_clkgate_enable,
>       .clkgate_fini = gk104_clkgate_fini,
>  };
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
> index c08097f2aff5..4caf401d001a 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
> @@ -36,7 +36,7 @@ gt215_therm_fan_sense(struct nvkm_therm *therm)
>       return -ENODEV;
>  }
>  
> -static void
> +void
>  gt215_therm_init(struct nvkm_therm *therm)
>  {
>       struct nvkm_device *device = therm->subdev.device;
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
> index f30202dd88e7..a737e9b8a584 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
> @@ -97,6 +97,8 @@ struct nvkm_therm_func {
>  
>       void (*program_alarms)(struct nvkm_therm *);
>  
> +     void (*clkgate_init)(struct nvkm_therm *,
> +                          const struct nvkm_therm_clkgate_pack *);
>       void (*clkgate_enable)(struct nvkm_therm *);
>       void (*clkgate_fini)(struct nvkm_therm *, bool);
>  };
> @@ -114,6 +116,9 @@ void g84_therm_fini(struct nvkm_therm *);
>  
>  int gt215_therm_fan_sense(struct nvkm_therm *);
>  
> +void gf100_clkgate_init(struct nvkm_therm *,
> +                     const struct nvkm_therm_clkgate_pack *);
> +
>  void g84_therm_init(struct nvkm_therm *);
>  
>  int gf119_fan_pwm_ctrl(struct nvkm_therm *, int, bool);
> @@ -122,6 +127,9 @@ int gf119_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
>  int gf119_fan_pwm_clock(struct nvkm_therm *, int);
>  void gf119_therm_init(struct nvkm_therm *);
>  
> +void gt215_therm_init(struct nvkm_therm *therm);
> +
> +void gk104_therm_init(struct nvkm_therm *);
>  void gk104_clkgate_enable(struct nvkm_therm *);
>  void gk104_clkgate_fini(struct nvkm_therm *, bool);
>  
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to