1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "priv.h"
26
27#include <subdev/therm.h>
28#include <subdev/timer.h>
29
30static int
31nv50_bus_hwsq_exec(struct nvkm_bus *bus, u32 *data, u32 size)
32{
33 struct nvkm_device *device = bus->subdev.device;
34 int i;
35
36 nvkm_mask(device, 0x001098, 0x00000008, 0x00000000);
37 nvkm_wr32(device, 0x001304, 0x00000000);
38 for (i = 0; i < size; i++)
39 nvkm_wr32(device, 0x001400 + (i * 4), data[i]);
40 nvkm_mask(device, 0x001098, 0x00000018, 0x00000018);
41 nvkm_wr32(device, 0x00130c, 0x00000003);
42
43 if (nvkm_msec(device, 2000,
44 if (!(nvkm_rd32(device, 0x001308) & 0x00000100))
45 break;
46 ) < 0)
47 return -ETIMEDOUT;
48
49 return 0;
50}
51
52void
53nv50_bus_intr(struct nvkm_bus *bus)
54{
55 struct nvkm_subdev *subdev = &bus->subdev;
56 struct nvkm_device *device = subdev->device;
57 u32 stat = nvkm_rd32(device, 0x001100) & nvkm_rd32(device, 0x001140);
58
59 if (stat & 0x00000008) {
60 u32 addr = nvkm_rd32(device, 0x009084);
61 u32 data = nvkm_rd32(device, 0x009088);
62
63 nvkm_error(subdev, "MMIO %s of %08x FAULT at %06x\n",
64 (addr & 0x00000002) ? "write" : "read", data,
65 (addr & 0x00fffffc));
66
67 stat &= ~0x00000008;
68 nvkm_wr32(device, 0x001100, 0x00000008);
69 }
70
71 if (stat & 0x00010000) {
72 struct nvkm_therm *therm = device->therm;
73 if (therm)
74 nvkm_subdev_intr(&therm->subdev);
75 stat &= ~0x00010000;
76 nvkm_wr32(device, 0x001100, 0x00010000);
77 }
78
79 if (stat) {
80 nvkm_error(subdev, "intr %08x\n", stat);
81 nvkm_mask(device, 0x001140, stat, 0);
82 }
83}
84
85void
86nv50_bus_init(struct nvkm_bus *bus)
87{
88 struct nvkm_device *device = bus->subdev.device;
89 nvkm_wr32(device, 0x001100, 0xffffffff);
90 nvkm_wr32(device, 0x001140, 0x00010008);
91}
92
93static const struct nvkm_bus_func
94nv50_bus = {
95 .init = nv50_bus_init,
96 .intr = nv50_bus_intr,
97 .hwsq_exec = nv50_bus_hwsq_exec,
98 .hwsq_size = 64,
99};
100
101int
102nv50_bus_new(struct nvkm_device *device, int index, struct nvkm_bus **pbus)
103{
104 return nvkm_bus_new_(&nv50_bus, device, index, pbus);
105}
106