1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "core.h"
23#include "head.h"
24
25#include <nvif/cl507d.h>
26#include <nvif/timer.h>
27
28#include "nouveau_bo.h"
29
30void
31core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
32{
33 u32 *push;
34 if ((push = evo_wait(&core->chan, 5))) {
35 if (ntfy) {
36 evo_mthd(push, 0x0084, 1);
37 evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY);
38 }
39 evo_mthd(push, 0x0080, 2);
40 evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] |
41 interlock[NV50_DISP_INTERLOCK_OVLY]);
42 evo_data(push, 0x00000000);
43 evo_kick(push, &core->chan);
44 }
45}
46
47int
48core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset,
49 struct nvif_device *device)
50{
51 s64 time = nvif_msec(device, 2000ULL,
52 if (nouveau_bo_rd32(bo, offset / 4))
53 break;
54 usleep_range(1, 2);
55 );
56 return time < 0 ? time : 0;
57}
58
59void
60core507d_ntfy_init(struct nouveau_bo *bo, u32 offset)
61{
62 nouveau_bo_wr32(bo, offset / 4, 0x00000000);
63}
64
65void
66core507d_init(struct nv50_core *core)
67{
68 u32 *push;
69 if ((push = evo_wait(&core->chan, 2))) {
70 evo_mthd(push, 0x0088, 1);
71 evo_data(push, core->chan.sync.handle);
72 evo_kick(push, &core->chan);
73 }
74}
75
76static const struct nv50_core_func
77core507d = {
78 .init = core507d_init,
79 .ntfy_init = core507d_ntfy_init,
80 .ntfy_wait_done = core507d_ntfy_wait_done,
81 .update = core507d_update,
82 .head = &head507d,
83 .dac = &dac507d,
84 .sor = &sor507d,
85 .pior = &pior507d,
86};
87
88int
89core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm,
90 s32 oclass, struct nv50_core **pcore)
91{
92 struct nv50_disp_core_channel_dma_v0 args = {};
93 struct nv50_disp *disp = nv50_disp(drm->dev);
94 struct nv50_core *core;
95 int ret;
96
97 if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL)))
98 return -ENOMEM;
99 core->func = func;
100
101 ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
102 &oclass, 0, &args, sizeof(args),
103 disp->sync->bo.offset, &core->chan);
104 if (ret) {
105 NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret);
106 return ret;
107 }
108
109 return 0;
110}
111
112int
113core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore)
114{
115 return core507d_new_(&core507d, drm, oclass, pcore);
116}
117