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 <engine/disp.h>
26
27#include <core/event.h>
28#include <core/class.h>
29
30struct nv04_disp_priv {
31 struct nouveau_disp base;
32};
33
34static struct nouveau_oclass
35nv04_disp_sclass[] = {
36 { NV04_DISP_CLASS, &nouveau_object_ofuncs },
37 {},
38};
39
40
41
42
43
44static void
45nv04_disp_vblank_enable(struct nouveau_event *event, int head)
46{
47 nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001);
48}
49
50static void
51nv04_disp_vblank_disable(struct nouveau_event *event, int head)
52{
53 nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000);
54}
55
56static void
57nv04_disp_intr(struct nouveau_subdev *subdev)
58{
59 struct nv04_disp_priv *priv = (void *)subdev;
60 u32 crtc0 = nv_rd32(priv, 0x600100);
61 u32 crtc1 = nv_rd32(priv, 0x602100);
62
63 if (crtc0 & 0x00000001) {
64 nouveau_event_trigger(priv->base.vblank, 0);
65 nv_wr32(priv, 0x600100, 0x00000001);
66 }
67
68 if (crtc1 & 0x00000001) {
69 nouveau_event_trigger(priv->base.vblank, 1);
70 nv_wr32(priv, 0x602100, 0x00000001);
71 }
72}
73
74static int
75nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
76 struct nouveau_oclass *oclass, void *data, u32 size,
77 struct nouveau_object **pobject)
78{
79 struct nv04_disp_priv *priv;
80 int ret;
81
82 ret = nouveau_disp_create(parent, engine, oclass, 2, "DISPLAY",
83 "display", &priv);
84 *pobject = nv_object(priv);
85 if (ret)
86 return ret;
87
88 nv_engine(priv)->sclass = nv04_disp_sclass;
89 nv_subdev(priv)->intr = nv04_disp_intr;
90 priv->base.vblank->priv = priv;
91 priv->base.vblank->enable = nv04_disp_vblank_enable;
92 priv->base.vblank->disable = nv04_disp_vblank_disable;
93 return 0;
94}
95
96struct nouveau_oclass
97nv04_disp_oclass = {
98 .handle = NV_ENGINE(DISP, 0x04),
99 .ofuncs = &(struct nouveau_ofuncs) {
100 .ctor = nv04_disp_ctor,
101 .dtor = _nouveau_disp_dtor,
102 .init = _nouveau_disp_init,
103 .fini = _nouveau_disp_fini,
104 },
105};
106