Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2022-2023 Intel Corporation
  4 *
  5 * High level display driver entry points. This is a layer between top level
  6 * driver code and low level display functionality; no low level display code or
  7 * details here.
  8 */
  9
 10#include <linux/vga_switcheroo.h>
 11#include <acpi/video.h>
 12#include <drm/display/drm_dp_mst_helper.h>
 13#include <drm/drm_atomic_helper.h>
 14#include <drm/drm_mode_config.h>
 15#include <drm/drm_privacy_screen_consumer.h>
 16#include <drm/drm_probe_helper.h>
 17#include <drm/drm_vblank.h>
 18
 19#include "i915_drv.h"
 20#include "i9xx_wm.h"
 21#include "intel_acpi.h"
 22#include "intel_atomic.h"
 23#include "intel_audio.h"
 24#include "intel_bios.h"
 25#include "intel_bw.h"
 26#include "intel_cdclk.h"
 27#include "intel_color.h"
 28#include "intel_crtc.h"
 29#include "intel_display_debugfs.h"
 30#include "intel_display_driver.h"
 31#include "intel_display_irq.h"
 32#include "intel_display_power.h"
 33#include "intel_display_types.h"
 34#include "intel_display_wa.h"
 35#include "intel_dkl_phy.h"
 36#include "intel_dmc.h"
 37#include "intel_dp.h"
 38#include "intel_dpll.h"
 39#include "intel_dpll_mgr.h"
 40#include "intel_fb.h"
 41#include "intel_fbc.h"
 42#include "intel_fbdev.h"
 43#include "intel_fdi.h"
 44#include "intel_gmbus.h"
 45#include "intel_hdcp.h"
 46#include "intel_hotplug.h"
 47#include "intel_hti.h"
 48#include "intel_modeset_setup.h"
 49#include "intel_opregion.h"
 50#include "intel_overlay.h"
 51#include "intel_plane_initial.h"
 52#include "intel_pmdemand.h"
 53#include "intel_pps.h"
 54#include "intel_quirks.h"
 55#include "intel_vga.h"
 56#include "intel_wm.h"
 57#include "skl_watermark.h"
 58
 59bool intel_display_driver_probe_defer(struct pci_dev *pdev)
 60{
 61	struct drm_privacy_screen *privacy_screen;
 62
 63	/*
 64	 * apple-gmux is needed on dual GPU MacBook Pro
 65	 * to probe the panel if we're the inactive GPU.
 66	 */
 67	if (vga_switcheroo_client_probe_defer(pdev))
 68		return true;
 69
 70	/* If the LCD panel has a privacy-screen, wait for it */
 71	privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL);
 72	if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER)
 73		return true;
 74
 75	drm_privacy_screen_put(privacy_screen);
 76
 77	return false;
 78}
 79
 80void intel_display_driver_init_hw(struct drm_i915_private *i915)
 81{
 82	struct intel_cdclk_state *cdclk_state;
 83
 84	if (!HAS_DISPLAY(i915))
 85		return;
 86
 87	cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state);
 88
 89	intel_update_cdclk(i915);
 90	intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");
 91	cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;
 92
 93	intel_display_wa_apply(i915);
 94}
 95
 96static const struct drm_mode_config_funcs intel_mode_funcs = {
 97	.fb_create = intel_user_framebuffer_create,
 98	.get_format_info = intel_fb_get_format_info,
 99	.output_poll_changed = intel_fbdev_output_poll_changed,
100	.mode_valid = intel_mode_valid,
101	.atomic_check = intel_atomic_check,
102	.atomic_commit = intel_atomic_commit,
103	.atomic_state_alloc = intel_atomic_state_alloc,
104	.atomic_state_clear = intel_atomic_state_clear,
105	.atomic_state_free = intel_atomic_state_free,
106};
107
108static const struct drm_mode_config_helper_funcs intel_mode_config_funcs = {
109	.atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
110};
111
112static void intel_mode_config_init(struct drm_i915_private *i915)
113{
114	struct drm_mode_config *mode_config = &i915->drm.mode_config;
115
116	drm_mode_config_init(&i915->drm);
117	INIT_LIST_HEAD(&i915->display.global.obj_list);
118
119	mode_config->min_width = 0;
120	mode_config->min_height = 0;
121
122	mode_config->preferred_depth = 24;
123	mode_config->prefer_shadow = 1;
124
125	mode_config->funcs = &intel_mode_funcs;
126	mode_config->helper_private = &intel_mode_config_funcs;
127
128	mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
129
130	/*
131	 * Maximum framebuffer dimensions, chosen to match
132	 * the maximum render engine surface size on gen4+.
133	 */
134	if (DISPLAY_VER(i915) >= 7) {
135		mode_config->max_width = 16384;
136		mode_config->max_height = 16384;
137	} else if (DISPLAY_VER(i915) >= 4) {
138		mode_config->max_width = 8192;
139		mode_config->max_height = 8192;
140	} else if (DISPLAY_VER(i915) == 3) {
141		mode_config->max_width = 4096;
142		mode_config->max_height = 4096;
143	} else {
144		mode_config->max_width = 2048;
145		mode_config->max_height = 2048;
146	}
147
148	if (IS_I845G(i915) || IS_I865G(i915)) {
149		mode_config->cursor_width = IS_I845G(i915) ? 64 : 512;
150		mode_config->cursor_height = 1023;
151	} else if (IS_I830(i915) || IS_I85X(i915) ||
152		   IS_I915G(i915) || IS_I915GM(i915)) {
153		mode_config->cursor_width = 64;
154		mode_config->cursor_height = 64;
155	} else {
156		mode_config->cursor_width = 256;
157		mode_config->cursor_height = 256;
158	}
159}
160
161static void intel_mode_config_cleanup(struct drm_i915_private *i915)
162{
163	intel_atomic_global_obj_cleanup(i915);
164	drm_mode_config_cleanup(&i915->drm);
165}
166
167static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
168{
169	struct intel_plane *plane;
170
171	for_each_intel_plane(&dev_priv->drm, plane) {
172		struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv,
173							      plane->pipe);
174
175		plane->base.possible_crtcs = drm_crtc_mask(&crtc->base);
176	}
177}
178
179void intel_display_driver_early_probe(struct drm_i915_private *i915)
180{
181	if (!HAS_DISPLAY(i915))
182		return;
183
184	spin_lock_init(&i915->display.fb_tracking.lock);
185	mutex_init(&i915->display.backlight.lock);
186	mutex_init(&i915->display.audio.mutex);
187	mutex_init(&i915->display.wm.wm_mutex);
188	mutex_init(&i915->display.pps.mutex);
189	mutex_init(&i915->display.hdcp.hdcp_mutex);
190
191	intel_display_irq_init(i915);
192	intel_dkl_phy_init(i915);
193	intel_color_init_hooks(i915);
194	intel_init_cdclk_hooks(i915);
195	intel_audio_hooks_init(i915);
196	intel_dpll_init_clock_hook(i915);
197	intel_init_display_hooks(i915);
198	intel_fdi_init_hook(i915);
199}
200
201/* part #1: call before irq install */
202int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
203{
204	int ret;
205
206	if (i915_inject_probe_failure(i915))
207		return -ENODEV;
208
209	if (HAS_DISPLAY(i915)) {
210		ret = drm_vblank_init(&i915->drm,
211				      INTEL_NUM_PIPES(i915));
212		if (ret)
213			return ret;
214	}
215
216	intel_bios_init(i915);
217
218	ret = intel_vga_register(i915);
219	if (ret)
220		goto cleanup_bios;
221
222	/* FIXME: completely on the wrong abstraction layer */
223	ret = intel_power_domains_init(i915);
224	if (ret < 0)
225		goto cleanup_vga;
226
227	intel_pmdemand_init_early(i915);
228
229	intel_power_domains_init_hw(i915, false);
230
231	if (!HAS_DISPLAY(i915))
232		return 0;
233
234	intel_dmc_init(i915);
235
236	i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
237	i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
238						WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
239
240	intel_mode_config_init(i915);
241
242	ret = intel_cdclk_init(i915);
243	if (ret)
244		goto cleanup_vga_client_pw_domain_dmc;
245
246	ret = intel_color_init(i915);
247	if (ret)
248		goto cleanup_vga_client_pw_domain_dmc;
249
250	ret = intel_dbuf_init(i915);
251	if (ret)
252		goto cleanup_vga_client_pw_domain_dmc;
253
254	ret = intel_bw_init(i915);
255	if (ret)
256		goto cleanup_vga_client_pw_domain_dmc;
257
258	ret = intel_pmdemand_init(i915);
259	if (ret)
260		goto cleanup_vga_client_pw_domain_dmc;
261
262	intel_init_quirks(i915);
263
264	intel_fbc_init(i915);
265
266	return 0;
267
268cleanup_vga_client_pw_domain_dmc:
269	intel_dmc_fini(i915);
270	intel_power_domains_driver_remove(i915);
271cleanup_vga:
272	intel_vga_unregister(i915);
273cleanup_bios:
274	intel_bios_driver_remove(i915);
275
276	return ret;
277}
278
279/* part #2: call after irq install, but before gem init */
280int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
281{
282	struct drm_device *dev = &i915->drm;
283	enum pipe pipe;
284	struct intel_crtc *crtc;
285	int ret;
286
287	if (!HAS_DISPLAY(i915))
288		return 0;
289
290	intel_wm_init(i915);
291
292	intel_panel_sanitize_ssc(i915);
293
294	intel_pps_setup(i915);
295
296	intel_gmbus_setup(i915);
297
298	drm_dbg_kms(&i915->drm, "%d display pipe%s available.\n",
299		    INTEL_NUM_PIPES(i915),
300		    INTEL_NUM_PIPES(i915) > 1 ? "s" : "");
301
302	for_each_pipe(i915, pipe) {
303		ret = intel_crtc_init(i915, pipe);
304		if (ret) {
305			intel_mode_config_cleanup(i915);
306			return ret;
307		}
308	}
309
310	intel_plane_possible_crtcs_init(i915);
311	intel_shared_dpll_init(i915);
312	intel_fdi_pll_freq_update(i915);
313
314	intel_update_czclk(i915);
315	intel_display_driver_init_hw(i915);
316	intel_dpll_update_ref_clks(i915);
317
318	intel_hdcp_component_init(i915);
319
320	if (i915->display.cdclk.max_cdclk_freq == 0)
321		intel_update_max_cdclk(i915);
322
323	intel_hti_init(i915);
324
325	/* Just disable it once at startup */
326	intel_vga_disable(i915);
327	intel_setup_outputs(i915);
328
329	drm_modeset_lock_all(dev);
330	intel_modeset_setup_hw_state(i915, dev->mode_config.acquire_ctx);
331	intel_acpi_assign_connector_fwnodes(i915);
332	drm_modeset_unlock_all(dev);
333
334	for_each_intel_crtc(dev, crtc) {
335		if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
336			continue;
337		intel_crtc_initial_plane_config(crtc);
338	}
339
340	/*
341	 * Make sure hardware watermarks really match the state we read out.
342	 * Note that we need to do this after reconstructing the BIOS fb's
343	 * since the watermark calculation done here will use pstate->fb.
344	 */
345	if (!HAS_GMCH(i915))
346		ilk_wm_sanitize(i915);
347
348	return 0;
349}
350
351/* part #3: call after gem init */
352int intel_display_driver_probe(struct drm_i915_private *i915)
353{
354	int ret;
355
356	if (!HAS_DISPLAY(i915))
357		return 0;
358
359	/*
360	 * Force all active planes to recompute their states. So that on
361	 * mode_setcrtc after probe, all the intel_plane_state variables
362	 * are already calculated and there is no assert_plane warnings
363	 * during bootup.
364	 */
365	ret = intel_initial_commit(&i915->drm);
366	if (ret)
367		drm_dbg_kms(&i915->drm, "Initial modeset failed, %d\n", ret);
368
369	intel_overlay_setup(i915);
370
371	ret = intel_fbdev_init(&i915->drm);
372	if (ret)
373		return ret;
374
375	/* Only enable hotplug handling once the fbdev is fully set up. */
376	intel_hpd_init(i915);
377	intel_hpd_poll_disable(i915);
378
379	skl_watermark_ipc_init(i915);
380
381	return 0;
382}
383
384void intel_display_driver_register(struct drm_i915_private *i915)
385{
386	struct drm_printer p = drm_debug_printer("i915 display info:");
387
388	if (!HAS_DISPLAY(i915))
389		return;
390
391	/* Must be done after probing outputs */
392	intel_opregion_register(i915);
393	intel_acpi_video_register(i915);
394
395	intel_audio_init(i915);
396
397	intel_display_debugfs_register(i915);
398
399	/*
400	 * Some ports require correctly set-up hpd registers for
401	 * detection to work properly (leading to ghost connected
402	 * connector status), e.g. VGA on gm45.  Hence we can only set
403	 * up the initial fbdev config after hpd irqs are fully
404	 * enabled. We do it last so that the async config cannot run
405	 * before the connectors are registered.
406	 */
407	intel_fbdev_initial_config_async(i915);
408
409	/*
410	 * We need to coordinate the hotplugs with the asynchronous
411	 * fbdev configuration, for which we use the
412	 * fbdev->async_cookie.
413	 */
414	drm_kms_helper_poll_init(&i915->drm);
415
416	intel_display_device_info_print(DISPLAY_INFO(i915),
417					DISPLAY_RUNTIME_INFO(i915), &p);
418}
419
420/* part #1: call before irq uninstall */
421void intel_display_driver_remove(struct drm_i915_private *i915)
422{
423	if (!HAS_DISPLAY(i915))
424		return;
425
426	flush_workqueue(i915->display.wq.flip);
427	flush_workqueue(i915->display.wq.modeset);
428
429	/*
430	 * MST topology needs to be suspended so we don't have any calls to
431	 * fbdev after it's finalized. MST will be destroyed later as part of
432	 * drm_mode_config_cleanup()
433	 */
434	intel_dp_mst_suspend(i915);
435}
436
437/* part #2: call after irq uninstall */
438void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
439{
440	if (!HAS_DISPLAY(i915))
441		return;
442
443	/*
444	 * Due to the hpd irq storm handling the hotplug work can re-arm the
445	 * poll handlers. Hence disable polling after hpd handling is shut down.
446	 */
447	intel_hpd_poll_fini(i915);
448
449	/* poll work can call into fbdev, hence clean that up afterwards */
450	intel_fbdev_fini(i915);
451
452	intel_unregister_dsm_handler();
453
454	/* flush any delayed tasks or pending work */
455	flush_workqueue(i915->unordered_wq);
456
457	intel_hdcp_component_fini(i915);
458
459	intel_mode_config_cleanup(i915);
460
461	intel_overlay_cleanup(i915);
462
463	intel_gmbus_teardown(i915);
464
465	destroy_workqueue(i915->display.wq.flip);
466	destroy_workqueue(i915->display.wq.modeset);
467
468	intel_fbc_cleanup(i915);
469}
470
471/* part #3: call after gem init */
472void intel_display_driver_remove_nogem(struct drm_i915_private *i915)
473{
474	intel_dmc_fini(i915);
475
476	intel_power_domains_driver_remove(i915);
477
478	intel_vga_unregister(i915);
479
480	intel_bios_driver_remove(i915);
481}
482
483void intel_display_driver_unregister(struct drm_i915_private *i915)
484{
485	if (!HAS_DISPLAY(i915))
486		return;
487
488	intel_fbdev_unregister(i915);
489	intel_audio_deinit(i915);
490
491	/*
492	 * After flushing the fbdev (incl. a late async config which
493	 * will have delayed queuing of a hotplug event), then flush
494	 * the hotplug events.
495	 */
496	drm_kms_helper_poll_fini(&i915->drm);
497	drm_atomic_helper_shutdown(&i915->drm);
498
499	acpi_video_unregister();
500	intel_opregion_unregister(i915);
501}
502
503/*
504 * turn all crtc's off, but do not adjust state
505 * This has to be paired with a call to intel_modeset_setup_hw_state.
506 */
507int intel_display_driver_suspend(struct drm_i915_private *i915)
508{
509	struct drm_atomic_state *state;
510	int ret;
511
512	if (!HAS_DISPLAY(i915))
513		return 0;
514
515	state = drm_atomic_helper_suspend(&i915->drm);
516	ret = PTR_ERR_OR_ZERO(state);
517	if (ret)
518		drm_err(&i915->drm, "Suspending crtc's failed with %i\n",
519			ret);
520	else
521		i915->display.restore.modeset_state = state;
522	return ret;
523}
524
525int
526__intel_display_driver_resume(struct drm_i915_private *i915,
527			      struct drm_atomic_state *state,
528			      struct drm_modeset_acquire_ctx *ctx)
529{
530	struct drm_crtc_state *crtc_state;
531	struct drm_crtc *crtc;
532	int ret, i;
533
534	intel_modeset_setup_hw_state(i915, ctx);
535	intel_vga_redisable(i915);
536
537	if (!state)
538		return 0;
539
540	/*
541	 * We've duplicated the state, pointers to the old state are invalid.
542	 *
543	 * Don't attempt to use the old state until we commit the duplicated state.
544	 */
545	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
546		/*
547		 * Force recalculation even if we restore
548		 * current state. With fast modeset this may not result
549		 * in a modeset when the state is compatible.
550		 */
551		crtc_state->mode_changed = true;
552	}
553
554	/* ignore any reset values/BIOS leftovers in the WM registers */
555	if (!HAS_GMCH(i915))
556		to_intel_atomic_state(state)->skip_intermediate_wm = true;
557
558	ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
559
560	drm_WARN_ON(&i915->drm, ret == -EDEADLK);
561
562	return ret;
563}
564
565void intel_display_driver_resume(struct drm_i915_private *i915)
566{
567	struct drm_atomic_state *state = i915->display.restore.modeset_state;
568	struct drm_modeset_acquire_ctx ctx;
569	int ret;
570
571	if (!HAS_DISPLAY(i915))
572		return;
573
574	i915->display.restore.modeset_state = NULL;
575	if (state)
576		state->acquire_ctx = &ctx;
577
578	drm_modeset_acquire_init(&ctx, 0);
579
580	while (1) {
581		ret = drm_modeset_lock_all_ctx(&i915->drm, &ctx);
582		if (ret != -EDEADLK)
583			break;
584
585		drm_modeset_backoff(&ctx);
586	}
587
588	if (!ret)
589		ret = __intel_display_driver_resume(i915, state, &ctx);
590
591	skl_watermark_ipc_update(i915);
592	drm_modeset_drop_locks(&ctx);
593	drm_modeset_acquire_fini(&ctx);
594
595	if (ret)
596		drm_err(&i915->drm,
597			"Restoring old state failed with %i\n", ret);
598	if (state)
599		drm_atomic_state_put(state);
600}