drm/nv50/disp: move remaining interrupt handling into core
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / nouveau / nv50_sor.c
1 /*
2  * Copyright (C) 2008 Maarten Maathuis.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  */
26
27 #include <drm/drmP.h>
28 #include <drm/drm_crtc_helper.h>
29
30 #define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
31 #include "nouveau_reg.h"
32 #include "nouveau_drm.h"
33 #include "nouveau_dma.h"
34 #include "nouveau_encoder.h"
35 #include "nouveau_connector.h"
36 #include "nouveau_crtc.h"
37 #include "nv50_display.h"
38
39 #include <core/class.h>
40
41 #include <subdev/timer.h>
42
43 static void
44 nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
45 {
46         struct nv50_display *disp = nv50_display(dev);
47         const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
48         const u32 moff = (link << 2) | or;
49         nv_call(disp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern);
50 }
51
52 static void
53 nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
54                       u8 lane, u8 swing, u8 preem)
55 {
56         struct nv50_display *disp = nv50_display(dev);
57         const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
58         const u32 moff = (link << 2) | or;
59         const u32 data = (swing << 8) | preem;
60         nv_call(disp->core, NV94_DISP_SOR_DP_DRVCTL(lane) + moff, data);
61 }
62
63 static void
64 nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc,
65                      int link_nr, u32 link_bw, bool enhframe)
66 {
67         struct nv50_display *disp = nv50_display(dev);
68         const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
69         const u32 moff = (crtc << 3) | (link << 2) | or;
70         u32 data = ((link_bw / 27000) << 8) | link_nr;
71         if (enhframe)
72                 data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
73         nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
74 }
75
76 static void
77 nv50_sor_disconnect(struct drm_encoder *encoder)
78 {
79         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
80         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
81         struct drm_device *dev = encoder->dev;
82         struct nouveau_channel *evo = nv50_display(dev)->master;
83         int ret;
84
85         if (!nv_encoder->crtc)
86                 return;
87         nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
88
89         NV_DEBUG(drm, "Disconnecting SOR %d\n", nv_encoder->or);
90
91         ret = RING_SPACE(evo, 4);
92         if (ret) {
93                 NV_ERROR(drm, "no space while disconnecting SOR\n");
94                 return;
95         }
96         BEGIN_NV04(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
97         OUT_RING  (evo, 0);
98         BEGIN_NV04(evo, 0, NV50_EVO_UPDATE, 1);
99         OUT_RING  (evo, 0);
100
101         nouveau_hdmi_mode_set(encoder, NULL);
102
103         nv_encoder->crtc = NULL;
104         nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
105 }
106
107 static void
108 nv50_sor_dpms(struct drm_encoder *encoder, int mode)
109 {
110         struct nv50_display *priv = nv50_display(encoder->dev);
111         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
112         struct drm_device *dev = encoder->dev;
113         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
114         struct drm_encoder *enc;
115         int or = nv_encoder->or;
116
117         NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
118
119         nv_encoder->last_dpms = mode;
120         list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
121                 struct nouveau_encoder *nvenc = nouveau_encoder(enc);
122
123                 if (nvenc == nv_encoder ||
124                     (nvenc->dcb->type != DCB_OUTPUT_TMDS &&
125                      nvenc->dcb->type != DCB_OUTPUT_LVDS &&
126                      nvenc->dcb->type != DCB_OUTPUT_DP) ||
127                     nvenc->dcb->or != nv_encoder->dcb->or)
128                         continue;
129
130                 if (nvenc->last_dpms == DRM_MODE_DPMS_ON)
131                         return;
132         }
133
134         nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON));
135
136         if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
137                 struct dp_train_func func = {
138                         .link_set = nv50_sor_dp_link_set,
139                         .train_set = nv50_sor_dp_train_set,
140                         .train_adj = nv50_sor_dp_train_adj
141                 };
142
143                 nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func);
144         }
145 }
146
147 static void
148 nv50_sor_save(struct drm_encoder *encoder)
149 {
150         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
151         NV_ERROR(drm, "!!\n");
152 }
153
154 static void
155 nv50_sor_restore(struct drm_encoder *encoder)
156 {
157         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
158         NV_ERROR(drm, "!!\n");
159 }
160
161 static bool
162 nv50_sor_mode_fixup(struct drm_encoder *encoder,
163                     const struct drm_display_mode *mode,
164                     struct drm_display_mode *adjusted_mode)
165 {
166         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
167         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
168         struct nouveau_connector *connector;
169
170         NV_DEBUG(drm, "or %d\n", nv_encoder->or);
171
172         connector = nouveau_encoder_connector_get(nv_encoder);
173         if (!connector) {
174                 NV_ERROR(drm, "Encoder has no connector\n");
175                 return false;
176         }
177
178         if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
179              connector->native_mode)
180                 drm_mode_copy(adjusted_mode, connector->native_mode);
181
182         return true;
183 }
184
185 static void
186 nv50_sor_prepare(struct drm_encoder *encoder)
187 {
188         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
189         nv50_sor_disconnect(encoder);
190         if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
191                 /* avoid race between link training and supervisor intr */
192                 nv50_display_sync(encoder->dev);
193         }
194 }
195
196 static void
197 nv50_sor_commit(struct drm_encoder *encoder)
198 {
199 }
200
201 static void
202 nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
203                   struct drm_display_mode *mode)
204 {
205         struct nouveau_channel *evo = nv50_display(encoder->dev)->master;
206         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
207         struct nouveau_drm *drm = nouveau_drm(encoder->dev);
208         struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
209         struct nouveau_connector *nv_connector;
210         struct nv50_display *disp = nv50_display(encoder->dev);
211         struct nvbios *bios = &drm->vbios;
212         uint32_t mode_ctl = 0, script;
213         int ret;
214
215         NV_DEBUG(drm, "or %d type %d -> crtc %d\n",
216                      nv_encoder->or, nv_encoder->dcb->type, crtc->index);
217         nv_encoder->crtc = encoder->crtc;
218
219         switch (nv_encoder->dcb->type) {
220         case DCB_OUTPUT_TMDS:
221                 if (nv_encoder->dcb->sorconf.link & 1) {
222                         if (mode->clock < 165000)
223                                 mode_ctl = 0x0100;
224                         else
225                                 mode_ctl = 0x0500;
226                 } else
227                         mode_ctl = 0x0200;
228
229                 nouveau_hdmi_mode_set(encoder, mode);
230                 break;
231         case DCB_OUTPUT_LVDS:
232                 script = 0x0000;
233                 if (bios->fp_no_ddc) {
234                         if (bios->fp.dual_link)
235                                 script |= 0x0100;
236                         if (bios->fp.if_is_24bit)
237                                 script |= 0x0200;
238                 } else {
239                         /* determine number of lvds links */
240                         nv_connector = nouveau_encoder_connector_get(nv_encoder);
241                         if (nv_connector && nv_connector->edid &&
242                             nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
243                                 /* http://www.spwg.org */
244                                 if (((u8 *)nv_connector->edid)[121] == 2)
245                                         script |= 0x0100;
246                         } else
247                         if (mode->clock >= bios->fp.duallink_transition_clk) {
248                                 script |= 0x0100;
249                         }
250
251                         /* determine panel depth */
252                         if (script & 0x0100) {
253                                 if (bios->fp.strapless_is_24bit & 2)
254                                         script |= 0x0200;
255                         } else {
256                                 if (bios->fp.strapless_is_24bit & 1)
257                                         script |= 0x0200;
258                         }
259
260                         if (nv_connector && nv_connector->edid &&
261                             (nv_connector->edid->revision >= 4) &&
262                             (nv_connector->edid->input & 0x70) >= 0x20)
263                                 script |= 0x0200;
264                 }
265
266                 nv_call(disp->core, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, script);
267                 break;
268         case DCB_OUTPUT_DP:
269                 nv_connector = nouveau_encoder_connector_get(nv_encoder);
270                 if (nv_connector && nv_connector->base.display_info.bpc == 6) {
271                         nv_encoder->dp.datarate = mode->clock * 18 / 8;
272                         mode_ctl |= 0x00020000;
273                 } else {
274                         nv_encoder->dp.datarate = mode->clock * 24 / 8;
275                         mode_ctl |= 0x00050000;
276                 }
277
278                 if (nv_encoder->dcb->sorconf.link & 1)
279                         mode_ctl |= 0x00000800;
280                 else
281                         mode_ctl |= 0x00000900;
282                 break;
283         default:
284                 break;
285         }
286
287         if (crtc->index == 1)
288                 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1;
289         else
290                 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0;
291
292         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
293                 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC;
294
295         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
296                 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC;
297
298         nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
299
300         ret = RING_SPACE(evo, 2);
301         if (ret) {
302                 NV_ERROR(drm, "no space while connecting SOR\n");
303                 nv_encoder->crtc = NULL;
304                 return;
305         }
306         BEGIN_NV04(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
307         OUT_RING(evo, mode_ctl);
308 }
309
310 static struct drm_crtc *
311 nv50_sor_crtc_get(struct drm_encoder *encoder)
312 {
313         return nouveau_encoder(encoder)->crtc;
314 }
315
316 static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
317         .dpms = nv50_sor_dpms,
318         .save = nv50_sor_save,
319         .restore = nv50_sor_restore,
320         .mode_fixup = nv50_sor_mode_fixup,
321         .prepare = nv50_sor_prepare,
322         .commit = nv50_sor_commit,
323         .mode_set = nv50_sor_mode_set,
324         .get_crtc = nv50_sor_crtc_get,
325         .detect = NULL,
326         .disable = nv50_sor_disconnect
327 };
328
329 static void
330 nv50_sor_destroy(struct drm_encoder *encoder)
331 {
332         struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
333
334         drm_encoder_cleanup(encoder);
335         kfree(nv_encoder);
336 }
337
338 static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
339         .destroy = nv50_sor_destroy,
340 };
341
342 int
343 nv50_sor_create(struct drm_connector *connector, struct dcb_output *entry)
344 {
345         struct nouveau_encoder *nv_encoder = NULL;
346         struct drm_device *dev = connector->dev;
347         struct drm_encoder *encoder;
348         int type;
349
350         switch (entry->type) {
351         case DCB_OUTPUT_TMDS:
352         case DCB_OUTPUT_DP:
353                 type = DRM_MODE_ENCODER_TMDS;
354                 break;
355         case DCB_OUTPUT_LVDS:
356                 type = DRM_MODE_ENCODER_LVDS;
357                 break;
358         default:
359                 return -EINVAL;
360         }
361
362         nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
363         if (!nv_encoder)
364                 return -ENOMEM;
365         encoder = to_drm_encoder(nv_encoder);
366
367         nv_encoder->dcb = entry;
368         nv_encoder->or = ffs(entry->or) - 1;
369         nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
370
371         drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
372         drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
373
374         encoder->possible_crtcs = entry->heads;
375         encoder->possible_clones = 0;
376
377         drm_mode_connector_attach_encoder(connector, encoder);
378         return 0;
379 }