2 * Copyright (C) 2008 Maarten Maathuis.
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:
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.
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.
28 #include <drm/drm_crtc_helper.h>
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"
39 #include <core/class.h>
41 #include <subdev/timer.h>
44 nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
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);
53 nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
54 u8 lane, u8 swing, u8 preem)
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);
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)
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;
72 data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
73 nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
77 nv50_sor_dp_link_get(struct drm_device *dev, u32 or, u32 link, u32 *nr, u32 *bw)
79 struct nouveau_device *device = nouveau_dev(dev);
80 u32 dpctrl = nv_rd32(device, NV50_SOR_DP_CTRL(or, link)) & 0x000f0000;
81 u32 clksor = nv_rd32(device, 0x614300 + (or * 0x800));
82 if (clksor & 0x000c0000)
87 if (dpctrl > 0x00030000) *nr = 4;
88 else if (dpctrl > 0x00010000) *nr = 2;
93 nv50_sor_dp_calc_tu(struct drm_device *dev, int or, int link, u32 clk, u32 bpp)
95 struct nouveau_device *device = nouveau_dev(dev);
96 struct nouveau_drm *drm = nouveau_drm(dev);
97 const u32 symbol = 100000;
98 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
99 int TU, VTUi, VTUf, VTUa;
100 u64 link_data_rate, link_ratio, unk;
101 u32 best_diff = 64 * symbol;
102 u32 link_nr, link_bw, r;
104 /* calculate packed data rate for each lane */
105 nv50_sor_dp_link_get(dev, or, link, &link_nr, &link_bw);
106 link_data_rate = (clk * bpp / 8) / link_nr;
108 /* calculate ratio of packed data rate to link symbol rate */
109 link_ratio = link_data_rate * symbol;
110 r = do_div(link_ratio, link_bw);
112 for (TU = 64; TU >= 32; TU--) {
113 /* calculate average number of valid symbols in each TU */
114 u32 tu_valid = link_ratio * TU;
117 /* find a hw representation for the fraction.. */
118 VTUi = tu_valid / symbol;
119 calc = VTUi * symbol;
120 diff = tu_valid - calc;
122 if (diff >= (symbol / 2)) {
123 VTUf = symbol / (symbol - diff);
124 if (symbol - (VTUf * diff))
129 calc += symbol - (symbol / VTUf);
137 VTUf = min((int)(symbol / diff), 15);
138 calc += symbol / VTUf;
141 diff = calc - tu_valid;
143 /* no remainder, but the hw doesn't like the fractional
144 * part to be zero. decrement the integer part and
145 * have the fraction add a whole symbol back
152 if (diff < best_diff) {
164 NV_ERROR(drm, "DP: unable to find suitable config\n");
168 /* XXX close to vbios numbers, but not right */
169 unk = (symbol - link_ratio) * bestTU;
171 r = do_div(unk, symbol);
172 r = do_div(unk, symbol);
175 nv_mask(device, NV50_SOR_DP_CTRL(or, link), 0x000001fc, bestTU << 2);
176 nv_mask(device, NV50_SOR_DP_SCFG(or, link), 0x010f7f3f, bestVTUa << 24 |
182 nv50_sor_disconnect(struct drm_encoder *encoder)
184 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
185 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
186 struct drm_device *dev = encoder->dev;
187 struct nouveau_channel *evo = nv50_display(dev)->master;
190 if (!nv_encoder->crtc)
192 nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
194 NV_DEBUG(drm, "Disconnecting SOR %d\n", nv_encoder->or);
196 ret = RING_SPACE(evo, 4);
198 NV_ERROR(drm, "no space while disconnecting SOR\n");
201 BEGIN_NV04(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
203 BEGIN_NV04(evo, 0, NV50_EVO_UPDATE, 1);
206 nouveau_hdmi_mode_set(encoder, NULL);
208 nv_encoder->crtc = NULL;
209 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
213 nv50_sor_dpms(struct drm_encoder *encoder, int mode)
215 struct nv50_display *priv = nv50_display(encoder->dev);
216 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
217 struct drm_device *dev = encoder->dev;
218 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
219 struct drm_encoder *enc;
220 int or = nv_encoder->or;
222 NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
224 nv_encoder->last_dpms = mode;
225 list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
226 struct nouveau_encoder *nvenc = nouveau_encoder(enc);
228 if (nvenc == nv_encoder ||
229 (nvenc->dcb->type != DCB_OUTPUT_TMDS &&
230 nvenc->dcb->type != DCB_OUTPUT_LVDS &&
231 nvenc->dcb->type != DCB_OUTPUT_DP) ||
232 nvenc->dcb->or != nv_encoder->dcb->or)
235 if (nvenc->last_dpms == DRM_MODE_DPMS_ON)
239 nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON));
241 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
242 struct dp_train_func func = {
243 .link_set = nv50_sor_dp_link_set,
244 .train_set = nv50_sor_dp_train_set,
245 .train_adj = nv50_sor_dp_train_adj
248 nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func);
253 nv50_sor_save(struct drm_encoder *encoder)
255 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
256 NV_ERROR(drm, "!!\n");
260 nv50_sor_restore(struct drm_encoder *encoder)
262 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
263 NV_ERROR(drm, "!!\n");
267 nv50_sor_mode_fixup(struct drm_encoder *encoder,
268 const struct drm_display_mode *mode,
269 struct drm_display_mode *adjusted_mode)
271 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
272 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
273 struct nouveau_connector *connector;
275 NV_DEBUG(drm, "or %d\n", nv_encoder->or);
277 connector = nouveau_encoder_connector_get(nv_encoder);
279 NV_ERROR(drm, "Encoder has no connector\n");
283 if (connector->scaling_mode != DRM_MODE_SCALE_NONE &&
284 connector->native_mode)
285 drm_mode_copy(adjusted_mode, connector->native_mode);
291 nv50_sor_prepare(struct drm_encoder *encoder)
293 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
294 nv50_sor_disconnect(encoder);
295 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
296 /* avoid race between link training and supervisor intr */
297 nv50_display_sync(encoder->dev);
302 nv50_sor_commit(struct drm_encoder *encoder)
307 nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
308 struct drm_display_mode *mode)
310 struct nouveau_channel *evo = nv50_display(encoder->dev)->master;
311 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
312 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
313 struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
314 struct nouveau_connector *nv_connector;
315 uint32_t mode_ctl = 0;
318 NV_DEBUG(drm, "or %d type %d -> crtc %d\n",
319 nv_encoder->or, nv_encoder->dcb->type, crtc->index);
320 nv_encoder->crtc = encoder->crtc;
322 switch (nv_encoder->dcb->type) {
323 case DCB_OUTPUT_TMDS:
324 if (nv_encoder->dcb->sorconf.link & 1) {
325 if (mode->clock < 165000)
332 nouveau_hdmi_mode_set(encoder, mode);
335 nv_connector = nouveau_encoder_connector_get(nv_encoder);
336 if (nv_connector && nv_connector->base.display_info.bpc == 6) {
337 nv_encoder->dp.datarate = mode->clock * 18 / 8;
338 mode_ctl |= 0x00020000;
340 nv_encoder->dp.datarate = mode->clock * 24 / 8;
341 mode_ctl |= 0x00050000;
344 if (nv_encoder->dcb->sorconf.link & 1)
345 mode_ctl |= 0x00000800;
347 mode_ctl |= 0x00000900;
353 if (crtc->index == 1)
354 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1;
356 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0;
358 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
359 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC;
361 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
362 mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC;
364 nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
366 ret = RING_SPACE(evo, 2);
368 NV_ERROR(drm, "no space while connecting SOR\n");
369 nv_encoder->crtc = NULL;
372 BEGIN_NV04(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
373 OUT_RING(evo, mode_ctl);
376 static struct drm_crtc *
377 nv50_sor_crtc_get(struct drm_encoder *encoder)
379 return nouveau_encoder(encoder)->crtc;
382 static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
383 .dpms = nv50_sor_dpms,
384 .save = nv50_sor_save,
385 .restore = nv50_sor_restore,
386 .mode_fixup = nv50_sor_mode_fixup,
387 .prepare = nv50_sor_prepare,
388 .commit = nv50_sor_commit,
389 .mode_set = nv50_sor_mode_set,
390 .get_crtc = nv50_sor_crtc_get,
392 .disable = nv50_sor_disconnect
396 nv50_sor_destroy(struct drm_encoder *encoder)
398 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
400 drm_encoder_cleanup(encoder);
404 static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
405 .destroy = nv50_sor_destroy,
409 nv50_sor_create(struct drm_connector *connector, struct dcb_output *entry)
411 struct nouveau_encoder *nv_encoder = NULL;
412 struct drm_device *dev = connector->dev;
413 struct drm_encoder *encoder;
416 switch (entry->type) {
417 case DCB_OUTPUT_TMDS:
419 type = DRM_MODE_ENCODER_TMDS;
421 case DCB_OUTPUT_LVDS:
422 type = DRM_MODE_ENCODER_LVDS;
428 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
431 encoder = to_drm_encoder(nv_encoder);
433 nv_encoder->dcb = entry;
434 nv_encoder->or = ffs(entry->or) - 1;
435 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
437 drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
438 drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
440 encoder->possible_crtcs = entry->heads;
441 encoder->possible_clones = 0;
443 drm_mode_connector_attach_encoder(connector, encoder);