xref: /openbmc/linux/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
1e1fc44fbSBen Skeggs /*
2e1fc44fbSBen Skeggs  * Copyright 2015 Red Hat Inc.
3e1fc44fbSBen Skeggs  *
4e1fc44fbSBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
5e1fc44fbSBen Skeggs  * copy of this software and associated documentation files (the "Software"),
6e1fc44fbSBen Skeggs  * to deal in the Software without restriction, including without limitation
7e1fc44fbSBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e1fc44fbSBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
9e1fc44fbSBen Skeggs  * Software is furnished to do so, subject to the following conditions:
10e1fc44fbSBen Skeggs  *
11e1fc44fbSBen Skeggs  * The above copyright notice and this permission notice shall be included in
12e1fc44fbSBen Skeggs  * all copies or substantial portions of the Software.
13e1fc44fbSBen Skeggs  *
14e1fc44fbSBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15e1fc44fbSBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16e1fc44fbSBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17e1fc44fbSBen Skeggs  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18e1fc44fbSBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19e1fc44fbSBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20e1fc44fbSBen Skeggs  * OTHER DEALINGS IN THE SOFTWARE.
21e1fc44fbSBen Skeggs  *
22e1fc44fbSBen Skeggs  * Authors: Ben Skeggs
23e1fc44fbSBen Skeggs  */
24e2ca4e7dSBen Skeggs #define gf119_pmu_code gk110_pmu_code
25e2ca4e7dSBen Skeggs #define gf119_pmu_data gk110_pmu_data
26e1fc44fbSBen Skeggs #include "priv.h"
27e2ca4e7dSBen Skeggs #include "fuc/gf119.fuc4.h"
28e1fc44fbSBen Skeggs 
29e1fc44fbSBen Skeggs #include <subdev/timer.h>
30e1fc44fbSBen Skeggs 
31f02a0e84SBen Skeggs void
gk110_pmu_pgob(struct nvkm_pmu * pmu,bool enable)32e1fc44fbSBen Skeggs gk110_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
33e1fc44fbSBen Skeggs {
34bef002e8SBen Skeggs 	struct nvkm_device *device = pmu->subdev.device;
35e1fc44fbSBen Skeggs 	static const struct {
36e1fc44fbSBen Skeggs 		u32 addr;
37e1fc44fbSBen Skeggs 		u32 data;
38e1fc44fbSBen Skeggs 	} magic[] = {
39e1fc44fbSBen Skeggs 		{ 0x020520, 0xfffffffc },
40e1fc44fbSBen Skeggs 		{ 0x020524, 0xfffffffe },
41e1fc44fbSBen Skeggs 		{ 0x020524, 0xfffffffc },
42e1fc44fbSBen Skeggs 		{ 0x020524, 0xfffffff8 },
43e1fc44fbSBen Skeggs 		{ 0x020524, 0xffffffe0 },
44e1fc44fbSBen Skeggs 		{ 0x020530, 0xfffffffe },
45e1fc44fbSBen Skeggs 		{ 0x02052c, 0xfffffffa },
46e1fc44fbSBen Skeggs 		{ 0x02052c, 0xfffffff0 },
47e1fc44fbSBen Skeggs 		{ 0x02052c, 0xffffffc0 },
48e1fc44fbSBen Skeggs 		{ 0x02052c, 0xffffff00 },
49e1fc44fbSBen Skeggs 		{ 0x02052c, 0xfffffc00 },
50e1fc44fbSBen Skeggs 		{ 0x02052c, 0xfffcfc00 },
51e1fc44fbSBen Skeggs 		{ 0x02052c, 0xfff0fc00 },
52e1fc44fbSBen Skeggs 		{ 0x02052c, 0xff80fc00 },
53e1fc44fbSBen Skeggs 		{ 0x020528, 0xfffffffe },
54e1fc44fbSBen Skeggs 		{ 0x020528, 0xfffffffc },
55e1fc44fbSBen Skeggs 	};
56e1fc44fbSBen Skeggs 	int i;
57e1fc44fbSBen Skeggs 
58bef002e8SBen Skeggs 	nvkm_mask(device, 0x000200, 0x00001000, 0x00000000);
59bef002e8SBen Skeggs 	nvkm_rd32(device, 0x000200);
60bef002e8SBen Skeggs 	nvkm_mask(device, 0x000200, 0x08000000, 0x08000000);
61e1fc44fbSBen Skeggs 	msleep(50);
62e1fc44fbSBen Skeggs 
63bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000002, 0x00000002);
64bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000001, 0x00000001);
65bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000001, 0x00000000);
66e1fc44fbSBen Skeggs 
67bef002e8SBen Skeggs 	nvkm_mask(device, 0x0206b4, 0x00000000, 0x00000000);
68e1fc44fbSBen Skeggs 	for (i = 0; i < ARRAY_SIZE(magic); i++) {
69bef002e8SBen Skeggs 		nvkm_wr32(device, magic[i].addr, magic[i].data);
70dd4bb3ecSBen Skeggs 		nvkm_msec(device, 2000,
71dd4bb3ecSBen Skeggs 			if (!(nvkm_rd32(device, magic[i].addr) & 0x80000000))
72dd4bb3ecSBen Skeggs 				break;
73dd4bb3ecSBen Skeggs 		);
74e1fc44fbSBen Skeggs 	}
75e1fc44fbSBen Skeggs 
76bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000002, 0x00000000);
77bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000001, 0x00000001);
78bef002e8SBen Skeggs 	nvkm_mask(device, 0x10a78c, 0x00000001, 0x00000000);
79e1fc44fbSBen Skeggs 
80bef002e8SBen Skeggs 	nvkm_mask(device, 0x000200, 0x08000000, 0x00000000);
81bef002e8SBen Skeggs 	nvkm_mask(device, 0x000200, 0x00001000, 0x00001000);
82bef002e8SBen Skeggs 	nvkm_rd32(device, 0x000200);
83e1fc44fbSBen Skeggs }
84e1fc44fbSBen Skeggs 
85e2ca4e7dSBen Skeggs static const struct nvkm_pmu_func
86e2ca4e7dSBen Skeggs gk110_pmu = {
872952a2b4SBen Skeggs 	.flcn = &gt215_pmu_flcn,
88e1fc44fbSBen Skeggs 	.code.data = gk110_pmu_code,
89e1fc44fbSBen Skeggs 	.code.size = sizeof(gk110_pmu_code),
90e1fc44fbSBen Skeggs 	.data.data = gk110_pmu_data,
91e1fc44fbSBen Skeggs 	.data.size = sizeof(gk110_pmu_data),
926b1277c8SBen Skeggs 	.enabled = gf100_pmu_enabled,
93715e7d26SBen Skeggs 	.reset = gf100_pmu_reset,
94da7d2062SBen Skeggs 	.init = gt215_pmu_init,
95da7d2062SBen Skeggs 	.fini = gt215_pmu_fini,
96da7d2062SBen Skeggs 	.intr = gt215_pmu_intr,
97da7d2062SBen Skeggs 	.send = gt215_pmu_send,
98da7d2062SBen Skeggs 	.recv = gt215_pmu_recv,
99e1fc44fbSBen Skeggs 	.pgob = gk110_pmu_pgob,
100e2ca4e7dSBen Skeggs };
101e2ca4e7dSBen Skeggs 
102989863d7SBen Skeggs static const struct nvkm_pmu_fwif
103989863d7SBen Skeggs gk110_pmu_fwif[] = {
104989863d7SBen Skeggs 	{ -1, gf100_pmu_nofw, &gk110_pmu },
105989863d7SBen Skeggs 	{}
106989863d7SBen Skeggs };
107989863d7SBen Skeggs 
108e2ca4e7dSBen Skeggs int
gk110_pmu_new(struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_pmu ** ppmu)109*e4b15b4cSBen Skeggs gk110_pmu_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
110*e4b15b4cSBen Skeggs 	      struct nvkm_pmu **ppmu)
111e2ca4e7dSBen Skeggs {
112*e4b15b4cSBen Skeggs 	return nvkm_pmu_new_(gk110_pmu_fwif, device, type, inst, ppmu);
113e2ca4e7dSBen Skeggs }
114