1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "rootnv50.h"
25#include "head.h"
26#include "dmacnv50.h"
27
28#include <core/ramht.h>
29#include <subdev/timer.h>
30
31#include <nvif/class.h>
32
33void
34gf119_disp_root_fini(struct nv50_disp_root *root)
35{
36 struct nvkm_device *device = root->disp->base.engine.subdev.device;
37
38 nvkm_wr32(device, 0x6100b0, 0x00000000);
39}
40
41int
42gf119_disp_root_init(struct nv50_disp_root *root)
43{
44 struct nv50_disp *disp = root->disp;
45 struct nvkm_head *head;
46 struct nvkm_device *device = disp->base.engine.subdev.device;
47 u32 tmp;
48 int i;
49
50
51
52
53
54
55
56 list_for_each_entry(head, &disp->base.head, head) {
57 const u32 hoff = head->id * 0x800;
58 tmp = nvkm_rd32(device, 0x616104 + hoff);
59 nvkm_wr32(device, 0x6101b4 + hoff, tmp);
60 tmp = nvkm_rd32(device, 0x616108 + hoff);
61 nvkm_wr32(device, 0x6101b8 + hoff, tmp);
62 tmp = nvkm_rd32(device, 0x61610c + hoff);
63 nvkm_wr32(device, 0x6101bc + hoff, tmp);
64 }
65
66
67 for (i = 0; i < disp->func->dac.nr; i++) {
68 tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
69 nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp);
70 }
71
72
73 for (i = 0; i < disp->func->sor.nr; i++) {
74 tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
75 nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp);
76 }
77
78
79 if (nvkm_rd32(device, 0x6100ac) & 0x00000100) {
80 nvkm_wr32(device, 0x6100ac, 0x00000100);
81 nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
82 if (nvkm_msec(device, 2000,
83 if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
84 break;
85 ) < 0)
86 return -EBUSY;
87 }
88
89
90 nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9);
91
92
93 nvkm_wr32(device, 0x610090, 0x00000000);
94 nvkm_wr32(device, 0x6100a0, 0x00000000);
95 nvkm_wr32(device, 0x6100b0, 0x00000307);
96
97
98
99
100
101
102
103 list_for_each_entry(head, &disp->base.head, head) {
104 const u32 hoff = head->id * 0x800;
105 nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010);
106 }
107
108 return 0;
109}
110
111static const struct nv50_disp_root_func
112gf119_disp_root = {
113 .init = gf119_disp_root_init,
114 .fini = gf119_disp_root_fini,
115 .dmac = {
116 &gf119_disp_core_oclass,
117 &gf119_disp_base_oclass,
118 &gf119_disp_ovly_oclass,
119 },
120 .pioc = {
121 &gf119_disp_oimm_oclass,
122 &gf119_disp_curs_oclass,
123 },
124};
125
126static int
127gf119_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
128 void *data, u32 size, struct nvkm_object **pobject)
129{
130 return nv50_disp_root_new_(&gf119_disp_root, disp, oclass,
131 data, size, pobject);
132}
133
134const struct nvkm_disp_oclass
135gf119_disp_root_oclass = {
136 .base.oclass = GF110_DISP,
137 .base.minver = -1,
138 .base.maxver = -1,
139 .ctor = gf119_disp_root_new,
140};
141