drm/nouveau/disp: split user classes out from engine implementations
[deliverable/linux.git] / drivers / gpu / drm / nouveau / nvkm / engine / disp / rootgf119.c
CommitLineData
2a7909c0
BS
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24#include "rootnv50.h"
25#include "dmacnv50.h"
26
27#include <core/client.h>
28#include <core/ramht.h>
29#include <subdev/timer.h>
30
31#include <nvif/class.h>
32#include <nvif/unpack.h>
33
34int
35gf119_disp_root_scanoutpos(NV50_DISP_MTHD_V0)
36{
37 struct nvkm_device *device = disp->base.engine.subdev.device;
38 const u32 total = nvkm_rd32(device, 0x640414 + (head * 0x300));
39 const u32 blanke = nvkm_rd32(device, 0x64041c + (head * 0x300));
40 const u32 blanks = nvkm_rd32(device, 0x640420 + (head * 0x300));
41 union {
42 struct nv04_disp_scanoutpos_v0 v0;
43 } *args = data;
44 int ret;
45
46 nvif_ioctl(object, "disp scanoutpos size %d\n", size);
47 if (nvif_unpack(args->v0, 0, 0, false)) {
48 nvif_ioctl(object, "disp scanoutpos vers %d\n",
49 args->v0.version);
50 args->v0.vblanke = (blanke & 0xffff0000) >> 16;
51 args->v0.hblanke = (blanke & 0x0000ffff);
52 args->v0.vblanks = (blanks & 0xffff0000) >> 16;
53 args->v0.hblanks = (blanks & 0x0000ffff);
54 args->v0.vtotal = ( total & 0xffff0000) >> 16;
55 args->v0.htotal = ( total & 0x0000ffff);
56 args->v0.time[0] = ktime_to_ns(ktime_get());
57 args->v0.vline = /* vline read locks hline */
58 nvkm_rd32(device, 0x616340 + (head * 0x800)) & 0xffff;
59 args->v0.time[1] = ktime_to_ns(ktime_get());
60 args->v0.hline =
61 nvkm_rd32(device, 0x616344 + (head * 0x800)) & 0xffff;
62 } else
63 return ret;
64
65 return 0;
66}
67
68static int
69gf119_disp_root_init(struct nvkm_object *object)
70{
71 struct nv50_disp *disp = (void *)object->engine;
72 struct nv50_disp_root *root = (void *)object;
73 struct nvkm_device *device = disp->base.engine.subdev.device;
74 int ret, i;
75 u32 tmp;
76
77 ret = nvkm_parent_init(&root->base);
78 if (ret)
79 return ret;
80
81 /* The below segments of code copying values from one register to
82 * another appear to inform EVO of the display capabilities or
83 * something similar.
84 */
85
86 /* ... CRTC caps */
87 for (i = 0; i < disp->head.nr; i++) {
88 tmp = nvkm_rd32(device, 0x616104 + (i * 0x800));
89 nvkm_wr32(device, 0x6101b4 + (i * 0x800), tmp);
90 tmp = nvkm_rd32(device, 0x616108 + (i * 0x800));
91 nvkm_wr32(device, 0x6101b8 + (i * 0x800), tmp);
92 tmp = nvkm_rd32(device, 0x61610c + (i * 0x800));
93 nvkm_wr32(device, 0x6101bc + (i * 0x800), tmp);
94 }
95
96 /* ... DAC caps */
97 for (i = 0; i < disp->dac.nr; i++) {
98 tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
99 nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp);
100 }
101
102 /* ... SOR caps */
103 for (i = 0; i < disp->sor.nr; i++) {
104 tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
105 nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp);
106 }
107
108 /* steal display away from vbios, or something like that */
109 if (nvkm_rd32(device, 0x6100ac) & 0x00000100) {
110 nvkm_wr32(device, 0x6100ac, 0x00000100);
111 nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
112 if (nvkm_msec(device, 2000,
113 if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
114 break;
115 ) < 0)
116 return -EBUSY;
117 }
118
119 /* point at display engine memory area (hash table, objects) */
120 nvkm_wr32(device, 0x610010, (nv_gpuobj(object->parent)->addr >> 8) | 9);
121
122 /* enable supervisor interrupts, disable everything else */
123 nvkm_wr32(device, 0x610090, 0x00000000);
124 nvkm_wr32(device, 0x6100a0, 0x00000000);
125 nvkm_wr32(device, 0x6100b0, 0x00000307);
126
127 /* disable underflow reporting, preventing an intermittent issue
128 * on some gk104 boards where the production vbios left this
129 * setting enabled by default.
130 *
131 * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt
132 */
133 for (i = 0; i < disp->head.nr; i++)
134 nvkm_mask(device, 0x616308 + (i * 0x800), 0x00000111, 0x00000010);
135
136 return 0;
137}
138
139static int
140gf119_disp_root_fini(struct nvkm_object *object, bool suspend)
141{
142 struct nv50_disp *disp = (void *)object->engine;
143 struct nv50_disp_root *root = (void *)object;
144 struct nvkm_device *device = disp->base.engine.subdev.device;
145
146 /* disable all interrupts */
147 nvkm_wr32(device, 0x6100b0, 0x00000000);
148
149 return nvkm_parent_fini(&root->base, suspend);
150}
151
152struct nvkm_ofuncs
153gf119_disp_root_ofuncs = {
154 .ctor = nv50_disp_root_ctor,
155 .dtor = nv50_disp_root_dtor,
156 .init = gf119_disp_root_init,
157 .fini = gf119_disp_root_fini,
158 .mthd = nv50_disp_root_mthd,
159 .ntfy = nvkm_disp_ntfy,
160};
161
162struct nvkm_oclass
163gf119_disp_root_oclass[] = {
164 { GF110_DISP, &gf119_disp_root_ofuncs },
165 {}
166};
167
168struct nvkm_oclass
169gf119_disp_sclass[] = {
170 { GF110_DISP_CORE_CHANNEL_DMA, &gf119_disp_core_ofuncs.base },
171 { GF110_DISP_BASE_CHANNEL_DMA, &gf119_disp_base_ofuncs.base },
172 { GF110_DISP_OVERLAY_CONTROL_DMA, &gf119_disp_ovly_ofuncs.base },
173 { GF110_DISP_OVERLAY, &gf119_disp_oimm_ofuncs.base },
174 { GF110_DISP_CURSOR, &gf119_disp_curs_ofuncs.base },
175 {}
176};
This page took 0.031366 seconds and 5 git commands to generate.