Received: by 10.223.176.5 with SMTP id f5csp898499wra; Sat, 27 Jan 2018 11:59:20 -0800 (PST) X-Google-Smtp-Source: AH8x2242dXcubgjOdhwMTB3Wqt/EZQPYil+U9f6A4I7DU9P1taUghwdFS+RrlY1B1pp4b/cHBgVx X-Received: by 2002:a17:902:5a8c:: with SMTP id r12-v6mr1438007pli.87.1517083160600; Sat, 27 Jan 2018 11:59:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517083160; cv=none; d=google.com; s=arc-20160816; b=iGTyO6TgSCc5aCoGBDrJQXopYVXOBrbH1z1i5YXrz3ipGCKLnsjXLSEE01GOt1kdrj 8XkV9yZj/Ik6HqSWOmWynhR/oFPWEBfTZyWN7mTka2n0FcKmXq/CI7Cu+4GCOkE9bYCN tn5HTe5RuJUD8QSjSpZ8ExYlZXDfqYMjqUruERiU5zlYExjcXVjX00zEV608h+KY+Lis iLo+L5PkXEBJBa4hvBC2/1WqHRoWJVUF2nawkANlocyh5SROo3He2GxJ+xTl6D2xNtxs +SGUW5rzGPaJvVoSQbMXvwPRmaAG/FZDzk0Ad+FVx4AhNtLXstv/u3KQddoBsxsR2uP9 qx8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:arc-authentication-results; bh=SAT9G6uSjPteykDbKNM2yLpiVKwSD+pWv8dmbGT1jzI=; b=CKCpUduw7UYNY/iK+QThgOfrVkaeAA8FU8f5hQKRsflvGsezUxPZMZ9VgGVUtU0OHL 8vtQwZ97z/MhA251lwnGm5TBVWq+LMJKLZB5O9/b+Kt9GpVvwbEnk7nbL8/qBcjZ9z/t /I8sGSIqDuZb+MvK2DPVxjYR1RsCBTD+/D4GRjZVVTIURVlS23Hmg02QpXw3QOr2LkMD RSEiuQifrKeOxgEWwzqelyp23Wx85j7n87k+VXRGUCvfz4+T6gvzZbm3jcj3FDr/5HW7 z5MTEGxkHhv/2PwXbsksHNgDI9Ortg8I17w3ym54smkM+wMJMUFL4LmL3BPKCCLGJelN Of4w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v61-v6si238710plb.16.2018.01.27.11.58.36; Sat, 27 Jan 2018 11:59:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752524AbeA0T5o (ORCPT + 99 others); Sat, 27 Jan 2018 14:57:44 -0500 Received: from smtp5-g21.free.fr ([212.27.42.5]:50220 "EHLO smtp5-g21.free.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751406AbeA0T5m (ORCPT ); Sat, 27 Jan 2018 14:57:42 -0500 Received: from [IPv6:2001:14ba:9f3:f800:ab83:f5b1:ec92:56e6] (unknown [IPv6:2001:14ba:9f3:f800:ab83:f5b1:ec92:56e6]) (Authenticated sender: martin.peres) by smtp5-g21.free.fr (Postfix) with ESMTPSA id 374135FF10; Sat, 27 Jan 2018 20:57:12 +0100 (CET) Subject: Re: [RFC v3 2/4] drm/nouveau: Add support for BLCG on Kepler1 To: Lyude Paul , nouveau@lists.freedesktop.org Cc: Ben Skeggs , David Airlie , Karol Herbst , Rhys Kidd , Thomas Gleixner , Greg Kroah-Hartman , Alexandre Courbot , Philippe Ombredanne , Kate Stewart , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org References: <20180126210013.29190-1-lyude@redhat.com> <20180126210013.29190-3-lyude@redhat.com> From: Martin Peres Message-ID: <1f270f2a-4115-1b36-f0ff-98d0082a23c1@free.fr> Date: Sat, 27 Jan 2018 21:57:10 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 In-Reply-To: <20180126210013.29190-3-lyude@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Language: fr-xx-moderne Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 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 > --- > .../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 > */ > #include "gf100.h" > +#include "gk104.h" > #include "ctxgf100.h" > > #include > @@ -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 > + */ > +#ifndef __GK104_GR_H__ > +#define __GK104_GR_H__ > + > +#include > + > +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 > #include > +#include > > 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 > + > +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 > +#include > 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 > + > +#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); > >