lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 27 Jan 2018 21:57:10 +0200
From:   Martin Peres <martin.peres@...e.fr>
To:     Lyude Paul <lyude@...hat.com>, nouveau@...ts.freedesktop.org
Cc:     Ben Skeggs <bskeggs@...hat.com>, David Airlie <airlied@...ux.ie>,
        Karol Herbst <karolherbst@...il.com>,
        Rhys Kidd <rhyskidd@...il.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Alexandre Courbot <acourbot@...dia.com>,
        Philippe Ombredanne <pombredanne@...b.com>,
        Kate Stewart <kstewart@...uxfoundation.org>,
        linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org
Subject: Re: [RFC v3 2/4] drm/nouveau: Add support for BLCG on Kepler1

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.peres@...e.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 <lyude@...hat.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 <bskeggs@...hat.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 <lyude@...hat.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);
>  
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ