This source file includes following definitions.
- nvkm_sec2_dtor
- nvkm_sec2_intr
- nvkm_sec2_recv
- nvkm_sec2_oneinit
- nvkm_sec2_fini
- nvkm_sec2_new_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "priv.h"
23
24 #include <core/msgqueue.h>
25 #include <subdev/top.h>
26 #include <engine/falcon.h>
27
28 static void *
29 nvkm_sec2_dtor(struct nvkm_engine *engine)
30 {
31 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
32 nvkm_msgqueue_del(&sec2->queue);
33 nvkm_falcon_del(&sec2->falcon);
34 return sec2;
35 }
36
37 static void
38 nvkm_sec2_intr(struct nvkm_engine *engine)
39 {
40 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
41 struct nvkm_subdev *subdev = &engine->subdev;
42 struct nvkm_device *device = subdev->device;
43 u32 disp = nvkm_rd32(device, sec2->addr + 0x01c);
44 u32 intr = nvkm_rd32(device, sec2->addr + 0x008) & disp & ~(disp >> 16);
45
46 if (intr & 0x00000040) {
47 schedule_work(&sec2->work);
48 nvkm_wr32(device, sec2->addr + 0x004, 0x00000040);
49 intr &= ~0x00000040;
50 }
51
52 if (intr) {
53 nvkm_error(subdev, "unhandled intr %08x\n", intr);
54 nvkm_wr32(device, sec2->addr + 0x004, intr);
55
56 }
57 }
58
59 static void
60 nvkm_sec2_recv(struct work_struct *work)
61 {
62 struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work);
63
64 if (!sec2->queue) {
65 nvkm_warn(&sec2->engine.subdev,
66 "recv function called while no firmware set!\n");
67 return;
68 }
69
70 nvkm_msgqueue_recv(sec2->queue);
71 }
72
73
74 static int
75 nvkm_sec2_oneinit(struct nvkm_engine *engine)
76 {
77 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
78 struct nvkm_subdev *subdev = &sec2->engine.subdev;
79
80 if (!sec2->addr) {
81 sec2->addr = nvkm_top_addr(subdev->device, subdev->index);
82 if (WARN_ON(!sec2->addr))
83 return -EINVAL;
84 }
85
86 return nvkm_falcon_v1_new(subdev, "SEC2", sec2->addr, &sec2->falcon);
87 }
88
89 static int
90 nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)
91 {
92 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
93 flush_work(&sec2->work);
94 return 0;
95 }
96
97 static const struct nvkm_engine_func
98 nvkm_sec2 = {
99 .dtor = nvkm_sec2_dtor,
100 .oneinit = nvkm_sec2_oneinit,
101 .fini = nvkm_sec2_fini,
102 .intr = nvkm_sec2_intr,
103 };
104
105 int
106 nvkm_sec2_new_(struct nvkm_device *device, int index, u32 addr,
107 struct nvkm_sec2 **psec2)
108 {
109 struct nvkm_sec2 *sec2;
110
111 if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))
112 return -ENOMEM;
113 sec2->addr = addr;
114 INIT_WORK(&sec2->work, nvkm_sec2_recv);
115
116 return nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine);
117 };