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 <acpi/button.h> |
28 | |
29 | #include <linux/pm_runtime.h> |
30 | #include <linux/vga_switcheroo.h> |
31 | |
32 | #include <drm/drm_atomic_helper.h> |
33 | #include <drm/drm_edid.h> |
34 | #include <drm/drm_crtc_helper.h> |
35 | #include <drm/drm_probe_helper.h> |
36 | #include <drm/drm_atomic.h> |
37 | |
38 | #include "nouveau_reg.h" |
39 | #include "nouveau_drv.h" |
40 | #include "dispnv04/hw.h" |
41 | #include "dispnv50/disp.h" |
42 | #include "nouveau_acpi.h" |
43 | |
44 | #include "nouveau_display.h" |
45 | #include "nouveau_connector.h" |
46 | #include "nouveau_encoder.h" |
47 | #include "nouveau_crtc.h" |
48 | |
49 | #include <nvif/class.h> |
50 | #include <nvif/if0011.h> |
51 | |
52 | struct drm_display_mode * |
53 | nouveau_conn_native_mode(struct drm_connector *connector) |
54 | { |
55 | const struct drm_connector_helper_funcs *helper = connector->helper_private; |
56 | struct nouveau_drm *drm = nouveau_drm(dev: connector->dev); |
57 | struct drm_device *dev = connector->dev; |
58 | struct drm_display_mode *mode, *largest = NULL; |
59 | int high_w = 0, high_h = 0, high_v = 0; |
60 | |
61 | list_for_each_entry(mode, &connector->probed_modes, head) { |
62 | if (helper->mode_valid(connector, mode) != MODE_OK || |
63 | (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
64 | continue; |
65 | |
66 | /* Use preferred mode if there is one.. */ |
67 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { |
68 | NV_DEBUG(drm, "native mode from preferred\n" ); |
69 | return drm_mode_duplicate(dev, mode); |
70 | } |
71 | |
72 | /* Otherwise, take the resolution with the largest width, then |
73 | * height, then vertical refresh |
74 | */ |
75 | if (mode->hdisplay < high_w) |
76 | continue; |
77 | |
78 | if (mode->hdisplay == high_w && mode->vdisplay < high_h) |
79 | continue; |
80 | |
81 | if (mode->hdisplay == high_w && mode->vdisplay == high_h && |
82 | drm_mode_vrefresh(mode) < high_v) |
83 | continue; |
84 | |
85 | high_w = mode->hdisplay; |
86 | high_h = mode->vdisplay; |
87 | high_v = drm_mode_vrefresh(mode); |
88 | largest = mode; |
89 | } |
90 | |
91 | NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n" , |
92 | high_w, high_h, high_v); |
93 | return largest ? drm_mode_duplicate(dev, mode: largest) : NULL; |
94 | } |
95 | |
96 | int |
97 | nouveau_conn_atomic_get_property(struct drm_connector *connector, |
98 | const struct drm_connector_state *state, |
99 | struct drm_property *property, u64 *val) |
100 | { |
101 | struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); |
102 | struct nouveau_display *disp = nouveau_display(dev: connector->dev); |
103 | struct drm_device *dev = connector->dev; |
104 | |
105 | if (property == dev->mode_config.scaling_mode_property) |
106 | *val = asyc->scaler.mode; |
107 | else if (property == disp->underscan_property) |
108 | *val = asyc->scaler.underscan.mode; |
109 | else if (property == disp->underscan_hborder_property) |
110 | *val = asyc->scaler.underscan.hborder; |
111 | else if (property == disp->underscan_vborder_property) |
112 | *val = asyc->scaler.underscan.vborder; |
113 | else if (property == disp->dithering_mode) |
114 | *val = asyc->dither.mode; |
115 | else if (property == disp->dithering_depth) |
116 | *val = asyc->dither.depth; |
117 | else if (property == disp->vibrant_hue_property) |
118 | *val = asyc->procamp.vibrant_hue; |
119 | else if (property == disp->color_vibrance_property) |
120 | *val = asyc->procamp.color_vibrance; |
121 | else |
122 | return -EINVAL; |
123 | |
124 | return 0; |
125 | } |
126 | |
127 | int |
128 | nouveau_conn_atomic_set_property(struct drm_connector *connector, |
129 | struct drm_connector_state *state, |
130 | struct drm_property *property, u64 val) |
131 | { |
132 | struct drm_device *dev = connector->dev; |
133 | struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); |
134 | struct nouveau_display *disp = nouveau_display(dev); |
135 | |
136 | if (property == dev->mode_config.scaling_mode_property) { |
137 | switch (val) { |
138 | case DRM_MODE_SCALE_NONE: |
139 | /* We allow 'None' for EDID modes, even on a fixed |
140 | * panel (some exist with support for lower refresh |
141 | * rates, which people might want to use for power- |
142 | * saving purposes). |
143 | * |
144 | * Non-EDID modes will force the use of GPU scaling |
145 | * to the native mode regardless of this setting. |
146 | */ |
147 | switch (connector->connector_type) { |
148 | case DRM_MODE_CONNECTOR_LVDS: |
149 | case DRM_MODE_CONNECTOR_eDP: |
150 | /* ... except prior to G80, where the code |
151 | * doesn't support such things. |
152 | */ |
153 | if (disp->disp.object.oclass < NV50_DISP) |
154 | return -EINVAL; |
155 | break; |
156 | default: |
157 | break; |
158 | } |
159 | break; |
160 | case DRM_MODE_SCALE_FULLSCREEN: |
161 | case DRM_MODE_SCALE_CENTER: |
162 | case DRM_MODE_SCALE_ASPECT: |
163 | break; |
164 | default: |
165 | return -EINVAL; |
166 | } |
167 | |
168 | if (asyc->scaler.mode != val) { |
169 | asyc->scaler.mode = val; |
170 | asyc->set.scaler = true; |
171 | } |
172 | } else |
173 | if (property == disp->underscan_property) { |
174 | if (asyc->scaler.underscan.mode != val) { |
175 | asyc->scaler.underscan.mode = val; |
176 | asyc->set.scaler = true; |
177 | } |
178 | } else |
179 | if (property == disp->underscan_hborder_property) { |
180 | if (asyc->scaler.underscan.hborder != val) { |
181 | asyc->scaler.underscan.hborder = val; |
182 | asyc->set.scaler = true; |
183 | } |
184 | } else |
185 | if (property == disp->underscan_vborder_property) { |
186 | if (asyc->scaler.underscan.vborder != val) { |
187 | asyc->scaler.underscan.vborder = val; |
188 | asyc->set.scaler = true; |
189 | } |
190 | } else |
191 | if (property == disp->dithering_mode) { |
192 | if (asyc->dither.mode != val) { |
193 | asyc->dither.mode = val; |
194 | asyc->set.dither = true; |
195 | } |
196 | } else |
197 | if (property == disp->dithering_depth) { |
198 | if (asyc->dither.mode != val) { |
199 | asyc->dither.depth = val; |
200 | asyc->set.dither = true; |
201 | } |
202 | } else |
203 | if (property == disp->vibrant_hue_property) { |
204 | if (asyc->procamp.vibrant_hue != val) { |
205 | asyc->procamp.vibrant_hue = val; |
206 | asyc->set.procamp = true; |
207 | } |
208 | } else |
209 | if (property == disp->color_vibrance_property) { |
210 | if (asyc->procamp.color_vibrance != val) { |
211 | asyc->procamp.color_vibrance = val; |
212 | asyc->set.procamp = true; |
213 | } |
214 | } else { |
215 | return -EINVAL; |
216 | } |
217 | |
218 | return 0; |
219 | } |
220 | |
221 | void |
222 | nouveau_conn_atomic_destroy_state(struct drm_connector *connector, |
223 | struct drm_connector_state *state) |
224 | { |
225 | struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); |
226 | __drm_atomic_helper_connector_destroy_state(state: &asyc->state); |
227 | kfree(objp: asyc); |
228 | } |
229 | |
230 | struct drm_connector_state * |
231 | nouveau_conn_atomic_duplicate_state(struct drm_connector *connector) |
232 | { |
233 | struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); |
234 | struct nouveau_conn_atom *asyc; |
235 | if (!(asyc = kmalloc(size: sizeof(*asyc), GFP_KERNEL))) |
236 | return NULL; |
237 | __drm_atomic_helper_connector_duplicate_state(connector, state: &asyc->state); |
238 | asyc->dither = armc->dither; |
239 | asyc->scaler = armc->scaler; |
240 | asyc->procamp = armc->procamp; |
241 | asyc->set.mask = 0; |
242 | return &asyc->state; |
243 | } |
244 | |
245 | void |
246 | nouveau_conn_reset(struct drm_connector *connector) |
247 | { |
248 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
249 | struct nouveau_conn_atom *asyc; |
250 | |
251 | if (drm_drv_uses_atomic_modeset(dev: connector->dev)) { |
252 | if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) |
253 | return; |
254 | |
255 | if (connector->state) |
256 | nouveau_conn_atomic_destroy_state(connector, |
257 | state: connector->state); |
258 | |
259 | __drm_atomic_helper_connector_reset(connector, conn_state: &asyc->state); |
260 | } else { |
261 | asyc = &nv_connector->properties_state; |
262 | } |
263 | |
264 | asyc->dither.mode = DITHERING_MODE_AUTO; |
265 | asyc->dither.depth = DITHERING_DEPTH_AUTO; |
266 | asyc->scaler.mode = DRM_MODE_SCALE_NONE; |
267 | asyc->scaler.underscan.mode = UNDERSCAN_OFF; |
268 | asyc->procamp.color_vibrance = 150; |
269 | asyc->procamp.vibrant_hue = 90; |
270 | |
271 | if (nouveau_display(dev: connector->dev)->disp.object.oclass < NV50_DISP) { |
272 | switch (connector->connector_type) { |
273 | case DRM_MODE_CONNECTOR_LVDS: |
274 | /* See note in nouveau_conn_atomic_set_property(). */ |
275 | asyc->scaler.mode = DRM_MODE_SCALE_FULLSCREEN; |
276 | break; |
277 | default: |
278 | break; |
279 | } |
280 | } |
281 | } |
282 | |
283 | void |
284 | nouveau_conn_attach_properties(struct drm_connector *connector) |
285 | { |
286 | struct drm_device *dev = connector->dev; |
287 | struct nouveau_display *disp = nouveau_display(dev); |
288 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
289 | struct nouveau_conn_atom *armc; |
290 | |
291 | if (drm_drv_uses_atomic_modeset(dev: connector->dev)) |
292 | armc = nouveau_conn_atom(connector->state); |
293 | else |
294 | armc = &nv_connector->properties_state; |
295 | |
296 | /* Init DVI-I specific properties. */ |
297 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) |
298 | drm_object_attach_property(obj: &connector->base, property: dev->mode_config. |
299 | dvi_i_subconnector_property, init_val: 0); |
300 | |
301 | /* Add overscan compensation options to digital outputs. */ |
302 | if (disp->underscan_property && |
303 | (connector->connector_type == DRM_MODE_CONNECTOR_DVID || |
304 | connector->connector_type == DRM_MODE_CONNECTOR_DVII || |
305 | connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || |
306 | connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)) { |
307 | drm_object_attach_property(obj: &connector->base, |
308 | property: disp->underscan_property, |
309 | init_val: UNDERSCAN_OFF); |
310 | drm_object_attach_property(obj: &connector->base, |
311 | property: disp->underscan_hborder_property, init_val: 0); |
312 | drm_object_attach_property(obj: &connector->base, |
313 | property: disp->underscan_vborder_property, init_val: 0); |
314 | } |
315 | |
316 | /* Add hue and saturation options. */ |
317 | if (disp->vibrant_hue_property) |
318 | drm_object_attach_property(obj: &connector->base, |
319 | property: disp->vibrant_hue_property, |
320 | init_val: armc->procamp.vibrant_hue); |
321 | if (disp->color_vibrance_property) |
322 | drm_object_attach_property(obj: &connector->base, |
323 | property: disp->color_vibrance_property, |
324 | init_val: armc->procamp.color_vibrance); |
325 | |
326 | /* Scaling mode property. */ |
327 | switch (connector->connector_type) { |
328 | case DRM_MODE_CONNECTOR_TV: |
329 | break; |
330 | case DRM_MODE_CONNECTOR_VGA: |
331 | if (disp->disp.object.oclass < NV50_DISP) |
332 | break; /* Can only scale on DFPs. */ |
333 | fallthrough; |
334 | default: |
335 | drm_object_attach_property(obj: &connector->base, property: dev->mode_config. |
336 | scaling_mode_property, |
337 | init_val: armc->scaler.mode); |
338 | break; |
339 | } |
340 | |
341 | /* Dithering properties. */ |
342 | switch (connector->connector_type) { |
343 | case DRM_MODE_CONNECTOR_TV: |
344 | case DRM_MODE_CONNECTOR_VGA: |
345 | break; |
346 | default: |
347 | if (disp->dithering_mode) { |
348 | drm_object_attach_property(obj: &connector->base, |
349 | property: disp->dithering_mode, |
350 | init_val: armc->dither.mode); |
351 | } |
352 | if (disp->dithering_depth) { |
353 | drm_object_attach_property(obj: &connector->base, |
354 | property: disp->dithering_depth, |
355 | init_val: armc->dither.depth); |
356 | } |
357 | break; |
358 | } |
359 | } |
360 | |
361 | MODULE_PARM_DESC(tv_disable, "Disable TV-out detection" ); |
362 | int nouveau_tv_disable = 0; |
363 | module_param_named(tv_disable, nouveau_tv_disable, int, 0400); |
364 | |
365 | MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status" ); |
366 | int nouveau_ignorelid = 0; |
367 | module_param_named(ignorelid, nouveau_ignorelid, int, 0400); |
368 | |
369 | MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)" ); |
370 | int nouveau_duallink = 1; |
371 | module_param_named(duallink, nouveau_duallink, int, 0400); |
372 | |
373 | MODULE_PARM_DESC(hdmimhz, "Force a maximum HDMI pixel clock (in MHz)" ); |
374 | int nouveau_hdmimhz = 0; |
375 | module_param_named(hdmimhz, nouveau_hdmimhz, int, 0400); |
376 | |
377 | struct nouveau_encoder * |
378 | find_encoder(struct drm_connector *connector, int type) |
379 | { |
380 | struct nouveau_encoder *nv_encoder; |
381 | struct drm_encoder *enc; |
382 | |
383 | drm_connector_for_each_possible_encoder(connector, enc) { |
384 | nv_encoder = nouveau_encoder(enc); |
385 | |
386 | if (type == DCB_OUTPUT_ANY || |
387 | (nv_encoder->dcb && nv_encoder->dcb->type == type)) |
388 | return nv_encoder; |
389 | } |
390 | |
391 | return NULL; |
392 | } |
393 | |
394 | static void |
395 | nouveau_connector_destroy(struct drm_connector *connector) |
396 | { |
397 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
398 | nvif_event_dtor(&nv_connector->irq); |
399 | nvif_event_dtor(&nv_connector->hpd); |
400 | kfree(objp: nv_connector->edid); |
401 | drm_connector_unregister(connector); |
402 | drm_connector_cleanup(connector); |
403 | if (nv_connector->aux.transfer) |
404 | drm_dp_cec_unregister_connector(aux: &nv_connector->aux); |
405 | nvif_conn_dtor(&nv_connector->conn); |
406 | kfree(objp: connector); |
407 | } |
408 | |
409 | static struct nouveau_encoder * |
410 | nouveau_connector_ddc_detect(struct drm_connector *connector) |
411 | { |
412 | struct drm_device *dev = connector->dev; |
413 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
414 | struct nouveau_connector *conn = nouveau_connector(con: connector); |
415 | struct nouveau_encoder *nv_encoder = NULL, *found = NULL; |
416 | struct drm_encoder *encoder; |
417 | int ret; |
418 | bool switcheroo_ddc = false; |
419 | |
420 | drm_connector_for_each_possible_encoder(connector, encoder) { |
421 | nv_encoder = nouveau_encoder(enc: encoder); |
422 | |
423 | if (nvif_object_constructed(&nv_encoder->outp.object)) { |
424 | enum nvif_outp_detect_status status; |
425 | |
426 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { |
427 | ret = nouveau_dp_detect(conn, nv_encoder); |
428 | if (ret == NOUVEAU_DP_MST) |
429 | return NULL; |
430 | if (ret != NOUVEAU_DP_SST) |
431 | continue; |
432 | |
433 | return nv_encoder; |
434 | } else { |
435 | status = nvif_outp_detect(&nv_encoder->outp); |
436 | switch (status) { |
437 | case PRESENT: |
438 | return nv_encoder; |
439 | case NOT_PRESENT: |
440 | continue; |
441 | case UNKNOWN: |
442 | break; |
443 | default: |
444 | WARN_ON(1); |
445 | break; |
446 | } |
447 | } |
448 | } |
449 | |
450 | if (!nv_encoder->i2c) |
451 | continue; |
452 | |
453 | if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS) { |
454 | switcheroo_ddc = !!(vga_switcheroo_handler_flags() & |
455 | VGA_SWITCHEROO_CAN_SWITCH_DDC); |
456 | } |
457 | |
458 | if (switcheroo_ddc) |
459 | vga_switcheroo_lock_ddc(pdev); |
460 | if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) |
461 | found = nv_encoder; |
462 | if (switcheroo_ddc) |
463 | vga_switcheroo_unlock_ddc(pdev); |
464 | |
465 | if (found) |
466 | break; |
467 | } |
468 | |
469 | return found; |
470 | } |
471 | |
472 | static struct nouveau_encoder * |
473 | nouveau_connector_of_detect(struct drm_connector *connector) |
474 | { |
475 | #ifdef __powerpc__ |
476 | struct drm_device *dev = connector->dev; |
477 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
478 | struct nouveau_encoder *nv_encoder; |
479 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
480 | struct device_node *cn, *dn = pci_device_to_OF_node(pdev); |
481 | |
482 | if (!dn || |
483 | !((nv_encoder = find_encoder(connector, DCB_OUTPUT_TMDS)) || |
484 | (nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG)))) |
485 | return NULL; |
486 | |
487 | for_each_child_of_node(dn, cn) { |
488 | const char *name = of_get_property(cn, "name" , NULL); |
489 | const void *edid = of_get_property(cn, "EDID" , NULL); |
490 | int idx = name ? name[strlen(name) - 1] - 'A' : 0; |
491 | |
492 | if (nv_encoder->dcb->i2c_index == idx && edid) { |
493 | nv_connector->edid = |
494 | kmemdup(edid, EDID_LENGTH, GFP_KERNEL); |
495 | of_node_put(cn); |
496 | return nv_encoder; |
497 | } |
498 | } |
499 | #endif |
500 | return NULL; |
501 | } |
502 | |
503 | static void |
504 | nouveau_connector_set_encoder(struct drm_connector *connector, |
505 | struct nouveau_encoder *nv_encoder) |
506 | { |
507 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
508 | struct nouveau_drm *drm = nouveau_drm(dev: connector->dev); |
509 | struct drm_device *dev = connector->dev; |
510 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
511 | |
512 | if (nv_connector->detected_encoder == nv_encoder) |
513 | return; |
514 | nv_connector->detected_encoder = nv_encoder; |
515 | |
516 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
517 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) |
518 | connector->interlace_allowed = |
519 | nv_encoder->caps.dp_interlace; |
520 | else |
521 | connector->interlace_allowed = |
522 | drm->client.device.info.family < NV_DEVICE_INFO_V0_VOLTA; |
523 | connector->doublescan_allowed = true; |
524 | } else |
525 | if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS || |
526 | nv_encoder->dcb->type == DCB_OUTPUT_TMDS) { |
527 | connector->doublescan_allowed = false; |
528 | connector->interlace_allowed = false; |
529 | } else { |
530 | connector->doublescan_allowed = true; |
531 | if (drm->client.device.info.family == NV_DEVICE_INFO_V0_KELVIN || |
532 | (drm->client.device.info.family == NV_DEVICE_INFO_V0_CELSIUS && |
533 | (pdev->device & 0x0ff0) != 0x0100 && |
534 | (pdev->device & 0x0ff0) != 0x0150)) |
535 | /* HW is broken */ |
536 | connector->interlace_allowed = false; |
537 | else |
538 | connector->interlace_allowed = true; |
539 | } |
540 | |
541 | if (nv_connector->type == DCB_CONNECTOR_DVI_I) { |
542 | drm_object_property_set_value(&connector->base, |
543 | dev->mode_config.dvi_i_subconnector_property, |
544 | nv_encoder->dcb->type == DCB_OUTPUT_TMDS ? |
545 | DRM_MODE_SUBCONNECTOR_DVID : |
546 | DRM_MODE_SUBCONNECTOR_DVIA); |
547 | } |
548 | } |
549 | |
550 | static void |
551 | nouveau_connector_set_edid(struct nouveau_connector *nv_connector, |
552 | struct edid *edid) |
553 | { |
554 | if (nv_connector->edid != edid) { |
555 | struct edid *old_edid = nv_connector->edid; |
556 | |
557 | drm_connector_update_edid_property(connector: &nv_connector->base, edid); |
558 | kfree(objp: old_edid); |
559 | nv_connector->edid = edid; |
560 | } |
561 | } |
562 | |
563 | static enum drm_connector_status |
564 | nouveau_connector_detect(struct drm_connector *connector, bool force) |
565 | { |
566 | struct drm_device *dev = connector->dev; |
567 | struct nouveau_drm *drm = nouveau_drm(dev); |
568 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
569 | struct nouveau_encoder *nv_encoder = NULL; |
570 | struct nouveau_encoder *nv_partner; |
571 | int type; |
572 | int ret; |
573 | enum drm_connector_status conn_status = connector_status_disconnected; |
574 | |
575 | /* Outputs are only polled while runtime active, so resuming the |
576 | * device here is unnecessary (and would deadlock upon runtime suspend |
577 | * because it waits for polling to finish). We do however, want to |
578 | * prevent the autosuspend timer from elapsing during this operation |
579 | * if possible. |
580 | */ |
581 | if (drm_kms_helper_is_poll_worker()) { |
582 | pm_runtime_get_noresume(dev: dev->dev); |
583 | } else { |
584 | ret = pm_runtime_get_sync(dev: dev->dev); |
585 | if (ret < 0 && ret != -EACCES) { |
586 | pm_runtime_put_autosuspend(dev: dev->dev); |
587 | nouveau_connector_set_edid(nv_connector, NULL); |
588 | return conn_status; |
589 | } |
590 | } |
591 | |
592 | nv_encoder = nouveau_connector_ddc_detect(connector); |
593 | if (nv_encoder) { |
594 | struct edid *new_edid = NULL; |
595 | |
596 | if (nv_encoder->i2c) { |
597 | if ((vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) && |
598 | nv_connector->type == DCB_CONNECTOR_LVDS) |
599 | new_edid = drm_get_edid_switcheroo(connector, adapter: nv_encoder->i2c); |
600 | else |
601 | new_edid = drm_get_edid(connector, adapter: nv_encoder->i2c); |
602 | } else { |
603 | ret = nvif_outp_edid_get(&nv_encoder->outp, (u8 **)&new_edid); |
604 | if (ret < 0) |
605 | return connector_status_disconnected; |
606 | } |
607 | |
608 | nouveau_connector_set_edid(nv_connector, edid: new_edid); |
609 | if (!nv_connector->edid) { |
610 | NV_ERROR(drm, "DDC responded, but no EDID for %s\n" , |
611 | connector->name); |
612 | goto detect_analog; |
613 | } |
614 | |
615 | /* Override encoder type for DVI-I based on whether EDID |
616 | * says the display is digital or analog, both use the |
617 | * same i2c channel so the value returned from ddc_detect |
618 | * isn't necessarily correct. |
619 | */ |
620 | nv_partner = NULL; |
621 | if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS) |
622 | nv_partner = find_encoder(connector, DCB_OUTPUT_ANALOG); |
623 | if (nv_encoder->dcb->type == DCB_OUTPUT_ANALOG) |
624 | nv_partner = find_encoder(connector, DCB_OUTPUT_TMDS); |
625 | |
626 | if (nv_partner && ((nv_encoder->dcb->type == DCB_OUTPUT_ANALOG && |
627 | nv_partner->dcb->type == DCB_OUTPUT_TMDS) || |
628 | (nv_encoder->dcb->type == DCB_OUTPUT_TMDS && |
629 | nv_partner->dcb->type == DCB_OUTPUT_ANALOG))) { |
630 | if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) |
631 | type = DCB_OUTPUT_TMDS; |
632 | else |
633 | type = DCB_OUTPUT_ANALOG; |
634 | |
635 | nv_encoder = find_encoder(connector, type); |
636 | } |
637 | |
638 | nouveau_connector_set_encoder(connector, nv_encoder); |
639 | conn_status = connector_status_connected; |
640 | |
641 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) |
642 | drm_dp_cec_set_edid(aux: &nv_connector->aux, edid: nv_connector->edid); |
643 | |
644 | goto out; |
645 | } else { |
646 | nouveau_connector_set_edid(nv_connector, NULL); |
647 | } |
648 | |
649 | nv_encoder = nouveau_connector_of_detect(connector); |
650 | if (nv_encoder) { |
651 | nouveau_connector_set_encoder(connector, nv_encoder); |
652 | conn_status = connector_status_connected; |
653 | goto out; |
654 | } |
655 | |
656 | detect_analog: |
657 | nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG); |
658 | if (!nv_encoder && !nouveau_tv_disable) |
659 | nv_encoder = find_encoder(connector, DCB_OUTPUT_TV); |
660 | if (nv_encoder && force) { |
661 | struct drm_encoder *encoder = to_drm_encoder(enc: nv_encoder); |
662 | const struct drm_encoder_helper_funcs *helper = |
663 | encoder->helper_private; |
664 | |
665 | if (helper->detect(encoder, connector) == |
666 | connector_status_connected) { |
667 | nouveau_connector_set_encoder(connector, nv_encoder); |
668 | conn_status = connector_status_connected; |
669 | goto out; |
670 | } |
671 | } |
672 | |
673 | out: |
674 | if (!nv_connector->edid) |
675 | drm_dp_cec_unset_edid(aux: &nv_connector->aux); |
676 | |
677 | pm_runtime_mark_last_busy(dev: dev->dev); |
678 | pm_runtime_put_autosuspend(dev: dev->dev); |
679 | |
680 | return conn_status; |
681 | } |
682 | |
683 | static enum drm_connector_status |
684 | nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) |
685 | { |
686 | struct drm_device *dev = connector->dev; |
687 | struct nouveau_drm *drm = nouveau_drm(dev); |
688 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
689 | struct nouveau_encoder *nv_encoder = NULL; |
690 | struct edid *edid = NULL; |
691 | enum drm_connector_status status = connector_status_disconnected; |
692 | |
693 | nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); |
694 | if (!nv_encoder) |
695 | goto out; |
696 | |
697 | /* Try retrieving EDID via DDC */ |
698 | if (!drm->vbios.fp_no_ddc) { |
699 | status = nouveau_connector_detect(connector, force); |
700 | if (status == connector_status_connected) { |
701 | edid = nv_connector->edid; |
702 | goto out; |
703 | } |
704 | } |
705 | |
706 | /* On some laptops (Sony, i'm looking at you) there appears to |
707 | * be no direct way of accessing the panel's EDID. The only |
708 | * option available to us appears to be to ask ACPI for help.. |
709 | * |
710 | * It's important this check's before trying straps, one of the |
711 | * said manufacturer's laptops are configured in such a way |
712 | * the nouveau decides an entry in the VBIOS FP mode table is |
713 | * valid - it's not (rh#613284) |
714 | */ |
715 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { |
716 | edid = nouveau_acpi_edid(dev, connector); |
717 | if (edid) { |
718 | status = connector_status_connected; |
719 | goto out; |
720 | } |
721 | } |
722 | |
723 | /* If no EDID found above, and the VBIOS indicates a hardcoded |
724 | * modeline is avalilable for the panel, set it as the panel's |
725 | * native mode and exit. |
726 | */ |
727 | if (nouveau_bios_fp_mode(dev, NULL) && (drm->vbios.fp_no_ddc || |
728 | nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { |
729 | status = connector_status_connected; |
730 | goto out; |
731 | } |
732 | |
733 | /* Still nothing, some VBIOS images have a hardcoded EDID block |
734 | * stored for the panel stored in them. |
735 | */ |
736 | if (!drm->vbios.fp_no_ddc) { |
737 | edid = (struct edid *)nouveau_bios_embedded_edid(dev); |
738 | if (edid) { |
739 | edid = kmemdup(p: edid, EDID_LENGTH, GFP_KERNEL); |
740 | if (edid) |
741 | status = connector_status_connected; |
742 | } |
743 | } |
744 | |
745 | out: |
746 | #if defined(CONFIG_ACPI_BUTTON) || \ |
747 | (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) |
748 | if (status == connector_status_connected && |
749 | !nouveau_ignorelid && !acpi_lid_open()) |
750 | status = connector_status_unknown; |
751 | #endif |
752 | |
753 | nouveau_connector_set_edid(nv_connector, edid); |
754 | if (nv_encoder) |
755 | nouveau_connector_set_encoder(connector, nv_encoder); |
756 | return status; |
757 | } |
758 | |
759 | static void |
760 | nouveau_connector_force(struct drm_connector *connector) |
761 | { |
762 | struct nouveau_drm *drm = nouveau_drm(dev: connector->dev); |
763 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
764 | struct nouveau_encoder *nv_encoder; |
765 | int type; |
766 | |
767 | if (nv_connector->type == DCB_CONNECTOR_DVI_I) { |
768 | if (connector->force == DRM_FORCE_ON_DIGITAL) |
769 | type = DCB_OUTPUT_TMDS; |
770 | else |
771 | type = DCB_OUTPUT_ANALOG; |
772 | } else |
773 | type = DCB_OUTPUT_ANY; |
774 | |
775 | nv_encoder = find_encoder(connector, type); |
776 | if (!nv_encoder) { |
777 | NV_ERROR(drm, "can't find encoder to force %s on!\n" , |
778 | connector->name); |
779 | connector->status = connector_status_disconnected; |
780 | return; |
781 | } |
782 | |
783 | nouveau_connector_set_encoder(connector, nv_encoder); |
784 | } |
785 | |
786 | static int |
787 | nouveau_connector_set_property(struct drm_connector *connector, |
788 | struct drm_property *property, uint64_t value) |
789 | { |
790 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
791 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
792 | struct nouveau_conn_atom *asyc = &nv_connector->properties_state; |
793 | struct drm_encoder *encoder = to_drm_encoder(enc: nv_encoder); |
794 | int ret; |
795 | |
796 | ret = connector->funcs->atomic_set_property(&nv_connector->base, |
797 | &asyc->state, |
798 | property, value); |
799 | if (ret) { |
800 | if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV) |
801 | return get_slave_funcs(enc: encoder)->set_property( |
802 | encoder, connector, property, value); |
803 | return ret; |
804 | } |
805 | |
806 | nv_connector->scaling_mode = asyc->scaler.mode; |
807 | nv_connector->dithering_mode = asyc->dither.mode; |
808 | |
809 | if (connector->encoder && connector->encoder->crtc) { |
810 | ret = drm_crtc_helper_set_mode(crtc: connector->encoder->crtc, |
811 | mode: &connector->encoder->crtc->mode, |
812 | x: connector->encoder->crtc->x, |
813 | y: connector->encoder->crtc->y, |
814 | NULL); |
815 | if (!ret) |
816 | return -EINVAL; |
817 | } |
818 | |
819 | return 0; |
820 | } |
821 | |
822 | struct moderec { |
823 | int hdisplay; |
824 | int vdisplay; |
825 | }; |
826 | |
827 | static struct moderec scaler_modes[] = { |
828 | { 1920, 1200 }, |
829 | { 1920, 1080 }, |
830 | { 1680, 1050 }, |
831 | { 1600, 1200 }, |
832 | { 1400, 1050 }, |
833 | { 1280, 1024 }, |
834 | { 1280, 960 }, |
835 | { 1152, 864 }, |
836 | { 1024, 768 }, |
837 | { 800, 600 }, |
838 | { 720, 400 }, |
839 | { 640, 480 }, |
840 | { 640, 400 }, |
841 | { 640, 350 }, |
842 | {} |
843 | }; |
844 | |
845 | static int |
846 | nouveau_connector_scaler_modes_add(struct drm_connector *connector) |
847 | { |
848 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
849 | struct drm_display_mode *native = nv_connector->native_mode, *m; |
850 | struct drm_device *dev = connector->dev; |
851 | struct moderec *mode = &scaler_modes[0]; |
852 | int modes = 0; |
853 | |
854 | if (!native) |
855 | return 0; |
856 | |
857 | while (mode->hdisplay) { |
858 | if (mode->hdisplay <= native->hdisplay && |
859 | mode->vdisplay <= native->vdisplay && |
860 | (mode->hdisplay != native->hdisplay || |
861 | mode->vdisplay != native->vdisplay)) { |
862 | m = drm_cvt_mode(dev, hdisplay: mode->hdisplay, vdisplay: mode->vdisplay, |
863 | vrefresh: drm_mode_vrefresh(mode: native), reduced: false, |
864 | interlaced: false, margins: false); |
865 | if (!m) |
866 | continue; |
867 | |
868 | drm_mode_probed_add(connector, mode: m); |
869 | modes++; |
870 | } |
871 | |
872 | mode++; |
873 | } |
874 | |
875 | return modes; |
876 | } |
877 | |
878 | static void |
879 | nouveau_connector_detect_depth(struct drm_connector *connector) |
880 | { |
881 | struct nouveau_drm *drm = nouveau_drm(dev: connector->dev); |
882 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
883 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
884 | struct nvbios *bios = &drm->vbios; |
885 | struct drm_display_mode *mode = nv_connector->native_mode; |
886 | bool duallink; |
887 | |
888 | /* if the edid is feeling nice enough to provide this info, use it */ |
889 | if (nv_connector->edid && connector->display_info.bpc) |
890 | return; |
891 | |
892 | /* EDID 1.4 is *supposed* to be supported on eDP, but, Apple... */ |
893 | if (nv_connector->type == DCB_CONNECTOR_eDP) { |
894 | connector->display_info.bpc = 6; |
895 | return; |
896 | } |
897 | |
898 | /* we're out of options unless we're LVDS, default to 8bpc */ |
899 | if (nv_encoder->dcb->type != DCB_OUTPUT_LVDS) { |
900 | connector->display_info.bpc = 8; |
901 | return; |
902 | } |
903 | |
904 | connector->display_info.bpc = 6; |
905 | |
906 | /* LVDS: panel straps */ |
907 | if (bios->fp_no_ddc) { |
908 | if (bios->fp.if_is_24bit) |
909 | connector->display_info.bpc = 8; |
910 | return; |
911 | } |
912 | |
913 | /* LVDS: DDC panel, need to first determine the number of links to |
914 | * know which if_is_24bit flag to check... |
915 | */ |
916 | if (nv_connector->edid && |
917 | nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) |
918 | duallink = ((u8 *)nv_connector->edid)[121] == 2; |
919 | else |
920 | duallink = mode->clock >= bios->fp.duallink_transition_clk; |
921 | |
922 | if ((!duallink && (bios->fp.strapless_is_24bit & 1)) || |
923 | ( duallink && (bios->fp.strapless_is_24bit & 2))) |
924 | connector->display_info.bpc = 8; |
925 | } |
926 | |
927 | static int |
928 | nouveau_connector_late_register(struct drm_connector *connector) |
929 | { |
930 | int ret; |
931 | |
932 | ret = nouveau_backlight_init(connector); |
933 | if (ret) |
934 | return ret; |
935 | |
936 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || |
937 | connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
938 | ret = drm_dp_aux_register(aux: &nouveau_connector(con: connector)->aux); |
939 | if (ret) |
940 | goto backlight_fini; |
941 | } |
942 | |
943 | return 0; |
944 | backlight_fini: |
945 | nouveau_backlight_fini(connector); |
946 | return ret; |
947 | } |
948 | |
949 | static void |
950 | nouveau_connector_early_unregister(struct drm_connector *connector) |
951 | { |
952 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || |
953 | connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) |
954 | drm_dp_aux_unregister(aux: &nouveau_connector(con: connector)->aux); |
955 | |
956 | nouveau_backlight_fini(connector); |
957 | } |
958 | |
959 | static int |
960 | nouveau_connector_get_modes(struct drm_connector *connector) |
961 | { |
962 | struct drm_device *dev = connector->dev; |
963 | struct nouveau_drm *drm = nouveau_drm(dev); |
964 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
965 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
966 | struct drm_encoder *encoder = to_drm_encoder(enc: nv_encoder); |
967 | int ret = 0; |
968 | |
969 | /* destroy the native mode, the attached monitor could have changed. |
970 | */ |
971 | if (nv_connector->native_mode) { |
972 | drm_mode_destroy(dev, mode: nv_connector->native_mode); |
973 | nv_connector->native_mode = NULL; |
974 | } |
975 | |
976 | if (nv_connector->edid) |
977 | ret = drm_add_edid_modes(connector, edid: nv_connector->edid); |
978 | else |
979 | if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS && |
980 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || |
981 | drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { |
982 | struct drm_display_mode mode; |
983 | |
984 | nouveau_bios_fp_mode(dev, &mode); |
985 | nv_connector->native_mode = drm_mode_duplicate(dev, mode: &mode); |
986 | } |
987 | |
988 | /* Determine display colour depth for everything except LVDS now, |
989 | * DP requires this before mode_valid() is called. |
990 | */ |
991 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) |
992 | nouveau_connector_detect_depth(connector); |
993 | |
994 | /* Find the native mode if this is a digital panel, if we didn't |
995 | * find any modes through DDC previously add the native mode to |
996 | * the list of modes. |
997 | */ |
998 | if (!nv_connector->native_mode) |
999 | nv_connector->native_mode = nouveau_conn_native_mode(connector); |
1000 | if (ret == 0 && nv_connector->native_mode) { |
1001 | struct drm_display_mode *mode; |
1002 | |
1003 | mode = drm_mode_duplicate(dev, mode: nv_connector->native_mode); |
1004 | drm_mode_probed_add(connector, mode); |
1005 | ret = 1; |
1006 | } |
1007 | |
1008 | /* Determine LVDS colour depth, must happen after determining |
1009 | * "native" mode as some VBIOS tables require us to use the |
1010 | * pixel clock as part of the lookup... |
1011 | */ |
1012 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode) |
1013 | nouveau_connector_detect_depth(connector); |
1014 | |
1015 | if (nv_encoder->dcb->type == DCB_OUTPUT_TV) |
1016 | ret = get_slave_funcs(enc: encoder)->get_modes(encoder, connector); |
1017 | |
1018 | if (nv_connector->type == DCB_CONNECTOR_LVDS || |
1019 | nv_connector->type == DCB_CONNECTOR_LVDS_SPWG || |
1020 | nv_connector->type == DCB_CONNECTOR_eDP) |
1021 | ret += nouveau_connector_scaler_modes_add(connector); |
1022 | |
1023 | return ret; |
1024 | } |
1025 | |
1026 | static unsigned |
1027 | get_tmds_link_bandwidth(struct drm_connector *connector) |
1028 | { |
1029 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
1030 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
1031 | struct nouveau_drm *drm = nouveau_drm(dev: connector->dev); |
1032 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; |
1033 | struct drm_display_info *info = NULL; |
1034 | unsigned duallink_scale = |
1035 | nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1; |
1036 | |
1037 | if (drm_detect_hdmi_monitor(edid: nv_connector->edid)) { |
1038 | info = &nv_connector->base.display_info; |
1039 | duallink_scale = 1; |
1040 | } |
1041 | |
1042 | if (info) { |
1043 | if (nouveau_hdmimhz > 0) |
1044 | return nouveau_hdmimhz * 1000; |
1045 | /* Note: these limits are conservative, some Fermi's |
1046 | * can do 297 MHz. Unclear how this can be determined. |
1047 | */ |
1048 | if (drm->client.device.info.chipset >= 0x120) { |
1049 | const int max_tmds_clock = |
1050 | info->hdmi.scdc.scrambling.supported ? |
1051 | 594000 : 340000; |
1052 | return info->max_tmds_clock ? |
1053 | min(info->max_tmds_clock, max_tmds_clock) : |
1054 | max_tmds_clock; |
1055 | } |
1056 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER) |
1057 | return 297000; |
1058 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) |
1059 | return 225000; |
1060 | } |
1061 | |
1062 | if (dcb->location != DCB_LOC_ON_CHIP || |
1063 | drm->client.device.info.chipset >= 0x46) |
1064 | return 165000 * duallink_scale; |
1065 | else if (drm->client.device.info.chipset >= 0x40) |
1066 | return 155000 * duallink_scale; |
1067 | else if (drm->client.device.info.chipset >= 0x18) |
1068 | return 135000 * duallink_scale; |
1069 | else |
1070 | return 112000 * duallink_scale; |
1071 | } |
1072 | |
1073 | static enum drm_mode_status |
1074 | nouveau_connector_mode_valid(struct drm_connector *connector, |
1075 | struct drm_display_mode *mode) |
1076 | { |
1077 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
1078 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
1079 | struct drm_encoder *encoder = to_drm_encoder(enc: nv_encoder); |
1080 | unsigned int min_clock = 25000, max_clock = min_clock, clock = mode->clock; |
1081 | |
1082 | switch (nv_encoder->dcb->type) { |
1083 | case DCB_OUTPUT_LVDS: |
1084 | if (nv_connector->native_mode && |
1085 | (mode->hdisplay > nv_connector->native_mode->hdisplay || |
1086 | mode->vdisplay > nv_connector->native_mode->vdisplay)) |
1087 | return MODE_PANEL; |
1088 | |
1089 | min_clock = 0; |
1090 | max_clock = 400000; |
1091 | break; |
1092 | case DCB_OUTPUT_TMDS: |
1093 | max_clock = get_tmds_link_bandwidth(connector); |
1094 | break; |
1095 | case DCB_OUTPUT_ANALOG: |
1096 | max_clock = nv_encoder->dcb->crtconf.maxfreq; |
1097 | if (!max_clock) |
1098 | max_clock = 350000; |
1099 | break; |
1100 | case DCB_OUTPUT_TV: |
1101 | return get_slave_funcs(enc: encoder)->mode_valid(encoder, mode); |
1102 | case DCB_OUTPUT_DP: |
1103 | return nv50_dp_mode_valid(nv_encoder, mode, NULL); |
1104 | default: |
1105 | BUG(); |
1106 | return MODE_BAD; |
1107 | } |
1108 | |
1109 | if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) |
1110 | clock *= 2; |
1111 | |
1112 | if (clock < min_clock) |
1113 | return MODE_CLOCK_LOW; |
1114 | if (clock > max_clock) |
1115 | return MODE_CLOCK_HIGH; |
1116 | |
1117 | return MODE_OK; |
1118 | } |
1119 | |
1120 | static struct drm_encoder * |
1121 | nouveau_connector_best_encoder(struct drm_connector *connector) |
1122 | { |
1123 | struct nouveau_connector *nv_connector = nouveau_connector(con: connector); |
1124 | |
1125 | if (nv_connector->detected_encoder) |
1126 | return to_drm_encoder(enc: nv_connector->detected_encoder); |
1127 | |
1128 | return NULL; |
1129 | } |
1130 | |
1131 | static int |
1132 | nouveau_connector_atomic_check(struct drm_connector *connector, struct drm_atomic_state *state) |
1133 | { |
1134 | struct nouveau_connector *nv_conn = nouveau_connector(con: connector); |
1135 | struct drm_connector_state *conn_state = |
1136 | drm_atomic_get_new_connector_state(state, connector); |
1137 | |
1138 | if (!nv_conn->dp_encoder || !nv_conn->dp_encoder->dp.mstm) |
1139 | return 0; |
1140 | |
1141 | return drm_dp_mst_root_conn_atomic_check(new_conn_state: conn_state, mgr: &nv_conn->dp_encoder->dp.mstm->mgr); |
1142 | } |
1143 | |
1144 | static const struct drm_connector_helper_funcs |
1145 | nouveau_connector_helper_funcs = { |
1146 | .get_modes = nouveau_connector_get_modes, |
1147 | .mode_valid = nouveau_connector_mode_valid, |
1148 | .best_encoder = nouveau_connector_best_encoder, |
1149 | .atomic_check = nouveau_connector_atomic_check, |
1150 | }; |
1151 | |
1152 | static const struct drm_connector_funcs |
1153 | nouveau_connector_funcs = { |
1154 | .dpms = drm_helper_connector_dpms, |
1155 | .reset = nouveau_conn_reset, |
1156 | .detect = nouveau_connector_detect, |
1157 | .force = nouveau_connector_force, |
1158 | .fill_modes = drm_helper_probe_single_connector_modes, |
1159 | .set_property = nouveau_connector_set_property, |
1160 | .destroy = nouveau_connector_destroy, |
1161 | .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, |
1162 | .atomic_destroy_state = nouveau_conn_atomic_destroy_state, |
1163 | .atomic_set_property = nouveau_conn_atomic_set_property, |
1164 | .atomic_get_property = nouveau_conn_atomic_get_property, |
1165 | .late_register = nouveau_connector_late_register, |
1166 | .early_unregister = nouveau_connector_early_unregister, |
1167 | }; |
1168 | |
1169 | static const struct drm_connector_funcs |
1170 | nouveau_connector_funcs_lvds = { |
1171 | .dpms = drm_helper_connector_dpms, |
1172 | .reset = nouveau_conn_reset, |
1173 | .detect = nouveau_connector_detect_lvds, |
1174 | .force = nouveau_connector_force, |
1175 | .fill_modes = drm_helper_probe_single_connector_modes, |
1176 | .set_property = nouveau_connector_set_property, |
1177 | .destroy = nouveau_connector_destroy, |
1178 | .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, |
1179 | .atomic_destroy_state = nouveau_conn_atomic_destroy_state, |
1180 | .atomic_set_property = nouveau_conn_atomic_set_property, |
1181 | .atomic_get_property = nouveau_conn_atomic_get_property, |
1182 | .late_register = nouveau_connector_late_register, |
1183 | .early_unregister = nouveau_connector_early_unregister, |
1184 | }; |
1185 | |
1186 | void |
1187 | nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits) |
1188 | { |
1189 | struct nouveau_drm *drm = nouveau_drm(dev: nv_connector->base.dev); |
1190 | u32 mask = drm_connector_mask(connector: &nv_connector->base); |
1191 | unsigned long flags; |
1192 | |
1193 | spin_lock_irqsave(&drm->hpd_lock, flags); |
1194 | if (!(drm->hpd_pending & mask)) { |
1195 | nv_connector->hpd_pending |= bits; |
1196 | drm->hpd_pending |= mask; |
1197 | schedule_work(work: &drm->hpd_work); |
1198 | } |
1199 | spin_unlock_irqrestore(lock: &drm->hpd_lock, flags); |
1200 | } |
1201 | |
1202 | static int |
1203 | nouveau_connector_irq(struct nvif_event *event, void *repv, u32 repc) |
1204 | { |
1205 | struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), irq); |
1206 | |
1207 | schedule_work(work: &nv_connector->irq_work); |
1208 | return NVIF_EVENT_KEEP; |
1209 | } |
1210 | |
1211 | static int |
1212 | nouveau_connector_hotplug(struct nvif_event *event, void *repv, u32 repc) |
1213 | { |
1214 | struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), hpd); |
1215 | struct nvif_conn_event_v0 *rep = repv; |
1216 | |
1217 | nouveau_connector_hpd(nv_connector, bits: rep->types); |
1218 | return NVIF_EVENT_KEEP; |
1219 | } |
1220 | |
1221 | static ssize_t |
1222 | nouveau_connector_aux_xfer(struct drm_dp_aux *obj, struct drm_dp_aux_msg *msg) |
1223 | { |
1224 | struct nouveau_connector *nv_connector = |
1225 | container_of(obj, typeof(*nv_connector), aux); |
1226 | struct nouveau_encoder *nv_encoder; |
1227 | u8 size = msg->size; |
1228 | int ret; |
1229 | |
1230 | nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP); |
1231 | if (!nv_encoder) |
1232 | return -ENODEV; |
1233 | if (WARN_ON(msg->size > 16)) |
1234 | return -E2BIG; |
1235 | |
1236 | ret = nvif_outp_dp_aux_xfer(&nv_encoder->outp, |
1237 | msg->request, &size, msg->address, msg->buffer); |
1238 | if (ret >= 0) { |
1239 | msg->reply = ret; |
1240 | return size; |
1241 | } |
1242 | |
1243 | return ret; |
1244 | } |
1245 | |
1246 | static int |
1247 | drm_conntype_from_dcb(enum dcb_connector_type dcb) |
1248 | { |
1249 | switch (dcb) { |
1250 | case DCB_CONNECTOR_VGA : return DRM_MODE_CONNECTOR_VGA; |
1251 | case DCB_CONNECTOR_TV_0 : |
1252 | case DCB_CONNECTOR_TV_1 : |
1253 | case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV; |
1254 | case DCB_CONNECTOR_DMS59_0 : |
1255 | case DCB_CONNECTOR_DMS59_1 : |
1256 | case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII; |
1257 | case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID; |
1258 | case DCB_CONNECTOR_LVDS : |
1259 | case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS; |
1260 | case DCB_CONNECTOR_DMS59_DP0: |
1261 | case DCB_CONNECTOR_DMS59_DP1: |
1262 | case DCB_CONNECTOR_DP : |
1263 | case DCB_CONNECTOR_mDP : |
1264 | case DCB_CONNECTOR_USB_C : return DRM_MODE_CONNECTOR_DisplayPort; |
1265 | case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; |
1266 | case DCB_CONNECTOR_HDMI_0 : |
1267 | case DCB_CONNECTOR_HDMI_1 : |
1268 | case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA; |
1269 | case DCB_CONNECTOR_WFD : return DRM_MODE_CONNECTOR_VIRTUAL; |
1270 | default: |
1271 | break; |
1272 | } |
1273 | |
1274 | return DRM_MODE_CONNECTOR_Unknown; |
1275 | } |
1276 | |
1277 | struct drm_connector * |
1278 | nouveau_connector_create(struct drm_device *dev, int index) |
1279 | { |
1280 | struct nouveau_drm *drm = nouveau_drm(dev); |
1281 | struct nouveau_display *disp = nouveau_display(dev); |
1282 | struct nouveau_connector *nv_connector = NULL; |
1283 | struct drm_connector *connector; |
1284 | struct drm_connector_list_iter conn_iter; |
1285 | int type, ret = 0; |
1286 | bool dummy; |
1287 | |
1288 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
1289 | nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { |
1290 | nv_connector = nouveau_connector(con: connector); |
1291 | if (nv_connector->index == index) { |
1292 | drm_connector_list_iter_end(iter: &conn_iter); |
1293 | return connector; |
1294 | } |
1295 | } |
1296 | drm_connector_list_iter_end(iter: &conn_iter); |
1297 | |
1298 | nv_connector = kzalloc(size: sizeof(*nv_connector), GFP_KERNEL); |
1299 | if (!nv_connector) |
1300 | return ERR_PTR(error: -ENOMEM); |
1301 | |
1302 | connector = &nv_connector->base; |
1303 | nv_connector->index = index; |
1304 | INIT_WORK(&nv_connector->irq_work, nouveau_dp_irq); |
1305 | |
1306 | if (disp->disp.conn_mask & BIT(nv_connector->index)) { |
1307 | ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index, |
1308 | &nv_connector->conn); |
1309 | if (ret) { |
1310 | kfree(objp: nv_connector); |
1311 | return ERR_PTR(error: ret); |
1312 | } |
1313 | |
1314 | switch (nv_connector->conn.info.type) { |
1315 | case NVIF_CONN_VGA : type = DCB_CONNECTOR_VGA; break; |
1316 | case NVIF_CONN_DVI_I : type = DCB_CONNECTOR_DVI_I; break; |
1317 | case NVIF_CONN_DVI_D : type = DCB_CONNECTOR_DVI_D; break; |
1318 | case NVIF_CONN_LVDS : type = DCB_CONNECTOR_LVDS; break; |
1319 | case NVIF_CONN_LVDS_SPWG: type = DCB_CONNECTOR_LVDS_SPWG; break; |
1320 | case NVIF_CONN_DP : type = DCB_CONNECTOR_DP; break; |
1321 | case NVIF_CONN_EDP : type = DCB_CONNECTOR_eDP; break; |
1322 | case NVIF_CONN_HDMI : type = DCB_CONNECTOR_HDMI_0; break; |
1323 | default: |
1324 | WARN_ON(1); |
1325 | return NULL; |
1326 | } |
1327 | |
1328 | nv_connector->type = type; |
1329 | } else { |
1330 | u8 *dcb = olddcb_conn(dev, idx: nv_connector->index); |
1331 | |
1332 | if (dcb) |
1333 | nv_connector->type = dcb[0]; |
1334 | else |
1335 | nv_connector->type = DCB_CONNECTOR_NONE; |
1336 | |
1337 | /* attempt to parse vbios connector type and hotplug gpio */ |
1338 | if (nv_connector->type != DCB_CONNECTOR_NONE) { |
1339 | if (drm_conntype_from_dcb(dcb: nv_connector->type) == |
1340 | DRM_MODE_CONNECTOR_Unknown) { |
1341 | NV_WARN(drm, "unknown connector type %02x\n" , |
1342 | nv_connector->type); |
1343 | nv_connector->type = DCB_CONNECTOR_NONE; |
1344 | } |
1345 | } |
1346 | |
1347 | /* no vbios data, or an unknown dcb connector type - attempt to |
1348 | * figure out something suitable ourselves |
1349 | */ |
1350 | if (nv_connector->type == DCB_CONNECTOR_NONE && |
1351 | !WARN_ON(drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA)) { |
1352 | struct dcb_table *dcbt = &drm->vbios.dcb; |
1353 | u32 encoders = 0; |
1354 | int i; |
1355 | |
1356 | for (i = 0; i < dcbt->entries; i++) { |
1357 | if (dcbt->entry[i].connector == nv_connector->index) |
1358 | encoders |= (1 << dcbt->entry[i].type); |
1359 | } |
1360 | |
1361 | if (encoders & (1 << DCB_OUTPUT_TMDS)) { |
1362 | if (encoders & (1 << DCB_OUTPUT_ANALOG)) |
1363 | nv_connector->type = DCB_CONNECTOR_DVI_I; |
1364 | else |
1365 | nv_connector->type = DCB_CONNECTOR_DVI_D; |
1366 | } else |
1367 | if (encoders & (1 << DCB_OUTPUT_ANALOG)) { |
1368 | nv_connector->type = DCB_CONNECTOR_VGA; |
1369 | } else |
1370 | if (encoders & (1 << DCB_OUTPUT_LVDS)) { |
1371 | nv_connector->type = DCB_CONNECTOR_LVDS; |
1372 | } else |
1373 | if (encoders & (1 << DCB_OUTPUT_TV)) { |
1374 | nv_connector->type = DCB_CONNECTOR_TV_0; |
1375 | } |
1376 | } |
1377 | } |
1378 | |
1379 | type = drm_conntype_from_dcb(dcb: nv_connector->type); |
1380 | if (type == DRM_MODE_CONNECTOR_LVDS) |
1381 | drm_connector_init(dev, connector, funcs: &nouveau_connector_funcs_lvds, connector_type: type); |
1382 | else |
1383 | drm_connector_init(dev, connector, funcs: &nouveau_connector_funcs, connector_type: type); |
1384 | |
1385 | switch (type) { |
1386 | case DRM_MODE_CONNECTOR_LVDS: |
1387 | ret = nouveau_bios_parse_lvds_table(dev, pxclk: 0, dl: &dummy, if_is_24bit: &dummy); |
1388 | if (ret) { |
1389 | NV_ERROR(drm, "Error parsing LVDS table, disabling\n" ); |
1390 | kfree(objp: nv_connector); |
1391 | return ERR_PTR(error: ret); |
1392 | } |
1393 | |
1394 | break; |
1395 | case DRM_MODE_CONNECTOR_DisplayPort: |
1396 | case DRM_MODE_CONNECTOR_eDP: |
1397 | nv_connector->aux.dev = connector->kdev; |
1398 | nv_connector->aux.drm_dev = dev; |
1399 | nv_connector->aux.transfer = nouveau_connector_aux_xfer; |
1400 | nv_connector->aux.name = connector->name; |
1401 | drm_dp_aux_init(aux: &nv_connector->aux); |
1402 | break; |
1403 | default: |
1404 | break; |
1405 | } |
1406 | |
1407 | /* HDMI 3D support */ |
1408 | if ((disp->disp.object.oclass >= G82_DISP) |
1409 | && ((type == DRM_MODE_CONNECTOR_DisplayPort) |
1410 | || (type == DRM_MODE_CONNECTOR_eDP) |
1411 | || (type == DRM_MODE_CONNECTOR_HDMIA))) |
1412 | connector->stereo_allowed = true; |
1413 | |
1414 | /* defaults, will get overridden in detect() */ |
1415 | connector->interlace_allowed = false; |
1416 | connector->doublescan_allowed = false; |
1417 | |
1418 | drm_connector_helper_add(connector, funcs: &nouveau_connector_helper_funcs); |
1419 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1420 | |
1421 | if (nvif_object_constructed(&nv_connector->conn.object)) { |
1422 | ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug" , |
1423 | nouveau_connector_hotplug, |
1424 | NVIF_CONN_EVENT_V0_PLUG | NVIF_CONN_EVENT_V0_UNPLUG, |
1425 | &nv_connector->hpd); |
1426 | if (ret == 0) |
1427 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
1428 | |
1429 | if (nv_connector->aux.transfer) { |
1430 | ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsDpIrq" , |
1431 | nouveau_connector_irq, NVIF_CONN_EVENT_V0_IRQ, |
1432 | &nv_connector->irq); |
1433 | if (ret) { |
1434 | nvif_event_dtor(&nv_connector->hpd); |
1435 | nvif_conn_dtor(&nv_connector->conn); |
1436 | goto drm_conn_err; |
1437 | } |
1438 | } |
1439 | } |
1440 | |
1441 | connector->funcs->reset(connector); |
1442 | nouveau_conn_attach_properties(connector); |
1443 | |
1444 | /* Default scaling mode */ |
1445 | switch (nv_connector->type) { |
1446 | case DCB_CONNECTOR_LVDS: |
1447 | case DCB_CONNECTOR_LVDS_SPWG: |
1448 | case DCB_CONNECTOR_eDP: |
1449 | /* see note in nouveau_connector_set_property() */ |
1450 | if (disp->disp.object.oclass < NV50_DISP) { |
1451 | nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; |
1452 | break; |
1453 | } |
1454 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; |
1455 | break; |
1456 | default: |
1457 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; |
1458 | break; |
1459 | } |
1460 | |
1461 | /* dithering properties */ |
1462 | switch (nv_connector->type) { |
1463 | case DCB_CONNECTOR_TV_0: |
1464 | case DCB_CONNECTOR_TV_1: |
1465 | case DCB_CONNECTOR_TV_3: |
1466 | case DCB_CONNECTOR_VGA: |
1467 | break; |
1468 | default: |
1469 | nv_connector->dithering_mode = DITHERING_MODE_AUTO; |
1470 | break; |
1471 | } |
1472 | |
1473 | switch (type) { |
1474 | case DRM_MODE_CONNECTOR_DisplayPort: |
1475 | nv_connector->dp_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP); |
1476 | fallthrough; |
1477 | case DRM_MODE_CONNECTOR_eDP: |
1478 | drm_dp_cec_register_connector(aux: &nv_connector->aux, connector); |
1479 | break; |
1480 | } |
1481 | |
1482 | drm_connector_register(connector); |
1483 | return connector; |
1484 | |
1485 | drm_conn_err: |
1486 | drm_connector_cleanup(connector); |
1487 | kfree(objp: nv_connector); |
1488 | return ERR_PTR(error: ret); |
1489 | } |
1490 | |