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 = >215_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