DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2006-2007 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*
|
|
|
|
|
* Authors:
|
|
|
|
|
* Eric Anholt <eric@anholt.net>
|
|
|
|
|
*/
|
|
|
|
|
|
2021-02-12 20:27:55 -08:00
|
|
|
#include <acpi/video.h>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
#include <linux/i2c.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
#include <linux/input.h>
|
|
|
|
|
#include <linux/intel-iommu.h>
|
2009-06-26 11:23:55 +08:00
|
|
|
#include <linux/kernel.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
#include <linux/module.h>
|
2019-08-11 10:06:32 +02:00
|
|
|
#include <linux/dma-resv.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 17:04:11 +09:00
|
|
|
#include <linux/slab.h>
|
2022-02-25 15:46:28 -08:00
|
|
|
#include <linux/string_helpers.h>
|
2021-10-05 22:23:21 +02:00
|
|
|
#include <linux/vga_switcheroo.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
|
2022-04-21 09:31:02 +02:00
|
|
|
#include <drm/display/drm_dp_helper.h>
|
2015-03-12 20:16:32 +08:00
|
|
|
#include <drm/drm_atomic.h>
|
2015-01-21 16:35:48 -08:00
|
|
|
#include <drm/drm_atomic_helper.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
#include <drm/drm_atomic_uapi.h>
|
2020-06-25 18:01:47 -07:00
|
|
|
#include <drm/drm_damage_helper.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
#include <drm/drm_edid.h>
|
|
|
|
|
#include <drm/drm_fourcc.h>
|
2014-05-29 08:06:54 -07:00
|
|
|
#include <drm/drm_plane_helper.h>
|
2021-10-05 22:23:22 +02:00
|
|
|
#include <drm/drm_privacy_screen_consumer.h>
|
2019-01-17 22:03:34 +01:00
|
|
|
#include <drm/drm_probe_helper.h>
|
2014-05-29 08:06:54 -07:00
|
|
|
#include <drm/drm_rect.h>
|
2019-01-26 13:25:24 +01:00
|
|
|
|
2021-02-12 20:27:55 -08:00
|
|
|
#include "display/intel_audio.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
#include "display/intel_crt.h"
|
|
|
|
|
#include "display/intel_ddi.h"
|
2020-12-02 21:28:14 +00:00
|
|
|
#include "display/intel_display_debugfs.h"
|
2022-04-15 00:06:53 +03:00
|
|
|
#include "display/intel_display_power.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
#include "display/intel_dp.h"
|
2019-12-22 17:06:49 -08:00
|
|
|
#include "display/intel_dp_mst.h"
|
2021-01-14 13:13:46 +02:00
|
|
|
#include "display/intel_dpll.h"
|
2020-07-16 15:05:50 -07:00
|
|
|
#include "display/intel_dpll_mgr.h"
|
2021-09-03 15:10:36 -07:00
|
|
|
#include "display/intel_drrs.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
#include "display/intel_dsi.h"
|
|
|
|
|
#include "display/intel_dvo.h"
|
2021-03-25 23:47:49 +02:00
|
|
|
#include "display/intel_fb.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
#include "display/intel_gmbus.h"
|
|
|
|
|
#include "display/intel_hdmi.h"
|
|
|
|
|
#include "display/intel_lvds.h"
|
|
|
|
|
#include "display/intel_sdvo.h"
|
2021-07-23 10:42:32 -07:00
|
|
|
#include "display/intel_snps_phy.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
#include "display/intel_tv.h"
|
|
|
|
|
#include "display/intel_vdsc.h"
|
2021-01-22 15:26:35 -08:00
|
|
|
#include "display/intel_vrr.h"
|
2019-06-13 11:44:15 +03:00
|
|
|
|
2021-05-06 19:19:24 +03:00
|
|
|
#include "gem/i915_gem_lmem.h"
|
2021-01-15 23:39:52 +02:00
|
|
|
#include "gem/i915_gem_object.h"
|
|
|
|
|
|
2021-05-06 19:19:24 +03:00
|
|
|
#include "gt/gen8_ppgtt.h"
|
2019-10-24 22:16:41 +01:00
|
|
|
|
2021-03-18 18:10:13 +02:00
|
|
|
#include "g4x_dp.h"
|
2021-03-18 18:10:14 +02:00
|
|
|
#include "g4x_hdmi.h"
|
2022-02-09 13:35:23 +02:00
|
|
|
#include "hsw_ips.h"
|
2019-01-26 13:25:24 +01:00
|
|
|
#include "i915_drv.h"
|
2022-03-29 10:02:04 +01:00
|
|
|
#include "i915_utils.h"
|
2021-11-22 13:15:04 +02:00
|
|
|
#include "icl_dsi.h"
|
2019-05-02 18:02:42 +03:00
|
|
|
#include "intel_acpi.h"
|
2019-04-29 15:53:31 +03:00
|
|
|
#include "intel_atomic.h"
|
2019-04-05 14:00:19 +03:00
|
|
|
#include "intel_atomic_plane.h"
|
2019-05-24 18:36:14 +03:00
|
|
|
#include "intel_bw.h"
|
2019-04-05 14:00:25 +03:00
|
|
|
#include "intel_cdclk.h"
|
2019-08-06 14:39:33 +03:00
|
|
|
#include "intel_color.h"
|
2021-01-14 13:13:45 +02:00
|
|
|
#include "intel_crtc.h"
|
2022-06-16 12:48:16 +03:00
|
|
|
#include "intel_crtc_state_dump.h"
|
2021-04-30 17:39:44 +03:00
|
|
|
#include "intel_de.h"
|
2019-08-06 14:39:33 +03:00
|
|
|
#include "intel_display_types.h"
|
2021-05-18 14:34:44 -07:00
|
|
|
#include "intel_dmc.h"
|
2019-10-29 12:39:47 +02:00
|
|
|
#include "intel_dp_link_training.h"
|
2021-08-23 15:25:31 +03:00
|
|
|
#include "intel_dpt.h"
|
2019-04-05 14:00:08 +03:00
|
|
|
#include "intel_fbc.h"
|
2019-04-05 14:00:16 +03:00
|
|
|
#include "intel_fbdev.h"
|
2021-10-14 13:28:57 +03:00
|
|
|
#include "intel_fdi.h"
|
2019-04-29 15:29:24 +03:00
|
|
|
#include "intel_fifo_underrun.h"
|
2019-01-26 13:25:24 +01:00
|
|
|
#include "intel_frontbuffer.h"
|
2019-04-05 14:00:13 +03:00
|
|
|
#include "intel_hdcp.h"
|
2019-04-29 15:50:11 +03:00
|
|
|
#include "intel_hotplug.h"
|
2022-06-16 12:48:15 +03:00
|
|
|
#include "intel_modeset_verify.h"
|
2022-06-17 12:48:16 +03:00
|
|
|
#include "intel_modeset_setup.h"
|
2019-04-29 15:29:31 +03:00
|
|
|
#include "intel_overlay.h"
|
2021-08-18 13:11:08 +03:00
|
|
|
#include "intel_panel.h"
|
2021-10-15 10:16:18 +03:00
|
|
|
#include "intel_pch_display.h"
|
2021-10-15 10:16:17 +03:00
|
|
|
#include "intel_pch_refclk.h"
|
2021-10-14 13:28:57 +03:00
|
|
|
#include "intel_pcode.h"
|
2019-04-05 14:00:20 +03:00
|
|
|
#include "intel_pipe_crc.h"
|
2021-10-12 14:34:58 +10:00
|
|
|
#include "intel_plane_initial.h"
|
2019-04-05 14:00:15 +03:00
|
|
|
#include "intel_pm.h"
|
2021-01-20 12:18:32 +02:00
|
|
|
#include "intel_pps.h"
|
2019-04-05 14:00:09 +03:00
|
|
|
#include "intel_psr.h"
|
2019-04-29 15:29:30 +03:00
|
|
|
#include "intel_quirks.h"
|
2019-04-05 14:00:24 +03:00
|
|
|
#include "intel_sprite.h"
|
2019-06-28 17:36:25 +03:00
|
|
|
#include "intel_tc.h"
|
2019-10-01 18:25:06 +03:00
|
|
|
#include "intel_vga.h"
|
2020-12-21 13:09:57 +02:00
|
|
|
#include "i9xx_plane.h"
|
2021-02-05 16:48:42 +02:00
|
|
|
#include "skl_scaler.h"
|
2021-02-05 16:48:36 +02:00
|
|
|
#include "skl_universal_plane.h"
|
2022-02-18 00:40:22 +02:00
|
|
|
#include "vlv_dsi.h"
|
2021-11-22 13:15:02 +02:00
|
|
|
#include "vlv_dsi_pll.h"
|
2022-02-18 00:40:22 +02:00
|
|
|
#include "vlv_dsi_regs.h"
|
2021-10-13 13:11:59 +03:00
|
|
|
#include "vlv_sideband.h"
|
2017-08-01 09:58:16 -07:00
|
|
|
|
2020-10-08 14:45:26 -07:00
|
|
|
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
|
2018-10-04 11:45:54 +02:00
|
|
|
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
|
2021-09-13 17:44:29 +03:00
|
|
|
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
|
2019-04-12 21:30:08 +03:00
|
|
|
static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state);
|
2019-12-24 00:40:09 -08:00
|
|
|
static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
|
2013-08-08 22:28:59 +01:00
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
/**
|
|
|
|
|
* intel_update_watermarks - update FIFO watermark values based on current modes
|
|
|
|
|
* @dev_priv: i915 device
|
|
|
|
|
*
|
|
|
|
|
* Calculate watermark values for the various WM regs based on current mode
|
|
|
|
|
* and plane configuration.
|
|
|
|
|
*
|
|
|
|
|
* There are several cases to deal with here:
|
|
|
|
|
* - normal (i.e. non-self-refresh)
|
|
|
|
|
* - self-refresh (SR) mode
|
|
|
|
|
* - lines are large relative to FIFO size (buffer can hold up to 2)
|
|
|
|
|
* - lines are small relative to FIFO size (buffer can hold more than 2
|
|
|
|
|
* lines), so need to account for TLB latency
|
|
|
|
|
*
|
|
|
|
|
* The normal calculation is:
|
|
|
|
|
* watermark = dotclock * bytes per pixel * latency
|
|
|
|
|
* where latency is platform & configuration dependent (we assume pessimal
|
|
|
|
|
* values here).
|
|
|
|
|
*
|
|
|
|
|
* The SR calculation is:
|
|
|
|
|
* watermark = (trunc(latency/line time)+1) * surface width *
|
|
|
|
|
* bytes per pixel
|
|
|
|
|
* where
|
|
|
|
|
* line time = htotal / dotclock
|
|
|
|
|
* surface width = hdisplay for normal plane and 64 for cursor
|
|
|
|
|
* and latency is assumed to be high, as above.
|
|
|
|
|
*
|
|
|
|
|
* The final value programmed to the register should always be rounded up,
|
|
|
|
|
* and include an extra 2 entries to account for clock crossings.
|
|
|
|
|
*
|
|
|
|
|
* We don't use the sprite, so we can ignore that. And on Crestline we have
|
|
|
|
|
* to set the non-SR watermarks to 8.
|
|
|
|
|
*/
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_update_watermarks(struct drm_i915_private *dev_priv)
|
2021-09-29 01:57:48 +03:00
|
|
|
{
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->update_wm)
|
|
|
|
|
dev_priv->display.funcs.wm->update_wm(dev_priv);
|
2021-09-29 01:57:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int intel_compute_pipe_wm(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->compute_pipe_wm)
|
|
|
|
|
return dev_priv->display.funcs.wm->compute_pipe_wm(state, crtc);
|
2021-09-29 01:57:48 +03:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int intel_compute_intermediate_wm(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (!dev_priv->display.funcs.wm->compute_intermediate_wm)
|
2021-09-29 01:57:48 +03:00
|
|
|
return 0;
|
|
|
|
|
if (drm_WARN_ON(&dev_priv->drm,
|
2022-08-24 16:15:31 +03:00
|
|
|
!dev_priv->display.funcs.wm->compute_pipe_wm))
|
2021-09-29 01:57:48 +03:00
|
|
|
return 0;
|
2022-08-24 16:15:31 +03:00
|
|
|
return dev_priv->display.funcs.wm->compute_intermediate_wm(state, crtc);
|
2021-09-29 01:57:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool intel_initial_watermarks(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->initial_watermarks) {
|
|
|
|
|
dev_priv->display.funcs.wm->initial_watermarks(state, crtc);
|
2021-09-29 01:57:48 +03:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_atomic_update_watermarks(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->atomic_update_watermarks)
|
|
|
|
|
dev_priv->display.funcs.wm->atomic_update_watermarks(state, crtc);
|
2021-09-29 01:57:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_optimize_watermarks(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->optimize_watermarks)
|
|
|
|
|
dev_priv->display.funcs.wm->optimize_watermarks(state, crtc);
|
2021-09-29 01:57:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int intel_compute_global_watermarks(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2022-08-24 16:15:31 +03:00
|
|
|
if (dev_priv->display.funcs.wm->compute_global_watermarks)
|
|
|
|
|
return dev_priv->display.funcs.wm->compute_global_watermarks(state);
|
2021-09-29 01:57:48 +03:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-24 23:29:18 +03:00
|
|
|
/* returns HPLL frequency in kHz */
|
2017-02-07 20:33:45 +02:00
|
|
|
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
|
2015-09-24 23:29:18 +03:00
|
|
|
{
|
|
|
|
|
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
|
|
|
|
|
|
|
|
|
|
/* Obtain SKU information */
|
|
|
|
|
hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
|
|
|
|
|
CCK_FUSE_HPLL_FREQ_MASK;
|
|
|
|
|
|
|
|
|
|
return vco_freq[hpll_freq] * 1000;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 21:43:02 +02:00
|
|
|
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
|
|
|
|
|
const char *name, u32 reg, int ref_freq)
|
2015-09-24 23:29:18 +03:00
|
|
|
{
|
|
|
|
|
u32 val;
|
|
|
|
|
int divider;
|
|
|
|
|
|
|
|
|
|
val = vlv_cck_read(dev_priv, reg);
|
|
|
|
|
divider = val & CCK_FREQUENCY_VALUES;
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN(&dev_priv->drm, (val & CCK_FREQUENCY_STATUS) !=
|
|
|
|
|
(divider << CCK_FREQUENCY_STATUS_SHIFT),
|
|
|
|
|
"%s change in progress\n", name);
|
2015-09-24 23:29:18 +03:00
|
|
|
|
2016-03-04 21:43:02 +02:00
|
|
|
return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
|
|
|
|
|
const char *name, u32 reg)
|
2016-03-04 21:43:02 +02:00
|
|
|
{
|
2019-04-26 09:17:20 +01:00
|
|
|
int hpll;
|
|
|
|
|
|
|
|
|
|
vlv_cck_get(dev_priv);
|
|
|
|
|
|
2016-03-04 21:43:02 +02:00
|
|
|
if (dev_priv->hpll_freq == 0)
|
2017-02-07 20:33:45 +02:00
|
|
|
dev_priv->hpll_freq = vlv_get_hpll_vco(dev_priv);
|
2016-03-04 21:43:02 +02:00
|
|
|
|
2019-04-26 09:17:20 +01:00
|
|
|
hpll = vlv_get_cck_clock(dev_priv, name, reg, dev_priv->hpll_freq);
|
|
|
|
|
|
|
|
|
|
vlv_cck_put(dev_priv);
|
|
|
|
|
|
|
|
|
|
return hpll;
|
2015-09-24 23:29:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_update_czclk(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
2015-12-09 12:29:35 -08:00
|
|
|
if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)))
|
2015-09-24 23:29:18 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
|
|
|
|
|
CCK_CZ_CLOCK_CONTROL);
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg(&dev_priv->drm, "CZ clock rate: %d kHz\n",
|
|
|
|
|
dev_priv->czclk_freq);
|
2015-09-24 23:29:18 +03:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 17:06:58 +05:30
|
|
|
static bool is_hdr_mode(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
return (crtc_state->active_planes &
|
|
|
|
|
~(icl_hdr_plane_mask() | BIT(PLANE_CURSOR))) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-17 11:59:01 -07:00
|
|
|
/* WA Display #0827: Gen9:all */
|
2018-04-09 09:11:09 +05:30
|
|
|
static void
|
2019-08-21 20:30:31 +03:00
|
|
|
skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable)
|
2018-04-09 09:11:09 +05:30
|
|
|
{
|
|
|
|
|
if (enable)
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe),
|
|
|
|
|
intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) | DUPS1_GATING_DIS | DUPS2_GATING_DIS);
|
2018-04-09 09:11:09 +05:30
|
|
|
else
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe),
|
|
|
|
|
intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS));
|
2018-04-09 09:11:09 +05:30
|
|
|
}
|
|
|
|
|
|
2020-04-13 13:53:22 -04:00
|
|
|
/* Wa_2006604312:icl,ehl */
|
2019-04-17 11:59:01 -07:00
|
|
|
static void
|
|
|
|
|
icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
|
|
|
bool enable)
|
|
|
|
|
{
|
|
|
|
|
if (enable)
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe),
|
|
|
|
|
intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) | DPFR_GATING_DIS);
|
2019-04-17 11:59:01 -07:00
|
|
|
else
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe),
|
|
|
|
|
intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~DPFR_GATING_DIS);
|
2019-04-17 11:59:01 -07:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 10:54:42 +05:30
|
|
|
/* Wa_1604331009:icl,jsl,ehl */
|
|
|
|
|
static void
|
|
|
|
|
icl_wa_cursorclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
|
|
|
bool enable)
|
|
|
|
|
{
|
|
|
|
|
intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), CURSOR_GATING_DIS,
|
|
|
|
|
enable ? CURSOR_GATING_DIS : 0);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 18:48:31 +02:00
|
|
|
static bool
|
|
|
|
|
is_trans_port_sync_slave(const struct intel_crtc_state *crtc_state)
|
2019-10-18 10:27:20 -07:00
|
|
|
{
|
2020-03-13 18:48:31 +02:00
|
|
|
return crtc_state->master_transcoder != INVALID_TRANSCODER;
|
2019-10-18 10:27:20 -07:00
|
|
|
}
|
|
|
|
|
|
2019-12-05 13:03:50 -08:00
|
|
|
static bool
|
2020-03-13 18:48:31 +02:00
|
|
|
is_trans_port_sync_master(const struct intel_crtc_state *crtc_state)
|
2019-12-05 13:03:50 -08:00
|
|
|
{
|
2020-03-13 18:48:31 +02:00
|
|
|
return crtc_state->sync_mode_slaves_mask != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
return is_trans_port_sync_master(crtc_state) ||
|
|
|
|
|
is_trans_port_sync_slave(crtc_state);
|
2019-12-05 13:03:50 -08:00
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
return ffs(crtc_state->bigjoiner_pipes) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2022-02-23 15:13:03 +02:00
|
|
|
if (crtc_state->bigjoiner_pipes)
|
|
|
|
|
return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2022-02-03 20:38:23 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
|
|
|
|
|
return crtc_state->bigjoiner_pipes &&
|
|
|
|
|
crtc->pipe != bigjoiner_master_pipe(crtc_state);
|
2022-02-03 20:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
|
|
|
|
|
return crtc_state->bigjoiner_pipes &&
|
|
|
|
|
crtc->pipe == bigjoiner_master_pipe(crtc_state);
|
2022-02-03 20:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:14 +02:00
|
|
|
static int intel_bigjoiner_num_pipes(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
return hweight8(crtc_state->bigjoiner_pipes);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state)
|
2021-10-22 13:32:59 +03:00
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
|
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(crtc_state))
|
2022-02-03 20:38:23 +02:00
|
|
|
return intel_crtc_for_pipe(i915, bigjoiner_master_pipe(crtc_state));
|
2021-10-22 13:32:59 +03:00
|
|
|
else
|
|
|
|
|
return to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-29 17:37:30 +02:00
|
|
|
static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum pipe pipe)
|
2013-10-11 14:21:31 +03:00
|
|
|
{
|
drm/i915: Type safe register read/write
Make I915_READ and I915_WRITE more type safe by wrapping the register
offset in a struct. This should eliminate most of the fumbles we've had
with misplaced parens.
This only takes care of normal mmio registers. We could extend the idea
to other register types and define each with its own struct. That way
you wouldn't be able to accidentally pass the wrong thing to a specific
register access function.
The gpio_reg setup is probably the ugliest thing left. But I figure I'd
just leave it for now, and wait for some divine inspiration to strike
before making it nice.
As for the generated code, it's actually a bit better sometimes. Eg.
looking at i915_irq_handler(), we can see the following change:
lea 0x70024(%rdx,%rax,1),%r9d
mov $0x1,%edx
- movslq %r9d,%r9
- mov %r9,%rsi
- mov %r9,-0x58(%rbp)
- callq *0xd8(%rbx)
+ mov %r9d,%esi
+ mov %r9d,-0x48(%rbp)
callq *0xd8(%rbx)
So previously gcc thought the register offset might be signed and
decided to sign extend it, just in case. The rest appears to be
mostly just minor shuffling of instructions.
v2: i915_mmio_reg_{offset,equal,valid}() helpers added
s/_REG/_MMIO/ in the register defines
mo more switch statements left to worry about
ring_emit stuff got sorted in a prep patch
cmd parser, lrc context and w/a batch buildup also in prep patch
vgpu stuff cleaned up and moved to a prep patch
all other unrelated changes split out
v3: Rebased due to BXT DSI/BLC, MOCS, etc.
v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
|
|
|
i915_reg_t reg = PIPEDSL(pipe);
|
2013-10-11 14:21:31 +03:00
|
|
|
u32 line1, line2;
|
|
|
|
|
|
2021-11-12 21:38:05 +02:00
|
|
|
line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
|
2015-07-07 09:10:40 +02:00
|
|
|
msleep(5);
|
2021-11-12 21:38:05 +02:00
|
|
|
line2 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
|
2013-10-11 14:21:31 +03:00
|
|
|
|
2017-11-29 17:37:30 +02:00
|
|
|
return line1 != line2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void wait_for_pipe_scanline_moving(struct intel_crtc *crtc, bool state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
|
|
|
|
/* Wait for the display line to settle/start moving */
|
|
|
|
|
if (wait_for(pipe_scanline_is_moving(dev_priv, pipe) == state, 100))
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm,
|
|
|
|
|
"pipe %c scanline %s wait timed out\n",
|
2022-02-25 15:46:31 -08:00
|
|
|
pipe_name(pipe), str_on_off(state));
|
2017-11-29 17:37:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
wait_for_pipe_scanline_moving(crtc, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
wait_for_pipe_scanline_moving(crtc, true);
|
2013-10-11 14:21:31 +03:00
|
|
|
}
|
|
|
|
|
|
2017-11-29 17:37:32 +02:00
|
|
|
static void
|
|
|
|
|
intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
|
2010-08-18 13:20:54 -07:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2010-10-03 00:33:06 -07:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 4) {
|
2017-11-29 17:37:32 +02:00
|
|
|
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
|
2010-10-03 00:33:06 -07:00
|
|
|
|
|
|
|
|
/* Wait for the Pipe State to go off */
|
2021-11-12 21:38:08 +02:00
|
|
|
if (intel_de_wait_for_clear(dev_priv, PIPECONF(cpu_transcoder),
|
|
|
|
|
PIPECONF_STATE_ENABLE, 100))
|
|
|
|
|
drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n");
|
2010-10-03 00:33:06 -07:00
|
|
|
} else {
|
2017-11-29 17:37:30 +02:00
|
|
|
intel_wait_for_pipe_scanline_stopped(crtc);
|
2010-10-03 00:33:06 -07:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
void assert_transcoder(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum transcoder cpu_transcoder, bool state)
|
2011-01-04 15:09:30 -08:00
|
|
|
{
|
2011-01-04 15:09:33 -08:00
|
|
|
bool cur_state;
|
2016-02-12 18:55:14 +02:00
|
|
|
enum intel_display_power_domain power_domain;
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_wakeref_t wakeref;
|
2011-01-04 15:09:30 -08:00
|
|
|
|
2017-06-01 17:36:19 +03:00
|
|
|
/* we keep both pipes enabled on 830 */
|
|
|
|
|
if (IS_I830(dev_priv))
|
2012-01-22 01:36:48 +01:00
|
|
|
state = true;
|
|
|
|
|
|
2016-02-12 18:55:14 +02:00
|
|
|
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
|
2019-01-14 14:21:24 +00:00
|
|
|
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
|
|
|
|
if (wakeref) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
u32 val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
|
2013-01-29 16:35:19 -02:00
|
|
|
cur_state = !!(val & PIPECONF_ENABLE);
|
2016-02-12 18:55:14 +02:00
|
|
|
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_display_power_put(dev_priv, power_domain, wakeref);
|
2016-02-12 18:55:14 +02:00
|
|
|
} else {
|
|
|
|
|
cur_state = false;
|
2013-01-29 16:35:19 -02:00
|
|
|
}
|
|
|
|
|
|
2014-12-15 13:56:32 -05:00
|
|
|
I915_STATE_WARN(cur_state != state,
|
2019-11-12 18:38:12 +02:00
|
|
|
"transcoder %s assertion failure (expected %s, current %s)\n",
|
|
|
|
|
transcoder_name(cpu_transcoder),
|
2022-02-25 15:46:31 -08:00
|
|
|
str_on_off(state), str_on_off(cur_state));
|
2011-01-04 15:09:30 -08:00
|
|
|
}
|
|
|
|
|
|
2017-11-17 21:19:08 +02:00
|
|
|
static void assert_plane(struct intel_plane *plane, bool state)
|
2011-01-04 15:09:30 -08:00
|
|
|
{
|
2018-01-30 22:38:03 +02:00
|
|
|
enum pipe pipe;
|
|
|
|
|
bool cur_state;
|
|
|
|
|
|
|
|
|
|
cur_state = plane->get_hw_state(plane, &pipe);
|
2011-01-04 15:09:30 -08:00
|
|
|
|
2014-12-15 13:56:32 -05:00
|
|
|
I915_STATE_WARN(cur_state != state,
|
2017-11-17 21:19:08 +02:00
|
|
|
"%s assertion failure (expected %s, current %s)\n",
|
2022-02-25 15:46:31 -08:00
|
|
|
plane->base.name, str_on_off(state),
|
|
|
|
|
str_on_off(cur_state));
|
2011-01-04 15:09:30 -08:00
|
|
|
}
|
|
|
|
|
|
2017-11-17 21:19:08 +02:00
|
|
|
#define assert_plane_enabled(p) assert_plane(p, true)
|
|
|
|
|
#define assert_plane_disabled(p) assert_plane(p, false)
|
2012-01-16 23:01:13 +00:00
|
|
|
|
2017-11-17 21:19:08 +02:00
|
|
|
static void assert_planes_disabled(struct intel_crtc *crtc)
|
2011-01-04 15:09:30 -08:00
|
|
|
{
|
2017-11-17 21:19:08 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
struct intel_plane *plane;
|
2013-03-28 09:55:38 -07:00
|
|
|
|
2017-11-17 21:19:08 +02:00
|
|
|
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane)
|
|
|
|
|
assert_plane_disabled(plane);
|
2013-03-28 09:55:38 -07:00
|
|
|
}
|
|
|
|
|
|
2013-11-06 14:36:35 +08:00
|
|
|
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
|
2020-06-30 21:50:54 -07:00
|
|
|
struct intel_digital_port *dig_port,
|
2015-04-10 18:21:31 +03:00
|
|
|
unsigned int expected_mask)
|
2013-04-18 14:51:36 -07:00
|
|
|
{
|
|
|
|
|
u32 port_mask;
|
drm/i915: Type safe register read/write
Make I915_READ and I915_WRITE more type safe by wrapping the register
offset in a struct. This should eliminate most of the fumbles we've had
with misplaced parens.
This only takes care of normal mmio registers. We could extend the idea
to other register types and define each with its own struct. That way
you wouldn't be able to accidentally pass the wrong thing to a specific
register access function.
The gpio_reg setup is probably the ugliest thing left. But I figure I'd
just leave it for now, and wait for some divine inspiration to strike
before making it nice.
As for the generated code, it's actually a bit better sometimes. Eg.
looking at i915_irq_handler(), we can see the following change:
lea 0x70024(%rdx,%rax,1),%r9d
mov $0x1,%edx
- movslq %r9d,%r9
- mov %r9,%rsi
- mov %r9,-0x58(%rbp)
- callq *0xd8(%rbx)
+ mov %r9d,%esi
+ mov %r9d,-0x48(%rbp)
callq *0xd8(%rbx)
So previously gcc thought the register offset might be signed and
decided to sign extend it, just in case. The rest appears to be
mostly just minor shuffling of instructions.
v2: i915_mmio_reg_{offset,equal,valid}() helpers added
s/_REG/_MMIO/ in the register defines
mo more switch statements left to worry about
ring_emit stuff got sorted in a prep patch
cmd parser, lrc context and w/a batch buildup also in prep patch
vgpu stuff cleaned up and moved to a prep patch
all other unrelated changes split out
v3: Rebased due to BXT DSI/BLC, MOCS, etc.
v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
|
|
|
i915_reg_t dpll_reg;
|
2013-04-18 14:51:36 -07:00
|
|
|
|
2020-06-30 21:50:54 -07:00
|
|
|
switch (dig_port->base.port) {
|
2022-05-31 19:25:27 +03:00
|
|
|
default:
|
|
|
|
|
MISSING_CASE(dig_port->base.port);
|
|
|
|
|
fallthrough;
|
2013-11-06 14:36:35 +08:00
|
|
|
case PORT_B:
|
2013-04-18 14:51:36 -07:00
|
|
|
port_mask = DPLL_PORTB_READY_MASK;
|
2014-04-09 13:28:15 +03:00
|
|
|
dpll_reg = DPLL(0);
|
2013-11-06 14:36:35 +08:00
|
|
|
break;
|
|
|
|
|
case PORT_C:
|
2013-04-18 14:51:36 -07:00
|
|
|
port_mask = DPLL_PORTC_READY_MASK;
|
2014-04-09 13:28:15 +03:00
|
|
|
dpll_reg = DPLL(0);
|
2015-04-10 18:21:31 +03:00
|
|
|
expected_mask <<= 4;
|
2014-04-09 13:28:15 +03:00
|
|
|
break;
|
|
|
|
|
case PORT_D:
|
|
|
|
|
port_mask = DPLL_PORTD_READY_MASK;
|
|
|
|
|
dpll_reg = DPIO_PHY_STATUS;
|
2013-11-06 14:36:35 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2013-04-18 14:51:36 -07:00
|
|
|
|
2019-08-15 18:23:43 -07:00
|
|
|
if (intel_de_wait_for_register(dev_priv, dpll_reg,
|
|
|
|
|
port_mask, expected_mask, 1000))
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN(&dev_priv->drm, 1,
|
|
|
|
|
"timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n",
|
2020-06-30 21:50:54 -07:00
|
|
|
dig_port->base.base.base.id, dig_port->base.base.name,
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
intel_de_read(dev_priv, dpll_reg) & port_mask,
|
|
|
|
|
expected_mask);
|
2013-04-18 14:51:36 -07:00
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
|
2011-01-04 15:09:30 -08:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
|
2017-11-29 17:37:32 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
|
2014-01-17 13:51:09 -02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
drm/i915: Type safe register read/write
Make I915_READ and I915_WRITE more type safe by wrapping the register
offset in a struct. This should eliminate most of the fumbles we've had
with misplaced parens.
This only takes care of normal mmio registers. We could extend the idea
to other register types and define each with its own struct. That way
you wouldn't be able to accidentally pass the wrong thing to a specific
register access function.
The gpio_reg setup is probably the ugliest thing left. But I figure I'd
just leave it for now, and wait for some divine inspiration to strike
before making it nice.
As for the generated code, it's actually a bit better sometimes. Eg.
looking at i915_irq_handler(), we can see the following change:
lea 0x70024(%rdx,%rax,1),%r9d
mov $0x1,%edx
- movslq %r9d,%r9
- mov %r9,%rsi
- mov %r9,-0x58(%rbp)
- callq *0xd8(%rbx)
+ mov %r9d,%esi
+ mov %r9d,-0x48(%rbp)
callq *0xd8(%rbx)
So previously gcc thought the register offset might be signed and
decided to sign extend it, just in case. The rest appears to be
mostly just minor shuffling of instructions.
v2: i915_mmio_reg_{offset,equal,valid}() helpers added
s/_REG/_MMIO/ in the register defines
mo more switch statements left to worry about
ring_emit stuff got sorted in a prep patch
cmd parser, lrc context and w/a batch buildup also in prep patch
vgpu stuff cleaned up and moved to a prep patch
all other unrelated changes split out
v3: Rebased due to BXT DSI/BLC, MOCS, etc.
v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
|
|
|
i915_reg_t reg;
|
2011-01-04 15:09:30 -08:00
|
|
|
u32 val;
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "enabling pipe %c\n", pipe_name(pipe));
|
2015-06-24 21:59:35 +03:00
|
|
|
|
2017-11-17 21:19:08 +02:00
|
|
|
assert_planes_disabled(crtc);
|
2013-04-11 16:29:09 +02:00
|
|
|
|
2011-01-04 15:09:30 -08:00
|
|
|
/*
|
|
|
|
|
* A pipe without a PLL won't actually be able to drive bits from
|
|
|
|
|
* a plane. On ILK+ the pipe PLLs are integrated, so we don't
|
|
|
|
|
* need the check.
|
|
|
|
|
*/
|
2019-02-04 14:25:38 -08:00
|
|
|
if (HAS_GMCH(dev_priv)) {
|
2017-11-29 17:37:32 +02:00
|
|
|
if (intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI))
|
2013-08-27 15:12:22 +03:00
|
|
|
assert_dsi_pll_enabled(dev_priv);
|
|
|
|
|
else
|
|
|
|
|
assert_pll_enabled(dev_priv, pipe);
|
2016-08-05 20:41:34 +03:00
|
|
|
} else {
|
2017-11-29 17:37:32 +02:00
|
|
|
if (new_crtc_state->has_pch_encoder) {
|
2011-01-03 12:14:26 -08:00
|
|
|
/* if driving the PCH, we need FDI enabled */
|
2016-10-14 20:02:53 +03:00
|
|
|
assert_fdi_rx_pll_enabled(dev_priv,
|
2017-07-17 11:14:03 -07:00
|
|
|
intel_crtc_pch_transcoder(crtc));
|
2012-11-29 22:18:51 +01:00
|
|
|
assert_fdi_tx_pll_enabled(dev_priv,
|
|
|
|
|
(enum pipe) cpu_transcoder);
|
2011-01-03 12:14:26 -08:00
|
|
|
}
|
|
|
|
|
/* FIXME: assert CPU port conditions for SNB+ */
|
|
|
|
|
}
|
2011-01-04 15:09:30 -08:00
|
|
|
|
2021-07-12 17:38:49 -07:00
|
|
|
/* Wa_22012358565:adl-p */
|
2021-05-26 20:36:00 +03:00
|
|
|
if (DISPLAY_VER(dev_priv) == 13)
|
|
|
|
|
intel_de_rmw(dev_priv, PIPE_ARB_CTL(pipe),
|
|
|
|
|
0, PIPE_ARB_USE_PROG_SLOTS);
|
|
|
|
|
|
2012-10-23 18:29:59 -02:00
|
|
|
reg = PIPECONF(cpu_transcoder);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
val = intel_de_read(dev_priv, reg);
|
2014-01-17 13:51:13 -02:00
|
|
|
if (val & PIPECONF_ENABLE) {
|
2017-06-01 17:36:19 +03:00
|
|
|
/* we keep both pipes enabled on 830 */
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv));
|
2011-03-17 07:18:29 +00:00
|
|
|
return;
|
2014-01-17 13:51:13 -02:00
|
|
|
}
|
2011-03-17 07:18:29 +00:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, reg, val | PIPECONF_ENABLE);
|
|
|
|
|
intel_de_posting_read(dev_priv, reg);
|
2015-12-14 18:23:43 +02:00
|
|
|
|
|
|
|
|
/*
|
2017-11-29 17:37:30 +02:00
|
|
|
* Until the pipe starts PIPEDSL reads will return a stale value,
|
|
|
|
|
* which causes an apparent vblank timestamp jump when PIPEDSL
|
|
|
|
|
* resets to its proper value. That also messes up the frame count
|
|
|
|
|
* when it's derived from the timestamps. So let's wait for the
|
|
|
|
|
* pipe to start properly before we call drm_crtc_vblank_on()
|
2015-12-14 18:23:43 +02:00
|
|
|
*/
|
2018-11-27 22:05:50 +02:00
|
|
|
if (intel_crtc_max_vblank_count(new_crtc_state) == 0)
|
2017-11-29 17:37:30 +02:00
|
|
|
intel_wait_for_pipe_scanline_moving(crtc);
|
2011-01-04 15:09:30 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
2011-01-04 15:09:30 -08:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2017-11-29 17:37:32 +02:00
|
|
|
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
|
2014-08-15 01:21:56 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
drm/i915: Type safe register read/write
Make I915_READ and I915_WRITE more type safe by wrapping the register
offset in a struct. This should eliminate most of the fumbles we've had
with misplaced parens.
This only takes care of normal mmio registers. We could extend the idea
to other register types and define each with its own struct. That way
you wouldn't be able to accidentally pass the wrong thing to a specific
register access function.
The gpio_reg setup is probably the ugliest thing left. But I figure I'd
just leave it for now, and wait for some divine inspiration to strike
before making it nice.
As for the generated code, it's actually a bit better sometimes. Eg.
looking at i915_irq_handler(), we can see the following change:
lea 0x70024(%rdx,%rax,1),%r9d
mov $0x1,%edx
- movslq %r9d,%r9
- mov %r9,%rsi
- mov %r9,-0x58(%rbp)
- callq *0xd8(%rbx)
+ mov %r9d,%esi
+ mov %r9d,-0x48(%rbp)
callq *0xd8(%rbx)
So previously gcc thought the register offset might be signed and
decided to sign extend it, just in case. The rest appears to be
mostly just minor shuffling of instructions.
v2: i915_mmio_reg_{offset,equal,valid}() helpers added
s/_REG/_MMIO/ in the register defines
mo more switch statements left to worry about
ring_emit stuff got sorted in a prep patch
cmd parser, lrc context and w/a batch buildup also in prep patch
vgpu stuff cleaned up and moved to a prep patch
all other unrelated changes split out
v3: Rebased due to BXT DSI/BLC, MOCS, etc.
v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
|
|
|
i915_reg_t reg;
|
2011-01-04 15:09:30 -08:00
|
|
|
u32 val;
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "disabling pipe %c\n", pipe_name(pipe));
|
2015-06-24 21:59:35 +03:00
|
|
|
|
2011-01-04 15:09:30 -08:00
|
|
|
/*
|
|
|
|
|
* Make sure planes won't keep trying to pump pixels to us,
|
|
|
|
|
* or we might hang the display.
|
|
|
|
|
*/
|
2017-11-17 21:19:08 +02:00
|
|
|
assert_planes_disabled(crtc);
|
2011-01-04 15:09:30 -08:00
|
|
|
|
2012-10-23 18:29:59 -02:00
|
|
|
reg = PIPECONF(cpu_transcoder);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
val = intel_de_read(dev_priv, reg);
|
2011-03-17 07:18:29 +00:00
|
|
|
if ((val & PIPECONF_ENABLE) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-08-15 01:21:57 +03:00
|
|
|
/*
|
|
|
|
|
* Double wide has implications for planes
|
|
|
|
|
* so best keep it disabled when not needed.
|
|
|
|
|
*/
|
2017-11-29 17:37:32 +02:00
|
|
|
if (old_crtc_state->double_wide)
|
2014-08-15 01:21:57 +03:00
|
|
|
val &= ~PIPECONF_DOUBLE_WIDE;
|
|
|
|
|
|
|
|
|
|
/* Don't disable pipe or pipe PLLs if needed */
|
2017-06-01 17:36:19 +03:00
|
|
|
if (!IS_I830(dev_priv))
|
2014-08-15 01:21:57 +03:00
|
|
|
val &= ~PIPECONF_ENABLE;
|
|
|
|
|
|
2021-07-23 10:06:18 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 12)
|
|
|
|
|
intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder),
|
|
|
|
|
FECSTALL_DIS_DPTSTREAM_DPTTG, 0);
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, reg, val);
|
2014-08-15 01:21:57 +03:00
|
|
|
if ((val & PIPECONF_ENABLE) == 0)
|
2017-11-29 17:37:32 +02:00
|
|
|
intel_wait_for_pipe_off(old_crtc_state);
|
2011-01-04 15:09:30 -08:00
|
|
|
}
|
|
|
|
|
|
2016-02-15 22:54:45 +02:00
|
|
|
unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)
|
|
|
|
|
{
|
|
|
|
|
unsigned int size = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
|
2021-03-25 23:48:06 +02:00
|
|
|
size += rot_info->plane[i].dst_stride * rot_info->plane[i].width;
|
2016-02-15 22:54:45 +02:00
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 15:21:52 +03:00
|
|
|
unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
|
|
|
|
|
{
|
|
|
|
|
unsigned int size = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
2021-09-06 21:27:14 +03:00
|
|
|
for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
|
2021-10-27 01:51:00 +03:00
|
|
|
unsigned int plane_size;
|
|
|
|
|
|
2021-10-27 01:51:02 +03:00
|
|
|
if (rem_info->plane[i].linear)
|
|
|
|
|
plane_size = rem_info->plane[i].size;
|
|
|
|
|
else
|
|
|
|
|
plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height;
|
|
|
|
|
|
2021-10-27 01:51:00 +03:00
|
|
|
if (plane_size == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
2021-09-06 21:27:14 +03:00
|
|
|
if (rem_info->plane_alignment)
|
|
|
|
|
size = ALIGN(size, rem_info->plane_alignment);
|
2021-10-27 01:51:00 +03:00
|
|
|
|
|
|
|
|
size += plane_size;
|
2021-09-06 21:27:14 +03:00
|
|
|
}
|
2019-05-09 15:21:52 +03:00
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-12 14:34:56 +10:00
|
|
|
bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
|
2018-02-21 20:48:07 +02:00
|
|
|
{
|
2019-10-31 12:26:08 +01:00
|
|
|
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
2018-02-21 20:48:07 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
return DISPLAY_VER(dev_priv) < 4 ||
|
2021-11-04 16:45:20 +02:00
|
|
|
(plane->fbc &&
|
2021-03-28 00:09:10 +02:00
|
|
|
plane_state->view.gtt.type == I915_GGTT_VIEW_NORMAL);
|
2018-02-21 20:48:07 +02:00
|
|
|
}
|
|
|
|
|
|
drm/i915: Rewrite fb rotation GTT handling
Redo the fb rotation handling in order to:
- eliminate the NV12 special casing
- handle fb->offsets[] properly
- make the rotation handling easier for the plane code
To achieve these goals we reduce intel_rotation_info to only contain
(for each plane) the rotated view width,height,stride in tile units,
and the page offset into the object where the plane starts. Each plane
is handled exactly the same way, no special casing for NV12 or other
formats. We then store the computed rotation_info under
intel_framebuffer so that we don't have to recompute it again.
To handle fb->offsets[] we treat them as a linear offsets and convert
them to x/y offsets from the start of the relevant GTT mapping (either
normal or rotated). We store the x/y offsets under intel_framebuffer,
and for some extra convenience we also store the rotated pitch (ie.
tile aligned plane height). So for each plane we have the normal
x/y offsets, rotated x/y offsets, and the rotated pitch. The normal
pitch is available already in fb->pitches[].
While we're gathering up all that extra information, we can also easily
compute the storage requirements for the framebuffer, so that we can
check that the object is big enough to hold it.
When it comes time to deal with the plane source coordinates, we first
rotate the clipped src coordinates to match the relevant GTT view
orientation, then add to them the fb x/y offsets. Next we compute
the aligned surface page offset, and as a result we're left with some
residual x/y offsets. Finally, if required by the hardware, we convert
the remaining x/y offsets into a linear offset.
For gen2/3 we simply skip computing the final page offset, and just
convert the src+fb x/y offsets directly into a linear offset since
that's what the hardware wants.
After this all platforms, incluing SKL+, compute these things in exactly
the same way (excluding alignemnt differences).
v2: Use BIT(DRM_ROTATE_270) instead of ROTATE_270 when rotating
plane src coordinates
Drop some spurious changes that got left behind during
development
v3: Split out more changes to prep patches (Daniel)
s/intel_fb->plane[].foo.bar/intel_fb->foo[].bar/ for brevity
Rename intel_surf_gtt_offset to intel_fb_gtt_offset
Kill the pointless 'plane' parameter from intel_fb_gtt_offset()
v4: Fix alignment vs. alignment-1 when calling
_intel_compute_tile_offset() from intel_fill_fb_info()
Pass the pitch in tiles in
stad of pixels to intel_adjust_tile_offset() from intel_fill_fb_info()
Pass the full width/height of the rotated area to
drm_rect_rotate() for clarity
Use u32 for more offsets
v5: Preserve the upper_32_bits()/lower_32_bits() handling for the
fb ggtt offset (Sivakumar)
v6: Rebase due to drm_plane_state src/dst rects
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-2-git-send-email-ville.syrjala@linux.intel.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-15 13:16:41 +03:00
|
|
|
/*
|
|
|
|
|
* Convert the x/y offsets into a linear offset.
|
|
|
|
|
* Only valid with 0/180 degree rotation, which is fine since linear
|
|
|
|
|
* offset is only used with linear buffers on pre-hsw and tiled buffers
|
|
|
|
|
* with gen2/3, and 90/270 degree rotations isn't supported on any of them.
|
|
|
|
|
*/
|
|
|
|
|
u32 intel_fb_xy_to_linear(int x, int y,
|
2016-01-20 18:02:50 +02:00
|
|
|
const struct intel_plane_state *state,
|
2018-09-07 18:24:07 +03:00
|
|
|
int color_plane)
|
drm/i915: Rewrite fb rotation GTT handling
Redo the fb rotation handling in order to:
- eliminate the NV12 special casing
- handle fb->offsets[] properly
- make the rotation handling easier for the plane code
To achieve these goals we reduce intel_rotation_info to only contain
(for each plane) the rotated view width,height,stride in tile units,
and the page offset into the object where the plane starts. Each plane
is handled exactly the same way, no special casing for NV12 or other
formats. We then store the computed rotation_info under
intel_framebuffer so that we don't have to recompute it again.
To handle fb->offsets[] we treat them as a linear offsets and convert
them to x/y offsets from the start of the relevant GTT mapping (either
normal or rotated). We store the x/y offsets under intel_framebuffer,
and for some extra convenience we also store the rotated pitch (ie.
tile aligned plane height). So for each plane we have the normal
x/y offsets, rotated x/y offsets, and the rotated pitch. The normal
pitch is available already in fb->pitches[].
While we're gathering up all that extra information, we can also easily
compute the storage requirements for the framebuffer, so that we can
check that the object is big enough to hold it.
When it comes time to deal with the plane source coordinates, we first
rotate the clipped src coordinates to match the relevant GTT view
orientation, then add to them the fb x/y offsets. Next we compute
the aligned surface page offset, and as a result we're left with some
residual x/y offsets. Finally, if required by the hardware, we convert
the remaining x/y offsets into a linear offset.
For gen2/3 we simply skip computing the final page offset, and just
convert the src+fb x/y offsets directly into a linear offset since
that's what the hardware wants.
After this all platforms, incluing SKL+, compute these things in exactly
the same way (excluding alignemnt differences).
v2: Use BIT(DRM_ROTATE_270) instead of ROTATE_270 when rotating
plane src coordinates
Drop some spurious changes that got left behind during
development
v3: Split out more changes to prep patches (Daniel)
s/intel_fb->plane[].foo.bar/intel_fb->foo[].bar/ for brevity
Rename intel_surf_gtt_offset to intel_fb_gtt_offset
Kill the pointless 'plane' parameter from intel_fb_gtt_offset()
v4: Fix alignment vs. alignment-1 when calling
_intel_compute_tile_offset() from intel_fill_fb_info()
Pass the pitch in tiles in
stad of pixels to intel_adjust_tile_offset() from intel_fill_fb_info()
Pass the full width/height of the rotated area to
drm_rect_rotate() for clarity
Use u32 for more offsets
v5: Preserve the upper_32_bits()/lower_32_bits() handling for the
fb ggtt offset (Sivakumar)
v6: Rebase due to drm_plane_state src/dst rects
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-2-git-send-email-ville.syrjala@linux.intel.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-15 13:16:41 +03:00
|
|
|
{
|
2019-10-31 12:26:07 +01:00
|
|
|
const struct drm_framebuffer *fb = state->hw.fb;
|
2018-09-07 18:24:07 +03:00
|
|
|
unsigned int cpp = fb->format->cpp[color_plane];
|
2021-10-27 01:51:03 +03:00
|
|
|
unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
|
drm/i915: Rewrite fb rotation GTT handling
Redo the fb rotation handling in order to:
- eliminate the NV12 special casing
- handle fb->offsets[] properly
- make the rotation handling easier for the plane code
To achieve these goals we reduce intel_rotation_info to only contain
(for each plane) the rotated view width,height,stride in tile units,
and the page offset into the object where the plane starts. Each plane
is handled exactly the same way, no special casing for NV12 or other
formats. We then store the computed rotation_info under
intel_framebuffer so that we don't have to recompute it again.
To handle fb->offsets[] we treat them as a linear offsets and convert
them to x/y offsets from the start of the relevant GTT mapping (either
normal or rotated). We store the x/y offsets under intel_framebuffer,
and for some extra convenience we also store the rotated pitch (ie.
tile aligned plane height). So for each plane we have the normal
x/y offsets, rotated x/y offsets, and the rotated pitch. The normal
pitch is available already in fb->pitches[].
While we're gathering up all that extra information, we can also easily
compute the storage requirements for the framebuffer, so that we can
check that the object is big enough to hold it.
When it comes time to deal with the plane source coordinates, we first
rotate the clipped src coordinates to match the relevant GTT view
orientation, then add to them the fb x/y offsets. Next we compute
the aligned surface page offset, and as a result we're left with some
residual x/y offsets. Finally, if required by the hardware, we convert
the remaining x/y offsets into a linear offset.
For gen2/3 we simply skip computing the final page offset, and just
convert the src+fb x/y offsets directly into a linear offset since
that's what the hardware wants.
After this all platforms, incluing SKL+, compute these things in exactly
the same way (excluding alignemnt differences).
v2: Use BIT(DRM_ROTATE_270) instead of ROTATE_270 when rotating
plane src coordinates
Drop some spurious changes that got left behind during
development
v3: Split out more changes to prep patches (Daniel)
s/intel_fb->plane[].foo.bar/intel_fb->foo[].bar/ for brevity
Rename intel_surf_gtt_offset to intel_fb_gtt_offset
Kill the pointless 'plane' parameter from intel_fb_gtt_offset()
v4: Fix alignment vs. alignment-1 when calling
_intel_compute_tile_offset() from intel_fill_fb_info()
Pass the pitch in tiles in
stad of pixels to intel_adjust_tile_offset() from intel_fill_fb_info()
Pass the full width/height of the rotated area to
drm_rect_rotate() for clarity
Use u32 for more offsets
v5: Preserve the upper_32_bits()/lower_32_bits() handling for the
fb ggtt offset (Sivakumar)
v6: Rebase due to drm_plane_state src/dst rects
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-2-git-send-email-ville.syrjala@linux.intel.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-15 13:16:41 +03:00
|
|
|
|
|
|
|
|
return y * pitch + x * cpp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Add the x/y offsets derived from fb->offsets[] to the user
|
|
|
|
|
* specified plane src x/y offsets. The resulting x/y offsets
|
|
|
|
|
* specify the start of scanout from the beginning of the gtt mapping.
|
|
|
|
|
*/
|
|
|
|
|
void intel_add_fb_offsets(int *x, int *y,
|
2016-01-20 18:02:50 +02:00
|
|
|
const struct intel_plane_state *state,
|
2018-09-07 18:24:07 +03:00
|
|
|
int color_plane)
|
drm/i915: Rewrite fb rotation GTT handling
Redo the fb rotation handling in order to:
- eliminate the NV12 special casing
- handle fb->offsets[] properly
- make the rotation handling easier for the plane code
To achieve these goals we reduce intel_rotation_info to only contain
(for each plane) the rotated view width,height,stride in tile units,
and the page offset into the object where the plane starts. Each plane
is handled exactly the same way, no special casing for NV12 or other
formats. We then store the computed rotation_info under
intel_framebuffer so that we don't have to recompute it again.
To handle fb->offsets[] we treat them as a linear offsets and convert
them to x/y offsets from the start of the relevant GTT mapping (either
normal or rotated). We store the x/y offsets under intel_framebuffer,
and for some extra convenience we also store the rotated pitch (ie.
tile aligned plane height). So for each plane we have the normal
x/y offsets, rotated x/y offsets, and the rotated pitch. The normal
pitch is available already in fb->pitches[].
While we're gathering up all that extra information, we can also easily
compute the storage requirements for the framebuffer, so that we can
check that the object is big enough to hold it.
When it comes time to deal with the plane source coordinates, we first
rotate the clipped src coordinates to match the relevant GTT view
orientation, then add to them the fb x/y offsets. Next we compute
the aligned surface page offset, and as a result we're left with some
residual x/y offsets. Finally, if required by the hardware, we convert
the remaining x/y offsets into a linear offset.
For gen2/3 we simply skip computing the final page offset, and just
convert the src+fb x/y offsets directly into a linear offset since
that's what the hardware wants.
After this all platforms, incluing SKL+, compute these things in exactly
the same way (excluding alignemnt differences).
v2: Use BIT(DRM_ROTATE_270) instead of ROTATE_270 when rotating
plane src coordinates
Drop some spurious changes that got left behind during
development
v3: Split out more changes to prep patches (Daniel)
s/intel_fb->plane[].foo.bar/intel_fb->foo[].bar/ for brevity
Rename intel_surf_gtt_offset to intel_fb_gtt_offset
Kill the pointless 'plane' parameter from intel_fb_gtt_offset()
v4: Fix alignment vs. alignment-1 when calling
_intel_compute_tile_offset() from intel_fill_fb_info()
Pass the pitch in tiles in
stad of pixels to intel_adjust_tile_offset() from intel_fill_fb_info()
Pass the full width/height of the rotated area to
drm_rect_rotate() for clarity
Use u32 for more offsets
v5: Preserve the upper_32_bits()/lower_32_bits() handling for the
fb ggtt offset (Sivakumar)
v6: Rebase due to drm_plane_state src/dst rects
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-2-git-send-email-ville.syrjala@linux.intel.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-15 13:16:41 +03:00
|
|
|
|
|
|
|
|
{
|
2021-03-28 00:09:10 +02:00
|
|
|
*x += state->view.color_plane[color_plane].x;
|
|
|
|
|
*y += state->view.color_plane[color_plane].y;
|
drm/i915: Rewrite fb rotation GTT handling
Redo the fb rotation handling in order to:
- eliminate the NV12 special casing
- handle fb->offsets[] properly
- make the rotation handling easier for the plane code
To achieve these goals we reduce intel_rotation_info to only contain
(for each plane) the rotated view width,height,stride in tile units,
and the page offset into the object where the plane starts. Each plane
is handled exactly the same way, no special casing for NV12 or other
formats. We then store the computed rotation_info under
intel_framebuffer so that we don't have to recompute it again.
To handle fb->offsets[] we treat them as a linear offsets and convert
them to x/y offsets from the start of the relevant GTT mapping (either
normal or rotated). We store the x/y offsets under intel_framebuffer,
and for some extra convenience we also store the rotated pitch (ie.
tile aligned plane height). So for each plane we have the normal
x/y offsets, rotated x/y offsets, and the rotated pitch. The normal
pitch is available already in fb->pitches[].
While we're gathering up all that extra information, we can also easily
compute the storage requirements for the framebuffer, so that we can
check that the object is big enough to hold it.
When it comes time to deal with the plane source coordinates, we first
rotate the clipped src coordinates to match the relevant GTT view
orientation, then add to them the fb x/y offsets. Next we compute
the aligned surface page offset, and as a result we're left with some
residual x/y offsets. Finally, if required by the hardware, we convert
the remaining x/y offsets into a linear offset.
For gen2/3 we simply skip computing the final page offset, and just
convert the src+fb x/y offsets directly into a linear offset since
that's what the hardware wants.
After this all platforms, incluing SKL+, compute these things in exactly
the same way (excluding alignemnt differences).
v2: Use BIT(DRM_ROTATE_270) instead of ROTATE_270 when rotating
plane src coordinates
Drop some spurious changes that got left behind during
development
v3: Split out more changes to prep patches (Daniel)
s/intel_fb->plane[].foo.bar/intel_fb->foo[].bar/ for brevity
Rename intel_surf_gtt_offset to intel_fb_gtt_offset
Kill the pointless 'plane' parameter from intel_fb_gtt_offset()
v4: Fix alignment vs. alignment-1 when calling
_intel_compute_tile_offset() from intel_fill_fb_info()
Pass the pitch in tiles in
stad of pixels to intel_adjust_tile_offset() from intel_fill_fb_info()
Pass the full width/height of the rotated area to
drm_rect_rotate() for clarity
Use u32 for more offsets
v5: Preserve the upper_32_bits()/lower_32_bits() handling for the
fb ggtt offset (Sivakumar)
v6: Rebase due to drm_plane_state src/dst rects
Cc: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-2-git-send-email-ville.syrjala@linux.intel.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-15 13:16:41 +03:00
|
|
|
}
|
|
|
|
|
|
2019-05-09 15:21:56 +03:00
|
|
|
u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
|
|
|
|
|
u32 pixel_format, u64 modifier)
|
2019-05-09 15:21:55 +03:00
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2019-05-09 15:21:55 +03:00
|
|
|
/*
|
|
|
|
|
* We assume the primary plane for pipe A has
|
2020-02-24 18:10:02 +05:30
|
|
|
* the highest stride limits of them all,
|
|
|
|
|
* if in case pipe A is disabled, use the first pipe from pipe_mask.
|
2019-05-09 15:21:55 +03:00
|
|
|
*/
|
2021-12-03 13:20:29 +02:00
|
|
|
crtc = intel_first_crtc(dev_priv);
|
2019-11-06 19:23:49 +02:00
|
|
|
if (!crtc)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2019-05-09 15:21:55 +03:00
|
|
|
plane = to_intel_plane(crtc->base.primary);
|
|
|
|
|
|
|
|
|
|
return plane->max_stride(plane, pixel_format, modifier,
|
|
|
|
|
DRM_MODE_ROTATE_0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_set_plane_visible(struct intel_crtc_state *crtc_state,
|
|
|
|
|
struct intel_plane_state *plane_state,
|
|
|
|
|
bool visible)
|
2017-03-02 19:14:51 +02:00
|
|
|
{
|
2019-10-31 12:26:08 +01:00
|
|
|
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
2017-03-02 19:14:51 +02:00
|
|
|
|
2019-10-31 12:26:08 +01:00
|
|
|
plane_state->uapi.visible = visible;
|
2017-03-02 19:14:51 +02:00
|
|
|
|
2018-10-03 17:50:17 +03:00
|
|
|
if (visible)
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.plane_mask |= drm_plane_mask(&plane->base);
|
2018-10-03 17:50:17 +03:00
|
|
|
else
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.plane_mask &= ~drm_plane_mask(&plane->base);
|
2017-03-02 19:14:51 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state)
|
2018-10-03 17:50:17 +03:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
2018-10-03 17:50:17 +03:00
|
|
|
struct drm_plane *plane;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Active_planes aliases if multiple "primary" or cursor planes
|
|
|
|
|
* have been used on the same (or wrong) pipe. plane_mask uses
|
|
|
|
|
* unique ids, hence we can use that to reconstruct active_planes.
|
|
|
|
|
*/
|
2020-11-24 22:11:53 +02:00
|
|
|
crtc_state->enabled_planes = 0;
|
2018-10-03 17:50:17 +03:00
|
|
|
crtc_state->active_planes = 0;
|
|
|
|
|
|
|
|
|
|
drm_for_each_plane_mask(plane, &dev_priv->drm,
|
2020-11-24 22:11:53 +02:00
|
|
|
crtc_state->uapi.plane_mask) {
|
|
|
|
|
crtc_state->enabled_planes |= BIT(to_intel_plane(plane)->id);
|
2018-10-03 17:50:17 +03:00
|
|
|
crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
|
2020-11-24 22:11:53 +02:00
|
|
|
}
|
2018-10-03 17:50:17 +03:00
|
|
|
}
|
|
|
|
|
|
2021-10-12 14:34:58 +10:00
|
|
|
void intel_plane_disable_noatomic(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_plane *plane)
|
2017-11-17 21:19:09 +02:00
|
|
|
{
|
2019-11-27 21:05:55 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2017-11-17 21:19:09 +02:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
to_intel_crtc_state(crtc->base.state);
|
|
|
|
|
struct intel_plane_state *plane_state =
|
|
|
|
|
to_intel_plane_state(plane->base.state);
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Disabling [PLANE:%d:%s] on [CRTC:%d:%s]\n",
|
|
|
|
|
plane->base.base.id, plane->base.name,
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
2018-10-03 17:50:52 +03:00
|
|
|
|
2017-11-17 21:19:09 +02:00
|
|
|
intel_set_plane_visible(crtc_state, plane_state, false);
|
2022-06-17 12:48:16 +03:00
|
|
|
intel_plane_fixup_bitmasks(crtc_state);
|
2019-05-24 18:36:14 +03:00
|
|
|
crtc_state->data_rate[plane->id] = 0;
|
2022-03-03 21:12:00 +02:00
|
|
|
crtc_state->data_rate_y[plane->id] = 0;
|
2022-03-03 21:12:01 +02:00
|
|
|
crtc_state->rel_data_rate[plane->id] = 0;
|
|
|
|
|
crtc_state->rel_data_rate_y[plane->id] = 0;
|
2019-10-15 22:30:26 +03:00
|
|
|
crtc_state->min_cdclk[plane->id] = 0;
|
2017-11-17 21:19:09 +02:00
|
|
|
|
2022-02-09 13:35:25 +02:00
|
|
|
if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 &&
|
|
|
|
|
hsw_ips_disable(crtc_state)) {
|
|
|
|
|
crtc_state->ips_enabled = false;
|
2022-02-09 13:35:20 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2022-02-09 13:35:25 +02:00
|
|
|
}
|
2019-11-27 21:05:55 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Vblank time updates from the shadow to live plane control register
|
|
|
|
|
* are blocked if the memory self-refresh mode is active at that
|
|
|
|
|
* moment. So to make sure the plane gets truly disabled, disable
|
|
|
|
|
* first the self-refresh mode. The self-refresh enable bit in turn
|
|
|
|
|
* will be checked/applied by the HW only at the next frame start
|
|
|
|
|
* event which is after the vblank start event, so we need to have a
|
|
|
|
|
* wait-for-vblank between disabling the plane and the pipe.
|
|
|
|
|
*/
|
|
|
|
|
if (HAS_GMCH(dev_priv) &&
|
|
|
|
|
intel_set_memory_cxsr(dev_priv, false))
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2019-11-27 21:05:55 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Gen2 reports pipe underruns whenever all planes are disabled.
|
|
|
|
|
* So disable underrun reporting before all the planes get disabled.
|
|
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes)
|
2019-11-27 21:05:55 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
|
2017-11-17 21:19:09 +02:00
|
|
|
|
2021-10-18 14:50:25 +03:00
|
|
|
intel_plane_disable_arm(plane, crtc_state);
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2017-11-17 21:19:09 +02:00
|
|
|
}
|
2021-05-06 19:19:24 +03:00
|
|
|
|
2020-04-29 13:10:25 +03:00
|
|
|
unsigned int
|
|
|
|
|
intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
|
|
|
|
|
{
|
|
|
|
|
int x = 0, y = 0;
|
|
|
|
|
|
|
|
|
|
intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
|
2021-03-28 00:09:10 +02:00
|
|
|
plane_state->view.color_plane[0].offset, 0);
|
2020-04-29 13:10:25 +03:00
|
|
|
|
|
|
|
|
return y;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-05 23:28:27 +03:00
|
|
|
static int
|
2022-06-16 12:48:20 +03:00
|
|
|
__intel_display_resume(struct drm_i915_private *i915,
|
2017-01-16 10:37:38 +01:00
|
|
|
struct drm_atomic_state *state,
|
|
|
|
|
struct drm_modeset_acquire_ctx *ctx)
|
2016-08-05 23:28:27 +03:00
|
|
|
{
|
|
|
|
|
struct drm_crtc_state *crtc_state;
|
|
|
|
|
struct drm_crtc *crtc;
|
|
|
|
|
int i, ret;
|
2015-09-10 16:07:58 +02:00
|
|
|
|
2022-06-17 12:48:17 +03:00
|
|
|
intel_modeset_setup_hw_state(i915, ctx);
|
2022-06-16 12:48:20 +03:00
|
|
|
intel_vga_redisable(i915);
|
2016-08-05 23:28:27 +03:00
|
|
|
|
|
|
|
|
if (!state)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2017-03-09 15:52:04 +01:00
|
|
|
/*
|
|
|
|
|
* We've duplicated the state, pointers to the old state are invalid.
|
|
|
|
|
*
|
|
|
|
|
* Don't attempt to use the old state until we commit the duplicated state.
|
|
|
|
|
*/
|
|
|
|
|
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
|
2016-08-05 23:28:27 +03:00
|
|
|
/*
|
|
|
|
|
* Force recalculation even if we restore
|
|
|
|
|
* current state. With fast modeset this may not result
|
|
|
|
|
* in a modeset when the state is compatible.
|
|
|
|
|
*/
|
|
|
|
|
crtc_state->mode_changed = true;
|
2013-02-18 19:08:49 +02:00
|
|
|
}
|
2016-08-05 23:28:27 +03:00
|
|
|
|
|
|
|
|
/* ignore any reset values/BIOS leftovers in the WM registers */
|
2022-06-16 12:48:20 +03:00
|
|
|
if (!HAS_GMCH(i915))
|
2017-03-02 19:15:02 +02:00
|
|
|
to_intel_atomic_state(state)->skip_intermediate_wm = true;
|
2016-08-05 23:28:27 +03:00
|
|
|
|
2017-01-16 10:37:38 +01:00
|
|
|
ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
|
2016-08-05 23:28:27 +03:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
drm_WARN_ON(&i915->drm, ret == -EDEADLK);
|
|
|
|
|
|
2016-08-05 23:28:27 +03:00
|
|
|
return ret;
|
2013-02-18 19:08:49 +02:00
|
|
|
}
|
|
|
|
|
|
2016-08-05 23:28:29 +03:00
|
|
|
static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
2019-01-03 11:21:04 +00:00
|
|
|
return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display &&
|
2021-12-14 21:33:33 +02:00
|
|
|
intel_has_gpu_reset(to_gt(dev_priv)));
|
2016-08-05 23:28:29 +03:00
|
|
|
}
|
|
|
|
|
|
2020-11-06 14:55:24 -08:00
|
|
|
void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
|
2014-11-24 18:28:11 +02:00
|
|
|
{
|
2016-08-05 23:28:27 +03:00
|
|
|
struct drm_device *dev = &dev_priv->drm;
|
|
|
|
|
struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
|
|
|
|
|
struct drm_atomic_state *state;
|
|
|
|
|
int ret;
|
|
|
|
|
|
2020-11-06 14:55:26 -08:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
|
|
|
|
return;
|
|
|
|
|
|
2017-07-19 14:54:55 +02:00
|
|
|
/* reset doesn't touch the display */
|
2020-06-18 18:04:02 +03:00
|
|
|
if (!dev_priv->params.force_reset_modeset_test &&
|
2017-07-19 14:54:55 +02:00
|
|
|
!gpu_reset_clobbers_display(dev_priv))
|
|
|
|
|
return;
|
|
|
|
|
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
/* We have a modeset vs reset deadlock, defensively unbreak it. */
|
2021-12-14 21:33:33 +02:00
|
|
|
set_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags);
|
2019-07-12 20:29:53 +01:00
|
|
|
smp_mb__after_atomic();
|
2021-12-14 21:33:33 +02:00
|
|
|
wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET);
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
|
|
|
|
|
if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Modeset potentially stuck, unbreaking through wedging\n");
|
2021-12-14 21:33:33 +02:00
|
|
|
intel_gt_set_wedged(to_gt(dev_priv));
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
}
|
2017-08-08 10:08:26 +02:00
|
|
|
|
2016-08-05 23:28:27 +03:00
|
|
|
/*
|
|
|
|
|
* Need mode_config.mutex so that we don't
|
|
|
|
|
* trample ongoing ->detect() and whatnot.
|
|
|
|
|
*/
|
|
|
|
|
mutex_lock(&dev->mode_config.mutex);
|
|
|
|
|
drm_modeset_acquire_init(ctx, 0);
|
|
|
|
|
while (1) {
|
|
|
|
|
ret = drm_modeset_lock_all_ctx(dev, ctx);
|
|
|
|
|
if (ret != -EDEADLK)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
drm_modeset_backoff(ctx);
|
|
|
|
|
}
|
2014-11-21 21:54:30 +02:00
|
|
|
/*
|
|
|
|
|
* Disabling the crtcs gracefully seems nicer. Also the
|
|
|
|
|
* g33 docs say we should at least disable all the planes.
|
|
|
|
|
*/
|
2016-08-05 23:28:27 +03:00
|
|
|
state = drm_atomic_helper_duplicate_state(dev, ctx);
|
|
|
|
|
if (IS_ERR(state)) {
|
|
|
|
|
ret = PTR_ERR(state);
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm, "Duplicating state failed with %i\n",
|
|
|
|
|
ret);
|
2017-01-18 14:34:28 +02:00
|
|
|
return;
|
2016-08-05 23:28:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = drm_atomic_helper_disable_all(dev, ctx);
|
|
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
|
|
|
|
|
ret);
|
2017-01-18 14:34:28 +02:00
|
|
|
drm_atomic_state_put(state);
|
|
|
|
|
return;
|
2016-08-05 23:28:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev_priv->modeset_restore_state = state;
|
|
|
|
|
state->acquire_ctx = ctx;
|
2014-11-24 18:28:11 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
void intel_display_finish_reset(struct drm_i915_private *i915)
|
2014-11-24 18:28:11 +02:00
|
|
|
{
|
2022-06-16 12:48:20 +03:00
|
|
|
struct drm_modeset_acquire_ctx *ctx = &i915->reset_ctx;
|
2018-04-05 13:37:14 +01:00
|
|
|
struct drm_atomic_state *state;
|
2016-08-05 23:28:27 +03:00
|
|
|
int ret;
|
|
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
if (!HAS_DISPLAY(i915))
|
2020-11-06 14:55:26 -08:00
|
|
|
return;
|
|
|
|
|
|
2017-07-19 14:54:55 +02:00
|
|
|
/* reset doesn't touch the display */
|
2022-06-16 12:48:20 +03:00
|
|
|
if (!test_bit(I915_RESET_MODESET, &to_gt(i915)->reset.flags))
|
2017-07-19 14:54:55 +02:00
|
|
|
return;
|
|
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
state = fetch_and_zero(&i915->modeset_restore_state);
|
2017-07-19 14:54:55 +02:00
|
|
|
if (!state)
|
|
|
|
|
goto unlock;
|
|
|
|
|
|
2014-11-24 18:28:11 +02:00
|
|
|
/* reset doesn't touch the display */
|
2022-06-16 12:48:20 +03:00
|
|
|
if (!gpu_reset_clobbers_display(i915)) {
|
2017-07-19 14:54:55 +02:00
|
|
|
/* for testing only restore the display */
|
2022-06-16 12:48:20 +03:00
|
|
|
ret = __intel_display_resume(i915, state, ctx);
|
2017-08-28 11:46:04 +01:00
|
|
|
if (ret)
|
2022-06-16 12:48:20 +03:00
|
|
|
drm_err(&i915->drm,
|
2020-01-22 00:46:41 +03:00
|
|
|
"Restoring old state failed with %i\n", ret);
|
2016-08-05 23:28:27 +03:00
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* The display has been reset as well,
|
|
|
|
|
* so need a full re-initialization.
|
|
|
|
|
*/
|
2022-06-16 12:48:20 +03:00
|
|
|
intel_pps_unlock_regs_wa(i915);
|
|
|
|
|
intel_modeset_init_hw(i915);
|
|
|
|
|
intel_init_clock_gating(i915);
|
|
|
|
|
intel_hpd_init(i915);
|
2014-11-24 18:28:11 +02:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
ret = __intel_display_resume(i915, state, ctx);
|
2016-08-05 23:28:27 +03:00
|
|
|
if (ret)
|
2022-06-16 12:48:20 +03:00
|
|
|
drm_err(&i915->drm,
|
2020-01-22 00:46:41 +03:00
|
|
|
"Restoring old state failed with %i\n", ret);
|
2014-11-24 18:28:11 +02:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
intel_hpd_poll_disable(i915);
|
2016-08-05 23:28:27 +03:00
|
|
|
}
|
2014-11-24 18:28:11 +02:00
|
|
|
|
2017-07-19 14:54:55 +02:00
|
|
|
drm_atomic_state_put(state);
|
|
|
|
|
unlock:
|
2016-08-05 23:28:27 +03:00
|
|
|
drm_modeset_drop_locks(ctx);
|
|
|
|
|
drm_modeset_acquire_fini(ctx);
|
2022-06-16 12:48:20 +03:00
|
|
|
mutex_unlock(&i915->drm.mode_config.mutex);
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
clear_bit_unlock(I915_RESET_MODESET, &to_gt(i915)->reset.flags);
|
2014-11-24 18:28:11 +02:00
|
|
|
}
|
|
|
|
|
|
2021-07-27 07:50:56 -07:00
|
|
|
static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-02-04 22:21:39 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
u32 tmp;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPE_CHICKEN(pipe));
|
2019-02-04 22:21:39 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Display WA #1153: icl
|
|
|
|
|
* enable hardware to bypass the alpha math
|
|
|
|
|
* and rounding for per-pixel values 00 and 0xff
|
|
|
|
|
*/
|
|
|
|
|
tmp |= PER_PIXEL_ALPHA_BYPASS_EN;
|
2019-03-06 18:14:12 -08:00
|
|
|
/*
|
|
|
|
|
* Display WA # 1605353570: icl
|
|
|
|
|
* Set the pixel rounding bit to 1 for allowing
|
|
|
|
|
* passthrough of Frame buffer pixels unmodified
|
|
|
|
|
* across pipe
|
|
|
|
|
*/
|
|
|
|
|
tmp |= PIXEL_ROUNDING_TRUNC_FB_PASSTHRU;
|
2021-05-26 20:35:59 +03:00
|
|
|
|
2021-11-03 18:08:58 -07:00
|
|
|
/*
|
|
|
|
|
* Underrun recovery must always be disabled on display 13+.
|
|
|
|
|
* DG2 chicken bit meaning is inverted compared to other platforms.
|
|
|
|
|
*/
|
|
|
|
|
if (IS_DG2(dev_priv))
|
2021-07-27 07:50:56 -07:00
|
|
|
tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2;
|
2021-11-03 18:08:58 -07:00
|
|
|
else if (DISPLAY_VER(dev_priv) >= 13)
|
|
|
|
|
tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;
|
2021-05-26 20:35:59 +03:00
|
|
|
|
2021-11-16 09:48:15 -08:00
|
|
|
/* Wa_14010547955:dg2 */
|
|
|
|
|
if (IS_DG2_DISPLAY_STEP(dev_priv, STEP_B0, STEP_FOREVER))
|
|
|
|
|
tmp |= DG2_RENDER_CCSTAG_4_3_EN;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);
|
2019-02-04 22:21:39 +02:00
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:50:08 +00:00
|
|
|
bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
|
2014-01-20 10:17:36 +00:00
|
|
|
{
|
2017-07-20 19:57:52 +02:00
|
|
|
struct drm_crtc *crtc;
|
|
|
|
|
bool cleanup_done;
|
|
|
|
|
|
|
|
|
|
drm_for_each_crtc(crtc, &dev_priv->drm) {
|
|
|
|
|
struct drm_crtc_commit *commit;
|
|
|
|
|
spin_lock(&crtc->commit_lock);
|
|
|
|
|
commit = list_first_entry_or_null(&crtc->commit_list,
|
|
|
|
|
struct drm_crtc_commit, commit_entry);
|
|
|
|
|
cleanup_done = commit ?
|
|
|
|
|
try_wait_for_completion(&commit->cleanup_done) : true;
|
|
|
|
|
spin_unlock(&crtc->commit_lock);
|
|
|
|
|
|
|
|
|
|
if (cleanup_done)
|
2014-01-20 10:17:36 +00:00
|
|
|
continue;
|
|
|
|
|
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc));
|
2014-01-20 10:17:36 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-18 18:29:25 +03:00
|
|
|
/*
|
|
|
|
|
* Finds the encoder associated with the given CRTC. This can only be
|
|
|
|
|
* used when we know that the CRTC isn't feeding multiple encoders!
|
|
|
|
|
*/
|
2021-01-14 13:13:46 +02:00
|
|
|
struct intel_encoder *
|
2018-05-18 18:29:27 +03:00
|
|
|
intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
|
|
|
|
|
const struct intel_crtc_state *crtc_state)
|
2018-05-18 18:29:25 +03:00
|
|
|
{
|
|
|
|
|
const struct drm_connector_state *connector_state;
|
|
|
|
|
const struct drm_connector *connector;
|
|
|
|
|
struct intel_encoder *encoder = NULL;
|
2021-10-22 13:33:03 +03:00
|
|
|
struct intel_crtc *master_crtc;
|
2018-05-18 18:29:25 +03:00
|
|
|
int num_encoders = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
2021-10-22 13:33:03 +03:00
|
|
|
master_crtc = intel_master_crtc(crtc_state);
|
|
|
|
|
|
2018-05-18 18:29:27 +03:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
2021-10-22 13:33:03 +03:00
|
|
|
if (connector_state->crtc != &master_crtc->base)
|
2018-05-18 18:29:25 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
encoder = to_intel_encoder(connector_state->best_encoder);
|
|
|
|
|
num_encoders++;
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915/display: Make WARN* drm specific where encoder ptr is available
Drm specific drm_WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where intel_encoder struct pointer is available.
The conversion was done automatically with below coccinelle semantic
patch.
@@
identifier func, T;
@@
func(...) {
...
struct intel_encoder *T = ...;
<...
(
-WARN(
+drm_WARN(T->base.dev,
...)
|
-WARN_ON(
+drm_WARN_ON(T->base.dev,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T->base.dev,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T->base.dev,
...)
)
...>
}
@@
identifier func, T;
@@
func(struct intel_encoder *T,...) {
<...
(
-WARN(
+drm_WARN(T->base.dev,
...)
|
-WARN_ON(
+drm_WARN_ON(T->base.dev,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T->base.dev,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T->base.dev,
...)
)
...>
}
command: spatch --sp-file <script> --dir drivers/gpu/drm/i915/display \
--linux-spacing --in-place
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200115034455.17658-5-pankaj.laxminarayan.bharadiya@intel.com
2020-01-15 09:14:48 +05:30
|
|
|
drm_WARN(encoder->base.dev, num_encoders != 1,
|
|
|
|
|
"%d encoders for pipe %c\n",
|
2021-10-22 13:33:03 +03:00
|
|
|
num_encoders, pipe_name(master_crtc->pipe));
|
2018-05-18 18:29:25 +03:00
|
|
|
|
|
|
|
|
return encoder;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:27 +02:00
|
|
|
static void cpt_verify_modeset(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum pipe pipe)
|
2011-10-11 10:43:02 -07:00
|
|
|
{
|
drm/i915: Type safe register read/write
Make I915_READ and I915_WRITE more type safe by wrapping the register
offset in a struct. This should eliminate most of the fumbles we've had
with misplaced parens.
This only takes care of normal mmio registers. We could extend the idea
to other register types and define each with its own struct. That way
you wouldn't be able to accidentally pass the wrong thing to a specific
register access function.
The gpio_reg setup is probably the ugliest thing left. But I figure I'd
just leave it for now, and wait for some divine inspiration to strike
before making it nice.
As for the generated code, it's actually a bit better sometimes. Eg.
looking at i915_irq_handler(), we can see the following change:
lea 0x70024(%rdx,%rax,1),%r9d
mov $0x1,%edx
- movslq %r9d,%r9
- mov %r9,%rsi
- mov %r9,-0x58(%rbp)
- callq *0xd8(%rbx)
+ mov %r9d,%esi
+ mov %r9d,-0x48(%rbp)
callq *0xd8(%rbx)
So previously gcc thought the register offset might be signed and
decided to sign extend it, just in case. The rest appears to be
mostly just minor shuffling of instructions.
v2: i915_mmio_reg_{offset,equal,valid}() helpers added
s/_REG/_MMIO/ in the register defines
mo more switch statements left to worry about
ring_emit stuff got sorted in a prep patch
cmd parser, lrc context and w/a batch buildup also in prep patch
vgpu stuff cleaned up and moved to a prep patch
all other unrelated changes split out
v3: Rebased due to BXT DSI/BLC, MOCS, etc.
v4: Rebased due to churn, s/i915_mmio_reg_t/i915_reg_t/
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1447853606-2751-1-git-send-email-ville.syrjala@linux.intel.com
2015-11-18 15:33:26 +02:00
|
|
|
i915_reg_t dslreg = PIPEDSL(pipe);
|
2011-10-11 10:43:02 -07:00
|
|
|
u32 temp;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
temp = intel_de_read(dev_priv, dslreg);
|
2011-10-11 10:43:02 -07:00
|
|
|
udelay(500);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (wait_for(intel_de_read(dev_priv, dslreg) != temp, 5)) {
|
|
|
|
|
if (wait_for(intel_de_read(dev_priv, dslreg) != temp, 5))
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm,
|
|
|
|
|
"mode set failed: pipe %c stuck\n",
|
|
|
|
|
pipe_name(pipe));
|
2011-10-11 10:43:02 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state)
|
2013-04-25 12:55:02 -07:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2020-04-22 19:19:14 +03:00
|
|
|
const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
|
2019-08-21 20:30:31 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2020-04-22 19:19:14 +03:00
|
|
|
int width = drm_rect_width(dst);
|
|
|
|
|
int height = drm_rect_height(dst);
|
|
|
|
|
int x = dst->x1;
|
|
|
|
|
int y = dst->y1;
|
2013-04-25 12:55:02 -07:00
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
if (!crtc_state->pch_pfit.enabled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Force use of hard-coded filter coefficients
|
|
|
|
|
* as some pre-programmed values are broken,
|
|
|
|
|
* e.g. x201.
|
|
|
|
|
*/
|
|
|
|
|
if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv))
|
2022-02-24 18:51:01 +02:00
|
|
|
intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE |
|
|
|
|
|
PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe));
|
2020-04-22 19:19:13 +03:00
|
|
|
else
|
2022-02-24 18:51:01 +02:00
|
|
|
intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE |
|
|
|
|
|
PF_FILTER_MED_3x3);
|
|
|
|
|
intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), x << 16 | y);
|
|
|
|
|
intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), width << 16 | height);
|
2011-10-11 10:43:02 -07:00
|
|
|
}
|
|
|
|
|
|
2021-06-09 11:56:32 +03:00
|
|
|
static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc)
|
2014-05-08 19:23:13 +03:00
|
|
|
{
|
2021-06-09 11:56:32 +03:00
|
|
|
if (crtc->overlay)
|
|
|
|
|
(void) intel_overlay_switch_off(crtc->overlay);
|
2014-05-08 19:23:13 +03:00
|
|
|
|
|
|
|
|
/* Let userspace switch the overlay on again. In most cases userspace
|
|
|
|
|
* has to recompute where to put it anyway.
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:50 +02:00
|
|
|
static bool needs_nv12_wa(const struct intel_crtc_state *crtc_state)
|
2018-05-12 03:03:12 +05:30
|
|
|
{
|
2019-11-27 21:05:50 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
|
|
|
|
|
2018-05-12 03:03:12 +05:30
|
|
|
if (!crtc_state->nv12_planes)
|
|
|
|
|
return false;
|
|
|
|
|
|
2018-10-31 09:28:45 -07:00
|
|
|
/* WA Display #0827: Gen9:all */
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 9)
|
2018-05-12 03:03:12 +05:30
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:50 +02:00
|
|
|
static bool needs_scalerclk_wa(const struct intel_crtc_state *crtc_state)
|
2019-04-17 11:59:01 -07:00
|
|
|
{
|
2019-11-27 21:05:50 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
|
|
|
|
|
2020-04-13 13:53:22 -04:00
|
|
|
/* Wa_2006604312:icl,ehl */
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (crtc_state->scaler_state.scaler_users > 0 && DISPLAY_VER(dev_priv) == 11)
|
2019-04-17 11:59:01 -07:00
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-29 10:54:42 +05:30
|
|
|
static bool needs_cursorclk_wa(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
|
|
|
|
|
|
|
|
|
/* Wa_1604331009:icl,jsl,ehl */
|
|
|
|
|
if (is_hdr_mode(crtc_state) &&
|
|
|
|
|
crtc_state->active_planes & BIT(PLANE_CURSOR) &&
|
|
|
|
|
DISPLAY_VER(dev_priv) == 11)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-30 22:09:43 +03:00
|
|
|
static void intel_async_flip_vtd_wa(struct drm_i915_private *i915,
|
|
|
|
|
enum pipe pipe, bool enable)
|
|
|
|
|
{
|
|
|
|
|
if (DISPLAY_VER(i915) == 9) {
|
|
|
|
|
/*
|
|
|
|
|
* "Plane N strech max must be programmed to 11b (x1)
|
|
|
|
|
* when Async flips are enabled on that plane."
|
|
|
|
|
*/
|
|
|
|
|
intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe),
|
|
|
|
|
SKL_PLANE1_STRETCH_MAX_MASK,
|
|
|
|
|
enable ? SKL_PLANE1_STRETCH_MAX_X1 : SKL_PLANE1_STRETCH_MAX_X8);
|
|
|
|
|
} else {
|
|
|
|
|
/* Also needed on HSW/BDW albeit undocumented */
|
|
|
|
|
intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe),
|
|
|
|
|
HSW_PRI_STRETCH_MAX_MASK,
|
|
|
|
|
enable ? HSW_PRI_STRETCH_MAX_X1 : HSW_PRI_STRETCH_MAX_X8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
|
|
|
|
|
2022-03-29 10:02:04 +01:00
|
|
|
return crtc_state->uapi.async_flip && i915_vtd_active(i915) &&
|
2021-09-30 22:09:43 +03:00
|
|
|
(DISPLAY_VER(i915) == 9 || IS_BROADWELL(i915) || IS_HASWELL(i915));
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:54 +02:00
|
|
|
static bool planes_enabling(const struct intel_crtc_state *old_crtc_state,
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
2020-12-21 11:04:45 +02:00
|
|
|
return (!old_crtc_state->active_planes || intel_crtc_needs_modeset(new_crtc_state)) &&
|
2019-11-27 21:05:54 +02:00
|
|
|
new_crtc_state->active_planes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool planes_disabling(const struct intel_crtc_state *old_crtc_state,
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
|
|
|
|
return old_crtc_state->active_planes &&
|
2020-12-21 11:04:45 +02:00
|
|
|
(!new_crtc_state->active_planes || intel_crtc_needs_modeset(new_crtc_state));
|
2019-11-27 21:05:54 +02:00
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:53 +02:00
|
|
|
static void intel_post_plane_update(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-05-24 17:13:53 +02:00
|
|
|
{
|
2019-11-27 21:05:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-27 21:05:54 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2019-11-27 21:05:53 +02:00
|
|
|
intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2019-11-27 21:05:52 +02:00
|
|
|
if (new_crtc_state->update_wm_post && new_crtc_state->hw.active)
|
2021-09-29 01:57:47 +03:00
|
|
|
intel_update_watermarks(dev_priv);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2022-02-09 13:35:22 +02:00
|
|
|
hsw_ips_post_update(state, crtc);
|
2019-12-13 15:34:50 +02:00
|
|
|
intel_fbc_post_update(state, crtc);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2021-09-30 22:09:43 +03:00
|
|
|
if (needs_async_flip_vtd_wa(old_crtc_state) &&
|
|
|
|
|
!needs_async_flip_vtd_wa(new_crtc_state))
|
|
|
|
|
intel_async_flip_vtd_wa(dev_priv, pipe, false);
|
|
|
|
|
|
2019-11-27 21:05:50 +02:00
|
|
|
if (needs_nv12_wa(old_crtc_state) &&
|
2019-11-27 21:05:52 +02:00
|
|
|
!needs_nv12_wa(new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
skl_wa_827(dev_priv, pipe, false);
|
2019-04-17 11:59:01 -07:00
|
|
|
|
2019-11-27 21:05:50 +02:00
|
|
|
if (needs_scalerclk_wa(old_crtc_state) &&
|
2019-11-27 21:05:52 +02:00
|
|
|
!needs_scalerclk_wa(new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
icl_wa_scalerclkgating(dev_priv, pipe, false);
|
2021-09-29 10:54:42 +05:30
|
|
|
|
|
|
|
|
if (needs_cursorclk_wa(old_crtc_state) &&
|
|
|
|
|
!needs_cursorclk_wa(new_crtc_state))
|
|
|
|
|
icl_wa_cursorclkgating(dev_priv, pipe, false);
|
|
|
|
|
|
2022-03-15 15:27:52 +02:00
|
|
|
intel_drrs_activate(new_crtc_state);
|
2016-05-24 17:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
2021-01-11 18:37:05 +02:00
|
|
|
static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
u8 update_planes = crtc_state->update_planes;
|
|
|
|
|
const struct intel_plane_state *plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
2022-02-14 12:55:31 +02:00
|
|
|
if (plane->pipe == crtc->pipe &&
|
|
|
|
|
update_planes & BIT(plane->id))
|
2021-01-11 18:37:05 +02:00
|
|
|
plane->enable_flip_done(plane);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_crtc_disable_flip_done(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
u8 update_planes = crtc_state->update_planes;
|
|
|
|
|
const struct intel_plane_state *plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
2022-02-14 12:55:31 +02:00
|
|
|
if (plane->pipe == crtc->pipe &&
|
|
|
|
|
update_planes & BIT(plane->id))
|
2021-01-11 18:37:05 +02:00
|
|
|
plane->disable_flip_done(plane);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-11 18:37:07 +02:00
|
|
|
static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2020-09-21 16:32:08 +05:30
|
|
|
{
|
2021-01-11 18:37:07 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
u8 update_planes = new_crtc_state->update_planes;
|
|
|
|
|
const struct intel_plane_state *old_plane_state;
|
2020-09-21 16:32:08 +05:30
|
|
|
struct intel_plane *plane;
|
2021-01-11 18:37:07 +02:00
|
|
|
bool need_vbl_wait = false;
|
2020-09-21 16:32:08 +05:30
|
|
|
int i;
|
|
|
|
|
|
2021-01-11 18:37:07 +02:00
|
|
|
for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
|
|
|
|
|
if (plane->need_async_flip_disable_wa &&
|
|
|
|
|
plane->pipe == crtc->pipe &&
|
|
|
|
|
update_planes & BIT(plane->id)) {
|
|
|
|
|
/*
|
|
|
|
|
* Apart from the async flip bit we want to
|
|
|
|
|
* preserve the old state for the plane.
|
|
|
|
|
*/
|
|
|
|
|
plane->async_flip(plane, old_crtc_state,
|
|
|
|
|
old_plane_state, false);
|
|
|
|
|
need_vbl_wait = true;
|
|
|
|
|
}
|
2020-09-21 16:32:08 +05:30
|
|
|
}
|
|
|
|
|
|
2021-01-11 18:37:07 +02:00
|
|
|
if (need_vbl_wait)
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2020-09-21 16:32:08 +05:30
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:53 +02:00
|
|
|
static void intel_pre_plane_update(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2015-06-15 12:33:49 +02:00
|
|
|
{
|
2019-11-27 21:05:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-27 21:05:54 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2015-06-15 12:33:49 +02:00
|
|
|
|
2022-03-15 15:27:52 +02:00
|
|
|
intel_drrs_deactivate(old_crtc_state);
|
2022-03-15 23:39:44 +02:00
|
|
|
|
2021-10-22 13:32:56 +03:00
|
|
|
intel_psr_pre_plane_update(state, crtc);
|
|
|
|
|
|
2022-02-09 13:35:22 +02:00
|
|
|
if (hsw_ips_pre_update(state, crtc))
|
2022-02-09 13:35:20 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2017-11-22 19:39:01 +01:00
|
|
|
|
2019-12-13 15:34:50 +02:00
|
|
|
if (intel_fbc_pre_update(state, crtc))
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2019-11-28 17:03:38 +02:00
|
|
|
|
2021-09-30 22:09:43 +03:00
|
|
|
if (!needs_async_flip_vtd_wa(old_crtc_state) &&
|
|
|
|
|
needs_async_flip_vtd_wa(new_crtc_state))
|
|
|
|
|
intel_async_flip_vtd_wa(dev_priv, pipe, true);
|
|
|
|
|
|
2018-05-12 03:03:12 +05:30
|
|
|
/* Display WA 827 */
|
2019-11-27 21:05:50 +02:00
|
|
|
if (!needs_nv12_wa(old_crtc_state) &&
|
2019-11-27 21:05:52 +02:00
|
|
|
needs_nv12_wa(new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
skl_wa_827(dev_priv, pipe, true);
|
2019-04-17 11:59:01 -07:00
|
|
|
|
2020-04-13 13:53:22 -04:00
|
|
|
/* Wa_2006604312:icl,ehl */
|
2019-11-27 21:05:50 +02:00
|
|
|
if (!needs_scalerclk_wa(old_crtc_state) &&
|
2019-11-27 21:05:52 +02:00
|
|
|
needs_scalerclk_wa(new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
icl_wa_scalerclkgating(dev_priv, pipe, true);
|
2018-05-12 03:03:12 +05:30
|
|
|
|
2021-09-29 10:54:42 +05:30
|
|
|
/* Wa_1604331009:icl,jsl,ehl */
|
|
|
|
|
if (!needs_cursorclk_wa(old_crtc_state) &&
|
|
|
|
|
needs_cursorclk_wa(new_crtc_state))
|
|
|
|
|
icl_wa_cursorclkgating(dev_priv, pipe, true);
|
|
|
|
|
|
2017-03-02 19:15:00 +02:00
|
|
|
/*
|
|
|
|
|
* Vblank time updates from the shadow to live plane control register
|
|
|
|
|
* are blocked if the memory self-refresh mode is active at that
|
|
|
|
|
* moment. So to make sure the plane gets truly disabled, disable
|
|
|
|
|
* first the self-refresh mode. The self-refresh enable bit in turn
|
|
|
|
|
* will be checked/applied by the HW only at the next frame start
|
|
|
|
|
* event which is after the vblank start event, so we need to have a
|
|
|
|
|
* wait-for-vblank between disabling the plane and the pipe.
|
|
|
|
|
*/
|
2019-10-31 12:26:02 +01:00
|
|
|
if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&
|
2019-11-27 21:05:52 +02:00
|
|
|
new_crtc_state->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2015-12-03 13:49:13 +01:00
|
|
|
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
/*
|
|
|
|
|
* IVB workaround: must disable low power watermarks for at least
|
|
|
|
|
* one frame before enabling scaling. LP watermarks can be re-enabled
|
|
|
|
|
* when scaling is disabled.
|
|
|
|
|
*
|
|
|
|
|
* WaCxSRDisabledForSpriteScaling:ivb
|
|
|
|
|
*/
|
2019-11-27 21:05:52 +02:00
|
|
|
if (old_crtc_state->hw.active &&
|
|
|
|
|
new_crtc_state->disable_lp_wm && ilk_disable_lp_wm(dev_priv))
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
|
|
|
|
|
/*
|
2019-11-27 21:05:54 +02:00
|
|
|
* If we're doing a modeset we don't need to do any
|
|
|
|
|
* pre-vblank watermark programming here.
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
*/
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state)) {
|
2019-11-27 21:05:54 +02:00
|
|
|
/*
|
|
|
|
|
* For platforms that support atomic watermarks, program the
|
|
|
|
|
* 'intermediate' watermarks immediately. On pre-gen9 platforms, these
|
|
|
|
|
* will be the intermediate values that are safe for both pre- and
|
|
|
|
|
* post- vblank; when vblank happens, the 'active' values will be set
|
|
|
|
|
* to the final 'target' values and we'll do this again to get the
|
|
|
|
|
* optimal watermarks. For gen9+ platforms, the values we program here
|
|
|
|
|
* will be the final target values which will get automatically latched
|
|
|
|
|
* at vblank time; no further programming will be necessary.
|
|
|
|
|
*
|
|
|
|
|
* If a platform hasn't been transitioned to atomic watermarks yet,
|
|
|
|
|
* we'll continue to update watermarks the old way, if flags tell
|
|
|
|
|
* us to.
|
|
|
|
|
*/
|
2021-09-29 01:57:48 +03:00
|
|
|
if (!intel_initial_watermarks(state, crtc))
|
|
|
|
|
if (new_crtc_state->update_wm_pre)
|
|
|
|
|
intel_update_watermarks(dev_priv);
|
2019-11-27 21:05:54 +02:00
|
|
|
}
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
|
|
|
|
|
/*
|
2019-11-27 21:05:54 +02:00
|
|
|
* Gen2 reports pipe underruns whenever all planes are disabled.
|
|
|
|
|
* So disable underrun reporting before all the planes get disabled.
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
*
|
2019-11-27 21:05:54 +02:00
|
|
|
* We do this after .initial_watermarks() so that we have a
|
|
|
|
|
* chance of catching underruns with the intermediate watermarks
|
|
|
|
|
* vs. the old plane configuration.
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2 && planes_disabling(old_crtc_state, new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
|
2020-09-21 16:32:08 +05:30
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* WA for platforms where async address update enable bit
|
|
|
|
|
* is double buffered and only latched at start of vblank.
|
|
|
|
|
*/
|
2021-01-11 18:37:07 +02:00
|
|
|
if (old_crtc_state->uapi.async_flip && !new_crtc_state->uapi.async_flip)
|
|
|
|
|
intel_crtc_async_flip_disable_wa(state, crtc);
|
2015-06-15 12:33:49 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-14 23:07:20 +02:00
|
|
|
static void intel_crtc_disable_planes(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2015-04-21 17:12:54 +03:00
|
|
|
{
|
2018-11-14 23:07:20 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
unsigned int update_mask = new_crtc_state->update_planes;
|
|
|
|
|
const struct intel_plane_state *old_plane_state;
|
2018-09-20 12:27:07 +02:00
|
|
|
struct intel_plane *plane;
|
|
|
|
|
unsigned fb_bits = 0;
|
2018-11-14 23:07:20 +02:00
|
|
|
int i;
|
2015-04-21 17:12:54 +03:00
|
|
|
|
2018-09-20 12:27:07 +02:00
|
|
|
intel_crtc_dpms_overlay_disable(crtc);
|
2015-04-21 17:12:52 +03:00
|
|
|
|
2018-11-14 23:07:20 +02:00
|
|
|
for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
|
|
|
|
|
if (crtc->pipe != plane->pipe ||
|
|
|
|
|
!(update_mask & BIT(plane->id)))
|
|
|
|
|
continue;
|
|
|
|
|
|
2021-10-18 14:50:25 +03:00
|
|
|
intel_plane_disable_arm(plane, new_crtc_state);
|
2014-05-22 17:48:06 +03:00
|
|
|
|
2019-10-31 12:26:08 +01:00
|
|
|
if (old_plane_state->uapi.visible)
|
2018-09-20 12:27:07 +02:00
|
|
|
fb_bits |= plane->frontbuffer_bit;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 23:07:20 +02:00
|
|
|
intel_frontbuffer_flip(dev_priv, fb_bits);
|
2014-03-07 18:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-28 17:36:32 +03:00
|
|
|
/*
|
|
|
|
|
* intel_connector_primary_encoder - get the primary encoder for a connector
|
|
|
|
|
* @connector: connector for which to return the encoder
|
|
|
|
|
*
|
|
|
|
|
* Returns the primary encoder for a connector. There is a 1:1 mapping from
|
|
|
|
|
* all connectors to their encoder, except for DP-MST connectors which have
|
|
|
|
|
* both a virtual and a primary encoder. These DP-MST primary encoders can be
|
|
|
|
|
* pointed to by as many DP-MST connectors as there are pipes.
|
|
|
|
|
*/
|
|
|
|
|
static struct intel_encoder *
|
|
|
|
|
intel_connector_primary_encoder(struct intel_connector *connector)
|
|
|
|
|
{
|
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
|
|
|
|
|
if (connector->mst_port)
|
|
|
|
|
return &dp_to_dig_port(connector->mst_port)->base;
|
|
|
|
|
|
2019-12-04 20:05:42 +02:00
|
|
|
encoder = intel_attached_encoder(connector);
|
2020-04-06 16:57:46 +05:30
|
|
|
drm_WARN_ON(connector->base.dev, !encoder);
|
2019-06-28 17:36:32 +03:00
|
|
|
|
|
|
|
|
return encoder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_encoders_update_prepare(struct intel_atomic_state *state)
|
|
|
|
|
{
|
2021-11-15 20:11:21 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
|
|
|
|
struct intel_crtc_state *new_crtc_state, *old_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
2019-06-28 17:36:32 +03:00
|
|
|
struct drm_connector_state *new_conn_state;
|
2019-12-22 17:06:48 -08:00
|
|
|
struct drm_connector *connector;
|
2019-06-28 17:36:32 +03:00
|
|
|
int i;
|
|
|
|
|
|
2021-11-15 20:11:21 +02:00
|
|
|
/*
|
|
|
|
|
* Make sure the DPLL state is up-to-date for fastset TypeC ports after non-blocking commits.
|
|
|
|
|
* TODO: Update the DPLL state for all cases in the encoder->update_prepare() hook.
|
|
|
|
|
*/
|
|
|
|
|
if (i915->dpll.mgr) {
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
|
|
|
|
if (intel_crtc_needs_modeset(new_crtc_state))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
new_crtc_state->shared_dpll = old_crtc_state->shared_dpll;
|
|
|
|
|
new_crtc_state->dpll_hw_state = old_crtc_state->dpll_hw_state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!state->modeset)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, new_conn_state,
|
|
|
|
|
i) {
|
|
|
|
|
struct intel_connector *intel_connector;
|
2019-06-28 17:36:32 +03:00
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
if (!intel_connector_needs_modeset(state, connector))
|
2019-06-28 17:36:32 +03:00
|
|
|
continue;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
intel_connector = to_intel_connector(connector);
|
|
|
|
|
encoder = intel_connector_primary_encoder(intel_connector);
|
2019-06-28 17:36:32 +03:00
|
|
|
if (!encoder->update_prepare)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
crtc = new_conn_state->crtc ?
|
|
|
|
|
to_intel_crtc(new_conn_state->crtc) : NULL;
|
|
|
|
|
encoder->update_prepare(state, encoder, crtc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_encoders_update_complete(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_connector_state *new_conn_state;
|
2019-12-22 17:06:48 -08:00
|
|
|
struct drm_connector *connector;
|
2019-06-28 17:36:32 +03:00
|
|
|
int i;
|
|
|
|
|
|
2021-11-15 20:11:21 +02:00
|
|
|
if (!state->modeset)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, new_conn_state,
|
|
|
|
|
i) {
|
|
|
|
|
struct intel_connector *intel_connector;
|
2019-06-28 17:36:32 +03:00
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
if (!intel_connector_needs_modeset(state, connector))
|
2019-06-28 17:36:32 +03:00
|
|
|
continue;
|
|
|
|
|
|
2019-12-22 17:06:48 -08:00
|
|
|
intel_connector = to_intel_connector(connector);
|
|
|
|
|
encoder = intel_connector_primary_encoder(intel_connector);
|
2019-06-28 17:36:32 +03:00
|
|
|
if (!encoder->update_complete)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
crtc = new_conn_state->crtc ?
|
|
|
|
|
to_intel_crtc(new_conn_state->crtc) : NULL;
|
|
|
|
|
encoder->update_complete(state, encoder, crtc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_pre_pll_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (encoder->pre_pll_enable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->pre_pll_enable(state, encoder,
|
|
|
|
|
crtc_state, conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_pre_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (encoder->pre_enable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->pre_enable(state, encoder,
|
|
|
|
|
crtc_state, conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
2018-10-16 15:41:34 +03:00
|
|
|
if (encoder->enable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->enable(state, encoder,
|
|
|
|
|
crtc_state, conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
intel_opregion_notify_encoder(encoder, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *old_conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(old_conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (old_conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_opregion_notify_encoder(encoder, false);
|
2018-10-16 15:41:34 +03:00
|
|
|
if (encoder->disable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->disable(state, encoder,
|
|
|
|
|
old_crtc_state, old_conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_post_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *old_conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(old_conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (old_conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (encoder->post_disable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->post_disable(state, encoder,
|
|
|
|
|
old_crtc_state, old_conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_post_pll_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-09 17:04:03 +02:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *old_conn_state;
|
2016-08-09 17:04:03 +02:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
|
2016-08-09 17:04:03 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(old_conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (old_conn_state->crtc != &crtc->base)
|
2016-08-09 17:04:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (encoder->post_pll_disable)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->post_pll_disable(state, encoder,
|
|
|
|
|
old_crtc_state, old_conn_state);
|
2016-08-09 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:21 +02:00
|
|
|
static void intel_encoders_update_pipe(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2018-12-20 14:21:18 +01:00
|
|
|
{
|
2019-11-18 18:44:21 +02:00
|
|
|
const struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct drm_connector_state *conn_state;
|
2018-12-20 14:21:18 +01:00
|
|
|
struct drm_connector *conn;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
|
2018-12-20 14:21:18 +01:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(conn_state->best_encoder);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (conn_state->crtc != &crtc->base)
|
2018-12-20 14:21:18 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (encoder->update_pipe)
|
2020-03-13 18:48:30 +02:00
|
|
|
encoder->update_pipe(state, encoder,
|
|
|
|
|
crtc_state, conn_state);
|
2018-12-20 14:21:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-07 22:21:46 +02:00
|
|
|
static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-02-07 22:21:46 +02:00
|
|
|
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
|
|
|
|
|
|
2021-10-18 14:50:25 +03:00
|
|
|
plane->disable_arm(plane, crtc_state);
|
2019-02-07 22:21:46 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-01 11:19:09 +02:00
|
|
|
static void ilk_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
|
|
|
|
|
|
|
|
|
if (crtc_state->has_pch_encoder) {
|
|
|
|
|
intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->fdi_m_n);
|
|
|
|
|
} else if (intel_crtc_has_dp_encoder(crtc_state)) {
|
|
|
|
|
intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m_n);
|
|
|
|
|
intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m2_n2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intel_set_transcoder_timings(crtc_state);
|
|
|
|
|
|
|
|
|
|
ilk_set_pipeconf(crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
static void ilk_crtc_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2011-01-05 10:31:48 -08:00
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2011-01-05 10:31:48 -08:00
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
|
2011-01-05 10:31:48 -08:00
|
|
|
return;
|
|
|
|
|
|
2016-04-01 21:53:17 +03:00
|
|
|
/*
|
|
|
|
|
* Sometimes spurious CPU pipe underruns happen during FDI
|
|
|
|
|
* training, at least with VGA+HDMI cloning. Suppress them.
|
|
|
|
|
*
|
|
|
|
|
* On ILK we get an occasional spurious CPU pipe underruns
|
|
|
|
|
* between eDP port A enable and vdd enable. Also PCH port
|
|
|
|
|
* enable seems to result in the occasional CPU pipe underrun.
|
|
|
|
|
*
|
|
|
|
|
* Spurious PCH underruns also occur during PCH enabling.
|
|
|
|
|
*/
|
2018-05-24 22:04:06 +03:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
|
|
|
|
|
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
|
2015-10-30 19:21:31 +02:00
|
|
|
|
2022-02-01 11:19:09 +02:00
|
|
|
ilk_configure_cpu_transcoder(new_crtc_state);
|
2014-04-24 23:55:08 +02:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_set_pipe_src_size(new_crtc_state);
|
2014-04-24 23:55:08 +02:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
crtc->active = true;
|
drm/i915: report Gen5+ CPU and PCH FIFO underruns
In this commit we enable both CPU and PCH FIFO underrun reporting and
start reporting them. We follow a few rules:
- after we receive one of these errors, we mask the interrupt, so
we won't get an "interrupt storm" and we also won't flood dmesg;
- at each mode set we enable the interrupts again, so we'll see each
message at most once per mode set;
- in the specific places where we need to ignore the errors, we
completely mask the interrupts.
The downside of this patch is that since we're completely disabling
(masking) the interrupts instead of just not printing error messages,
we will mask more than just what we want on IVB/HSW CPU interrupts
(due to GEN7_ERR_INT) and on CPT/PPT/LPT PCHs (due to SERR_INT). So
when we decide to mask PCH FIFO underruns for pipe A on CPT, we'll
also be masking PCH FIFO underruns for pipe B, because both are
reported by SERR_INT, which has to be either completely enabled or
completely disabled (in othe words, there's no way to disable/enable
specific bits of GEN7_ERR_INT and SERR_INT).
V2: Rename some functions and variables, downgrade messages to
DRM_DEBUG_DRIVER and rebase.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-12 17:57:57 -03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_pre_enable(state, crtc);
|
2011-01-05 10:31:48 -08:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
if (new_crtc_state->has_pch_encoder) {
|
2022-01-24 21:31:36 +02:00
|
|
|
ilk_pch_pre_enable(state, crtc);
|
2012-09-06 22:08:33 +02:00
|
|
|
} else {
|
|
|
|
|
assert_fdi_tx_disabled(dev_priv, pipe);
|
|
|
|
|
assert_fdi_rx_disabled(dev_priv, pipe);
|
|
|
|
|
}
|
2011-01-05 10:31:48 -08:00
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
ilk_pfit_enable(new_crtc_state);
|
2011-01-05 10:31:48 -08:00
|
|
|
|
2011-06-15 23:32:33 +02:00
|
|
|
/*
|
|
|
|
|
* On ILK+ LUT must be loaded before the pipe is running but with
|
|
|
|
|
* clocks enabled
|
|
|
|
|
*/
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_color_load_luts(new_crtc_state);
|
2022-02-24 18:51:02 +02:00
|
|
|
intel_color_commit_noarm(new_crtc_state);
|
|
|
|
|
intel_color_commit_arm(new_crtc_state);
|
2019-02-07 22:21:46 +02:00
|
|
|
/* update DSPCNTR to configure gamma for pipe bottom color */
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_disable_primary_plane(new_crtc_state);
|
2011-06-15 23:32:33 +02:00
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_initial_watermarks(state, crtc);
|
2021-09-13 17:44:29 +03:00
|
|
|
intel_enable_transcoder(new_crtc_state);
|
2011-01-05 10:31:48 -08:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
if (new_crtc_state->has_pch_encoder)
|
2021-10-15 10:16:19 +03:00
|
|
|
ilk_pch_enable(state, crtc);
|
2010-09-10 10:57:18 -07:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_crtc_vblank_on(new_crtc_state);
|
2015-01-07 13:54:39 +01:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_enable(state, crtc);
|
2012-07-02 00:16:19 +02:00
|
|
|
|
2016-10-13 11:02:53 +01:00
|
|
|
if (HAS_PCH_CPT(dev_priv))
|
2019-11-18 18:44:27 +02:00
|
|
|
cpt_verify_modeset(dev_priv, pipe);
|
2015-10-30 19:20:27 +02:00
|
|
|
|
2018-05-24 22:04:05 +03:00
|
|
|
/*
|
|
|
|
|
* Must wait for vblank to avoid spurious PCH FIFO underruns.
|
|
|
|
|
* And a second vblank wait is needed at least on ILK with
|
|
|
|
|
* some interlaced HDMI modes. Let's do the double wait always
|
|
|
|
|
* in case there are more corner cases we don't know about.
|
|
|
|
|
*/
|
2019-11-18 18:44:29 +02:00
|
|
|
if (new_crtc_state->has_pch_encoder) {
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
|
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2018-05-24 22:04:05 +03:00
|
|
|
}
|
2016-04-01 21:53:17 +03:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
2015-10-30 19:20:27 +02:00
|
|
|
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
|
2010-09-10 10:26:01 -07:00
|
|
|
}
|
|
|
|
|
|
2017-10-02 10:55:57 +03:00
|
|
|
static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum pipe pipe, bool apply)
|
|
|
|
|
{
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
u32 val = intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe));
|
2017-10-02 10:55:57 +03:00
|
|
|
u32 mask = DPF_GATING_DIS | DPF_RAM_GATING_DIS | DPFR_GATING_DIS;
|
|
|
|
|
|
|
|
|
|
if (apply)
|
|
|
|
|
val |= mask;
|
|
|
|
|
else
|
|
|
|
|
val &= ~mask;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), val);
|
2017-10-02 10:55:57 +03:00
|
|
|
}
|
|
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
static void hsw_set_linetime_wm(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
|
|
|
|
|
intel_de_write(dev_priv, WM_LINETIME(crtc->pipe),
|
|
|
|
|
HSW_LINETIME(crtc_state->linetime) |
|
|
|
|
|
HSW_IPS_LINETIME(crtc_state->ips_linetime));
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 15:21:38 +03:00
|
|
|
static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
i915_reg_t reg = CHICKEN_TRANS(crtc_state->cpu_transcoder);
|
|
|
|
|
u32 val;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
val = intel_de_read(dev_priv, reg);
|
2019-10-24 15:21:38 +03:00
|
|
|
val &= ~HSW_FRAME_START_DELAY_MASK;
|
2022-02-21 13:03:53 +02:00
|
|
|
val |= HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, reg, val);
|
2019-10-24 15:21:38 +03:00
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:08 -08:00
|
|
|
static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
|
|
|
|
|
const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2022-02-03 20:38:18 +02:00
|
|
|
struct intel_crtc *master_crtc = intel_master_crtc(crtc_state);
|
2020-11-17 11:47:08 -08:00
|
|
|
|
2021-10-22 13:33:03 +03:00
|
|
|
/*
|
|
|
|
|
* Enable sequence steps 1-7 on bigjoiner master
|
|
|
|
|
*/
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(crtc_state))
|
2021-10-22 13:32:59 +03:00
|
|
|
intel_encoders_pre_pll_enable(state, master_crtc);
|
2021-10-22 13:33:03 +03:00
|
|
|
|
|
|
|
|
if (crtc_state->shared_dpll)
|
|
|
|
|
intel_enable_shared_dpll(crtc_state);
|
|
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(crtc_state))
|
2021-10-22 13:32:59 +03:00
|
|
|
intel_encoders_pre_enable(state, master_crtc);
|
2020-11-17 11:47:08 -08:00
|
|
|
}
|
|
|
|
|
|
2022-01-24 21:26:37 +02:00
|
|
|
static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
|
|
|
|
|
2022-01-28 12:37:48 +02:00
|
|
|
if (crtc_state->has_pch_encoder) {
|
|
|
|
|
intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->fdi_m_n);
|
|
|
|
|
} else if (intel_crtc_has_dp_encoder(crtc_state)) {
|
|
|
|
|
intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m_n);
|
|
|
|
|
intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m2_n2);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-24 21:26:37 +02:00
|
|
|
intel_set_transcoder_timings(crtc_state);
|
|
|
|
|
|
|
|
|
|
if (cpu_transcoder != TRANSCODER_EDP)
|
|
|
|
|
intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
|
|
|
|
|
crtc_state->pixel_multiplier - 1);
|
|
|
|
|
|
|
|
|
|
hsw_set_frame_start_delay(crtc_state);
|
|
|
|
|
|
|
|
|
|
hsw_set_transconf(crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:05 -08:00
|
|
|
static void hsw_crtc_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2012-10-23 18:29:51 -02:00
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
|
2019-11-18 18:44:29 +02:00
|
|
|
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
|
2017-10-02 10:55:57 +03:00
|
|
|
bool psl_clkgate_wa;
|
2012-10-23 18:29:51 -02:00
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
|
2012-10-23 18:29:51 -02:00
|
|
|
return;
|
|
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
if (!new_crtc_state->bigjoiner_pipes) {
|
2020-11-17 11:47:08 -08:00
|
|
|
intel_encoders_pre_pll_enable(state, crtc);
|
2014-06-25 22:02:03 +03:00
|
|
|
|
2020-11-17 11:47:08 -08:00
|
|
|
if (new_crtc_state->shared_dpll)
|
|
|
|
|
intel_enable_shared_dpll(new_crtc_state);
|
2018-05-02 14:58:51 -07:00
|
|
|
|
2020-11-17 11:47:08 -08:00
|
|
|
intel_encoders_pre_enable(state, crtc);
|
|
|
|
|
} else {
|
|
|
|
|
icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
|
|
|
|
|
}
|
2016-03-18 17:05:42 +02:00
|
|
|
|
2022-01-25 08:39:37 +02:00
|
|
|
intel_dsc_enable(new_crtc_state);
|
|
|
|
|
|
|
|
|
|
if (DISPLAY_VER(dev_priv) >= 13)
|
|
|
|
|
intel_uncompressed_joiner_enable(new_crtc_state);
|
|
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_set_pipe_src_size(new_crtc_state);
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
|
2020-11-17 11:47:08 -08:00
|
|
|
bdw_set_pipemisc(new_crtc_state);
|
2014-04-24 23:55:09 +02:00
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
if (!intel_crtc_is_bigjoiner_slave(new_crtc_state) &&
|
|
|
|
|
!transcoder_is_dsi(cpu_transcoder))
|
2022-01-24 21:26:37 +02:00
|
|
|
hsw_configure_cpu_transcoder(new_crtc_state);
|
2014-04-24 23:55:09 +02:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
crtc->active = true;
|
drm/i915: report Gen5+ CPU and PCH FIFO underruns
In this commit we enable both CPU and PCH FIFO underrun reporting and
start reporting them. We follow a few rules:
- after we receive one of these errors, we mask the interrupt, so
we won't get an "interrupt storm" and we also won't flood dmesg;
- at each mode set we enable the interrupts again, so we'll see each
message at most once per mode set;
- in the specific places where we need to ignore the errors, we
completely mask the interrupts.
The downside of this patch is that since we're completely disabling
(masking) the interrupts instead of just not printing error messages,
we will mask more than just what we want on IVB/HSW CPU interrupts
(due to GEN7_ERR_INT) and on CPT/PPT/LPT PCHs (due to SERR_INT). So
when we decide to mask PCH FIFO underruns for pipe A on CPT, we'll
also be masking PCH FIFO underruns for pipe B, because both are
reported by SERR_INT, which has to be either completely enabled or
completely disabled (in othe words, there's no way to disable/enable
specific bits of GEN7_ERR_INT and SERR_INT).
V2: Rename some functions and variables, downgrade messages to
DRM_DEBUG_DRIVER and rebase.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-04-12 17:57:57 -03:00
|
|
|
|
2021-07-28 14:59:42 -07:00
|
|
|
/* Display WA #1180: WaDisableScalarClockGating: glk */
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
psl_clkgate_wa = DISPLAY_VER(dev_priv) == 10 &&
|
2019-11-18 18:44:29 +02:00
|
|
|
new_crtc_state->pch_pfit.enabled;
|
2017-10-02 10:55:57 +03:00
|
|
|
if (psl_clkgate_wa)
|
|
|
|
|
glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true);
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9)
|
2019-12-24 00:40:06 -08:00
|
|
|
skl_pfit_enable(new_crtc_state);
|
2015-01-21 17:19:54 -08:00
|
|
|
else
|
2019-12-24 00:40:09 -08:00
|
|
|
ilk_pfit_enable(new_crtc_state);
|
2012-10-23 18:29:51 -02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* On ILK+ LUT must be loaded before the pipe is running but with
|
|
|
|
|
* clocks enabled
|
|
|
|
|
*/
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_color_load_luts(new_crtc_state);
|
2022-02-24 18:51:02 +02:00
|
|
|
intel_color_commit_noarm(new_crtc_state);
|
|
|
|
|
intel_color_commit_arm(new_crtc_state);
|
2019-02-07 22:21:46 +02:00
|
|
|
/* update DSPCNTR to configure gamma/csc for pipe bottom color */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 9)
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_disable_primary_plane(new_crtc_state);
|
2012-10-23 18:29:51 -02:00
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
hsw_set_linetime_wm(new_crtc_state);
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 11)
|
2021-07-27 07:50:56 -07:00
|
|
|
icl_set_pipe_chicken(new_crtc_state);
|
2018-06-21 20:43:56 +05:30
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_initial_watermarks(state, crtc);
|
2016-03-18 17:05:42 +02:00
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
|
2020-11-17 11:47:08 -08:00
|
|
|
intel_crtc_vblank_on(new_crtc_state);
|
|
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_enable(state, crtc);
|
2012-10-23 18:29:51 -02:00
|
|
|
|
2017-10-02 10:55:57 +03:00
|
|
|
if (psl_clkgate_wa) {
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2017-10-02 10:55:57 +03:00
|
|
|
glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 16:21:19 -03:00
|
|
|
/* If we change the relative order between pipe/planes enabling, we need
|
|
|
|
|
* to change the workaround. */
|
2019-11-18 18:44:29 +02:00
|
|
|
hsw_workaround_pipe = new_crtc_state->hsw_workaround_pipe;
|
2016-10-13 11:03:01 +01:00
|
|
|
if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) {
|
2021-12-01 15:57:06 +02:00
|
|
|
struct intel_crtc *wa_crtc;
|
|
|
|
|
|
|
|
|
|
wa_crtc = intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe);
|
|
|
|
|
|
|
|
|
|
intel_crtc_wait_for_next_vblank(wa_crtc);
|
|
|
|
|
intel_crtc_wait_for_next_vblank(wa_crtc);
|
2015-06-01 12:50:09 +02:00
|
|
|
}
|
2012-10-23 18:29:51 -02:00
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state)
|
2013-05-08 10:36:30 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
2018-10-04 11:45:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2013-05-08 10:36:30 +02:00
|
|
|
|
|
|
|
|
/* To avoid upsetting the power well on haswell only disable the pfit if
|
|
|
|
|
* it's in use. The hw state code will make sure we get this right. */
|
2020-04-22 19:19:13 +03:00
|
|
|
if (!old_crtc_state->pch_pfit.enabled)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-02-24 18:51:01 +02:00
|
|
|
intel_de_write_fw(dev_priv, PF_CTL(pipe), 0);
|
|
|
|
|
intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), 0);
|
|
|
|
|
intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), 0);
|
2013-05-08 10:36:30 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
static void ilk_crtc_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2010-09-10 10:26:01 -07:00
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2010-06-12 14:32:27 +08:00
|
|
|
|
2016-04-01 21:53:17 +03:00
|
|
|
/*
|
|
|
|
|
* Sometimes spurious CPU pipe underruns happen when the
|
|
|
|
|
* pipe is already disabled, but FDI RX/TX is still enabled.
|
|
|
|
|
* Happens at least with VGA+HDMI cloning. Suppress them.
|
|
|
|
|
*/
|
2018-05-24 22:04:06 +03:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
|
|
|
|
|
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
|
2015-10-30 19:20:27 +02:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_disable(state, crtc);
|
2012-07-10 10:42:52 +02:00
|
|
|
|
2019-12-13 21:52:16 +02:00
|
|
|
intel_crtc_vblank_off(old_crtc_state);
|
2015-01-07 13:54:39 +01:00
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
intel_disable_transcoder(old_crtc_state);
|
2009-07-24 01:00:32 +08:00
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
ilk_pfit_disable(old_crtc_state);
|
2009-06-05 15:38:42 +08:00
|
|
|
|
2018-10-04 11:46:04 +02:00
|
|
|
if (old_crtc_state->has_pch_encoder)
|
2021-10-15 10:16:23 +03:00
|
|
|
ilk_pch_disable(state, crtc);
|
2015-05-05 17:17:38 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_post_disable(state, crtc);
|
2009-06-05 15:38:42 +08:00
|
|
|
|
2021-10-15 10:16:23 +03:00
|
|
|
if (old_crtc_state->has_pch_encoder)
|
|
|
|
|
ilk_pch_post_disable(state, crtc);
|
2015-10-30 19:21:31 +02:00
|
|
|
|
2016-04-01 21:53:17 +03:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
2015-10-30 19:21:31 +02:00
|
|
|
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
|
2010-09-10 10:26:01 -07:00
|
|
|
}
|
2009-11-25 13:09:38 +08:00
|
|
|
|
2019-12-24 00:40:05 -08:00
|
|
|
static void hsw_crtc_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2012-04-20 17:11:53 +01:00
|
|
|
{
|
2021-10-22 13:33:03 +03:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
|
2019-12-13 21:52:17 +02:00
|
|
|
/*
|
|
|
|
|
* FIXME collapse everything to one hook.
|
|
|
|
|
* Need care with mst->ddi interactions.
|
|
|
|
|
*/
|
2022-02-03 20:38:19 +02:00
|
|
|
if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
|
2021-10-22 13:33:03 +03:00
|
|
|
intel_encoders_disable(state, crtc);
|
|
|
|
|
intel_encoders_post_disable(state, crtc);
|
|
|
|
|
}
|
2012-10-23 18:29:51 -02:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 11:45:53 +02:00
|
|
|
static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
|
2013-04-25 12:55:01 -07:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2013-04-25 12:55:01 -07:00
|
|
|
|
2018-10-04 11:45:53 +02:00
|
|
|
if (!crtc_state->gmch_pfit.control)
|
2013-04-25 12:55:01 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/*
|
2013-05-28 12:05:54 +02:00
|
|
|
* The panel fitter should only be adjusted whilst the pipe is disabled,
|
|
|
|
|
* according to register description and PRM.
|
2013-04-25 12:55:01 -07:00
|
|
|
*/
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
|
|
|
|
intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_ENABLE);
|
2021-09-13 17:44:29 +03:00
|
|
|
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
|
2013-04-25 12:55:01 -07:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PFIT_PGM_RATIOS,
|
|
|
|
|
crtc_state->gmch_pfit.pgm_ratios);
|
|
|
|
|
intel_de_write(dev_priv, PFIT_CONTROL, crtc_state->gmch_pfit.control);
|
2013-04-25 22:52:18 +02:00
|
|
|
|
|
|
|
|
/* Border color in case we don't scale up to the full screen. Black by
|
|
|
|
|
* default, change to something else for debugging. */
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, BCLRPAT(crtc->pipe), 0);
|
2013-04-25 12:55:01 -07:00
|
|
|
}
|
|
|
|
|
|
2019-07-09 11:39:30 -07:00
|
|
|
bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
|
|
|
|
|
{
|
|
|
|
|
if (phy == PHY_NONE)
|
|
|
|
|
return false;
|
2021-01-25 06:07:47 -08:00
|
|
|
else if (IS_ALDERLAKE_S(dev_priv))
|
|
|
|
|
return phy <= PHY_E;
|
drm/i915/dg1: Enable ports
For DG1 we have a little of mix up wrt to DDI/port names and indexes.
Bspec refers to the ports as DDIA, DDIB, DDI USBC1 and DDI USBC2
(besides the DDIA, DDIB, DDIC, DDID), but the previous naming is the
most unambiguous one. This means that for any register on Display Engine
we should use the index of A, B, D and E. However in some places this is
not true:
- VBT: uses C and D and have to be mapped to D/E
- IO/Combo: uses C and D, but we already differentiate those when
we created the phy vs port distinction.
This additional mapping for VBT and phy are already covered in previous
patches, so now we can initialize all the DDIs as A, B, D and E.
v2: Squash previous patch enabling just ports A and B since most of the
pumbling code is already merged now
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Clinton Taylor <Clinton.A.Taylor@intel.com>
Signed-off-by: Aditya Swarup <aditya.swarup@intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201117084836.2318234-1-lucas.demarchi@intel.com
2020-11-17 00:48:36 -08:00
|
|
|
else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
|
2020-06-03 14:15:19 -07:00
|
|
|
return phy <= PHY_D;
|
2020-10-14 00:59:48 +05:30
|
|
|
else if (IS_JSL_EHL(dev_priv))
|
2019-07-09 11:39:30 -07:00
|
|
|
return phy <= PHY_C;
|
2022-07-25 15:50:28 -07:00
|
|
|
else if (IS_ALDERLAKE_P(dev_priv) || IS_DISPLAY_VER(dev_priv, 11, 12))
|
2019-07-09 11:39:30 -07:00
|
|
|
return phy <= PHY_B;
|
2020-06-03 14:15:19 -07:00
|
|
|
else
|
2022-07-25 15:50:28 -07:00
|
|
|
/*
|
|
|
|
|
* DG2 outputs labelled as "combo PHY" in the bspec use
|
|
|
|
|
* SNPS PHYs with completely different programming,
|
|
|
|
|
* hence we always return false here.
|
|
|
|
|
*/
|
2020-06-03 14:15:19 -07:00
|
|
|
return false;
|
2019-07-09 11:39:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
|
|
|
|
|
{
|
2021-07-13 20:15:35 -07:00
|
|
|
if (IS_DG2(dev_priv))
|
|
|
|
|
/* DG2's "TC1" output uses a SNPS PHY */
|
|
|
|
|
return false;
|
|
|
|
|
else if (IS_ALDERLAKE_P(dev_priv))
|
2021-05-18 17:06:12 -07:00
|
|
|
return phy >= PHY_F && phy <= PHY_I;
|
|
|
|
|
else if (IS_TIGERLAKE(dev_priv))
|
2019-07-11 10:31:07 -07:00
|
|
|
return phy >= PHY_D && phy <= PHY_I;
|
2021-01-25 06:07:47 -08:00
|
|
|
else if (IS_ICELAKE(dev_priv))
|
2019-07-09 11:39:30 -07:00
|
|
|
return phy >= PHY_C && phy <= PHY_F;
|
2020-06-03 14:15:19 -07:00
|
|
|
else
|
|
|
|
|
return false;
|
2019-07-09 11:39:30 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 20:15:35 -07:00
|
|
|
bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy)
|
|
|
|
|
{
|
|
|
|
|
if (phy == PHY_NONE)
|
|
|
|
|
return false;
|
|
|
|
|
else if (IS_DG2(dev_priv))
|
|
|
|
|
/*
|
|
|
|
|
* All four "combo" ports and the TC1 port (PHY E) use
|
|
|
|
|
* Synopsis PHYs.
|
|
|
|
|
*/
|
|
|
|
|
return phy <= PHY_E;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-09 11:39:30 -07:00
|
|
|
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port)
|
|
|
|
|
{
|
2021-05-14 08:36:53 -07:00
|
|
|
if (DISPLAY_VER(i915) >= 13 && port >= PORT_D_XELPD)
|
|
|
|
|
return PHY_D + port - PORT_D_XELPD;
|
|
|
|
|
else if (DISPLAY_VER(i915) >= 13 && port >= PORT_TC1)
|
|
|
|
|
return PHY_F + port - PORT_TC1;
|
|
|
|
|
else if (IS_ALDERLAKE_S(i915) && port >= PORT_TC1)
|
2021-01-25 06:07:47 -08:00
|
|
|
return PHY_B + port - PORT_TC1;
|
|
|
|
|
else if ((IS_DG1(i915) || IS_ROCKETLAKE(i915)) && port >= PORT_TC1)
|
2020-10-28 23:33:06 +02:00
|
|
|
return PHY_C + port - PORT_TC1;
|
2020-10-14 00:59:48 +05:30
|
|
|
else if (IS_JSL_EHL(i915) && port == PORT_D)
|
2019-07-09 11:39:30 -07:00
|
|
|
return PHY_A;
|
|
|
|
|
|
2020-10-28 23:33:06 +02:00
|
|
|
return PHY_A + port - PORT_A;
|
2019-07-09 11:39:30 -07:00
|
|
|
}
|
|
|
|
|
|
2018-05-21 17:25:37 -07:00
|
|
|
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port)
|
|
|
|
|
{
|
2019-07-09 11:39:30 -07:00
|
|
|
if (!intel_phy_is_tc(dev_priv, intel_port_to_phy(dev_priv, port)))
|
2020-10-28 23:33:05 +02:00
|
|
|
return TC_PORT_NONE;
|
2018-05-21 17:25:37 -07:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 12)
|
2020-10-28 23:33:06 +02:00
|
|
|
return TC_PORT_1 + port - PORT_TC1;
|
|
|
|
|
else
|
|
|
|
|
return TC_PORT_1 + port - PORT_C;
|
2018-05-21 17:25:37 -07:00
|
|
|
}
|
|
|
|
|
|
2018-11-01 16:04:23 +02:00
|
|
|
enum intel_display_power_domain
|
|
|
|
|
intel_aux_power_domain(struct intel_digital_port *dig_port)
|
|
|
|
|
{
|
2022-04-15 00:06:53 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
2019-06-28 17:36:19 +03:00
|
|
|
|
2022-04-15 00:06:53 +03:00
|
|
|
if (intel_tc_port_in_tbt_alt_mode(dig_port))
|
|
|
|
|
return intel_display_power_tbt_aux_domain(i915, dig_port->aux_ch);
|
2020-04-14 12:49:50 -07:00
|
|
|
|
2022-04-15 00:06:53 +03:00
|
|
|
return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch);
|
2018-11-01 16:04:23 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
static void get_crtc_power_domains(struct intel_crtc_state *crtc_state,
|
|
|
|
|
struct intel_power_domain_mask *mask)
|
2014-03-05 16:20:52 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-07-01 19:05:46 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2021-09-13 17:44:31 +03:00
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
2016-02-10 13:49:36 +01:00
|
|
|
struct drm_encoder *encoder;
|
2019-06-28 10:55:13 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2022-04-15 00:06:48 +03:00
|
|
|
|
|
|
|
|
bitmap_zero(mask->bits, POWER_DOMAIN_NUM);
|
2014-03-05 16:20:52 +02:00
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (!crtc_state->hw.active)
|
2022-04-15 00:06:48 +03:00
|
|
|
return;
|
2015-07-13 16:30:27 +02:00
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(POWER_DOMAIN_PIPE(pipe), mask->bits);
|
|
|
|
|
set_bit(POWER_DOMAIN_TRANSCODER(cpu_transcoder), mask->bits);
|
2016-02-10 13:49:36 +01:00
|
|
|
if (crtc_state->pch_pfit.enabled ||
|
|
|
|
|
crtc_state->pch_pfit.force_thru)
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe), mask->bits);
|
2014-03-05 16:20:52 +02:00
|
|
|
|
2019-07-01 19:05:46 +03:00
|
|
|
drm_for_each_encoder_mask(encoder, &dev_priv->drm,
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.encoder_mask) {
|
2016-02-10 13:49:36 +01:00
|
|
|
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
|
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(intel_encoder->power_domain, mask->bits);
|
2016-02-10 13:49:36 +01:00
|
|
|
}
|
2014-03-04 19:22:57 +02:00
|
|
|
|
2016-12-15 15:29:43 +01:00
|
|
|
if (HAS_DDI(dev_priv) && crtc_state->has_audio)
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(POWER_DOMAIN_AUDIO_MMIO, mask->bits);
|
2016-12-15 15:29:43 +01:00
|
|
|
|
2016-03-14 09:27:54 +01:00
|
|
|
if (crtc_state->shared_dpll)
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(POWER_DOMAIN_DISPLAY_CORE, mask->bits);
|
2016-03-14 09:27:54 +01:00
|
|
|
|
2020-11-17 11:47:07 -08:00
|
|
|
if (crtc_state->dsc.compression_enable)
|
2022-04-15 00:06:48 +03:00
|
|
|
set_bit(intel_dsc_power_domain(crtc, cpu_transcoder), mask->bits);
|
2014-03-05 16:20:52 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
|
|
|
|
|
struct intel_power_domain_mask *old_domains)
|
2014-03-05 16:20:52 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-06-28 10:55:13 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2015-07-13 16:30:27 +02:00
|
|
|
enum intel_display_power_domain domain;
|
2022-04-15 00:06:48 +03:00
|
|
|
struct intel_power_domain_mask domains, new_domains;
|
2014-03-05 16:20:52 +02:00
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
get_crtc_power_domains(crtc_state, &domains);
|
2014-03-05 16:20:52 +02:00
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
bitmap_andnot(new_domains.bits,
|
|
|
|
|
domains.bits,
|
|
|
|
|
crtc->enabled_power_domains.mask.bits,
|
|
|
|
|
POWER_DOMAIN_NUM);
|
|
|
|
|
bitmap_andnot(old_domains->bits,
|
|
|
|
|
crtc->enabled_power_domains.mask.bits,
|
|
|
|
|
domains.bits,
|
|
|
|
|
POWER_DOMAIN_NUM);
|
2015-07-13 16:30:27 +02:00
|
|
|
|
2022-04-15 00:06:48 +03:00
|
|
|
for_each_power_domain(domain, &new_domains)
|
2020-11-30 23:21:54 +02:00
|
|
|
intel_display_power_get_in_set(dev_priv,
|
|
|
|
|
&crtc->enabled_power_domains,
|
|
|
|
|
domain);
|
2015-07-13 16:30:27 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_power_domain_mask *domains)
|
2015-07-13 16:30:27 +02:00
|
|
|
{
|
2020-11-30 23:21:54 +02:00
|
|
|
intel_display_power_put_mask_in_set(to_i915(crtc->base.dev),
|
|
|
|
|
&crtc->enabled_power_domains,
|
|
|
|
|
domains);
|
2015-07-13 16:30:27 +02:00
|
|
|
}
|
2014-03-05 16:20:52 +02:00
|
|
|
|
2022-02-01 11:19:09 +02:00
|
|
|
static void i9xx_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
|
|
|
|
|
|
|
|
|
if (intel_crtc_has_dp_encoder(crtc_state)) {
|
|
|
|
|
intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m_n);
|
|
|
|
|
intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
|
|
|
|
|
&crtc_state->dp_m2_n2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intel_set_transcoder_timings(crtc_state);
|
|
|
|
|
|
|
|
|
|
i9xx_set_pipeconf(crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:30 +02:00
|
|
|
static void valleyview_crtc_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2015-08-18 14:36:59 +03:00
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2015-08-18 14:36:59 +03:00
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
|
2017-02-07 20:33:05 +02:00
|
|
|
return;
|
2015-08-18 14:36:59 +03:00
|
|
|
|
2022-02-01 11:19:09 +02:00
|
|
|
i9xx_configure_cpu_transcoder(new_crtc_state);
|
2016-05-13 23:41:27 +03:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_set_pipe_src_size(new_crtc_state);
|
2016-05-13 23:41:27 +03:00
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, CHV_BLEND(pipe), CHV_BLEND_LEGACY);
|
|
|
|
|
intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
|
2015-06-04 18:21:33 +01:00
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
crtc->active = true;
|
2016-05-11 22:44:45 +03:00
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
2016-05-13 23:41:38 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_pre_pll_enable(state, crtc);
|
2016-05-13 23:41:38 +03:00
|
|
|
|
2021-07-15 12:35:26 +03:00
|
|
|
if (IS_CHERRYVIEW(dev_priv))
|
2021-07-15 12:35:22 +03:00
|
|
|
chv_enable_pll(new_crtc_state);
|
2021-07-15 12:35:26 +03:00
|
|
|
else
|
2021-07-15 12:35:22 +03:00
|
|
|
vlv_enable_pll(new_crtc_state);
|
2016-05-13 23:41:38 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_pre_enable(state, crtc);
|
2016-05-13 23:41:38 +03:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
i9xx_pfit_enable(new_crtc_state);
|
2016-12-02 10:23:54 +02:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_color_load_luts(new_crtc_state);
|
2022-02-24 18:51:02 +02:00
|
|
|
intel_color_commit_noarm(new_crtc_state);
|
|
|
|
|
intel_color_commit_arm(new_crtc_state);
|
2019-02-07 22:21:46 +02:00
|
|
|
/* update DSPCNTR to configure gamma for pipe bottom color */
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_disable_primary_plane(new_crtc_state);
|
2016-12-02 10:23:54 +02:00
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_initial_watermarks(state, crtc);
|
2021-09-13 17:44:29 +03:00
|
|
|
intel_enable_transcoder(new_crtc_state);
|
2017-02-07 20:33:05 +02:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_crtc_vblank_on(new_crtc_state);
|
2016-12-02 10:23:54 +02:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_enable(state, crtc);
|
2016-12-02 10:23:54 +02:00
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:30 +02:00
|
|
|
static void i9xx_crtc_enable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-05-13 23:41:34 +03:00
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2016-05-13 23:41:34 +03:00
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(&dev_priv->drm, crtc->active))
|
2017-02-07 20:33:05 +02:00
|
|
|
return;
|
2016-05-13 23:41:34 +03:00
|
|
|
|
2022-02-01 11:19:09 +02:00
|
|
|
i9xx_configure_cpu_transcoder(new_crtc_state);
|
2016-05-13 23:41:35 +03:00
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_set_pipe_src_size(new_crtc_state);
|
2016-05-13 23:41:34 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
crtc->active = true;
|
2016-05-13 23:41:38 +03:00
|
|
|
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) != 2)
|
2017-02-07 20:33:05 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
2016-05-13 23:41:38 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_pre_enable(state, crtc);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2021-07-15 12:35:22 +03:00
|
|
|
i9xx_enable_pll(new_crtc_state);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
i9xx_pfit_enable(new_crtc_state);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_color_load_luts(new_crtc_state);
|
2022-02-24 18:51:02 +02:00
|
|
|
intel_color_commit_noarm(new_crtc_state);
|
|
|
|
|
intel_color_commit_arm(new_crtc_state);
|
2019-02-07 22:21:46 +02:00
|
|
|
/* update DSPCNTR to configure gamma for pipe bottom color */
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_disable_primary_plane(new_crtc_state);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
if (!intel_initial_watermarks(state, crtc))
|
2021-09-29 01:57:47 +03:00
|
|
|
intel_update_watermarks(dev_priv);
|
2021-09-13 17:44:29 +03:00
|
|
|
intel_enable_transcoder(new_crtc_state);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2019-11-18 18:44:29 +02:00
|
|
|
intel_crtc_vblank_on(new_crtc_state);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_enable(state, crtc);
|
2020-04-29 13:10:34 +03:00
|
|
|
|
|
|
|
|
/* prevents spurious underruns */
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2)
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2017-02-07 20:33:05 +02:00
|
|
|
}
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2018-10-04 11:45:53 +02:00
|
|
|
static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
|
2017-02-07 20:33:05 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
2018-10-04 11:45:53 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2014-11-24 13:37:39 +05:30
|
|
|
|
2018-10-04 11:45:53 +02:00
|
|
|
if (!old_crtc_state->gmch_pfit.control)
|
2014-11-24 13:37:39 +05:30
|
|
|
return;
|
|
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
|
2017-02-07 20:33:05 +02:00
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "disabling pfit, current: 0x%08x\n",
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_read(dev_priv, PFIT_CONTROL));
|
|
|
|
|
intel_de_write(dev_priv, PFIT_CONTROL, 0);
|
2014-11-24 13:37:39 +05:30
|
|
|
}
|
|
|
|
|
|
2019-11-18 18:44:30 +02:00
|
|
|
static void i9xx_crtc_disable(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2014-11-24 13:37:39 +05:30
|
|
|
{
|
2019-11-18 18:44:30 +02:00
|
|
|
struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
2019-11-18 18:44:28 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2016-05-24 15:38:33 +03:00
|
|
|
|
|
|
|
|
/*
|
2017-02-07 20:33:05 +02:00
|
|
|
* On gen2 planes are double buffered but the pipe isn't, so we must
|
|
|
|
|
* wait for planes to fully turn off before disabling the pipe.
|
2016-05-24 15:38:33 +03:00
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2)
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
2016-05-24 15:38:33 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_disable(state, crtc);
|
2016-05-24 15:38:33 +03:00
|
|
|
|
2019-12-13 21:52:16 +02:00
|
|
|
intel_crtc_vblank_off(old_crtc_state);
|
2016-05-24 15:38:33 +03:00
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
intel_disable_transcoder(old_crtc_state);
|
2016-05-24 15:38:33 +03:00
|
|
|
|
2018-10-04 11:45:53 +02:00
|
|
|
i9xx_pfit_disable(old_crtc_state);
|
2016-12-02 10:23:54 +02:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_post_disable(state, crtc);
|
2016-05-24 15:38:33 +03:00
|
|
|
|
2018-10-04 11:46:04 +02:00
|
|
|
if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI)) {
|
2017-02-07 20:33:05 +02:00
|
|
|
if (IS_CHERRYVIEW(dev_priv))
|
|
|
|
|
chv_disable_pll(dev_priv, pipe);
|
|
|
|
|
else if (IS_VALLEYVIEW(dev_priv))
|
|
|
|
|
vlv_disable_pll(dev_priv, pipe);
|
|
|
|
|
else
|
2018-10-04 11:45:57 +02:00
|
|
|
i9xx_disable_pll(old_crtc_state);
|
2017-02-07 20:33:05 +02:00
|
|
|
}
|
2016-04-01 16:02:43 +03:00
|
|
|
|
2019-11-18 18:44:28 +02:00
|
|
|
intel_encoders_post_pll_disable(state, crtc);
|
2016-12-02 10:23:54 +02:00
|
|
|
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) != 2)
|
2017-02-07 20:33:05 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
|
2017-03-02 19:14:57 +02:00
|
|
|
|
2022-08-24 16:15:31 +03:00
|
|
|
if (!dev_priv->display.funcs.wm->initial_watermarks)
|
2021-09-29 01:57:47 +03:00
|
|
|
intel_update_watermarks(dev_priv);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
|
|
|
|
/* clock the pipe down to 640x480@60 to potentially save power */
|
|
|
|
|
if (IS_I830(dev_priv))
|
|
|
|
|
i830_enable_pipe(dev_priv, pipe);
|
2014-11-24 13:37:39 +05:30
|
|
|
}
|
|
|
|
|
|
2015-06-12 11:15:39 +02:00
|
|
|
|
2015-06-01 12:49:47 +02:00
|
|
|
/*
|
|
|
|
|
* turn all crtc's off, but do not adjust state
|
|
|
|
|
* This has to be paired with a call to intel_modeset_setup_hw_state.
|
|
|
|
|
*/
|
2015-07-13 16:30:29 +02:00
|
|
|
int intel_display_suspend(struct drm_device *dev)
|
2012-04-20 17:11:53 +01:00
|
|
|
{
|
2016-02-16 10:06:14 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2015-07-13 16:30:29 +02:00
|
|
|
struct drm_atomic_state *state;
|
2016-02-16 10:06:14 +01:00
|
|
|
int ret;
|
2015-07-13 16:30:29 +02:00
|
|
|
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2016-02-16 10:06:14 +01:00
|
|
|
state = drm_atomic_helper_suspend(dev);
|
|
|
|
|
ret = PTR_ERR_OR_ZERO(state);
|
2015-07-13 16:30:29 +02:00
|
|
|
if (ret)
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
|
|
|
|
|
ret);
|
2016-02-16 10:06:14 +01:00
|
|
|
else
|
|
|
|
|
dev_priv->modeset_restore_state = state;
|
2015-07-13 16:30:29 +02:00
|
|
|
return ret;
|
2012-04-20 17:11:53 +01:00
|
|
|
}
|
|
|
|
|
|
2010-08-04 13:50:23 +01:00
|
|
|
void intel_encoder_destroy(struct drm_encoder *encoder)
|
2010-09-10 10:47:20 -07:00
|
|
|
{
|
2010-09-09 15:14:28 +01:00
|
|
|
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
2010-08-04 13:50:23 +01:00
|
|
|
|
|
|
|
|
drm_encoder_cleanup(encoder);
|
|
|
|
|
kfree(intel_encoder);
|
2010-09-10 10:47:20 -07:00
|
|
|
}
|
|
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
|
2015-05-22 11:22:33 +03:00
|
|
|
{
|
2017-02-07 20:33:05 +02:00
|
|
|
const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
/* GDG double wide on either pipe, otherwise pipe A only */
|
2021-03-19 21:42:42 -07:00
|
|
|
return DISPLAY_VER(dev_priv) < 4 &&
|
2017-02-07 20:33:05 +02:00
|
|
|
(crtc->pipe == PIPE_A || IS_I915G(dev_priv));
|
2015-05-22 11:22:33 +03:00
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
|
2017-01-20 20:22:05 +02:00
|
|
|
{
|
2020-11-12 21:17:18 +02:00
|
|
|
u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
|
2021-03-30 21:42:54 +03:00
|
|
|
struct drm_rect src;
|
2017-01-20 20:22:05 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We only use IF-ID interlacing. If we ever use
|
|
|
|
|
* PF-ID we'll need to adjust the pixel_rate here.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
if (!crtc_state->pch_pfit.enabled)
|
|
|
|
|
return pixel_rate;
|
2017-01-20 20:22:05 +02:00
|
|
|
|
2021-03-30 21:42:54 +03:00
|
|
|
drm_rect_init(&src, 0, 0,
|
2022-02-23 15:13:12 +02:00
|
|
|
drm_rect_width(&crtc_state->pipe_src) << 16,
|
|
|
|
|
drm_rect_height(&crtc_state->pipe_src) << 16);
|
2017-01-20 20:22:05 +02:00
|
|
|
|
2021-03-30 21:42:54 +03:00
|
|
|
return intel_adjusted_rate(&src, &crtc_state->pch_pfit.dst,
|
|
|
|
|
pixel_rate);
|
2017-01-20 20:22:05 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-12 21:17:16 +02:00
|
|
|
static void intel_mode_from_crtc_timings(struct drm_display_mode *mode,
|
|
|
|
|
const struct drm_display_mode *timings)
|
|
|
|
|
{
|
|
|
|
|
mode->hdisplay = timings->crtc_hdisplay;
|
|
|
|
|
mode->htotal = timings->crtc_htotal;
|
|
|
|
|
mode->hsync_start = timings->crtc_hsync_start;
|
|
|
|
|
mode->hsync_end = timings->crtc_hsync_end;
|
|
|
|
|
|
|
|
|
|
mode->vdisplay = timings->crtc_vdisplay;
|
|
|
|
|
mode->vtotal = timings->crtc_vtotal;
|
|
|
|
|
mode->vsync_start = timings->crtc_vsync_start;
|
|
|
|
|
mode->vsync_end = timings->crtc_vsync_end;
|
|
|
|
|
|
|
|
|
|
mode->flags = timings->flags;
|
|
|
|
|
mode->type = DRM_MODE_TYPE_DRIVER;
|
|
|
|
|
|
|
|
|
|
mode->clock = timings->crtc_clock;
|
|
|
|
|
|
|
|
|
|
drm_mode_set_name(mode);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
|
2015-05-22 11:22:33 +03:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2019-02-04 14:25:38 -08:00
|
|
|
if (HAS_GMCH(dev_priv))
|
2017-02-07 20:33:05 +02:00
|
|
|
/* FIXME calculate proper pipe pixel rate for GMCH pfit */
|
|
|
|
|
crtc_state->pixel_rate =
|
2020-11-12 21:17:18 +02:00
|
|
|
crtc_state->hw.pipe_mode.crtc_clock;
|
2017-02-07 20:33:05 +02:00
|
|
|
else
|
|
|
|
|
crtc_state->pixel_rate =
|
|
|
|
|
ilk_pipe_pixel_rate(crtc_state);
|
|
|
|
|
}
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2022-02-23 15:13:08 +02:00
|
|
|
static void intel_bigjoiner_adjust_timings(const struct intel_crtc_state *crtc_state,
|
|
|
|
|
struct drm_display_mode *mode)
|
|
|
|
|
{
|
2022-02-23 15:13:14 +02:00
|
|
|
int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
|
|
|
|
|
|
|
|
|
|
if (num_pipes < 2)
|
2022-02-23 15:13:08 +02:00
|
|
|
return;
|
|
|
|
|
|
2022-02-23 15:13:14 +02:00
|
|
|
mode->crtc_clock /= num_pipes;
|
|
|
|
|
mode->crtc_hdisplay /= num_pipes;
|
|
|
|
|
mode->crtc_hblank_start /= num_pipes;
|
|
|
|
|
mode->crtc_hblank_end /= num_pipes;
|
|
|
|
|
mode->crtc_hsync_start /= num_pipes;
|
|
|
|
|
mode->crtc_hsync_end /= num_pipes;
|
|
|
|
|
mode->crtc_htotal /= num_pipes;
|
2022-02-23 15:13:08 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:07 +02:00
|
|
|
static void intel_splitter_adjust_timings(const struct intel_crtc_state *crtc_state,
|
|
|
|
|
struct drm_display_mode *mode)
|
|
|
|
|
{
|
|
|
|
|
int overlap = crtc_state->splitter.pixel_overlap;
|
|
|
|
|
int n = crtc_state->splitter.link_count;
|
|
|
|
|
|
|
|
|
|
if (!crtc_state->splitter.enable)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* eDP MSO uses segment timings from EDID for transcoder
|
|
|
|
|
* timings, but full mode for everything else.
|
|
|
|
|
*
|
|
|
|
|
* h_full = (h_segment - pixel_overlap) * link_count
|
|
|
|
|
*/
|
|
|
|
|
mode->crtc_hdisplay = (mode->crtc_hdisplay - overlap) * n;
|
|
|
|
|
mode->crtc_hblank_start = (mode->crtc_hblank_start - overlap) * n;
|
|
|
|
|
mode->crtc_hblank_end = (mode->crtc_hblank_end - overlap) * n;
|
|
|
|
|
mode->crtc_hsync_start = (mode->crtc_hsync_start - overlap) * n;
|
|
|
|
|
mode->crtc_hsync_end = (mode->crtc_hsync_end - overlap) * n;
|
|
|
|
|
mode->crtc_htotal = (mode->crtc_htotal - overlap) * n;
|
|
|
|
|
mode->crtc_clock *= n;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-12 21:17:17 +02:00
|
|
|
static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_display_mode *mode = &crtc_state->hw.mode;
|
2020-11-12 21:17:18 +02:00
|
|
|
struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
|
2020-11-12 21:17:17 +02:00
|
|
|
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
|
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/*
|
|
|
|
|
* Start with the adjusted_mode crtc timings, which
|
|
|
|
|
* have been filled with the transcoder timings.
|
|
|
|
|
*/
|
2020-11-12 21:17:18 +02:00
|
|
|
drm_mode_copy(pipe_mode, adjusted_mode);
|
|
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/* Expand MSO per-segment transcoder timings to full */
|
|
|
|
|
intel_splitter_adjust_timings(crtc_state, pipe_mode);
|
2020-11-12 21:17:17 +02:00
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/*
|
|
|
|
|
* We want the full numbers in adjusted_mode normal timings,
|
|
|
|
|
* adjusted_mode crtc timings are left with the raw transcoder
|
|
|
|
|
* timings.
|
|
|
|
|
*/
|
|
|
|
|
intel_mode_from_crtc_timings(adjusted_mode, pipe_mode);
|
2020-11-12 21:17:17 +02:00
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/* Populate the "user" mode with full numbers */
|
|
|
|
|
drm_mode_copy(mode, pipe_mode);
|
|
|
|
|
intel_mode_from_crtc_timings(mode, mode);
|
2022-02-23 15:13:14 +02:00
|
|
|
mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) *
|
|
|
|
|
(intel_bigjoiner_num_pipes(crtc_state) ?: 1);
|
2022-02-23 15:13:12 +02:00
|
|
|
mode->vdisplay = drm_rect_height(&crtc_state->pipe_src);
|
2022-02-23 15:13:11 +02:00
|
|
|
|
|
|
|
|
/* Derive per-pipe timings in case bigjoiner is used */
|
|
|
|
|
intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
|
|
|
|
|
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
|
|
|
|
|
|
|
|
|
intel_crtc_compute_pixel_rate(crtc_state);
|
2020-11-12 21:17:17 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-16 12:48:15 +03:00
|
|
|
void intel_encoder_get_config(struct intel_encoder *encoder,
|
|
|
|
|
struct intel_crtc_state *crtc_state)
|
2020-11-12 21:17:13 +02:00
|
|
|
{
|
|
|
|
|
encoder->get_config(encoder, crtc_state);
|
2020-11-12 21:17:17 +02:00
|
|
|
|
|
|
|
|
intel_crtc_readout_derived_state(crtc_state);
|
2020-11-12 21:17:13 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:12 +02:00
|
|
|
static void intel_bigjoiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2022-02-23 15:13:14 +02:00
|
|
|
int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
|
2022-02-23 15:13:12 +02:00
|
|
|
int width, height;
|
|
|
|
|
|
2022-02-23 15:13:14 +02:00
|
|
|
if (num_pipes < 2)
|
2022-02-23 15:13:12 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
width = drm_rect_width(&crtc_state->pipe_src);
|
|
|
|
|
height = drm_rect_height(&crtc_state->pipe_src);
|
|
|
|
|
|
|
|
|
|
drm_rect_init(&crtc_state->pipe_src, 0, 0,
|
2022-02-23 15:13:14 +02:00
|
|
|
width / num_pipes, height);
|
2022-02-23 15:13:12 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:09 +02:00
|
|
|
static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
|
|
2022-02-23 15:13:12 +02:00
|
|
|
intel_bigjoiner_compute_pipe_src(crtc_state);
|
2022-02-23 15:13:09 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Pipe horizontal size must be even in:
|
|
|
|
|
* - DVO ganged mode
|
|
|
|
|
* - LVDS dual channel mode
|
|
|
|
|
* - Double wide pipe
|
|
|
|
|
*/
|
2022-02-23 15:13:12 +02:00
|
|
|
if (drm_rect_width(&crtc_state->pipe_src) & 1) {
|
2022-02-23 15:13:09 +02:00
|
|
|
if (crtc_state->double_wide) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] Odd pipe source width not supported with double wide pipe\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
|
|
|
|
|
intel_is_dual_link_lvds(i915)) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] Odd pipe source width not supported with dual link LVDS\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:10 +02:00
|
|
|
static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
|
2017-02-07 20:33:05 +02:00
|
|
|
{
|
2022-02-23 15:13:10 +02:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2022-02-23 15:13:06 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2022-02-23 15:13:11 +02:00
|
|
|
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
2022-02-23 15:13:06 +02:00
|
|
|
struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
|
|
|
|
|
int clock_limit = i915->max_dotclk_freq;
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/*
|
|
|
|
|
* Start with the adjusted_mode crtc timings, which
|
|
|
|
|
* have been filled with the transcoder timings.
|
|
|
|
|
*/
|
|
|
|
|
drm_mode_copy(pipe_mode, adjusted_mode);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/* Expand MSO per-segment transcoder timings to full */
|
2022-02-23 15:13:07 +02:00
|
|
|
intel_splitter_adjust_timings(crtc_state, pipe_mode);
|
2021-03-02 13:03:02 +02:00
|
|
|
|
2022-02-23 15:13:11 +02:00
|
|
|
/* Derive per-pipe timings in case bigjoiner is used */
|
|
|
|
|
intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
|
2020-11-12 21:17:18 +02:00
|
|
|
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
|
|
|
|
|
2022-02-23 15:13:06 +02:00
|
|
|
if (DISPLAY_VER(i915) < 4) {
|
|
|
|
|
clock_limit = i915->max_cdclk_freq * 9 / 10;
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
/*
|
|
|
|
|
* Enable double wide mode when the dot clock
|
|
|
|
|
* is > 90% of the (display) core speed.
|
|
|
|
|
*/
|
|
|
|
|
if (intel_crtc_supports_double_wide(crtc) &&
|
2020-11-12 21:17:18 +02:00
|
|
|
pipe_mode->crtc_clock > clock_limit) {
|
2022-02-23 15:13:06 +02:00
|
|
|
clock_limit = i915->max_dotclk_freq;
|
|
|
|
|
crtc_state->double_wide = true;
|
2017-02-07 20:33:05 +02:00
|
|
|
}
|
2015-05-22 11:22:33 +03:00
|
|
|
}
|
|
|
|
|
|
2020-11-12 21:17:18 +02:00
|
|
|
if (pipe_mode->crtc_clock > clock_limit) {
|
2022-02-23 15:13:06 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-23 15:13:10 +02:00
|
|
|
"[CRTC:%d:%s] requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name,
|
2020-11-12 21:17:18 +02:00
|
|
|
pipe_mode->crtc_clock, clock_limit,
|
2022-02-25 15:46:28 -08:00
|
|
|
str_yes_no(crtc_state->double_wide));
|
2017-02-07 20:33:05 +02:00
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2022-02-23 15:13:10 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
static int intel_crtc_compute_config(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2022-02-23 15:13:10 +02:00
|
|
|
{
|
2022-05-03 21:22:23 +03:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2022-02-23 15:13:10 +02:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = intel_crtc_compute_pipe_src(crtc_state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
ret = intel_crtc_compute_pipe_mode(crtc_state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2022-02-23 15:13:06 +02:00
|
|
|
intel_crtc_compute_pixel_rate(crtc_state);
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2022-02-23 15:13:06 +02:00
|
|
|
if (crtc_state->has_pch_encoder)
|
|
|
|
|
return ilk_fdi_compute_config(crtc, crtc_state);
|
2015-05-22 11:22:33 +03:00
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
return 0;
|
2015-05-22 11:22:33 +03:00
|
|
|
}
|
|
|
|
|
|
2009-06-05 15:38:42 +08:00
|
|
|
static void
|
2019-01-18 14:01:23 +02:00
|
|
|
intel_reduce_m_n_ratio(u32 *num, u32 *den)
|
2009-06-05 15:38:42 +08:00
|
|
|
{
|
2013-04-23 15:03:34 +03:00
|
|
|
while (*num > DATA_LINK_M_N_MASK ||
|
|
|
|
|
*den > DATA_LINK_M_N_MASK) {
|
2009-06-05 15:38:42 +08:00
|
|
|
*num >>= 1;
|
|
|
|
|
*den >>= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-23 15:03:34 +03:00
|
|
|
static void compute_m_n(unsigned int m, unsigned int n,
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 *ret_m, u32 *ret_n,
|
2018-09-11 23:22:50 -07:00
|
|
|
bool constant_n)
|
2013-04-23 15:03:34 +03:00
|
|
|
{
|
2017-03-27 14:33:25 +03:00
|
|
|
/*
|
2018-09-11 23:22:50 -07:00
|
|
|
* Several DP dongles in particular seem to be fussy about
|
|
|
|
|
* too large link M/N values. Give N value as 0x8000 that
|
|
|
|
|
* should be acceptable by specific devices. 0x8000 is the
|
|
|
|
|
* specified fixed N value for asynchronous clock mode,
|
|
|
|
|
* which the devices expect also in synchronous clock mode.
|
2017-03-27 14:33:25 +03:00
|
|
|
*/
|
2018-09-11 23:22:50 -07:00
|
|
|
if (constant_n)
|
2020-08-27 14:16:54 -07:00
|
|
|
*ret_n = DP_LINK_CONSTANT_N_VALUE;
|
2018-09-11 23:22:50 -07:00
|
|
|
else
|
|
|
|
|
*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
|
2017-03-27 14:33:25 +03:00
|
|
|
|
2019-04-08 18:27:01 +03:00
|
|
|
*ret_m = div_u64(mul_u32_u32(m, *ret_n), n);
|
2013-04-23 15:03:34 +03:00
|
|
|
intel_reduce_m_n_ratio(ret_m, ret_n);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 15:59:36 +01:00
|
|
|
void
|
2018-11-28 13:36:21 -08:00
|
|
|
intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
|
2012-11-29 15:59:36 +01:00
|
|
|
int pixel_clock, int link_clock,
|
2017-05-18 14:10:25 +03:00
|
|
|
struct intel_link_m_n *m_n,
|
2019-09-25 10:21:09 +02:00
|
|
|
bool constant_n, bool fec_enable)
|
2009-06-05 15:38:42 +08:00
|
|
|
{
|
2019-09-25 10:21:09 +02:00
|
|
|
u32 data_clock = bits_per_pixel * pixel_clock;
|
|
|
|
|
|
|
|
|
|
if (fec_enable)
|
|
|
|
|
data_clock = intel_dp_mode_to_fec_clock(data_clock);
|
2013-04-23 15:03:34 +03:00
|
|
|
|
2019-09-25 10:21:09 +02:00
|
|
|
m_n->tu = 64;
|
|
|
|
|
compute_m_n(data_clock,
|
2013-04-23 15:03:34 +03:00
|
|
|
link_clock * nlanes * 8,
|
2022-01-27 11:32:52 +02:00
|
|
|
&m_n->data_m, &m_n->data_n,
|
2018-09-11 23:22:50 -07:00
|
|
|
constant_n);
|
2013-04-23 15:03:34 +03:00
|
|
|
|
|
|
|
|
compute_m_n(pixel_clock, link_clock,
|
2017-05-18 14:10:25 +03:00
|
|
|
&m_n->link_m, &m_n->link_n,
|
2018-09-11 23:22:50 -07:00
|
|
|
constant_n);
|
2009-06-05 15:38:42 +08:00
|
|
|
}
|
|
|
|
|
|
2019-09-20 21:54:19 +03:00
|
|
|
static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* There may be no VBT; and if the BIOS enabled SSC we can
|
|
|
|
|
* just keep using it to avoid unnecessary flicker. Whereas if the
|
|
|
|
|
* BIOS isn't using it, don't assume it will work even if the VBT
|
|
|
|
|
* indicates as much.
|
|
|
|
|
*/
|
|
|
|
|
if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
bool bios_lvds_use_ssc = intel_de_read(dev_priv,
|
|
|
|
|
PCH_DREF_CONTROL) &
|
2019-09-20 21:54:19 +03:00
|
|
|
DREF_SSC1_ENABLE;
|
|
|
|
|
|
|
|
|
|
if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"SSC %s by BIOS, overriding VBT which says %s\n",
|
2022-02-25 15:46:30 -08:00
|
|
|
str_enabled_disabled(bios_lvds_use_ssc),
|
|
|
|
|
str_enabled_disabled(dev_priv->vbt.lvds_use_ssc));
|
2019-09-20 21:54:19 +03:00
|
|
|
dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:53 +02:00
|
|
|
void intel_zero_m_n(struct intel_link_m_n *m_n)
|
|
|
|
|
{
|
|
|
|
|
/* corresponds to 0 register value */
|
|
|
|
|
memset(m_n, 0, sizeof(*m_n));
|
|
|
|
|
m_n->tu = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:47 +02:00
|
|
|
void intel_set_m_n(struct drm_i915_private *i915,
|
|
|
|
|
const struct intel_link_m_n *m_n,
|
|
|
|
|
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
|
|
|
|
|
i915_reg_t link_m_reg, i915_reg_t link_n_reg)
|
2022-01-27 11:32:50 +02:00
|
|
|
{
|
2022-01-27 11:32:52 +02:00
|
|
|
intel_de_write(i915, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m);
|
|
|
|
|
intel_de_write(i915, data_n_reg, m_n->data_n);
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_de_write(i915, link_m_reg, m_n->link_m);
|
2022-01-28 12:37:57 +02:00
|
|
|
/*
|
|
|
|
|
* On BDW+ writing LINK_N arms the double buffered update
|
|
|
|
|
* of all the M/N registers, so it must be written last.
|
|
|
|
|
*/
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_de_write(i915, link_n_reg, m_n->link_n);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:53 +02:00
|
|
|
bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum transcoder transcoder)
|
2018-10-15 11:40:23 +02:00
|
|
|
{
|
|
|
|
|
if (IS_HASWELL(dev_priv))
|
|
|
|
|
return transcoder == TRANSCODER_EDP;
|
|
|
|
|
|
2022-01-28 12:37:52 +02:00
|
|
|
return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv);
|
2018-10-15 11:40:23 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:46 +02:00
|
|
|
void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
|
|
|
|
|
enum transcoder transcoder,
|
2022-01-28 12:37:44 +02:00
|
|
|
const struct intel_link_m_n *m_n)
|
2013-05-03 11:49:48 +02:00
|
|
|
{
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2018-10-11 12:04:49 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2013-05-03 11:49:48 +02:00
|
|
|
|
2022-01-28 12:37:44 +02:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 5)
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_set_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
|
|
|
|
|
PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
|
2022-01-28 12:37:44 +02:00
|
|
|
else
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_set_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
|
|
|
|
|
PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
|
2022-01-28 12:37:44 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:46 +02:00
|
|
|
void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
|
|
|
|
|
enum transcoder transcoder,
|
2022-01-28 12:37:44 +02:00
|
|
|
const struct intel_link_m_n *m_n)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
|
2022-01-28 12:37:53 +02:00
|
|
|
if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder))
|
2022-01-28 12:37:44 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
intel_set_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
|
|
|
|
|
PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
|
2013-05-03 11:49:48 +02:00
|
|
|
}
|
|
|
|
|
|
2020-10-08 14:45:26 -07:00
|
|
|
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
|
2012-10-01 18:10:53 -03:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:54 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
2019-10-31 12:26:02 +01:00
|
|
|
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 crtc_vtotal, crtc_vblank_end;
|
2014-03-28 23:29:32 +02:00
|
|
|
int vsyncshift = 0;
|
2013-05-03 11:49:51 +02:00
|
|
|
|
|
|
|
|
/* We need to be careful not to changed the adjusted mode, for otherwise
|
|
|
|
|
* the hw state checker will get angry at the mismatch. */
|
|
|
|
|
crtc_vtotal = adjusted_mode->crtc_vtotal;
|
|
|
|
|
crtc_vblank_end = adjusted_mode->crtc_vblank_end;
|
2012-10-01 18:10:53 -03:00
|
|
|
|
2014-03-28 23:29:30 +02:00
|
|
|
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
|
2012-10-01 18:10:53 -03:00
|
|
|
/* the chip adds 2 halflines automatically */
|
2013-05-03 11:49:51 +02:00
|
|
|
crtc_vtotal -= 1;
|
|
|
|
|
crtc_vblank_end -= 1;
|
2014-03-28 23:29:30 +02:00
|
|
|
|
2018-10-04 11:45:54 +02:00
|
|
|
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
|
2014-03-28 23:29:30 +02:00
|
|
|
vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2;
|
|
|
|
|
else
|
|
|
|
|
vsyncshift = adjusted_mode->crtc_hsync_start -
|
|
|
|
|
adjusted_mode->crtc_htotal / 2;
|
2014-03-28 23:29:32 +02:00
|
|
|
if (vsyncshift < 0)
|
|
|
|
|
vsyncshift += adjusted_mode->crtc_htotal;
|
2012-10-01 18:10:53 -03:00
|
|
|
}
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) > 3)
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, VSYNCSHIFT(cpu_transcoder),
|
|
|
|
|
vsyncshift);
|
|
|
|
|
|
|
|
|
|
intel_de_write(dev_priv, HTOTAL(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, HBLANK(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, HSYNC(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
|
|
|
|
|
|
|
|
|
|
intel_de_write(dev_priv, VTOTAL(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_vdisplay - 1) | ((crtc_vtotal - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, VBLANK(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_vblank_start - 1) | ((crtc_vblank_end - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, VSYNC(cpu_transcoder),
|
|
|
|
|
(adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
|
2012-10-01 18:10:53 -03:00
|
|
|
|
2012-10-24 11:34:43 -02:00
|
|
|
/* Workaround: when the EDP input selection is B, the VTOTAL_B must be
|
|
|
|
|
* programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is
|
|
|
|
|
* documented on the DDI_FUNC_CTL register description, EDP Input Select
|
|
|
|
|
* bits. */
|
2016-10-13 11:03:01 +01:00
|
|
|
if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP &&
|
2012-10-24 11:34:43 -02:00
|
|
|
(pipe == PIPE_B || pipe == PIPE_C))
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, VTOTAL(pipe),
|
|
|
|
|
intel_de_read(dev_priv, VTOTAL(cpu_transcoder)));
|
2012-10-24 11:34:43 -02:00
|
|
|
|
2016-03-18 17:05:39 +02:00
|
|
|
}
|
|
|
|
|
|
2018-10-04 11:45:54 +02:00
|
|
|
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
|
2016-03-18 17:05:39 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:54 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2022-02-23 15:13:12 +02:00
|
|
|
int width = drm_rect_width(&crtc_state->pipe_src);
|
|
|
|
|
int height = drm_rect_height(&crtc_state->pipe_src);
|
2018-10-04 11:45:54 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2016-03-18 17:05:39 +02:00
|
|
|
|
2012-10-01 18:10:53 -03:00
|
|
|
/* pipesrc controls the size that is scaled from, which should
|
|
|
|
|
* always be the user's requested size.
|
|
|
|
|
*/
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPESRC(pipe),
|
2022-02-23 15:13:12 +02:00
|
|
|
PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1));
|
2012-10-01 18:10:53 -03:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:50:48 +03:00
|
|
|
static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
2019-07-18 17:50:48 +03:00
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
|
|
|
|
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2)
|
2019-07-18 17:50:48 +03:00
|
|
|
return false;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 ||
|
2019-07-18 17:50:48 +03:00
|
|
|
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
return intel_de_read(dev_priv, PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK_HSW;
|
2019-07-18 17:50:48 +03:00
|
|
|
else
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
return intel_de_read(dev_priv, PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK;
|
2019-07-18 17:50:48 +03:00
|
|
|
}
|
|
|
|
|
|
2020-10-08 14:45:26 -07:00
|
|
|
static void intel_get_transcoder_timings(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config)
|
2013-04-29 21:56:12 +02:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2013-04-29 21:56:12 +02:00
|
|
|
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 tmp;
|
2013-04-29 21:56:12 +02:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, HTOTAL(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
|
2019-05-02 20:40:59 +05:30
|
|
|
|
|
|
|
|
if (!transcoder_is_dsi(cpu_transcoder)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, HBLANK(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_hblank_start =
|
2019-05-02 20:40:59 +05:30
|
|
|
(tmp & 0xffff) + 1;
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_hblank_end =
|
2019-05-02 20:40:59 +05:30
|
|
|
((tmp >> 16) & 0xffff) + 1;
|
|
|
|
|
}
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, HSYNC(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
|
2013-04-29 21:56:12 +02:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, VTOTAL(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
|
2019-05-02 20:40:59 +05:30
|
|
|
|
|
|
|
|
if (!transcoder_is_dsi(cpu_transcoder)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, VBLANK(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_vblank_start =
|
2019-05-02 20:40:59 +05:30
|
|
|
(tmp & 0xffff) + 1;
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_vblank_end =
|
2019-05-02 20:40:59 +05:30
|
|
|
((tmp >> 16) & 0xffff) + 1;
|
|
|
|
|
}
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, VSYNC(cpu_transcoder));
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
|
2013-04-29 21:56:12 +02:00
|
|
|
|
2019-07-18 17:50:48 +03:00
|
|
|
if (intel_pipe_is_interlaced(pipe_config)) {
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
|
|
|
|
|
pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
|
2013-04-29 21:56:12 +02:00
|
|
|
}
|
2016-03-18 17:05:39 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:15 +02:00
|
|
|
static void intel_bigjoiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
|
|
|
|
|
enum pipe master_pipe, pipe = crtc->pipe;
|
|
|
|
|
int width;
|
|
|
|
|
|
|
|
|
|
if (num_pipes < 2)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
master_pipe = bigjoiner_master_pipe(crtc_state);
|
|
|
|
|
width = drm_rect_width(&crtc_state->pipe_src);
|
|
|
|
|
|
|
|
|
|
drm_rect_translate_to(&crtc_state->pipe_src,
|
|
|
|
|
(pipe - master_pipe) * width, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-18 17:05:39 +02:00
|
|
|
static void intel_get_pipe_src_size(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config)
|
|
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2016-03-18 17:05:39 +02:00
|
|
|
u32 tmp;
|
2013-04-29 21:56:12 +02:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe));
|
2022-02-23 15:13:12 +02:00
|
|
|
|
|
|
|
|
drm_rect_init(&pipe_config->pipe_src, 0, 0,
|
|
|
|
|
REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1,
|
|
|
|
|
REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1);
|
2022-02-23 15:13:15 +02:00
|
|
|
|
|
|
|
|
intel_bigjoiner_adjust_pipe_src(pipe_config);
|
2013-04-29 21:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-13 22:26:07 +03:00
|
|
|
void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
|
2013-02-19 18:48:54 +01:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:52 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2022-02-02 13:16:16 +02:00
|
|
|
u32 pipeconf = 0;
|
2013-02-19 18:48:54 +01:00
|
|
|
|
2022-04-13 22:26:07 +03:00
|
|
|
/*
|
|
|
|
|
* - We keep both pipes enabled on 830
|
|
|
|
|
* - During modeset the pipe is still disabled and must remain so
|
|
|
|
|
* - During fastset the pipe is already enabled and must remain so
|
|
|
|
|
*/
|
|
|
|
|
if (IS_I830(dev_priv) || !intel_crtc_needs_modeset(crtc_state))
|
2022-02-02 13:16:16 +02:00
|
|
|
pipeconf |= PIPECONF_ENABLE;
|
2013-09-24 11:46:14 +02:00
|
|
|
|
2018-10-04 11:45:52 +02:00
|
|
|
if (crtc_state->double_wide)
|
2013-09-04 18:30:02 +03:00
|
|
|
pipeconf |= PIPECONF_DOUBLE_WIDE;
|
2013-02-19 18:48:54 +01:00
|
|
|
|
2013-04-24 14:57:17 +02:00
|
|
|
/* only g4x and later have fancy bpc/dither controls */
|
2016-10-13 11:03:06 +01:00
|
|
|
if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
|
|
|
|
|
IS_CHERRYVIEW(dev_priv)) {
|
2013-04-24 14:57:17 +02:00
|
|
|
/* Bspec claims that we can't use dithering for 30bpp pipes. */
|
2018-10-04 11:45:52 +02:00
|
|
|
if (crtc_state->dither && crtc_state->pipe_bpp != 30)
|
2013-04-24 14:57:17 +02:00
|
|
|
pipeconf |= PIPECONF_DITHER_EN |
|
2013-02-19 18:48:54 +01:00
|
|
|
PIPECONF_DITHER_TYPE_SP;
|
|
|
|
|
|
2018-10-04 11:45:52 +02:00
|
|
|
switch (crtc_state->pipe_bpp) {
|
2022-05-31 19:25:27 +03:00
|
|
|
default:
|
|
|
|
|
/* Case prevented by intel_choose_pipe_bpp_dither. */
|
|
|
|
|
MISSING_CASE(crtc_state->pipe_bpp);
|
|
|
|
|
fallthrough;
|
2013-04-24 14:57:17 +02:00
|
|
|
case 18:
|
2021-11-12 21:38:08 +02:00
|
|
|
pipeconf |= PIPECONF_BPC_6;
|
2013-04-24 14:57:17 +02:00
|
|
|
break;
|
|
|
|
|
case 24:
|
2021-11-12 21:38:08 +02:00
|
|
|
pipeconf |= PIPECONF_BPC_8;
|
2013-04-24 14:57:17 +02:00
|
|
|
break;
|
|
|
|
|
case 30:
|
2021-11-12 21:38:08 +02:00
|
|
|
pipeconf |= PIPECONF_BPC_10;
|
2013-04-24 14:57:17 +02:00
|
|
|
break;
|
2013-02-19 18:48:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 4 ||
|
2018-10-04 11:45:52 +02:00
|
|
|
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
|
2014-03-28 23:29:31 +02:00
|
|
|
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
|
|
|
|
|
else
|
|
|
|
|
pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
|
2019-03-18 22:26:51 +02:00
|
|
|
} else {
|
2021-11-12 21:38:08 +02:00
|
|
|
pipeconf |= PIPECONF_INTERLACE_PROGRESSIVE;
|
2019-03-18 22:26:51 +02:00
|
|
|
}
|
2013-02-19 18:48:54 +01:00
|
|
|
|
2016-10-14 10:13:44 +01:00
|
|
|
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
2018-10-04 11:45:52 +02:00
|
|
|
crtc_state->limited_color_range)
|
2013-06-13 00:54:58 +02:00
|
|
|
pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
|
2013-04-02 16:10:09 +03:00
|
|
|
|
2019-02-07 22:21:40 +02:00
|
|
|
pipeconf |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
|
|
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
pipeconf |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
|
2019-10-24 15:21:38 +03:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPECONF(crtc->pipe), pipeconf);
|
|
|
|
|
intel_de_posting_read(dev_priv, PIPECONF(crtc->pipe));
|
2013-02-19 18:48:54 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-19 16:23:29 +02:00
|
|
|
static bool i9xx_has_pfit(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
|
|
|
|
if (IS_I830(dev_priv))
|
|
|
|
|
return false;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
return DISPLAY_VER(dev_priv) >= 4 ||
|
2019-03-19 16:23:29 +02:00
|
|
|
IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
|
2013-05-07 23:34:16 +02:00
|
|
|
{
|
2020-04-22 19:19:13 +03:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 tmp;
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2019-03-19 16:23:29 +02:00
|
|
|
if (!i9xx_has_pfit(dev_priv))
|
2014-01-10 14:06:45 +02:00
|
|
|
return;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PFIT_CONTROL);
|
2013-07-11 13:35:40 +02:00
|
|
|
if (!(tmp & PFIT_ENABLE))
|
|
|
|
|
return;
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2013-07-11 13:35:40 +02:00
|
|
|
/* Check whether the pfit is attached to our pipe. */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 4) {
|
2013-05-07 23:34:16 +02:00
|
|
|
if (crtc->pipe != PIPE_B)
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
crtc_state->gmch_pfit.control = tmp;
|
|
|
|
|
crtc_state->gmch_pfit.pgm_ratios =
|
|
|
|
|
intel_de_read(dev_priv, PFIT_PGM_RATIOS);
|
2013-05-07 23:34:16 +02:00
|
|
|
}
|
|
|
|
|
|
2013-09-20 11:29:32 -07:00
|
|
|
static void vlv_crtc_clock_get(struct intel_crtc *crtc,
|
2015-01-15 14:55:21 +02:00
|
|
|
struct intel_crtc_state *pipe_config)
|
2013-09-20 11:29:32 -07:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2019-08-21 20:30:31 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2016-05-04 12:11:57 +03:00
|
|
|
struct dpll clock;
|
2013-09-20 11:29:32 -07:00
|
|
|
u32 mdiv;
|
2013-09-25 14:24:01 -07:00
|
|
|
int refclk = 100000;
|
2013-09-20 11:29:32 -07:00
|
|
|
|
2016-03-15 16:40:01 +02:00
|
|
|
/* In case of DSI, DPLL will not be used */
|
|
|
|
|
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
|
2014-07-30 20:32:37 +05:30
|
|
|
return;
|
|
|
|
|
|
2019-04-26 09:17:19 +01:00
|
|
|
vlv_dpio_get(dev_priv);
|
2013-11-07 10:43:30 +08:00
|
|
|
mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
|
2019-04-26 09:17:19 +01:00
|
|
|
vlv_dpio_put(dev_priv);
|
2013-09-20 11:29:32 -07:00
|
|
|
|
|
|
|
|
clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
|
|
|
|
|
clock.m2 = mdiv & DPIO_M2DIV_MASK;
|
|
|
|
|
clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
|
|
|
|
|
clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
|
|
|
|
|
clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
|
|
|
|
|
|
2015-06-22 23:35:51 +03:00
|
|
|
pipe_config->port_clock = vlv_calc_dpll_params(refclk, &clock);
|
2013-09-20 11:29:32 -07:00
|
|
|
}
|
|
|
|
|
|
2014-04-09 13:28:22 +03:00
|
|
|
static void chv_crtc_clock_get(struct intel_crtc *crtc,
|
2015-01-15 14:55:21 +02:00
|
|
|
struct intel_crtc_state *pipe_config)
|
2014-04-09 13:28:22 +03:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2019-08-21 20:30:31 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2014-04-09 13:28:22 +03:00
|
|
|
enum dpio_channel port = vlv_pipe_to_channel(pipe);
|
2016-05-04 12:11:57 +03:00
|
|
|
struct dpll clock;
|
2015-07-02 14:29:58 +03:00
|
|
|
u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3;
|
2014-04-09 13:28:22 +03:00
|
|
|
int refclk = 100000;
|
|
|
|
|
|
2016-03-15 16:40:01 +02:00
|
|
|
/* In case of DSI, DPLL will not be used */
|
|
|
|
|
if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-04-26 09:17:19 +01:00
|
|
|
vlv_dpio_get(dev_priv);
|
2014-04-09 13:28:22 +03:00
|
|
|
cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
|
|
|
|
|
pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
|
|
|
|
|
pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
|
|
|
|
|
pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
|
2015-07-02 14:29:58 +03:00
|
|
|
pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
|
2019-04-26 09:17:19 +01:00
|
|
|
vlv_dpio_put(dev_priv);
|
2014-04-09 13:28:22 +03:00
|
|
|
|
|
|
|
|
clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
|
2015-07-02 14:29:58 +03:00
|
|
|
clock.m2 = (pll_dw0 & 0xff) << 22;
|
|
|
|
|
if (pll_dw3 & DPIO_CHV_FRAC_DIV_EN)
|
|
|
|
|
clock.m2 |= pll_dw2 & 0x3fffff;
|
2014-04-09 13:28:22 +03:00
|
|
|
clock.n = (pll_dw1 >> DPIO_CHV_N_DIV_SHIFT) & 0xf;
|
|
|
|
|
clock.p1 = (cmn_dw13 >> DPIO_CHV_P1_DIV_SHIFT) & 0x7;
|
|
|
|
|
clock.p2 = (cmn_dw13 >> DPIO_CHV_P2_DIV_SHIFT) & 0x1f;
|
|
|
|
|
|
2015-06-22 23:35:51 +03:00
|
|
|
pipe_config->port_clock = chv_calc_dpll_params(refclk, &clock);
|
2014-04-09 13:28:22 +03:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:50:49 +03:00
|
|
|
static enum intel_output_format
|
|
|
|
|
bdw_get_pipemisc_output_format(struct intel_crtc *crtc)
|
2018-10-12 11:53:08 +05:30
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2019-07-18 17:50:49 +03:00
|
|
|
u32 tmp;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
|
2019-07-18 17:50:49 +03:00
|
|
|
|
|
|
|
|
if (tmp & PIPEMISC_YUV420_ENABLE) {
|
|
|
|
|
/* We support 4:2:0 in full blend mode only */
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
|
|
|
|
(tmp & PIPEMISC_YUV420_MODE_FULL_BLEND) == 0);
|
2018-10-12 11:53:08 +05:30
|
|
|
|
2019-07-18 17:50:49 +03:00
|
|
|
return INTEL_OUTPUT_FORMAT_YCBCR420;
|
|
|
|
|
} else if (tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV) {
|
|
|
|
|
return INTEL_OUTPUT_FORMAT_YCBCR444;
|
|
|
|
|
} else {
|
|
|
|
|
return INTEL_OUTPUT_FORMAT_RGB;
|
|
|
|
|
}
|
2018-10-12 11:53:08 +05:30
|
|
|
}
|
|
|
|
|
|
2019-02-07 22:39:13 +02:00
|
|
|
static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-02-07 22:39:13 +02:00
|
|
|
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
|
|
|
|
u32 tmp;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
|
2019-02-07 22:39:13 +02:00
|
|
|
|
2022-01-21 13:30:31 +02:00
|
|
|
if (tmp & DISP_PIPE_GAMMA_ENABLE)
|
2019-02-07 22:39:13 +02:00
|
|
|
crtc_state->gamma_enable = true;
|
2019-02-07 22:21:42 +02:00
|
|
|
|
|
|
|
|
if (!HAS_GMCH(dev_priv) &&
|
2022-01-21 13:30:31 +02:00
|
|
|
tmp & DISP_PIPE_CSC_ENABLE)
|
2019-02-07 22:21:42 +02:00
|
|
|
crtc_state->csc_enable = true;
|
2019-02-07 22:39:13 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-28 10:42:00 +01:00
|
|
|
static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
2015-01-15 14:55:21 +02:00
|
|
|
struct intel_crtc_state *pipe_config)
|
2013-03-28 10:42:00 +01:00
|
|
|
{
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2016-02-12 18:55:11 +02:00
|
|
|
enum intel_display_power_domain power_domain;
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_wakeref_t wakeref;
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 tmp;
|
2016-02-12 18:55:11 +02:00
|
|
|
bool ret;
|
2013-03-28 10:42:00 +01:00
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
|
2019-01-14 14:21:24 +00:00
|
|
|
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
|
|
|
|
if (!wakeref)
|
2014-03-05 16:20:55 +02:00
|
|
|
return false;
|
|
|
|
|
|
2018-10-12 11:53:07 +05:30
|
|
|
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
2013-07-04 12:01:15 +02:00
|
|
|
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
|
2016-03-08 17:46:18 +02:00
|
|
|
pipe_config->shared_dpll = NULL;
|
2013-05-22 00:50:22 +02:00
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
ret = false;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPECONF(crtc->pipe));
|
2013-03-28 10:42:00 +01:00
|
|
|
if (!(tmp & PIPECONF_ENABLE))
|
2016-02-12 18:55:11 +02:00
|
|
|
goto out;
|
2013-03-28 10:42:00 +01:00
|
|
|
|
2016-10-13 11:03:06 +01:00
|
|
|
if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
|
|
|
|
|
IS_CHERRYVIEW(dev_priv)) {
|
2013-09-06 23:29:00 +03:00
|
|
|
switch (tmp & PIPECONF_BPC_MASK) {
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_6:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 18;
|
|
|
|
|
break;
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_8:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 24;
|
|
|
|
|
break;
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_10:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 30;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2021-11-12 21:38:08 +02:00
|
|
|
MISSING_CASE(tmp);
|
2013-09-06 23:29:00 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-14 10:13:44 +01:00
|
|
|
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
2015-12-09 12:29:35 -08:00
|
|
|
(tmp & PIPECONF_COLOR_RANGE_SELECT))
|
2014-04-24 23:54:49 +02:00
|
|
|
pipe_config->limited_color_range = true;
|
|
|
|
|
|
2021-11-12 21:38:08 +02:00
|
|
|
pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp);
|
2019-02-07 22:21:40 +02:00
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1;
|
|
|
|
|
|
2019-02-18 21:31:32 +02:00
|
|
|
if (IS_CHERRYVIEW(dev_priv))
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->cgm_mode = intel_de_read(dev_priv,
|
|
|
|
|
CGM_PIPE_MODE(crtc->pipe));
|
2019-02-18 21:31:32 +02:00
|
|
|
|
2019-02-07 22:39:13 +02:00
|
|
|
i9xx_get_pipe_color_config(pipe_config);
|
2019-05-29 15:20:52 +05:30
|
|
|
intel_color_get_config(pipe_config);
|
2019-02-07 22:39:13 +02:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 4)
|
2013-09-04 18:30:03 +03:00
|
|
|
pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
|
|
|
|
|
|
2020-10-08 14:45:26 -07:00
|
|
|
intel_get_transcoder_timings(crtc, pipe_config);
|
2016-03-18 17:05:39 +02:00
|
|
|
intel_get_pipe_src_size(crtc, pipe_config);
|
2013-04-29 21:56:12 +02:00
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
i9xx_get_pfit_config(pipe_config);
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 4) {
|
2016-03-15 16:39:56 +02:00
|
|
|
/* No way to read it out on pipes B and C */
|
2016-10-14 10:13:44 +01:00
|
|
|
if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A)
|
2016-03-15 16:39:56 +02:00
|
|
|
tmp = dev_priv->chv_dpll_md[crtc->pipe];
|
|
|
|
|
else
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, DPLL_MD(crtc->pipe));
|
2013-06-06 12:45:25 +02:00
|
|
|
pipe_config->pixel_multiplier =
|
|
|
|
|
((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
|
|
|
|
|
>> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
|
2013-06-05 13:34:28 +02:00
|
|
|
pipe_config->dpll_hw_state.dpll_md = tmp;
|
2016-10-13 11:02:58 +01:00
|
|
|
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
|
2016-12-07 22:48:09 +02:00
|
|
|
IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, DPLL(crtc->pipe));
|
2013-06-06 12:45:25 +02:00
|
|
|
pipe_config->pixel_multiplier =
|
|
|
|
|
((tmp & SDVO_MULTIPLIER_MASK)
|
|
|
|
|
>> SDVO_MULTIPLIER_SHIFT_HIRES) + 1;
|
|
|
|
|
} else {
|
|
|
|
|
/* Note that on i915G/GM the pixel multiplier is in the sdvo
|
|
|
|
|
* port and will be fixed up in the encoder->get_config
|
|
|
|
|
* function. */
|
|
|
|
|
pipe_config->pixel_multiplier = 1;
|
|
|
|
|
}
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->dpll_hw_state.dpll = intel_de_read(dev_priv,
|
|
|
|
|
DPLL(crtc->pipe));
|
2016-10-14 10:13:44 +01:00
|
|
|
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->dpll_hw_state.fp0 = intel_de_read(dev_priv,
|
|
|
|
|
FP0(crtc->pipe));
|
|
|
|
|
pipe_config->dpll_hw_state.fp1 = intel_de_read(dev_priv,
|
|
|
|
|
FP1(crtc->pipe));
|
2013-06-26 17:44:15 +03:00
|
|
|
} else {
|
|
|
|
|
/* Mask out read-only status bits. */
|
|
|
|
|
pipe_config->dpll_hw_state.dpll &= ~(DPLL_LOCK_VLV |
|
|
|
|
|
DPLL_PORTC_READY_MASK |
|
|
|
|
|
DPLL_PORTB_READY_MASK);
|
2013-06-05 13:34:28 +02:00
|
|
|
}
|
2013-06-06 12:45:25 +02:00
|
|
|
|
2016-10-14 10:13:44 +01:00
|
|
|
if (IS_CHERRYVIEW(dev_priv))
|
2014-04-09 13:28:22 +03:00
|
|
|
chv_crtc_clock_get(crtc, pipe_config);
|
2016-10-13 11:03:08 +01:00
|
|
|
else if (IS_VALLEYVIEW(dev_priv))
|
2013-09-20 11:29:32 -07:00
|
|
|
vlv_crtc_clock_get(crtc, pipe_config);
|
|
|
|
|
else
|
|
|
|
|
i9xx_crtc_clock_get(crtc, pipe_config);
|
2013-09-13 16:00:08 +03:00
|
|
|
|
2015-08-26 19:39:18 +03:00
|
|
|
/*
|
|
|
|
|
* Normally the dotclock is filled in by the encoder .get_config()
|
|
|
|
|
* but in case the pipe is enabled w/o any ports we need a sane
|
|
|
|
|
* default.
|
|
|
|
|
*/
|
2019-10-31 12:26:02 +01:00
|
|
|
pipe_config->hw.adjusted_mode.crtc_clock =
|
2015-08-26 19:39:18 +03:00
|
|
|
pipe_config->port_clock / pipe_config->pixel_multiplier;
|
|
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
ret = true;
|
|
|
|
|
|
|
|
|
|
out:
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_display_power_put(dev_priv, power_domain, wakeref);
|
2016-02-12 18:55:11 +02:00
|
|
|
|
|
|
|
|
return ret;
|
2013-03-28 10:42:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-04-13 22:26:07 +03:00
|
|
|
void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:52 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
2022-04-13 22:26:07 +03:00
|
|
|
u32 val = 0;
|
2012-09-12 10:06:29 -03:00
|
|
|
|
2022-04-13 22:26:07 +03:00
|
|
|
/*
|
|
|
|
|
* - During modeset the pipe is still disabled and must remain so
|
|
|
|
|
* - During fastset the pipe is already enabled and must remain so
|
|
|
|
|
*/
|
|
|
|
|
if (!intel_crtc_needs_modeset(crtc_state))
|
|
|
|
|
val |= PIPECONF_ENABLE;
|
2012-09-12 10:06:29 -03:00
|
|
|
|
2018-10-04 11:45:52 +02:00
|
|
|
switch (crtc_state->pipe_bpp) {
|
2022-05-31 19:25:27 +03:00
|
|
|
default:
|
|
|
|
|
/* Case prevented by intel_choose_pipe_bpp_dither. */
|
|
|
|
|
MISSING_CASE(crtc_state->pipe_bpp);
|
|
|
|
|
fallthrough;
|
2012-09-12 10:06:29 -03:00
|
|
|
case 18:
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_BPC_6;
|
2012-09-12 10:06:29 -03:00
|
|
|
break;
|
|
|
|
|
case 24:
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_BPC_8;
|
2012-09-12 10:06:29 -03:00
|
|
|
break;
|
|
|
|
|
case 30:
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_BPC_10;
|
2012-09-12 10:06:29 -03:00
|
|
|
break;
|
|
|
|
|
case 36:
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_BPC_12;
|
2012-09-12 10:06:29 -03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-04 11:45:52 +02:00
|
|
|
if (crtc_state->dither)
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP;
|
2012-09-12 10:06:29 -03:00
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_INTERLACE_IF_ID_ILK;
|
2012-09-12 10:06:29 -03:00
|
|
|
else
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_INTERLACE_PF_PD_ILK;
|
2012-09-12 10:06:29 -03:00
|
|
|
|
2019-07-18 17:50:53 +03:00
|
|
|
/*
|
|
|
|
|
* This would end up with an odd purple hue over
|
|
|
|
|
* the entire display. Make sure we don't do it.
|
|
|
|
|
*/
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range &&
|
|
|
|
|
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB);
|
2019-07-18 17:50:53 +03:00
|
|
|
|
2020-01-08 20:12:38 +02:00
|
|
|
if (crtc_state->limited_color_range &&
|
|
|
|
|
!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
|
2013-01-17 16:31:28 +02:00
|
|
|
val |= PIPECONF_COLOR_RANGE_SELECT;
|
|
|
|
|
|
2019-07-18 17:50:53 +03:00
|
|
|
if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
|
|
|
|
|
val |= PIPECONF_OUTPUT_COLORSPACE_YUV709;
|
|
|
|
|
|
2019-02-07 22:21:40 +02:00
|
|
|
val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
|
|
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
val |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
|
2022-03-10 02:47:54 +02:00
|
|
|
val |= PIPECONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay);
|
2019-10-24 15:21:38 +03:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPECONF(pipe), val);
|
|
|
|
|
intel_de_posting_read(dev_priv, PIPECONF(pipe));
|
2012-09-12 10:06:29 -03:00
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:29 +03:00
|
|
|
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
|
2012-10-05 12:05:57 -03:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2018-10-04 11:45:52 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
2016-03-18 17:05:40 +02:00
|
|
|
u32 val = 0;
|
2012-10-05 12:05:57 -03:00
|
|
|
|
2022-04-13 22:26:07 +03:00
|
|
|
/*
|
|
|
|
|
* - During modeset the pipe is still disabled and must remain so
|
|
|
|
|
* - During fastset the pipe is already enabled and must remain so
|
|
|
|
|
*/
|
|
|
|
|
if (!intel_crtc_needs_modeset(crtc_state))
|
|
|
|
|
val |= PIPECONF_ENABLE;
|
|
|
|
|
|
2018-10-04 11:45:52 +02:00
|
|
|
if (IS_HASWELL(dev_priv) && crtc_state->dither)
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP;
|
2012-10-05 12:05:57 -03:00
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_INTERLACE_IF_ID_ILK;
|
2012-10-05 12:05:57 -03:00
|
|
|
else
|
2021-11-12 21:38:08 +02:00
|
|
|
val |= PIPECONF_INTERLACE_PF_PD_ILK;
|
2012-10-05 12:05:57 -03:00
|
|
|
|
2019-07-18 17:50:50 +03:00
|
|
|
if (IS_HASWELL(dev_priv) &&
|
|
|
|
|
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
|
|
|
|
|
val |= PIPECONF_OUTPUT_COLORSPACE_YUV_HSW;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPECONF(cpu_transcoder), val);
|
|
|
|
|
intel_de_posting_read(dev_priv, PIPECONF(cpu_transcoder));
|
2016-03-18 17:05:40 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-12 21:30:08 +03:00
|
|
|
static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
|
2016-03-18 17:05:40 +02:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2019-04-12 21:30:08 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
u32 val = 0;
|
2013-11-02 21:07:38 -07:00
|
|
|
|
2019-04-12 21:30:08 +03:00
|
|
|
switch (crtc_state->pipe_bpp) {
|
|
|
|
|
case 18:
|
2021-11-12 21:38:06 +02:00
|
|
|
val |= PIPEMISC_BPC_6;
|
2019-04-12 21:30:08 +03:00
|
|
|
break;
|
|
|
|
|
case 24:
|
2021-11-12 21:38:06 +02:00
|
|
|
val |= PIPEMISC_BPC_8;
|
2019-04-12 21:30:08 +03:00
|
|
|
break;
|
|
|
|
|
case 30:
|
2021-11-12 21:38:06 +02:00
|
|
|
val |= PIPEMISC_BPC_10;
|
2019-04-12 21:30:08 +03:00
|
|
|
break;
|
|
|
|
|
case 36:
|
2021-08-11 10:48:57 +05:30
|
|
|
/* Port output 12BPC defined for ADLP+ */
|
|
|
|
|
if (DISPLAY_VER(dev_priv) > 12)
|
2021-11-12 21:38:06 +02:00
|
|
|
val |= PIPEMISC_BPC_12_ADLP;
|
2019-04-12 21:30:08 +03:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
MISSING_CASE(crtc_state->pipe_bpp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-11-02 21:07:38 -07:00
|
|
|
|
2019-04-12 21:30:08 +03:00
|
|
|
if (crtc_state->dither)
|
|
|
|
|
val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
|
2013-11-02 21:07:38 -07:00
|
|
|
|
2019-04-12 21:30:08 +03:00
|
|
|
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
|
|
|
|
|
crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444)
|
|
|
|
|
val |= PIPEMISC_OUTPUT_COLORSPACE_YUV;
|
2018-10-12 11:53:09 +05:30
|
|
|
|
2019-04-12 21:30:08 +03:00
|
|
|
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
|
|
|
|
|
val |= PIPEMISC_YUV420_ENABLE |
|
|
|
|
|
PIPEMISC_YUV420_MODE_FULL_BLEND;
|
2017-07-24 19:19:32 +05:30
|
|
|
|
2021-09-07 17:06:58 +05:30
|
|
|
if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state))
|
2019-04-12 21:30:09 +03:00
|
|
|
val |= PIPEMISC_HDR_MODE_PRECISION;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 12)
|
2020-02-26 18:30:54 +02:00
|
|
|
val |= PIPEMISC_PIXEL_ROUNDING_TRUNC;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPEMISC(crtc->pipe), val);
|
2012-10-05 12:05:57 -03:00
|
|
|
}
|
|
|
|
|
|
2019-05-02 20:41:00 +05:30
|
|
|
int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
u32 tmp;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
|
2019-05-02 20:41:00 +05:30
|
|
|
|
2021-08-11 10:48:57 +05:30
|
|
|
switch (tmp & PIPEMISC_BPC_MASK) {
|
2021-11-12 21:38:06 +02:00
|
|
|
case PIPEMISC_BPC_6:
|
2019-05-02 20:41:00 +05:30
|
|
|
return 18;
|
2021-11-12 21:38:06 +02:00
|
|
|
case PIPEMISC_BPC_8:
|
2019-05-02 20:41:00 +05:30
|
|
|
return 24;
|
2021-11-12 21:38:06 +02:00
|
|
|
case PIPEMISC_BPC_10:
|
2019-05-02 20:41:00 +05:30
|
|
|
return 30;
|
2021-08-11 10:48:57 +05:30
|
|
|
/*
|
|
|
|
|
* PORT OUTPUT 12 BPC defined for ADLP+.
|
|
|
|
|
*
|
|
|
|
|
* TODO:
|
|
|
|
|
* For previous platforms with DSI interface, bits 5:7
|
|
|
|
|
* are used for storing pipe_bpp irrespective of dithering.
|
|
|
|
|
* Since the value of 12 BPC is not defined for these bits
|
|
|
|
|
* on older platforms, need to find a workaround for 12 BPC
|
|
|
|
|
* MIPI DSI HW readout.
|
|
|
|
|
*/
|
2021-11-12 21:38:06 +02:00
|
|
|
case PIPEMISC_BPC_12_ADLP:
|
2021-08-11 10:48:57 +05:30
|
|
|
if (DISPLAY_VER(dev_priv) > 12)
|
|
|
|
|
return 36;
|
|
|
|
|
fallthrough;
|
2019-05-02 20:41:00 +05:30
|
|
|
default:
|
|
|
|
|
MISSING_CASE(tmp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
int ilk_get_lanes_required(int target_clock, int link_bw, int bpp)
|
2012-11-29 11:29:32 -02:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Account for spread spectrum to avoid
|
|
|
|
|
* oversubscribing the link. Max center spread
|
|
|
|
|
* is 2.5%; use 5% for safety's sake.
|
|
|
|
|
*/
|
|
|
|
|
u32 bps = target_clock * bpp * 21 / 20;
|
2014-02-27 14:23:14 +02:00
|
|
|
return DIV_ROUND_UP(bps, link_bw * 8);
|
2012-11-29 11:29:32 -02:00
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:47 +02:00
|
|
|
void intel_get_m_n(struct drm_i915_private *i915,
|
|
|
|
|
struct intel_link_m_n *m_n,
|
|
|
|
|
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
|
|
|
|
|
i915_reg_t link_m_reg, i915_reg_t link_n_reg)
|
2022-01-27 11:32:50 +02:00
|
|
|
{
|
2022-01-27 14:02:19 +02:00
|
|
|
m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK;
|
|
|
|
|
m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK;
|
2022-01-27 11:32:52 +02:00
|
|
|
m_n->data_m = intel_de_read(i915, data_m_reg) & DATA_LINK_M_N_MASK;
|
|
|
|
|
m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK;
|
2022-01-27 14:02:19 +02:00
|
|
|
m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1;
|
2022-01-27 11:32:50 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-28 12:37:45 +02:00
|
|
|
void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
|
|
|
|
|
enum transcoder transcoder,
|
|
|
|
|
struct intel_link_m_n *m_n)
|
2013-04-04 13:28:53 +02:00
|
|
|
{
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2013-09-10 17:02:54 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
2013-04-04 13:28:53 +02:00
|
|
|
|
2022-01-28 12:37:45 +02:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 5)
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_get_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
|
|
|
|
|
PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
|
2022-01-28 12:37:45 +02:00
|
|
|
else
|
2022-01-27 11:32:50 +02:00
|
|
|
intel_get_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
|
|
|
|
|
PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
|
2022-01-28 12:37:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
|
|
|
|
|
enum transcoder transcoder,
|
|
|
|
|
struct intel_link_m_n *m_n)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
|
2022-01-28 12:37:53 +02:00
|
|
|
if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder))
|
2022-01-28 12:37:45 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
intel_get_m_n(dev_priv, m_n,
|
|
|
|
|
PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
|
|
|
|
|
PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
|
2013-09-10 17:02:54 +03:00
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:14 +03:00
|
|
|
static void ilk_get_pfit_pos_size(struct intel_crtc_state *crtc_state,
|
|
|
|
|
u32 pos, u32 size)
|
|
|
|
|
{
|
|
|
|
|
drm_rect_init(&crtc_state->pch_pfit.dst,
|
|
|
|
|
pos >> 16, pos & 0xffff,
|
|
|
|
|
size >> 16, size & 0xffff);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
static void skl_get_pfit_config(struct intel_crtc_state *crtc_state)
|
2014-11-13 17:51:47 +00:00
|
|
|
{
|
2020-04-22 19:19:13 +03:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state;
|
2015-04-07 15:28:45 -07:00
|
|
|
int id = -1;
|
|
|
|
|
int i;
|
2014-11-13 17:51:47 +00:00
|
|
|
|
2015-04-07 15:28:45 -07:00
|
|
|
/* find scaler attached to this pipe */
|
|
|
|
|
for (i = 0; i < crtc->num_scalers; i++) {
|
2020-04-22 19:19:14 +03:00
|
|
|
u32 ctl, pos, size;
|
2020-04-22 19:19:13 +03:00
|
|
|
|
2020-04-22 19:19:14 +03:00
|
|
|
ctl = intel_de_read(dev_priv, SKL_PS_CTRL(crtc->pipe, i));
|
|
|
|
|
if ((ctl & (PS_SCALER_EN | PS_PLANE_SEL_MASK)) != PS_SCALER_EN)
|
2020-04-22 19:19:13 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
id = i;
|
|
|
|
|
crtc_state->pch_pfit.enabled = true;
|
2020-04-22 19:19:14 +03:00
|
|
|
|
|
|
|
|
pos = intel_de_read(dev_priv, SKL_PS_WIN_POS(crtc->pipe, i));
|
|
|
|
|
size = intel_de_read(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, i));
|
|
|
|
|
|
|
|
|
|
ilk_get_pfit_pos_size(crtc_state, pos, size);
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
scaler_state->scalers[i].in_use = true;
|
|
|
|
|
break;
|
2015-04-07 15:28:45 -07:00
|
|
|
}
|
2014-11-13 17:51:47 +00:00
|
|
|
|
2015-04-07 15:28:45 -07:00
|
|
|
scaler_state->scaler_id = id;
|
2020-04-22 19:19:13 +03:00
|
|
|
if (id >= 0)
|
2015-04-07 15:28:45 -07:00
|
|
|
scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX);
|
2020-04-22 19:19:13 +03:00
|
|
|
else
|
2015-04-07 15:28:45 -07:00
|
|
|
scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX);
|
2014-11-13 17:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state)
|
2013-05-07 23:34:16 +02:00
|
|
|
{
|
2020-04-22 19:19:13 +03:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2020-04-22 19:19:14 +03:00
|
|
|
u32 ctl, pos, size;
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2020-04-22 19:19:14 +03:00
|
|
|
ctl = intel_de_read(dev_priv, PF_CTL(crtc->pipe));
|
|
|
|
|
if ((ctl & PF_ENABLE) == 0)
|
2020-04-22 19:19:13 +03:00
|
|
|
return;
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
crtc_state->pch_pfit.enabled = true;
|
2020-04-22 19:19:14 +03:00
|
|
|
|
|
|
|
|
pos = intel_de_read(dev_priv, PF_WIN_POS(crtc->pipe));
|
|
|
|
|
size = intel_de_read(dev_priv, PF_WIN_SZ(crtc->pipe));
|
|
|
|
|
|
|
|
|
|
ilk_get_pfit_pos_size(crtc_state, pos, size);
|
2020-04-22 19:19:13 +03:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We currently do not free assignements of panel fitters on
|
|
|
|
|
* ivb/hsw (since we don't use the higher upscaling modes which
|
|
|
|
|
* differentiates them) so just WARN about this case for now.
|
|
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 7 &&
|
2020-04-22 19:19:14 +03:00
|
|
|
(ctl & PF_PIPE_SEL_MASK_IVB) != PF_PIPE_SEL_IVB(crtc->pipe));
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:09 -08:00
|
|
|
static bool ilk_get_pipe_config(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config)
|
2013-03-28 10:42:00 +01:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2016-02-12 18:55:11 +02:00
|
|
|
enum intel_display_power_domain power_domain;
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_wakeref_t wakeref;
|
2019-01-18 14:01:23 +02:00
|
|
|
u32 tmp;
|
2016-02-12 18:55:11 +02:00
|
|
|
bool ret;
|
2013-03-28 10:42:00 +01:00
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
|
2019-01-14 14:21:24 +00:00
|
|
|
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
|
|
|
|
if (!wakeref)
|
2014-07-04 13:38:34 -03:00
|
|
|
return false;
|
|
|
|
|
|
2013-07-04 12:01:15 +02:00
|
|
|
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
|
2016-03-08 17:46:18 +02:00
|
|
|
pipe_config->shared_dpll = NULL;
|
2013-05-22 00:50:22 +02:00
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
ret = false;
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPECONF(crtc->pipe));
|
2013-03-28 10:42:00 +01:00
|
|
|
if (!(tmp & PIPECONF_ENABLE))
|
2016-02-12 18:55:11 +02:00
|
|
|
goto out;
|
2013-03-28 10:42:00 +01:00
|
|
|
|
2013-09-06 23:29:00 +03:00
|
|
|
switch (tmp & PIPECONF_BPC_MASK) {
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_6:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 18;
|
|
|
|
|
break;
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_8:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 24;
|
|
|
|
|
break;
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_10:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 30;
|
|
|
|
|
break;
|
2021-11-12 21:38:08 +02:00
|
|
|
case PIPECONF_BPC_12:
|
2013-09-06 23:29:00 +03:00
|
|
|
pipe_config->pipe_bpp = 36;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-24 23:54:49 +02:00
|
|
|
if (tmp & PIPECONF_COLOR_RANGE_SELECT)
|
|
|
|
|
pipe_config->limited_color_range = true;
|
|
|
|
|
|
2019-07-18 17:50:53 +03:00
|
|
|
switch (tmp & PIPECONF_OUTPUT_COLORSPACE_MASK) {
|
|
|
|
|
case PIPECONF_OUTPUT_COLORSPACE_YUV601:
|
|
|
|
|
case PIPECONF_OUTPUT_COLORSPACE_YUV709:
|
|
|
|
|
pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-12 21:38:08 +02:00
|
|
|
pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp);
|
2019-02-07 22:21:40 +02:00
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1;
|
|
|
|
|
|
2022-03-10 02:47:54 +02:00
|
|
|
pipe_config->msa_timing_delay = REG_FIELD_GET(PIPECONF_MSA_TIMING_DELAY_MASK, tmp);
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->csc_mode = intel_de_read(dev_priv,
|
|
|
|
|
PIPE_CSC_MODE(crtc->pipe));
|
2019-02-18 21:31:31 +02:00
|
|
|
|
2019-02-07 22:39:13 +02:00
|
|
|
i9xx_get_pipe_color_config(pipe_config);
|
2019-05-29 15:20:52 +05:30
|
|
|
intel_color_get_config(pipe_config);
|
2019-02-07 22:39:13 +02:00
|
|
|
|
2021-10-15 10:16:21 +03:00
|
|
|
pipe_config->pixel_multiplier = 1;
|
2013-06-05 13:34:20 +02:00
|
|
|
|
2021-10-15 10:16:21 +03:00
|
|
|
ilk_pch_get_config(pipe_config);
|
2013-04-29 19:33:42 +02:00
|
|
|
|
2020-10-08 14:45:26 -07:00
|
|
|
intel_get_transcoder_timings(crtc, pipe_config);
|
2016-03-18 17:05:39 +02:00
|
|
|
intel_get_pipe_src_size(crtc, pipe_config);
|
2013-04-29 21:56:12 +02:00
|
|
|
|
2020-04-22 19:19:13 +03:00
|
|
|
ilk_get_pfit_config(pipe_config);
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
ret = true;
|
|
|
|
|
|
|
|
|
|
out:
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_display_power_put(dev_priv, power_domain, wakeref);
|
2016-02-12 18:55:11 +02:00
|
|
|
|
|
|
|
|
return ret;
|
2013-03-28 10:42:00 +01:00
|
|
|
}
|
2019-12-24 00:40:05 -08:00
|
|
|
|
2021-10-22 13:33:02 +03:00
|
|
|
static u8 bigjoiner_pipes(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
if (DISPLAY_VER(i915) >= 12)
|
|
|
|
|
return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
|
|
|
|
|
else if (DISPLAY_VER(i915) >= 11)
|
|
|
|
|
return BIT(PIPE_B) | BIT(PIPE_C);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
|
|
|
|
|
enum transcoder cpu_transcoder)
|
|
|
|
|
{
|
|
|
|
|
enum intel_display_power_domain power_domain;
|
|
|
|
|
intel_wakeref_t wakeref;
|
|
|
|
|
u32 tmp = 0;
|
|
|
|
|
|
|
|
|
|
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
|
|
|
|
|
|
|
|
|
|
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
|
|
|
|
|
tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
|
|
|
|
|
|
|
|
|
|
return tmp & TRANS_DDI_FUNC_ENABLE;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:22 +02:00
|
|
|
static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
|
|
|
|
|
u8 *master_pipes, u8 *slave_pipes)
|
2021-10-22 13:33:02 +03:00
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
|
2022-02-03 20:38:22 +02:00
|
|
|
*master_pipes = 0;
|
|
|
|
|
*slave_pipes = 0;
|
|
|
|
|
|
2022-02-03 20:38:21 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
|
|
|
|
|
bigjoiner_pipes(dev_priv)) {
|
2021-10-22 13:33:02 +03:00
|
|
|
enum intel_display_power_domain power_domain;
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
intel_wakeref_t wakeref;
|
|
|
|
|
|
|
|
|
|
power_domain = intel_dsc_power_domain(crtc, (enum transcoder) pipe);
|
|
|
|
|
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
|
|
|
|
|
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
|
|
|
|
|
|
|
|
|
|
if (!(tmp & BIG_JOINER_ENABLE))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (tmp & MASTER_BIG_JOINER_ENABLE)
|
2022-02-03 20:38:22 +02:00
|
|
|
*master_pipes |= BIT(pipe);
|
2021-10-22 13:33:02 +03:00
|
|
|
else
|
2022-02-03 20:38:22 +02:00
|
|
|
*slave_pipes |= BIT(pipe);
|
2021-10-22 13:33:02 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (DISPLAY_VER(dev_priv) < 13)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
power_domain = POWER_DOMAIN_PIPE(pipe);
|
|
|
|
|
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
|
|
|
|
|
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
|
|
|
|
|
|
|
|
|
|
if (tmp & UNCOMPRESSED_JOINER_MASTER)
|
2022-02-03 20:38:22 +02:00
|
|
|
*master_pipes |= BIT(pipe);
|
2021-10-22 13:33:02 +03:00
|
|
|
if (tmp & UNCOMPRESSED_JOINER_SLAVE)
|
2022-02-03 20:38:22 +02:00
|
|
|
*slave_pipes |= BIT(pipe);
|
2021-10-22 13:33:02 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Bigjoiner pipes should always be consecutive master and slave */
|
2022-02-03 20:38:22 +02:00
|
|
|
drm_WARN(&dev_priv->drm, *slave_pipes != *master_pipes << 1,
|
2021-10-22 13:33:02 +03:00
|
|
|
"Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n",
|
2022-02-03 20:38:22 +02:00
|
|
|
*master_pipes, *slave_pipes);
|
2021-10-22 13:33:02 +03:00
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
static enum pipe get_bigjoiner_master_pipe(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
|
|
|
|
|
{
|
|
|
|
|
if ((slave_pipes & BIT(pipe)) == 0)
|
|
|
|
|
return pipe;
|
|
|
|
|
|
|
|
|
|
/* ignore everything above our pipe */
|
|
|
|
|
master_pipes &= ~GENMASK(7, pipe);
|
|
|
|
|
|
|
|
|
|
/* highest remaining bit should be our master pipe */
|
|
|
|
|
return fls(master_pipes) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static u8 get_bigjoiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
|
|
|
|
|
{
|
|
|
|
|
enum pipe master_pipe, next_master_pipe;
|
|
|
|
|
|
|
|
|
|
master_pipe = get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes);
|
|
|
|
|
|
|
|
|
|
if ((master_pipes & BIT(master_pipe)) == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* ignore our master pipe and everything below it */
|
|
|
|
|
master_pipes &= ~GENMASK(master_pipe, 0);
|
|
|
|
|
/* make sure a high bit is set for the ffs() */
|
|
|
|
|
master_pipes |= BIT(7);
|
|
|
|
|
/* lowest remaining bit should be the next master pipe */
|
|
|
|
|
next_master_pipe = ffs(master_pipes) - 1;
|
|
|
|
|
|
|
|
|
|
return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:32 +03:00
|
|
|
static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
u8 panel_transcoder_mask = BIT(TRANSCODER_EDP);
|
|
|
|
|
|
|
|
|
|
if (DISPLAY_VER(i915) >= 11)
|
|
|
|
|
panel_transcoder_mask |= BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
|
|
|
|
|
|
|
|
|
|
return panel_transcoder_mask;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
|
2016-03-18 17:05:41 +02:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2021-09-13 17:44:32 +03:00
|
|
|
u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
|
2021-09-13 17:44:33 +03:00
|
|
|
enum transcoder cpu_transcoder;
|
2022-02-03 20:38:22 +02:00
|
|
|
u8 master_pipes, slave_pipes;
|
2021-09-13 17:44:33 +03:00
|
|
|
u8 enabled_transcoders = 0;
|
2016-03-18 17:05:41 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* XXX: Do intel_display_power_get_if_enabled before reading this (for
|
|
|
|
|
* consistency and less surprising code; it's in always on power).
|
|
|
|
|
*/
|
2021-09-13 17:44:33 +03:00
|
|
|
for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder,
|
2020-06-05 19:57:37 -07:00
|
|
|
panel_transcoder_mask) {
|
2021-09-13 17:44:33 +03:00
|
|
|
enum intel_display_power_domain power_domain;
|
|
|
|
|
intel_wakeref_t wakeref;
|
2018-12-04 12:19:26 +02:00
|
|
|
enum pipe trans_pipe;
|
2021-09-13 17:44:33 +03:00
|
|
|
u32 tmp = 0;
|
2018-11-29 16:12:27 +02:00
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
|
|
|
|
|
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
|
|
|
|
|
tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
|
2018-11-29 16:12:27 +02:00
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
if (!(tmp & TRANS_DDI_FUNC_ENABLE))
|
2018-12-04 12:19:26 +02:00
|
|
|
continue;
|
2018-11-29 16:12:27 +02:00
|
|
|
|
2016-03-18 17:05:41 +02:00
|
|
|
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
|
|
|
|
|
default:
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN(dev, 1,
|
|
|
|
|
"unknown pipe linked to transcoder %s\n",
|
2021-09-13 17:44:33 +03:00
|
|
|
transcoder_name(cpu_transcoder));
|
2020-08-23 17:36:59 -05:00
|
|
|
fallthrough;
|
2016-03-18 17:05:41 +02:00
|
|
|
case TRANS_DDI_EDP_INPUT_A_ONOFF:
|
|
|
|
|
case TRANS_DDI_EDP_INPUT_A_ON:
|
2018-11-29 16:12:27 +02:00
|
|
|
trans_pipe = PIPE_A;
|
2016-03-18 17:05:41 +02:00
|
|
|
break;
|
|
|
|
|
case TRANS_DDI_EDP_INPUT_B_ONOFF:
|
2018-11-29 16:12:27 +02:00
|
|
|
trans_pipe = PIPE_B;
|
2016-03-18 17:05:41 +02:00
|
|
|
break;
|
|
|
|
|
case TRANS_DDI_EDP_INPUT_C_ONOFF:
|
2018-11-29 16:12:27 +02:00
|
|
|
trans_pipe = PIPE_C;
|
2016-03-18 17:05:41 +02:00
|
|
|
break;
|
2019-12-11 13:08:44 +02:00
|
|
|
case TRANS_DDI_EDP_INPUT_D_ONOFF:
|
|
|
|
|
trans_pipe = PIPE_D;
|
|
|
|
|
break;
|
2016-03-18 17:05:41 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
if (trans_pipe == crtc->pipe)
|
|
|
|
|
enabled_transcoders |= BIT(cpu_transcoder);
|
2016-03-18 17:05:41 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-22 13:33:02 +03:00
|
|
|
/* single pipe or bigjoiner master */
|
2021-09-13 17:44:33 +03:00
|
|
|
cpu_transcoder = (enum transcoder) crtc->pipe;
|
|
|
|
|
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
|
|
|
|
|
enabled_transcoders |= BIT(cpu_transcoder);
|
|
|
|
|
|
2021-10-22 13:33:02 +03:00
|
|
|
/* bigjoiner slave -> consider the master pipe's transcoder as well */
|
2022-02-03 20:38:22 +02:00
|
|
|
enabled_bigjoiner_pipes(dev_priv, &master_pipes, &slave_pipes);
|
|
|
|
|
if (slave_pipes & BIT(crtc->pipe)) {
|
2022-02-03 20:38:23 +02:00
|
|
|
cpu_transcoder = (enum transcoder)
|
|
|
|
|
get_bigjoiner_master_pipe(crtc->pipe, master_pipes, slave_pipes);
|
2021-10-22 13:33:02 +03:00
|
|
|
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
|
|
|
|
|
enabled_transcoders |= BIT(cpu_transcoder);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
return enabled_transcoders;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool has_edp_transcoders(u8 enabled_transcoders)
|
|
|
|
|
{
|
|
|
|
|
return enabled_transcoders & BIT(TRANSCODER_EDP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool has_dsi_transcoders(u8 enabled_transcoders)
|
|
|
|
|
{
|
|
|
|
|
return enabled_transcoders & (BIT(TRANSCODER_DSI_0) |
|
|
|
|
|
BIT(TRANSCODER_DSI_1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool has_pipe_transcoders(u8 enabled_transcoders)
|
|
|
|
|
{
|
|
|
|
|
return enabled_transcoders & ~(BIT(TRANSCODER_EDP) |
|
|
|
|
|
BIT(TRANSCODER_DSI_0) |
|
|
|
|
|
BIT(TRANSCODER_DSI_1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void assert_enabled_transcoders(struct drm_i915_private *i915,
|
|
|
|
|
u8 enabled_transcoders)
|
|
|
|
|
{
|
|
|
|
|
/* Only one type of transcoder please */
|
|
|
|
|
drm_WARN_ON(&i915->drm,
|
|
|
|
|
has_edp_transcoders(enabled_transcoders) +
|
|
|
|
|
has_dsi_transcoders(enabled_transcoders) +
|
|
|
|
|
has_pipe_transcoders(enabled_transcoders) > 1);
|
|
|
|
|
|
|
|
|
|
/* Only DSI transcoders can be ganged */
|
|
|
|
|
drm_WARN_ON(&i915->drm,
|
|
|
|
|
!has_dsi_transcoders(enabled_transcoders) &&
|
|
|
|
|
!is_power_of_2(enabled_transcoders));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config,
|
|
|
|
|
struct intel_display_power_domain_set *power_domain_set)
|
|
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
|
|
|
unsigned long enabled_transcoders;
|
|
|
|
|
u32 tmp;
|
|
|
|
|
|
|
|
|
|
enabled_transcoders = hsw_enabled_transcoders(crtc);
|
|
|
|
|
if (!enabled_transcoders)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
assert_enabled_transcoders(dev_priv, enabled_transcoders);
|
|
|
|
|
|
2018-12-04 12:19:26 +02:00
|
|
|
/*
|
2021-09-13 17:44:33 +03:00
|
|
|
* With the exception of DSI we should only ever have
|
|
|
|
|
* a single enabled transcoder. With DSI let's just
|
|
|
|
|
* pick the first one.
|
2018-12-04 12:19:26 +02:00
|
|
|
*/
|
2021-09-13 17:44:33 +03:00
|
|
|
pipe_config->cpu_transcoder = ffs(enabled_transcoders) - 1;
|
2018-12-04 12:19:26 +02:00
|
|
|
|
2020-12-01 18:13:39 +02:00
|
|
|
if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set,
|
|
|
|
|
POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder)))
|
2016-03-18 17:05:41 +02:00
|
|
|
return false;
|
2019-01-14 14:21:27 +00:00
|
|
|
|
2021-09-13 17:44:33 +03:00
|
|
|
if (hsw_panel_transcoders(dev_priv) & BIT(pipe_config->cpu_transcoder)) {
|
|
|
|
|
tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
|
|
|
|
|
|
|
|
|
|
if ((tmp & TRANS_DDI_EDP_INPUT_MASK) == TRANS_DDI_EDP_INPUT_A_ONOFF)
|
|
|
|
|
pipe_config->pch_pfit.force_thru = true;
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, PIPECONF(pipe_config->cpu_transcoder));
|
2016-03-18 17:05:41 +02:00
|
|
|
|
|
|
|
|
return tmp & PIPECONF_ENABLE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-18 17:05:42 +02:00
|
|
|
static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config,
|
2020-12-01 18:13:39 +02:00
|
|
|
struct intel_display_power_domain_set *power_domain_set)
|
2016-03-18 17:05:42 +02:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2016-03-18 17:05:42 +02:00
|
|
|
enum transcoder cpu_transcoder;
|
2019-04-06 09:03:41 +01:00
|
|
|
enum port port;
|
2016-03-18 17:05:42 +02:00
|
|
|
u32 tmp;
|
|
|
|
|
|
|
|
|
|
for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) {
|
|
|
|
|
if (port == PORT_A)
|
|
|
|
|
cpu_transcoder = TRANSCODER_DSI_A;
|
|
|
|
|
else
|
|
|
|
|
cpu_transcoder = TRANSCODER_DSI_C;
|
|
|
|
|
|
2020-12-01 18:13:39 +02:00
|
|
|
if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set,
|
|
|
|
|
POWER_DOMAIN_TRANSCODER(cpu_transcoder)))
|
2016-03-18 17:05:42 +02:00
|
|
|
continue;
|
2019-01-14 14:21:27 +00:00
|
|
|
|
2016-03-24 12:41:40 +02:00
|
|
|
/*
|
|
|
|
|
* The PLL needs to be enabled with a valid divider
|
|
|
|
|
* configuration, otherwise accessing DSI registers will hang
|
|
|
|
|
* the machine. See BSpec North Display Engine
|
|
|
|
|
* registers/MIPI[BXT]. We can break out here early, since we
|
|
|
|
|
* need the same DSI PLL to be enabled for both DSI ports.
|
|
|
|
|
*/
|
2018-07-05 16:25:08 +03:00
|
|
|
if (!bxt_dsi_pll_is_enabled(dev_priv))
|
2016-03-24 12:41:40 +02:00
|
|
|
break;
|
|
|
|
|
|
2016-03-18 17:05:42 +02:00
|
|
|
/* XXX: this works for video mode only */
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, BXT_MIPI_PORT_CTRL(port));
|
2016-03-18 17:05:42 +02:00
|
|
|
if (!(tmp & DPI_ENABLE))
|
|
|
|
|
continue;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
tmp = intel_de_read(dev_priv, MIPI_CTRL(port));
|
2016-03-18 17:05:42 +02:00
|
|
|
if ((tmp & BXT_PIPE_SELECT_MASK) != BXT_PIPE_SELECT(crtc->pipe))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pipe_config->cpu_transcoder = cpu_transcoder;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-22 21:57:07 +03:00
|
|
|
return transcoder_is_dsi(pipe_config->cpu_transcoder);
|
2016-03-18 17:05:42 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
static void intel_bigjoiner_get_config(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
|
u8 master_pipes, slave_pipes;
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
|
|
|
|
enabled_bigjoiner_pipes(i915, &master_pipes, &slave_pipes);
|
|
|
|
|
|
|
|
|
|
if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
crtc_state->bigjoiner_pipes =
|
|
|
|
|
BIT(get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes)) |
|
|
|
|
|
get_bigjoiner_slave_pipes(pipe, master_pipes, slave_pipes);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 00:40:05 -08:00
|
|
|
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config)
|
2013-03-28 10:42:00 +01:00
|
|
|
{
|
2016-11-16 12:32:42 +00:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2020-12-01 18:13:39 +02:00
|
|
|
struct intel_display_power_domain_set power_domain_set = { };
|
2016-03-18 17:05:41 +02:00
|
|
|
bool active;
|
2020-01-20 19:47:12 +02:00
|
|
|
u32 tmp;
|
2013-03-28 10:42:00 +01:00
|
|
|
|
2020-12-01 18:13:39 +02:00
|
|
|
if (!intel_display_power_get_in_set_if_enabled(dev_priv, &power_domain_set,
|
|
|
|
|
POWER_DOMAIN_PIPE(crtc->pipe)))
|
2014-03-05 16:20:55 +02:00
|
|
|
return false;
|
2019-04-06 09:03:41 +01:00
|
|
|
|
2016-03-08 17:46:18 +02:00
|
|
|
pipe_config->shared_dpll = NULL;
|
2013-06-07 23:11:08 +02:00
|
|
|
|
2020-12-01 18:13:39 +02:00
|
|
|
active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_set);
|
2013-05-22 00:50:22 +02:00
|
|
|
|
2021-04-07 13:39:45 -07:00
|
|
|
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
|
2020-12-01 18:13:39 +02:00
|
|
|
bxt_get_dsi_transcoder_state(crtc, pipe_config, &power_domain_set)) {
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm, active);
|
2016-06-22 21:57:07 +03:00
|
|
|
active = true;
|
2016-03-18 17:05:42 +02:00
|
|
|
}
|
|
|
|
|
|
2022-01-24 21:26:34 +02:00
|
|
|
if (!active)
|
|
|
|
|
goto out;
|
|
|
|
|
|
2020-11-17 11:47:09 -08:00
|
|
|
intel_dsc_get_config(pipe_config);
|
2022-02-03 20:38:23 +02:00
|
|
|
intel_bigjoiner_get_config(pipe_config);
|
2020-11-17 11:47:09 -08:00
|
|
|
|
2021-10-22 13:33:03 +03:00
|
|
|
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
|
|
|
|
|
DISPLAY_VER(dev_priv) >= 11)
|
2020-10-08 14:45:26 -07:00
|
|
|
intel_get_transcoder_timings(crtc, pipe_config);
|
2013-04-29 19:33:42 +02:00
|
|
|
|
2021-01-26 10:52:24 -08:00
|
|
|
if (HAS_VRR(dev_priv) && !transcoder_is_dsi(pipe_config->cpu_transcoder))
|
2021-01-22 15:26:43 -08:00
|
|
|
intel_vrr_get_config(crtc, pipe_config);
|
|
|
|
|
|
2016-03-18 17:05:39 +02:00
|
|
|
intel_get_pipe_src_size(crtc, pipe_config);
|
2019-07-18 17:50:49 +03:00
|
|
|
|
2019-07-18 17:50:50 +03:00
|
|
|
if (IS_HASWELL(dev_priv)) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
u32 tmp = intel_de_read(dev_priv,
|
|
|
|
|
PIPECONF(pipe_config->cpu_transcoder));
|
2019-07-18 17:50:50 +03:00
|
|
|
|
|
|
|
|
if (tmp & PIPECONF_OUTPUT_COLORSPACE_YUV_HSW)
|
|
|
|
|
pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
|
|
|
|
|
else
|
|
|
|
|
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
|
|
|
|
} else {
|
2019-07-18 17:50:49 +03:00
|
|
|
pipe_config->output_format =
|
|
|
|
|
bdw_get_pipemisc_output_format(crtc);
|
|
|
|
|
}
|
2013-04-29 21:56:12 +02:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->gamma_mode = intel_de_read(dev_priv,
|
|
|
|
|
GAMMA_MODE(crtc->pipe));
|
2016-03-16 10:57:15 +00:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
pipe_config->csc_mode = intel_de_read(dev_priv,
|
|
|
|
|
PIPE_CSC_MODE(crtc->pipe));
|
2019-02-18 21:31:31 +02:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9) {
|
2020-01-20 19:47:12 +02:00
|
|
|
tmp = intel_de_read(dev_priv, SKL_BOTTOM_COLOR(crtc->pipe));
|
2019-02-07 22:39:13 +02:00
|
|
|
|
|
|
|
|
if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
|
|
|
|
|
pipe_config->gamma_enable = true;
|
2019-02-07 22:21:42 +02:00
|
|
|
|
|
|
|
|
if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
|
|
|
|
|
pipe_config->csc_enable = true;
|
2019-02-07 22:39:13 +02:00
|
|
|
} else {
|
|
|
|
|
i9xx_get_pipe_color_config(pipe_config);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-29 15:20:52 +05:30
|
|
|
intel_color_get_config(pipe_config);
|
|
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
tmp = intel_de_read(dev_priv, WM_LINETIME(crtc->pipe));
|
|
|
|
|
pipe_config->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, tmp);
|
|
|
|
|
if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
|
|
|
|
pipe_config->ips_linetime =
|
|
|
|
|
REG_FIELD_GET(HSW_IPS_LINETIME_MASK, tmp);
|
|
|
|
|
|
2020-12-01 18:13:39 +02:00
|
|
|
if (intel_display_power_get_in_set_if_enabled(dev_priv, &power_domain_set,
|
|
|
|
|
POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe))) {
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9)
|
2020-04-22 19:19:13 +03:00
|
|
|
skl_get_pfit_config(pipe_config);
|
2015-01-21 17:19:54 -08:00
|
|
|
else
|
2020-04-22 19:19:13 +03:00
|
|
|
ilk_get_pfit_config(pipe_config);
|
2014-11-13 17:51:47 +00:00
|
|
|
}
|
2013-03-28 10:42:01 +01:00
|
|
|
|
2022-02-09 13:35:24 +02:00
|
|
|
hsw_ips_get_config(pipe_config);
|
2017-11-22 19:39:01 +01:00
|
|
|
|
2021-10-22 13:33:03 +03:00
|
|
|
if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
|
2016-03-18 17:05:42 +02:00
|
|
|
!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
2014-09-30 10:30:22 -07:00
|
|
|
pipe_config->pixel_multiplier =
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_read(dev_priv,
|
|
|
|
|
PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
|
2014-09-30 10:30:22 -07:00
|
|
|
} else {
|
|
|
|
|
pipe_config->pixel_multiplier = 1;
|
|
|
|
|
}
|
2013-06-06 12:45:25 +02:00
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
|
|
|
|
tmp = intel_de_read(dev_priv, CHICKEN_TRANS(pipe_config->cpu_transcoder));
|
|
|
|
|
|
|
|
|
|
pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
|
|
|
|
|
} else {
|
|
|
|
|
/* no idea if this is correct */
|
|
|
|
|
pipe_config->framestart_delay = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-12 18:55:11 +02:00
|
|
|
out:
|
2020-12-01 18:13:39 +02:00
|
|
|
intel_display_power_put_all_in_set(dev_priv, &power_domain_set);
|
2016-02-12 18:55:11 +02:00
|
|
|
|
2016-03-18 17:05:41 +02:00
|
|
|
return active;
|
2013-03-28 10:42:00 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-16 12:48:15 +03:00
|
|
|
bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state)
|
2020-11-12 21:17:14 +02:00
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
if (!i915->display.funcs.display->get_pipe_config(crtc, crtc_state))
|
2020-11-12 21:17:15 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
crtc_state->hw.active = true;
|
|
|
|
|
|
2020-11-12 21:17:17 +02:00
|
|
|
intel_crtc_readout_derived_state(crtc_state);
|
|
|
|
|
|
2020-11-12 21:17:15 +02:00
|
|
|
return true;
|
2020-11-12 21:17:14 +02:00
|
|
|
}
|
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
/* VESA 640x480x72Hz mode to set on the pipe */
|
2017-05-18 22:38:37 +03:00
|
|
|
static const struct drm_display_mode load_detect_mode = {
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
|
|
|
|
|
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
|
|
|
|
|
};
|
|
|
|
|
|
2017-12-20 10:35:45 +01:00
|
|
|
static int intel_modeset_disable_planes(struct drm_atomic_state *state,
|
|
|
|
|
struct drm_crtc *crtc)
|
2015-04-21 17:13:09 +03:00
|
|
|
{
|
2017-12-20 10:35:45 +01:00
|
|
|
struct drm_plane *plane;
|
2015-04-21 17:13:09 +03:00
|
|
|
struct drm_plane_state *plane_state;
|
2017-12-20 10:35:45 +01:00
|
|
|
int ret, i;
|
2015-04-21 17:13:09 +03:00
|
|
|
|
2017-12-20 10:35:45 +01:00
|
|
|
ret = drm_atomic_add_affected_planes(state, crtc);
|
2015-04-21 17:13:09 +03:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2017-12-20 10:35:45 +01:00
|
|
|
|
|
|
|
|
for_each_new_plane_in_state(state, plane, plane_state, i) {
|
|
|
|
|
if (plane_state->crtc != crtc)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
drm_atomic_set_fb_for_plane(plane_state, NULL);
|
|
|
|
|
}
|
2015-04-21 17:13:09 +03:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-06 20:55:20 +02:00
|
|
|
int intel_get_load_detect_pipe(struct drm_connector *connector,
|
|
|
|
|
struct intel_load_detect_pipe *old,
|
|
|
|
|
struct drm_modeset_acquire_ctx *ctx)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2021-06-09 11:56:28 +03:00
|
|
|
struct intel_encoder *encoder =
|
2019-12-04 20:05:42 +02:00
|
|
|
intel_attached_encoder(to_intel_connector(connector));
|
2021-06-09 11:56:28 +03:00
|
|
|
struct intel_crtc *possible_crtc;
|
|
|
|
|
struct intel_crtc *crtc = NULL;
|
|
|
|
|
struct drm_device *dev = encoder->base.dev;
|
2016-10-31 22:37:06 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2013-11-19 12:10:12 -05:00
|
|
|
struct drm_mode_config *config = &dev->mode_config;
|
2016-02-17 09:18:35 +01:00
|
|
|
struct drm_atomic_state *state = NULL, *restore_state = NULL;
|
2015-03-20 16:18:07 +02:00
|
|
|
struct drm_connector_state *connector_state;
|
2015-04-21 17:13:01 +03:00
|
|
|
struct intel_crtc_state *crtc_state;
|
2021-06-09 11:56:27 +03:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
|
|
|
|
connector->base.id, connector->name,
|
2021-06-09 11:56:28 +03:00
|
|
|
encoder->base.base.id, encoder->base.name);
|
2011-04-19 08:36:26 +01:00
|
|
|
|
2016-02-17 09:18:35 +01:00
|
|
|
old->restore_state = NULL;
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(dev, !drm_modeset_is_locked(&config->connection_mutex));
|
drm: Split connection_mutex out of mode_config.mutex (v3)
After the split-out of crtc locks from the big mode_config.mutex
there's still two major areas it protects:
- Various connector probe states, like connector->status, EDID
properties, probed mode lists and similar information.
- The links from connector->encoder and encoder->crtc and other
modeset-relevant connector state (e.g. properties which control the
panel fitter).
The later is used by modeset operations. But they don't really care
about the former since it's allowed to e.g. enable a disconnected VGA
output or with a mode not in the probed list.
Thus far this hasn't been a problem, but for the atomic modeset
conversion Rob Clark needs to convert all modeset relevant locks into
w/w locks. This is required because the order of acquisition is
determined by how userspace supplies the atomic modeset data. This has
run into troubles in the detect path since the i915 load detect code
needs _both_ protections offered by the mode_config.mutex: It updates
probe state and it needs to change the modeset configuration to enable
the temporary load detect pipe.
The big deal here is that for the probe/detect users of this lock a
plain mutex fits best, but for atomic modesets we really want a w/w
mutex. To fix this lets split out a new connection_mutex lock for the
modeset relevant parts.
For simplicity I've decided to only add one additional lock for all
connector/encoder links and modeset configuration states. We have
piles of different modeset objects in addition to those (like bridges
or panels), so adding per-object locks would be much more effort.
Also, we're guaranteed (at least for now) to do a full modeset if we
need to acquire this lock. Which means that fine-grained locking is
fairly irrelevant compared to the amount of time the full modeset will
take.
I've done a full audit, and there's just a few things that justify
special focus:
- Locking in drm_sysfs.c is almost completely absent. We should
sprinkle mode_config.connection_mutex over this file a bit, but
since it already lacks mode_config.mutex this patch wont make the
situation any worse. This is material for a follow-up patch.
- omap has a omap_framebuffer_flush function which walks the
connector->encoder->crtc links and is called from many contexts.
Some look like they don't acquire mode_config.mutex, so this is
already racy. Again fixing this is material for a separate patch.
- The radeon hot_plug function to retrain DP links looks at
connector->dpms. Currently this happens without any locking, so is
already racy. I think radeon_hotplug_work_func should gain
mutex_lock/unlock calls for the mode_config.connection_mutex.
- Same applies to i915's intel_dp_hot_plug. But again, this is already
racy.
- i915 load_detect code needs to acquire this lock. Which means the
w/w dance due to Rob's work will be nicely contained to _just_ this
function.
I've added fixme comments everywhere where it looks suspicious but in
the sysfs code. After a quick irc discussion with Dave Airlie it
sounds like the lack of locking in there is due to sysfs cleanup fun
at module unload.
v1: original (only compile tested)
v2: missing mutex_init(), etc (from Rob Clark)
v3: i915 needs more care in the conversion:
- Protect the edp pp logic with the connection_mutex.
- Use connection_mutex in the backlight code due to
get_pipe_from_connector.
- Use drm_modeset_lock_all in suspend/resume paths.
- Update lock checks in the overlay code.
Cc: Alex Deucher <alexdeucher@gmail.com>
Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
/*
|
|
|
|
|
* Algorithm gets a little messy:
|
2011-04-19 23:21:12 +01:00
|
|
|
*
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
* - if the connector already has an assigned crtc, use it (but make
|
|
|
|
|
* sure it's on first)
|
2011-04-19 23:21:12 +01:00
|
|
|
*
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
* - try to find the first unused crtc that can drive this connector,
|
|
|
|
|
* and use that if we find one
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* See if we already have a CRTC for this connector */
|
2016-02-17 09:18:35 +01:00
|
|
|
if (connector->state->crtc) {
|
2021-06-09 11:56:28 +03:00
|
|
|
crtc = to_intel_crtc(connector->state->crtc);
|
2011-04-19 23:18:09 +01:00
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = drm_modeset_lock(&crtc->base.mutex, ctx);
|
2014-11-11 10:12:00 +01:00
|
|
|
if (ret)
|
2015-07-13 16:30:26 +02:00
|
|
|
goto fail;
|
2011-04-19 23:18:09 +01:00
|
|
|
|
|
|
|
|
/* Make sure the crtc and connector are running */
|
2016-02-17 09:18:35 +01:00
|
|
|
goto found;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find an unused one (if possible) */
|
2021-06-09 11:56:28 +03:00
|
|
|
for_each_intel_crtc(dev, possible_crtc) {
|
|
|
|
|
if (!(encoder->base.possible_crtcs &
|
|
|
|
|
drm_crtc_mask(&possible_crtc->base)))
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
continue;
|
2016-02-17 09:18:35 +01:00
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx);
|
2016-02-17 09:18:35 +01:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
if (possible_crtc->base.state->enable) {
|
|
|
|
|
drm_modeset_unlock(&possible_crtc->base.mutex);
|
2014-08-11 13:15:36 +03:00
|
|
|
continue;
|
2016-02-17 09:18:35 +01:00
|
|
|
}
|
2014-08-11 13:15:36 +03:00
|
|
|
|
|
|
|
|
crtc = possible_crtc;
|
|
|
|
|
break;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If we didn't find an unused CRTC, don't use any.
|
|
|
|
|
*/
|
|
|
|
|
if (!crtc) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"no pipe available for load-detect\n");
|
2017-04-14 22:54:25 +03:00
|
|
|
ret = -ENODEV;
|
2015-07-13 16:30:26 +02:00
|
|
|
goto fail;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2016-02-17 09:18:35 +01:00
|
|
|
found:
|
2015-03-20 16:18:03 +02:00
|
|
|
state = drm_atomic_state_alloc(dev);
|
2016-02-17 09:18:35 +01:00
|
|
|
restore_state = drm_atomic_state_alloc(dev);
|
|
|
|
|
if (!state || !restore_state) {
|
|
|
|
|
ret = -ENOMEM;
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2015-03-20 16:18:03 +02:00
|
|
|
|
|
|
|
|
state->acquire_ctx = ctx;
|
2016-02-17 09:18:35 +01:00
|
|
|
restore_state->acquire_ctx = ctx;
|
2015-03-20 16:18:03 +02:00
|
|
|
|
2015-03-20 16:18:07 +02:00
|
|
|
connector_state = drm_atomic_get_connector_state(state, connector);
|
|
|
|
|
if (IS_ERR(connector_state)) {
|
|
|
|
|
ret = PTR_ERR(connector_state);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base);
|
2016-02-17 09:18:35 +01:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2015-03-20 16:18:07 +02:00
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
crtc_state = intel_atomic_get_crtc_state(state, crtc);
|
2015-04-21 17:13:01 +03:00
|
|
|
if (IS_ERR(crtc_state)) {
|
|
|
|
|
ret = PTR_ERR(crtc_state);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 12:26:01 +01:00
|
|
|
crtc_state->uapi.active = true;
|
2015-04-21 17:13:01 +03:00
|
|
|
|
2019-10-31 12:26:03 +01:00
|
|
|
ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi,
|
2019-10-29 15:23:23 +02:00
|
|
|
&load_detect_mode);
|
2015-04-21 17:13:09 +03:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = intel_modeset_disable_planes(state, &crtc->base);
|
2016-02-17 09:18:35 +01:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
|
|
|
|
|
if (!ret)
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base));
|
2018-03-22 17:23:12 +02:00
|
|
|
if (!ret)
|
2021-06-09 11:56:28 +03:00
|
|
|
ret = drm_atomic_add_affected_planes(restore_state, &crtc->base);
|
2016-02-17 09:18:35 +01:00
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Failed to create a copy of old state to restore: %i\n",
|
|
|
|
|
ret);
|
2016-02-17 09:18:35 +01:00
|
|
|
goto fail;
|
|
|
|
|
}
|
2015-04-21 17:13:19 +03:00
|
|
|
|
2016-02-29 09:18:57 +01:00
|
|
|
ret = drm_atomic_commit(state);
|
|
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"failed to set mode on load-detect pipe\n");
|
2014-01-17 15:59:39 +02:00
|
|
|
goto fail;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
2016-02-17 09:18:35 +01:00
|
|
|
|
|
|
|
|
old->restore_state = restore_state;
|
2017-01-19 11:37:49 +00:00
|
|
|
drm_atomic_state_put(state);
|
2011-04-19 23:10:58 +01:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
/* let the connector get through one full cycle before testing */
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
|
|
|
|
|
2011-04-19 23:10:58 +01:00
|
|
|
return true;
|
2014-01-17 15:59:39 +02:00
|
|
|
|
2015-07-13 16:30:26 +02:00
|
|
|
fail:
|
2016-10-19 12:37:43 +01:00
|
|
|
if (state) {
|
|
|
|
|
drm_atomic_state_put(state);
|
|
|
|
|
state = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (restore_state) {
|
|
|
|
|
drm_atomic_state_put(restore_state);
|
|
|
|
|
restore_state = NULL;
|
|
|
|
|
}
|
2015-03-20 16:18:03 +02:00
|
|
|
|
2017-04-06 20:55:20 +02:00
|
|
|
if (ret == -EDEADLK)
|
|
|
|
|
return ret;
|
2013-11-19 12:10:12 -05:00
|
|
|
|
2014-01-17 15:59:39 +02:00
|
|
|
return false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2012-08-12 21:20:10 +02:00
|
|
|
void intel_release_load_detect_pipe(struct drm_connector *connector,
|
2015-03-20 16:18:02 +02:00
|
|
|
struct intel_load_detect_pipe *old,
|
|
|
|
|
struct drm_modeset_acquire_ctx *ctx)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2012-08-12 21:20:10 +02:00
|
|
|
struct intel_encoder *intel_encoder =
|
2019-12-04 20:05:42 +02:00
|
|
|
intel_attached_encoder(to_intel_connector(connector));
|
2020-01-22 00:46:41 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(intel_encoder->base.dev);
|
2010-09-09 15:14:28 +01:00
|
|
|
struct drm_encoder *encoder = &intel_encoder->base;
|
2016-02-17 09:18:35 +01:00
|
|
|
struct drm_atomic_state *state = old->restore_state;
|
2015-04-21 17:13:09 +03:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
|
|
|
|
|
connector->base.id, connector->name,
|
|
|
|
|
encoder->base.id, encoder->name);
|
2011-04-19 08:36:26 +01:00
|
|
|
|
2016-02-17 09:18:35 +01:00
|
|
|
if (!state)
|
2011-04-21 09:32:11 +01:00
|
|
|
return;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2017-01-16 10:37:38 +01:00
|
|
|
ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
|
2016-10-14 13:18:18 +01:00
|
|
|
if (ret)
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"Couldn't release load detect pipe: %i\n", ret);
|
2016-10-14 13:18:18 +01:00
|
|
|
drm_atomic_state_put(state);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2013-09-09 14:06:37 +03:00
|
|
|
static int i9xx_pll_refclk(struct drm_device *dev,
|
2015-01-15 14:55:21 +02:00
|
|
|
const struct intel_crtc_state *pipe_config)
|
2013-09-09 14:06:37 +03:00
|
|
|
{
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2013-09-09 14:06:37 +03:00
|
|
|
u32 dpll = pipe_config->dpll_hw_state.dpll;
|
|
|
|
|
|
|
|
|
|
if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
|
2013-12-09 18:54:16 +02:00
|
|
|
return dev_priv->vbt.lvds_ssc_freq;
|
2016-10-13 11:02:53 +01:00
|
|
|
else if (HAS_PCH_SPLIT(dev_priv))
|
2013-09-09 14:06:37 +03:00
|
|
|
return 120000;
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
else if (DISPLAY_VER(dev_priv) != 2)
|
2013-09-09 14:06:37 +03:00
|
|
|
return 96000;
|
|
|
|
|
else
|
|
|
|
|
return 48000;
|
|
|
|
|
}
|
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
/* Returns the clock of the currently programmed mode of the given pipe. */
|
2021-10-15 10:16:21 +03:00
|
|
|
void i9xx_crtc_clock_get(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *pipe_config)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2013-06-27 00:39:25 +03:00
|
|
|
struct drm_device *dev = crtc->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2013-09-13 16:18:46 +03:00
|
|
|
u32 dpll = pipe_config->dpll_hw_state.dpll;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
u32 fp;
|
2016-05-04 12:11:57 +03:00
|
|
|
struct dpll clock;
|
2015-06-22 23:35:51 +03:00
|
|
|
int port_clock;
|
2013-09-09 14:06:37 +03:00
|
|
|
int refclk = i9xx_pll_refclk(dev, pipe_config);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
|
|
|
|
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
|
2013-09-13 16:18:46 +03:00
|
|
|
fp = pipe_config->dpll_hw_state.fp0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
else
|
2013-09-13 16:18:46 +03:00
|
|
|
fp = pipe_config->dpll_hw_state.fp1;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
|
|
|
|
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
|
2016-10-31 22:37:15 +02:00
|
|
|
if (IS_PINEVIEW(dev_priv)) {
|
2009-12-03 17:14:42 -05:00
|
|
|
clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
|
|
|
|
|
clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT;
|
2009-02-23 15:19:16 +08:00
|
|
|
} else {
|
|
|
|
|
clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
|
|
|
|
|
clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) != 2) {
|
2016-10-31 22:37:15 +02:00
|
|
|
if (IS_PINEVIEW(dev_priv))
|
2009-12-03 17:14:42 -05:00
|
|
|
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >>
|
|
|
|
|
DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW);
|
2009-02-23 15:19:16 +08:00
|
|
|
else
|
|
|
|
|
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
DPLL_FPA01_P1_POST_DIV_SHIFT);
|
|
|
|
|
|
|
|
|
|
switch (dpll & DPLL_MODE_MASK) {
|
|
|
|
|
case DPLLB_MODE_DAC_SERIAL:
|
|
|
|
|
clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
|
|
|
|
|
5 : 10;
|
|
|
|
|
break;
|
|
|
|
|
case DPLLB_MODE_LVDS:
|
|
|
|
|
clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
|
|
|
|
|
7 : 14;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Unknown DPLL mode %08x in programmed "
|
|
|
|
|
"mode\n", (int)(dpll & DPLL_MODE_MASK));
|
2013-06-27 00:39:25 +03:00
|
|
|
return;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2016-10-31 22:37:15 +02:00
|
|
|
if (IS_PINEVIEW(dev_priv))
|
2015-06-22 23:35:51 +03:00
|
|
|
port_clock = pnv_calc_dpll_params(refclk, &clock);
|
2013-06-01 17:16:17 +02:00
|
|
|
else
|
2015-06-22 23:35:51 +03:00
|
|
|
port_clock = i9xx_calc_dpll_params(refclk, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
} else {
|
2021-07-15 12:35:19 +03:00
|
|
|
enum pipe lvds_pipe;
|
|
|
|
|
|
|
|
|
|
if (IS_I85X(dev_priv) &&
|
|
|
|
|
intel_lvds_port_enabled(dev_priv, LVDS, &lvds_pipe) &&
|
|
|
|
|
lvds_pipe == crtc->pipe) {
|
|
|
|
|
u32 lvds = intel_de_read(dev_priv, LVDS);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
|
|
|
|
clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
|
|
|
|
|
DPLL_FPA01_P1_POST_DIV_SHIFT);
|
2013-12-09 18:54:13 +02:00
|
|
|
|
|
|
|
|
if (lvds & LVDS_CLKB_POWER_UP)
|
|
|
|
|
clock.p2 = 7;
|
|
|
|
|
else
|
|
|
|
|
clock.p2 = 14;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
} else {
|
|
|
|
|
if (dpll & PLL_P1_DIVIDE_BY_TWO)
|
|
|
|
|
clock.p1 = 2;
|
|
|
|
|
else {
|
|
|
|
|
clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
|
|
|
|
|
DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
|
|
|
|
|
}
|
|
|
|
|
if (dpll & PLL_P2_DIVIDE_BY_4)
|
|
|
|
|
clock.p2 = 4;
|
|
|
|
|
else
|
|
|
|
|
clock.p2 = 2;
|
|
|
|
|
}
|
2013-09-09 14:06:37 +03:00
|
|
|
|
2015-06-22 23:35:51 +03:00
|
|
|
port_clock = i9xx_calc_dpll_params(refclk, &clock);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2013-09-13 16:00:08 +03:00
|
|
|
/*
|
|
|
|
|
* This value includes pixel_multiplier. We will use
|
2013-09-25 16:45:37 +01:00
|
|
|
* port_clock to compute adjusted_mode.crtc_clock in the
|
2013-09-13 16:00:08 +03:00
|
|
|
* encoder's get_config() function.
|
|
|
|
|
*/
|
2015-06-22 23:35:51 +03:00
|
|
|
pipe_config->port_clock = port_clock;
|
2013-06-27 00:39:25 +03:00
|
|
|
}
|
|
|
|
|
|
2013-09-13 15:59:11 +03:00
|
|
|
int intel_dotclock_calculate(int link_freq,
|
|
|
|
|
const struct intel_link_m_n *m_n)
|
2013-06-27 00:39:25 +03:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* The calculation for the data clock is:
|
2013-09-06 23:28:58 +03:00
|
|
|
* pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp
|
2013-06-27 00:39:25 +03:00
|
|
|
* But we want to avoid losing precison if possible, so:
|
2013-09-06 23:28:58 +03:00
|
|
|
* pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp))
|
2013-06-27 00:39:25 +03:00
|
|
|
*
|
|
|
|
|
* and the link clock is simpler:
|
2013-09-06 23:28:58 +03:00
|
|
|
* link_clock = (m * link_clock) / n
|
2013-06-27 00:39:25 +03:00
|
|
|
*/
|
|
|
|
|
|
2013-09-13 15:59:11 +03:00
|
|
|
if (!m_n->link_n)
|
|
|
|
|
return 0;
|
2013-06-27 00:39:25 +03:00
|
|
|
|
2017-09-13 11:51:53 +01:00
|
|
|
return div_u64(mul_u32_u32(m_n->link_m, link_freq), m_n->link_n);
|
2013-09-13 15:59:11 +03:00
|
|
|
}
|
2013-06-27 00:39:25 +03:00
|
|
|
|
2017-10-09 19:19:50 +03:00
|
|
|
/* Returns the currently programmed mode of the given encoder. */
|
|
|
|
|
struct drm_display_mode *
|
|
|
|
|
intel_encoder_current_mode(struct intel_encoder *encoder)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2017-10-09 19:19:50 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
|
|
|
|
struct intel_crtc_state *crtc_state;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
struct drm_display_mode *mode;
|
2017-10-09 19:19:50 +03:00
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
|
|
if (!encoder->get_hw_state(encoder, &pipe))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2021-12-01 15:57:04 +02:00
|
|
|
crtc = intel_crtc_for_pipe(dev_priv, pipe);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
|
|
|
|
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
|
|
|
|
|
if (!mode)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2019-12-19 13:14:30 +02:00
|
|
|
crtc_state = intel_crtc_state_alloc(crtc);
|
2017-10-09 19:19:50 +03:00
|
|
|
if (!crtc_state) {
|
2016-01-19 15:25:17 +00:00
|
|
|
kfree(mode);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-12 21:17:14 +02:00
|
|
|
if (!intel_crtc_get_pipe_config(crtc_state)) {
|
2017-10-09 19:19:50 +03:00
|
|
|
kfree(crtc_state);
|
|
|
|
|
kfree(mode);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2016-04-01 18:37:25 +03:00
|
|
|
|
2020-11-12 21:17:13 +02:00
|
|
|
intel_encoder_get_config(encoder, crtc_state);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2020-11-12 21:17:16 +02:00
|
|
|
intel_mode_from_crtc_timings(mode, &crtc_state->hw.adjusted_mode);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2017-10-09 19:19:50 +03:00
|
|
|
kfree(crtc_state);
|
2016-01-19 15:25:17 +00:00
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
return mode;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-15 12:33:40 +02:00
|
|
|
static bool encoders_cloneable(const struct intel_encoder *a,
|
|
|
|
|
const struct intel_encoder *b)
|
|
|
|
|
{
|
|
|
|
|
/* masks could be asymmetric, so check both ways */
|
|
|
|
|
return a == b || (a->cloneable & (1 << b->type) &&
|
|
|
|
|
b->cloneable & (1 << a->type));
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-13 07:56:54 -08:00
|
|
|
static bool check_single_encoder_cloning(struct intel_atomic_state *state,
|
2015-06-15 12:33:40 +02:00
|
|
|
struct intel_crtc *crtc,
|
|
|
|
|
struct intel_encoder *encoder)
|
|
|
|
|
{
|
|
|
|
|
struct intel_encoder *source_encoder;
|
|
|
|
|
struct drm_connector *connector;
|
|
|
|
|
struct drm_connector_state *connector_state;
|
|
|
|
|
int i;
|
|
|
|
|
|
2020-11-13 07:56:54 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
2015-06-15 12:33:40 +02:00
|
|
|
if (connector_state->crtc != &crtc->base)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
source_encoder =
|
|
|
|
|
to_intel_encoder(connector_state->best_encoder);
|
|
|
|
|
if (!encoders_cloneable(encoder, source_encoder))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
static int icl_add_linked_planes(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_plane *plane, *linked;
|
|
|
|
|
struct intel_plane_state *plane_state, *linked_plane_state;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
2019-09-20 13:42:20 +02:00
|
|
|
linked = plane_state->planar_linked_plane;
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
|
|
|
|
|
if (!linked)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
linked_plane_state = intel_atomic_get_plane_state(state, linked);
|
|
|
|
|
if (IS_ERR(linked_plane_state))
|
|
|
|
|
return PTR_ERR(linked_plane_state);
|
|
|
|
|
|
2020-04-06 16:57:46 +05:30
|
|
|
drm_WARN_ON(state->base.dev,
|
|
|
|
|
linked_plane_state->planar_linked_plane != plane);
|
|
|
|
|
drm_WARN_ON(state->base.dev,
|
|
|
|
|
linked_plane_state->planar_slave == plane_state->planar_slave);
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
struct intel_plane *plane, *linked;
|
|
|
|
|
struct intel_plane_state *plane_state;
|
|
|
|
|
int i;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 11)
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Destroy all old plane links and make the slave plane invisible
|
|
|
|
|
* in the crtc_state->active_planes mask.
|
|
|
|
|
*/
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
2019-09-20 13:42:20 +02:00
|
|
|
if (plane->pipe != crtc->pipe || !plane_state->planar_linked_plane)
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
continue;
|
|
|
|
|
|
2019-09-20 13:42:20 +02:00
|
|
|
plane_state->planar_linked_plane = NULL;
|
2019-10-31 12:26:08 +01:00
|
|
|
if (plane_state->planar_slave && !plane_state->uapi.visible) {
|
2020-11-24 22:11:53 +02:00
|
|
|
crtc_state->enabled_planes &= ~BIT(plane->id);
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
crtc_state->active_planes &= ~BIT(plane->id);
|
2018-11-27 18:37:42 +02:00
|
|
|
crtc_state->update_planes |= BIT(plane->id);
|
2022-03-03 21:12:00 +02:00
|
|
|
crtc_state->data_rate[plane->id] = 0;
|
2022-03-03 21:12:01 +02:00
|
|
|
crtc_state->rel_data_rate[plane->id] = 0;
|
2018-11-27 18:37:42 +02:00
|
|
|
}
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
|
2019-09-20 13:42:20 +02:00
|
|
|
plane_state->planar_slave = false;
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!crtc_state->nv12_planes)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
|
|
|
|
struct intel_plane_state *linked_state = NULL;
|
|
|
|
|
|
|
|
|
|
if (plane->pipe != crtc->pipe ||
|
|
|
|
|
!(crtc_state->nv12_planes & BIT(plane->id)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, linked) {
|
2020-05-04 15:52:12 -07:00
|
|
|
if (!icl_is_nv12_y_plane(dev_priv, linked->id))
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (crtc_state->active_planes & BIT(linked->id))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
linked_state = intel_atomic_get_plane_state(state, linked);
|
|
|
|
|
if (IS_ERR(linked_state))
|
|
|
|
|
return PTR_ERR(linked_state);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!linked_state) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Need %d free Y planes for planar YUV\n",
|
|
|
|
|
hweight8(crtc_state->nv12_planes));
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-20 13:42:20 +02:00
|
|
|
plane_state->planar_linked_plane = linked;
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
|
2019-09-20 13:42:20 +02:00
|
|
|
linked_state->planar_slave = true;
|
|
|
|
|
linked_state->planar_linked_plane = plane;
|
2020-11-24 22:11:53 +02:00
|
|
|
crtc_state->enabled_planes |= BIT(linked->id);
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
crtc_state->active_planes |= BIT(linked->id);
|
2018-11-27 18:37:42 +02:00
|
|
|
crtc_state->update_planes |= BIT(linked->id);
|
2022-03-03 21:12:00 +02:00
|
|
|
crtc_state->data_rate[linked->id] =
|
|
|
|
|
crtc_state->data_rate_y[plane->id];
|
2022-03-03 21:12:01 +02:00
|
|
|
crtc_state->rel_data_rate[linked->id] =
|
|
|
|
|
crtc_state->rel_data_rate_y[plane->id];
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "Using %s as Y plane for %s\n",
|
|
|
|
|
linked->base.name, plane->base.name);
|
2019-10-31 12:26:10 +01:00
|
|
|
|
|
|
|
|
/* Copy parameters to slave plane */
|
|
|
|
|
linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE;
|
|
|
|
|
linked_state->color_ctl = plane_state->color_ctl;
|
2020-01-10 20:32:23 +02:00
|
|
|
linked_state->view = plane_state->view;
|
2021-10-07 02:57:01 +03:00
|
|
|
linked_state->decrypt = plane_state->decrypt;
|
2019-10-31 12:26:10 +01:00
|
|
|
|
2020-11-17 11:47:04 -08:00
|
|
|
intel_plane_copy_hw_state(linked_state, plane_state);
|
2019-10-31 12:26:10 +01:00
|
|
|
linked_state->uapi.src = plane_state->uapi.src;
|
|
|
|
|
linked_state->uapi.dst = plane_state->uapi.dst;
|
|
|
|
|
|
|
|
|
|
if (icl_is_hdr_plane(dev_priv, plane->id)) {
|
|
|
|
|
if (linked->id == PLANE_SPRITE5)
|
2021-12-01 17:25:43 +02:00
|
|
|
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL;
|
2019-10-31 12:26:10 +01:00
|
|
|
else if (linked->id == PLANE_SPRITE4)
|
2021-12-01 17:25:43 +02:00
|
|
|
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL;
|
2020-05-04 15:52:12 -07:00
|
|
|
else if (linked->id == PLANE_SPRITE3)
|
2021-12-01 17:25:43 +02:00
|
|
|
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL;
|
2020-05-04 15:52:12 -07:00
|
|
|
else if (linked->id == PLANE_SPRITE2)
|
2021-12-01 17:25:43 +02:00
|
|
|
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL;
|
2019-10-31 12:26:10 +01:00
|
|
|
else
|
|
|
|
|
MISSING_CASE(linked->id);
|
|
|
|
|
}
|
drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously.
I've chosen to do this in the CRTC step after plane validation is done,
so we know what planes are (in)visible. The linked Y plane will get
updated in intel_plane_update_planes_on_crtc(), by the call to
update_slave, which gets the master's plane_state as argument.
The link requires both planes for atomic_update to work,
so make sure skl_ddb_add_affected_planes() adds both states.
Changes since v1:
- Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers.
- Put all the state updating login in intel_plane_atomic_check_with_state().
- Clean up changes in intel_plane_atomic_check().
Changes since v2:
- Fix intel_atomic_get_old_plane_state() to actually return old state.
- Move visibility changes to preparation patch.
- Only try to find a Y plane on gen11, earlier platforms only require
a single plane.
Changes since v3:
- Fix checkpatch warning about to_intel_crtc() usage.
- Add affected planes from icl_add_linked_planes() before check_planes(),
it's a cleaner way to do this. (Ville)
Changes since v4:
- Clear plane links in icl_check_nv12_planes() for clarity.
- Only pass crtc_state to icl_check_nv12_planes().
- Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes.
- Rename aux to linked. (Ville)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com
[mlankhorst: Change bool slave to u32, to satisfy checkpatch]
[mlankhorst: Add WARN_ON's based on Ville's suggestion]
2018-10-22 15:51:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-13 16:39:03 +03:00
|
|
|
static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
|
2019-05-13 16:39:03 +03:00
|
|
|
struct intel_atomic_state *state =
|
2019-10-31 12:26:03 +01:00
|
|
|
to_intel_atomic_state(new_crtc_state->uapi.state);
|
2019-05-13 16:39:03 +03:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
|
|
|
|
|
return !old_crtc_state->c8_planes != !new_crtc_state->c8_planes;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
2020-11-12 21:17:18 +02:00
|
|
|
const struct drm_display_mode *pipe_mode =
|
|
|
|
|
&crtc_state->hw.pipe_mode;
|
2020-06-25 23:00:03 +03:00
|
|
|
int linetime_wm;
|
2020-01-20 19:47:12 +02:00
|
|
|
|
|
|
|
|
if (!crtc_state->hw.enable)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2020-11-12 21:17:18 +02:00
|
|
|
linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
|
|
|
|
|
pipe_mode->crtc_clock);
|
2020-06-25 23:00:03 +03:00
|
|
|
|
|
|
|
|
return min(linetime_wm, 0x1ff);
|
2020-01-20 19:47:12 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 16:03:53 +02:00
|
|
|
static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state,
|
|
|
|
|
const struct intel_cdclk_state *cdclk_state)
|
2020-01-20 19:47:12 +02:00
|
|
|
{
|
2020-11-12 21:17:18 +02:00
|
|
|
const struct drm_display_mode *pipe_mode =
|
|
|
|
|
&crtc_state->hw.pipe_mode;
|
2020-06-25 23:00:03 +03:00
|
|
|
int linetime_wm;
|
2020-01-20 19:47:12 +02:00
|
|
|
|
|
|
|
|
if (!crtc_state->hw.enable)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2020-11-12 21:17:18 +02:00
|
|
|
linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
|
2020-06-25 23:00:03 +03:00
|
|
|
cdclk_state->logical.cdclk);
|
|
|
|
|
|
|
|
|
|
return min(linetime_wm, 0x1ff);
|
2020-01-20 19:47:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2020-11-12 21:17:18 +02:00
|
|
|
const struct drm_display_mode *pipe_mode =
|
|
|
|
|
&crtc_state->hw.pipe_mode;
|
2020-06-25 23:00:03 +03:00
|
|
|
int linetime_wm;
|
2020-01-20 19:47:12 +02:00
|
|
|
|
|
|
|
|
if (!crtc_state->hw.enable)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2020-11-12 21:17:18 +02:00
|
|
|
linetime_wm = DIV_ROUND_UP(pipe_mode->crtc_htotal * 1000 * 8,
|
2020-01-20 19:47:12 +02:00
|
|
|
crtc_state->pixel_rate);
|
|
|
|
|
|
|
|
|
|
/* Display WA #1135: BXT:ALL GLK:ALL */
|
2021-04-07 13:39:45 -07:00
|
|
|
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
|
|
|
|
|
dev_priv->ipc_enabled)
|
2020-01-20 19:47:12 +02:00
|
|
|
linetime_wm /= 2;
|
|
|
|
|
|
2020-06-25 23:00:03 +03:00
|
|
|
return min(linetime_wm, 0x1ff);
|
2020-01-20 19:47:12 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 16:03:53 +02:00
|
|
|
static int hsw_compute_linetime_wm(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_cdclk_state *cdclk_state;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9)
|
2020-01-21 16:03:53 +02:00
|
|
|
crtc_state->linetime = skl_linetime_wm(crtc_state);
|
|
|
|
|
else
|
|
|
|
|
crtc_state->linetime = hsw_linetime_wm(crtc_state);
|
|
|
|
|
|
|
|
|
|
if (!hsw_crtc_supports_ips(crtc))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
cdclk_state = intel_atomic_get_cdclk_state(state);
|
|
|
|
|
if (IS_ERR(cdclk_state))
|
|
|
|
|
return PTR_ERR(cdclk_state);
|
|
|
|
|
|
|
|
|
|
crtc_state->ips_linetime = hsw_ips_linetime_wm(crtc_state,
|
|
|
|
|
cdclk_state);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 15:53:14 +03:00
|
|
|
static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2015-06-15 12:33:40 +02:00
|
|
|
{
|
2019-09-13 22:31:57 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
struct intel_crtc_state *crtc_state =
|
2019-07-08 15:53:14 +03:00
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2020-12-21 11:04:45 +02:00
|
|
|
bool mode_changed = intel_crtc_needs_modeset(crtc_state);
|
2019-07-08 15:53:14 +03:00
|
|
|
int ret;
|
2015-06-15 12:33:40 +02:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv) &&
|
2019-10-31 12:26:02 +01:00
|
|
|
mode_changed && !crtc_state->hw.active)
|
2019-09-13 22:31:57 +03:00
|
|
|
crtc_state->update_wm_post = true;
|
2015-06-15 12:33:53 +02:00
|
|
|
|
2022-03-25 14:31:57 +02:00
|
|
|
if (mode_changed) {
|
2022-03-25 14:31:56 +02:00
|
|
|
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
2015-06-15 12:33:42 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2022-03-25 14:32:01 +02:00
|
|
|
|
|
|
|
|
ret = intel_dpll_crtc_get_shared_dpll(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2015-06-15 12:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-13 16:39:03 +03:00
|
|
|
/*
|
|
|
|
|
* May need to update pipe gamma enable bits
|
|
|
|
|
* when C8 planes are getting enabled/disabled.
|
|
|
|
|
*/
|
2019-09-13 22:31:57 +03:00
|
|
|
if (c8_planes_changed(crtc_state))
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.color_mgmt_changed = true;
|
2019-05-13 16:39:03 +03:00
|
|
|
|
2019-09-13 22:31:57 +03:00
|
|
|
if (mode_changed || crtc_state->update_pipe ||
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.color_mgmt_changed) {
|
2019-09-13 22:31:57 +03:00
|
|
|
ret = intel_color_check(crtc_state);
|
2016-03-16 10:57:16 +00:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
ret = intel_compute_pipe_wm(state, crtc);
|
|
|
|
|
if (ret) {
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"Target pipe watermarks are invalid\n");
|
|
|
|
|
return ret;
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
/*
|
|
|
|
|
* Calculate 'intermediate' watermarks that satisfy both the
|
|
|
|
|
* old state and the new state. We can program these
|
|
|
|
|
* immediately.
|
|
|
|
|
*/
|
|
|
|
|
ret = intel_compute_intermediate_wm(state, crtc);
|
|
|
|
|
if (ret) {
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"No valid intermediate pipe watermarks are possible\n");
|
|
|
|
|
return ret;
|
2015-09-24 15:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9) {
|
2020-02-07 17:22:28 +02:00
|
|
|
if (mode_changed || crtc_state->update_pipe) {
|
2019-09-13 22:31:57 +03:00
|
|
|
ret = skl_update_scaler_crtc(crtc_state);
|
2020-02-07 17:22:28 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = intel_atomic_setup_scalers(dev_priv, crtc, crtc_state);
|
2020-01-21 16:03:53 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2015-07-13 16:30:15 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-21 16:03:53 +02:00
|
|
|
if (HAS_IPS(dev_priv)) {
|
2022-02-09 13:35:21 +02:00
|
|
|
ret = hsw_ips_compute_config(state, crtc);
|
2020-01-21 16:03:53 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 ||
|
2020-01-21 16:03:53 +02:00
|
|
|
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) {
|
|
|
|
|
ret = hsw_compute_linetime_wm(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2017-11-22 19:39:01 +01:00
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-22 14:52:41 -07:00
|
|
|
ret = intel_psr2_sel_fetch_update(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2020-08-10 10:41:43 -07:00
|
|
|
|
2020-01-21 16:03:53 +02:00
|
|
|
return 0;
|
2015-06-15 12:33:40 +02:00
|
|
|
}
|
|
|
|
|
|
2018-10-22 18:44:00 -07:00
|
|
|
static int
|
2018-11-07 23:35:22 +02:00
|
|
|
compute_sink_pipe_bpp(const struct drm_connector_state *conn_state,
|
2022-05-03 21:22:24 +03:00
|
|
|
struct intel_crtc_state *crtc_state)
|
2013-06-02 13:26:23 +02:00
|
|
|
{
|
2018-11-07 23:35:22 +02:00
|
|
|
struct drm_connector *connector = conn_state->connector;
|
2022-05-03 21:22:24 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
2018-11-07 23:35:22 +02:00
|
|
|
const struct drm_display_info *info = &connector->display_info;
|
2018-10-22 18:44:00 -07:00
|
|
|
int bpp;
|
2013-06-02 13:26:23 +02:00
|
|
|
|
2018-10-22 18:44:00 -07:00
|
|
|
switch (conn_state->max_bpc) {
|
|
|
|
|
case 6 ... 7:
|
|
|
|
|
bpp = 6 * 3;
|
|
|
|
|
break;
|
|
|
|
|
case 8 ... 9:
|
|
|
|
|
bpp = 8 * 3;
|
|
|
|
|
break;
|
|
|
|
|
case 10 ... 11:
|
|
|
|
|
bpp = 10 * 3;
|
|
|
|
|
break;
|
2020-11-10 23:04:47 +02:00
|
|
|
case 12 ... 16:
|
2018-10-22 18:44:00 -07:00
|
|
|
bpp = 12 * 3;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2020-11-10 23:04:47 +02:00
|
|
|
MISSING_CASE(conn_state->max_bpc);
|
2018-10-22 18:44:00 -07:00
|
|
|
return -EINVAL;
|
2013-06-02 13:26:23 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
if (bpp < crtc_state->pipe_bpp) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-05-03 21:22:25 +03:00
|
|
|
"[CONNECTOR:%d:%s] Limiting display bpp to %d "
|
|
|
|
|
"(EDID bpp %d, max requested bpp %d, max platform bpp %d)\n",
|
2020-01-22 00:46:41 +03:00
|
|
|
connector->base.id, connector->name,
|
|
|
|
|
bpp, 3 * info->bpc,
|
|
|
|
|
3 * conn_state->max_requested_bpc,
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->pipe_bpp);
|
2018-11-07 23:35:22 +02:00
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->pipe_bpp = bpp;
|
2013-06-02 13:26:23 +02:00
|
|
|
}
|
2018-11-07 23:35:22 +02:00
|
|
|
|
2018-10-22 18:44:00 -07:00
|
|
|
return 0;
|
2013-06-02 13:26:23 +02:00
|
|
|
}
|
|
|
|
|
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
static int
|
2022-05-03 21:22:23 +03:00
|
|
|
compute_baseline_pipe_bpp(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
{
|
2016-10-13 11:03:06 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2022-05-03 21:22:24 +03:00
|
|
|
struct intel_crtc_state *crtc_state =
|
2022-05-03 21:22:23 +03:00
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2015-04-21 17:12:59 +03:00
|
|
|
struct drm_connector *connector;
|
|
|
|
|
struct drm_connector_state *connector_state;
|
2015-03-20 16:18:09 +02:00
|
|
|
int bpp, i;
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
|
2016-10-13 11:03:06 +01:00
|
|
|
if ((IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
|
|
|
|
|
IS_CHERRYVIEW(dev_priv)))
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
bpp = 10*3;
|
2021-03-19 21:42:42 -07:00
|
|
|
else if (DISPLAY_VER(dev_priv) >= 5)
|
2015-04-10 16:22:37 +02:00
|
|
|
bpp = 12*3;
|
|
|
|
|
else
|
|
|
|
|
bpp = 8*3;
|
|
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->pipe_bpp = bpp;
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
|
2018-11-07 23:35:22 +02:00
|
|
|
/* Clamp display bpp to connector max bpp */
|
2022-05-03 21:22:23 +03:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
2018-11-07 23:35:22 +02:00
|
|
|
int ret;
|
|
|
|
|
|
2015-04-21 17:12:59 +03:00
|
|
|
if (connector_state->crtc != &crtc->base)
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
continue;
|
|
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
ret = compute_sink_pipe_bpp(connector_state, crtc_state);
|
2018-11-07 23:35:22 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
2018-11-07 23:35:22 +02:00
|
|
|
return 0;
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 22:31:21 +03:00
|
|
|
static bool check_digital_port_conflicts(struct intel_atomic_state *state)
|
2014-12-02 14:10:46 +02:00
|
|
|
{
|
2019-05-17 22:31:21 +03:00
|
|
|
struct drm_device *dev = state->base.dev;
|
2015-04-21 17:12:59 +03:00
|
|
|
struct drm_connector *connector;
|
2017-05-11 16:10:44 -03:00
|
|
|
struct drm_connector_list_iter conn_iter;
|
2014-12-02 14:10:46 +02:00
|
|
|
unsigned int used_ports = 0;
|
2016-07-28 17:50:40 +03:00
|
|
|
unsigned int used_mst_ports = 0;
|
2018-02-15 10:14:25 +01:00
|
|
|
bool ret = true;
|
2014-12-02 14:10:46 +02:00
|
|
|
|
2019-10-15 22:30:24 +03:00
|
|
|
/*
|
|
|
|
|
* We're going to peek into connector->state,
|
|
|
|
|
* hence connection_mutex must be held.
|
|
|
|
|
*/
|
|
|
|
|
drm_modeset_lock_assert_held(&dev->mode_config.connection_mutex);
|
|
|
|
|
|
2014-12-02 14:10:46 +02:00
|
|
|
/*
|
|
|
|
|
* Walk the connector list instead of the encoder
|
|
|
|
|
* list to detect the problem on ddi platforms
|
|
|
|
|
* where there's just one encoder per digital port.
|
|
|
|
|
*/
|
2017-05-11 16:10:44 -03:00
|
|
|
drm_connector_list_iter_begin(dev, &conn_iter);
|
|
|
|
|
drm_for_each_connector_iter(connector, &conn_iter) {
|
2015-12-10 18:22:31 +02:00
|
|
|
struct drm_connector_state *connector_state;
|
|
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
|
2019-05-17 22:31:21 +03:00
|
|
|
connector_state =
|
|
|
|
|
drm_atomic_get_new_connector_state(&state->base,
|
|
|
|
|
connector);
|
2015-12-10 18:22:31 +02:00
|
|
|
if (!connector_state)
|
|
|
|
|
connector_state = connector->state;
|
|
|
|
|
|
2015-04-02 14:47:59 +03:00
|
|
|
if (!connector_state->best_encoder)
|
2014-12-02 14:10:46 +02:00
|
|
|
continue;
|
|
|
|
|
|
2015-04-02 14:47:59 +03:00
|
|
|
encoder = to_intel_encoder(connector_state->best_encoder);
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(dev, !connector_state->crtc);
|
2014-12-02 14:10:46 +02:00
|
|
|
|
|
|
|
|
switch (encoder->type) {
|
2017-10-27 22:31:24 +03:00
|
|
|
case INTEL_OUTPUT_DDI:
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(dev, !HAS_DDI(to_i915(dev))))
|
2014-12-02 14:10:46 +02:00
|
|
|
break;
|
2020-08-23 17:36:59 -05:00
|
|
|
fallthrough;
|
2016-06-22 21:57:06 +03:00
|
|
|
case INTEL_OUTPUT_DP:
|
2014-12-02 14:10:46 +02:00
|
|
|
case INTEL_OUTPUT_HDMI:
|
|
|
|
|
case INTEL_OUTPUT_EDP:
|
|
|
|
|
/* the same port mustn't appear more than once */
|
2020-02-20 16:05:17 -08:00
|
|
|
if (used_ports & BIT(encoder->port))
|
2018-02-15 10:14:25 +01:00
|
|
|
ret = false;
|
2014-12-02 14:10:46 +02:00
|
|
|
|
2020-02-20 16:05:17 -08:00
|
|
|
used_ports |= BIT(encoder->port);
|
2016-07-28 17:50:40 +03:00
|
|
|
break;
|
|
|
|
|
case INTEL_OUTPUT_DP_MST:
|
|
|
|
|
used_mst_ports |=
|
2017-11-09 17:24:34 +02:00
|
|
|
1 << encoder->port;
|
2016-07-28 17:50:40 +03:00
|
|
|
break;
|
2014-12-02 14:10:46 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-11 16:10:44 -03:00
|
|
|
drm_connector_list_iter_end(&conn_iter);
|
2014-12-02 14:10:46 +02:00
|
|
|
|
2016-07-28 17:50:40 +03:00
|
|
|
/* can't mix MST and SST/HDMI on the same port */
|
|
|
|
|
if (used_ports & used_mst_ports)
|
|
|
|
|
return false;
|
|
|
|
|
|
2018-02-15 10:14:25 +01:00
|
|
|
return ret;
|
2014-12-02 14:10:46 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 12:26:04 +01:00
|
|
|
static void
|
2020-11-13 07:56:54 -08:00
|
|
|
intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc *crtc)
|
2019-10-31 12:26:04 +01:00
|
|
|
{
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
|
|
|
|
|
crtc_state->uapi.degamma_lut);
|
|
|
|
|
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
|
|
|
|
|
crtc_state->uapi.gamma_lut);
|
|
|
|
|
drm_property_replace_blob(&crtc_state->hw.ctm,
|
|
|
|
|
crtc_state->uapi.ctm);
|
2019-10-31 12:26:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2022-02-04 09:20:49 +02:00
|
|
|
intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2019-10-31 12:26:04 +01:00
|
|
|
{
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2019-10-31 12:26:04 +01:00
|
|
|
crtc_state->hw.enable = crtc_state->uapi.enable;
|
|
|
|
|
crtc_state->hw.active = crtc_state->uapi.active;
|
drm/i915: Use drm_mode_copy()
struct drm_display_mode embeds a list head, so overwriting
the full struct with another one will corrupt the list
(if the destination mode is on a list). Use drm_mode_copy()
instead which explicitly preserves the list head of
the destination mode.
Even if we know the destination mode is not on any list
using drm_mode_copy() seems decent as it sets a good
example. Bad examples of not using it might eventually
get copied into code where preserving the list head
actually matters.
Obviously one case not covered here is when the mode
itself is embedded in a larger structure and the whole
structure is copied. But if we are careful when copying
into modes embedded in structures I think we can be a
little more reassured that bogus list heads haven't been
propagated in.
@is_mode_copy@
@@
drm_mode_copy(...)
{
...
}
@depends on !is_mode_copy@
struct drm_display_mode *mode;
expression E, S;
@@
(
- *mode = E
+ drm_mode_copy(mode, &E)
|
- memcpy(mode, E, S)
+ drm_mode_copy(mode, E)
)
@depends on !is_mode_copy@
struct drm_display_mode mode;
expression E;
@@
(
- mode = E
+ drm_mode_copy(&mode, &E)
|
- memcpy(&mode, E, S)
+ drm_mode_copy(&mode, E)
)
@@
struct drm_display_mode *mode;
@@
- &*mode
+ mode
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220218100403.7028-20-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2022-02-18 12:04:00 +02:00
|
|
|
drm_mode_copy(&crtc_state->hw.mode,
|
|
|
|
|
&crtc_state->uapi.mode);
|
|
|
|
|
drm_mode_copy(&crtc_state->hw.adjusted_mode,
|
|
|
|
|
&crtc_state->uapi.adjusted_mode);
|
2020-10-20 21:44:26 +05:30
|
|
|
crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter;
|
2020-11-13 07:56:54 -08:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
|
2019-10-31 12:26:04 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
static void
|
|
|
|
|
copy_bigjoiner_crtc_state_nomodeset(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *slave_crtc)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc_state *slave_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, slave_crtc);
|
|
|
|
|
struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
|
|
|
|
|
const struct intel_crtc_state *master_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, master_crtc);
|
|
|
|
|
|
|
|
|
|
drm_property_replace_blob(&slave_crtc_state->hw.degamma_lut,
|
|
|
|
|
master_crtc_state->hw.degamma_lut);
|
|
|
|
|
drm_property_replace_blob(&slave_crtc_state->hw.gamma_lut,
|
|
|
|
|
master_crtc_state->hw.gamma_lut);
|
|
|
|
|
drm_property_replace_blob(&slave_crtc_state->hw.ctm,
|
|
|
|
|
master_crtc_state->hw.ctm);
|
|
|
|
|
|
|
|
|
|
slave_crtc_state->uapi.color_mgmt_changed = master_crtc_state->uapi.color_mgmt_changed;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:06 -08:00
|
|
|
static int
|
2022-02-04 09:20:49 +02:00
|
|
|
copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *slave_crtc)
|
2020-11-17 11:47:06 -08:00
|
|
|
{
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc_state *slave_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, slave_crtc);
|
|
|
|
|
struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
|
|
|
|
|
const struct intel_crtc_state *master_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, master_crtc);
|
2020-11-17 11:47:06 -08:00
|
|
|
struct intel_crtc_state *saved_state;
|
|
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
WARN_ON(master_crtc_state->bigjoiner_pipes !=
|
|
|
|
|
slave_crtc_state->bigjoiner_pipes);
|
|
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
saved_state = kmemdup(master_crtc_state, sizeof(*saved_state), GFP_KERNEL);
|
2020-11-17 11:47:06 -08:00
|
|
|
if (!saved_state)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
/* preserve some things from the slave's original crtc state */
|
|
|
|
|
saved_state->uapi = slave_crtc_state->uapi;
|
|
|
|
|
saved_state->scaler_state = slave_crtc_state->scaler_state;
|
|
|
|
|
saved_state->shared_dpll = slave_crtc_state->shared_dpll;
|
|
|
|
|
saved_state->dpll_hw_state = slave_crtc_state->dpll_hw_state;
|
|
|
|
|
saved_state->crc_enabled = slave_crtc_state->crc_enabled;
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
intel_crtc_free_hw_state(slave_crtc_state);
|
|
|
|
|
memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
|
2020-11-17 11:47:06 -08:00
|
|
|
kfree(saved_state);
|
|
|
|
|
|
|
|
|
|
/* Re-init hw state */
|
2022-02-04 09:20:49 +02:00
|
|
|
memset(&slave_crtc_state->hw, 0, sizeof(slave_crtc_state->hw));
|
|
|
|
|
slave_crtc_state->hw.enable = master_crtc_state->hw.enable;
|
|
|
|
|
slave_crtc_state->hw.active = master_crtc_state->hw.active;
|
drm/i915: Use drm_mode_copy()
struct drm_display_mode embeds a list head, so overwriting
the full struct with another one will corrupt the list
(if the destination mode is on a list). Use drm_mode_copy()
instead which explicitly preserves the list head of
the destination mode.
Even if we know the destination mode is not on any list
using drm_mode_copy() seems decent as it sets a good
example. Bad examples of not using it might eventually
get copied into code where preserving the list head
actually matters.
Obviously one case not covered here is when the mode
itself is embedded in a larger structure and the whole
structure is copied. But if we are careful when copying
into modes embedded in structures I think we can be a
little more reassured that bogus list heads haven't been
propagated in.
@is_mode_copy@
@@
drm_mode_copy(...)
{
...
}
@depends on !is_mode_copy@
struct drm_display_mode *mode;
expression E, S;
@@
(
- *mode = E
+ drm_mode_copy(mode, &E)
|
- memcpy(mode, E, S)
+ drm_mode_copy(mode, E)
)
@depends on !is_mode_copy@
struct drm_display_mode mode;
expression E;
@@
(
- mode = E
+ drm_mode_copy(&mode, &E)
|
- memcpy(&mode, E, S)
+ drm_mode_copy(&mode, E)
)
@@
struct drm_display_mode *mode;
@@
- &*mode
+ mode
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220218100403.7028-20-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
2022-02-18 12:04:00 +02:00
|
|
|
drm_mode_copy(&slave_crtc_state->hw.mode,
|
|
|
|
|
&master_crtc_state->hw.mode);
|
|
|
|
|
drm_mode_copy(&slave_crtc_state->hw.pipe_mode,
|
|
|
|
|
&master_crtc_state->hw.pipe_mode);
|
|
|
|
|
drm_mode_copy(&slave_crtc_state->hw.adjusted_mode,
|
|
|
|
|
&master_crtc_state->hw.adjusted_mode);
|
2022-02-04 09:20:49 +02:00
|
|
|
slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
|
2022-02-04 09:20:09 +02:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
|
|
|
|
|
slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
|
|
|
|
|
slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
WARN_ON(master_crtc_state->bigjoiner_pipes !=
|
|
|
|
|
slave_crtc_state->bigjoiner_pipes);
|
|
|
|
|
|
2020-11-17 11:47:06 -08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-05 09:27:59 +00:00
|
|
|
static int
|
2020-11-13 07:56:54 -08:00
|
|
|
intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc *crtc)
|
2015-03-20 16:18:03 +02:00
|
|
|
{
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2019-12-19 13:14:30 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2019-02-05 09:27:59 +00:00
|
|
|
struct intel_crtc_state *saved_state;
|
|
|
|
|
|
2019-12-19 13:14:30 +02:00
|
|
|
saved_state = intel_crtc_state_alloc(crtc);
|
2019-02-05 09:27:59 +00:00
|
|
|
if (!saved_state)
|
|
|
|
|
return -ENOMEM;
|
2015-03-20 16:18:03 +02:00
|
|
|
|
2019-10-31 12:26:04 +01:00
|
|
|
/* free the old crtc_state->hw members */
|
|
|
|
|
intel_crtc_free_hw_state(crtc_state);
|
|
|
|
|
|
2015-05-20 09:03:27 +03:00
|
|
|
/* FIXME: before the switch to atomic started, a new pipe_config was
|
|
|
|
|
* kzalloc'd. Code that depends on any field being zero should be
|
|
|
|
|
* fixed, so that the crtc_state can be safely duplicated. For now,
|
|
|
|
|
* only fields that are know to not cause problems are preserved. */
|
|
|
|
|
|
2019-10-31 12:26:04 +01:00
|
|
|
saved_state->uapi = crtc_state->uapi;
|
2019-02-05 09:27:59 +00:00
|
|
|
saved_state->scaler_state = crtc_state->scaler_state;
|
|
|
|
|
saved_state->shared_dpll = crtc_state->shared_dpll;
|
|
|
|
|
saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
|
2019-06-28 17:36:31 +03:00
|
|
|
memcpy(saved_state->icl_port_dplls, crtc_state->icl_port_dplls,
|
|
|
|
|
sizeof(saved_state->icl_port_dplls));
|
2019-03-07 16:00:46 -08:00
|
|
|
saved_state->crc_enabled = crtc_state->crc_enabled;
|
2017-04-21 21:14:29 +03:00
|
|
|
if (IS_G4X(dev_priv) ||
|
|
|
|
|
IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
2019-02-05 09:27:59 +00:00
|
|
|
saved_state->wm = crtc_state->wm;
|
2015-04-21 17:13:21 +03:00
|
|
|
|
2019-10-31 12:26:04 +01:00
|
|
|
memcpy(crtc_state, saved_state, sizeof(*crtc_state));
|
2019-02-05 09:27:59 +00:00
|
|
|
kfree(saved_state);
|
2019-10-31 12:26:04 +01:00
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
intel_crtc_copy_uapi_to_hw_state_modeset(state, crtc);
|
2019-10-31 12:26:04 +01:00
|
|
|
|
2019-02-05 09:27:59 +00:00
|
|
|
return 0;
|
2015-03-20 16:18:03 +02:00
|
|
|
}
|
|
|
|
|
|
2015-04-21 17:13:02 +03:00
|
|
|
static int
|
2020-11-13 07:56:54 -08:00
|
|
|
intel_modeset_pipe_config(struct intel_atomic_state *state,
|
2022-05-03 21:22:23 +03:00
|
|
|
struct intel_crtc *crtc)
|
2012-04-20 17:11:53 +01:00
|
|
|
{
|
2022-05-03 21:22:23 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2022-05-03 21:22:24 +03:00
|
|
|
struct intel_crtc_state *crtc_state =
|
2022-05-03 21:22:23 +03:00
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2015-04-21 17:12:59 +03:00
|
|
|
struct drm_connector *connector;
|
2015-03-20 16:18:08 +02:00
|
|
|
struct drm_connector_state *connector_state;
|
2022-02-23 15:13:12 +02:00
|
|
|
int pipe_src_w, pipe_src_h;
|
2020-02-14 03:41:25 -08:00
|
|
|
int base_bpp, ret, i;
|
drm/i915: implement fdi auto-dithering
So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
into this, among them the default 1080p mode.
The solution is to dither down the pipe a bit so that everything fits,
which this patch implements.
But ports compute their state under the assumption that the bpp they
pick will be the one selected, e.g. the display port bw computations
won't work otherwise. Now we could adjust our code to again up-dither
to the computed DP link parameters, but that's pointless.
So instead when the pipe needs to adjust parameters we need to retry
the pipe_config computation at the encoder stage. Furthermore we need
to inform encoders that they should not increase bandwidth
requirements if possible. This is required for the hdmi code, which
prefers the pipe to up-dither to either of the two possible hdmi bpc
values.
LVDS has a similar requirement, although that's probably only
theoretical in nature: It's unlikely that we'll ever see an 8bpc
high-res lvds panel (which is required to hit the 2 fdi lane limit).
eDP is the only thing which could increase the pipe_bpp setting again,
even when in the retry-loop. This could hit the WARN. Two reasons for
not bothering:
- On many eDP panels we'll get a black screen if the bpp settings
don't match vbt. So failing the modeset is the right thing to do.
But since that also means it's the only way to light up the panel,
it should work. So we shouldn't be able to hit this WARN.
- There are still opens around the eDP panel handling, and maybe we
need additional tricks. Before that happens it's imo no use trying
to be too clever.
Worst case we just need to kill that WARN or maybe fail the compute
config stage if the eDP connector can't get the bpp setting it wants.
And since this can only happen with an fdi link in between and so for
pch eDP panels it's rather unlikely to blow up, if ever.
v2: Rebased on top of a bikeshed from Paulo.
v3: Improve commit message around eDP handling with the stuff
things with Imre.
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
|
|
|
bool retry = true;
|
2012-04-20 17:11:53 +01:00
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->cpu_transcoder = (enum transcoder) crtc->pipe;
|
2013-03-27 00:44:50 +01:00
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->framestart_delay = 1;
|
2022-02-21 13:03:53 +02:00
|
|
|
|
2013-07-30 13:36:32 +03:00
|
|
|
/*
|
|
|
|
|
* Sanitize sync polarity flags based on requested ones. If neither
|
|
|
|
|
* positive or negative polarity is requested, treat this as meaning
|
|
|
|
|
* negative polarity.
|
|
|
|
|
*/
|
2022-05-03 21:22:24 +03:00
|
|
|
if (!(crtc_state->hw.adjusted_mode.flags &
|
2013-07-30 13:36:32 +03:00
|
|
|
(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
|
2013-07-30 13:36:32 +03:00
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
if (!(crtc_state->hw.adjusted_mode.flags &
|
2013-07-30 13:36:32 +03:00
|
|
|
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
|
2013-07-30 13:36:32 +03:00
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
ret = compute_baseline_pipe_bpp(state, crtc);
|
2018-11-07 23:35:22 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
base_bpp = crtc_state->pipe_bpp;
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
|
2013-10-01 22:52:14 +03:00
|
|
|
/*
|
|
|
|
|
* Determine the real pipe dimensions. Note that stereo modes can
|
|
|
|
|
* increase the actual pipe size due to the frame doubling and
|
|
|
|
|
* insertion of additional space for blanks between the frame. This
|
|
|
|
|
* is stored in the crtc timings. We use the requested mode to do this
|
|
|
|
|
* computation to clearly distinguish it from the adjusted mode, which
|
|
|
|
|
* can be changed by the connectors in the below retry loop.
|
|
|
|
|
*/
|
2022-05-03 21:22:24 +03:00
|
|
|
drm_mode_get_hv_timing(&crtc_state->hw.mode,
|
2022-02-23 15:13:12 +02:00
|
|
|
&pipe_src_w, &pipe_src_h);
|
2022-05-03 21:22:24 +03:00
|
|
|
drm_rect_init(&crtc_state->pipe_src, 0, 0,
|
2022-02-23 15:13:12 +02:00
|
|
|
pipe_src_w, pipe_src_h);
|
2013-10-01 22:52:14 +03:00
|
|
|
|
2020-11-13 07:56:54 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
2020-01-15 21:08:13 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(connector_state->best_encoder);
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
if (connector_state->crtc != &crtc->base)
|
2016-06-22 21:57:01 +03:00
|
|
|
continue;
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
if (!check_single_encoder_cloning(state, crtc, encoder)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-05-03 21:22:25 +03:00
|
|
|
"[ENCODER:%d:%s] rejecting invalid cloning configuration\n",
|
|
|
|
|
encoder->base.base.id, encoder->base.name);
|
2018-11-07 23:35:21 +02:00
|
|
|
return -EINVAL;
|
2016-06-22 21:57:09 +03:00
|
|
|
}
|
|
|
|
|
|
2016-06-22 21:57:01 +03:00
|
|
|
/*
|
|
|
|
|
* Determine output_types before calling the .compute_config()
|
|
|
|
|
* hooks so that the hooks can use this information safely.
|
|
|
|
|
*/
|
2017-10-27 22:31:24 +03:00
|
|
|
if (encoder->compute_output_type)
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->output_types |=
|
|
|
|
|
BIT(encoder->compute_output_type(encoder, crtc_state,
|
2017-10-27 22:31:24 +03:00
|
|
|
connector_state));
|
|
|
|
|
else
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->output_types |= BIT(encoder->type);
|
2016-06-22 21:57:01 +03:00
|
|
|
}
|
|
|
|
|
|
drm/i915: implement fdi auto-dithering
So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
into this, among them the default 1080p mode.
The solution is to dither down the pipe a bit so that everything fits,
which this patch implements.
But ports compute their state under the assumption that the bpp they
pick will be the one selected, e.g. the display port bw computations
won't work otherwise. Now we could adjust our code to again up-dither
to the computed DP link parameters, but that's pointless.
So instead when the pipe needs to adjust parameters we need to retry
the pipe_config computation at the encoder stage. Furthermore we need
to inform encoders that they should not increase bandwidth
requirements if possible. This is required for the hdmi code, which
prefers the pipe to up-dither to either of the two possible hdmi bpc
values.
LVDS has a similar requirement, although that's probably only
theoretical in nature: It's unlikely that we'll ever see an 8bpc
high-res lvds panel (which is required to hit the 2 fdi lane limit).
eDP is the only thing which could increase the pipe_bpp setting again,
even when in the retry-loop. This could hit the WARN. Two reasons for
not bothering:
- On many eDP panels we'll get a black screen if the bpp settings
don't match vbt. So failing the modeset is the right thing to do.
But since that also means it's the only way to light up the panel,
it should work. So we shouldn't be able to hit this WARN.
- There are still opens around the eDP panel handling, and maybe we
need additional tricks. Before that happens it's imo no use trying
to be too clever.
Worst case we just need to kill that WARN or maybe fail the compute
config stage if the eDP connector can't get the bpp setting it wants.
And since this can only happen with an fdi link in between and so for
pch eDP panels it's rather unlikely to blow up, if ever.
v2: Rebased on top of a bikeshed from Paulo.
v3: Improve commit message around eDP handling with the stuff
things with Imre.
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
|
|
|
encoder_retry:
|
2013-06-01 17:17:04 +02:00
|
|
|
/* Ensure the port clock defaults are reset when retrying. */
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->port_clock = 0;
|
|
|
|
|
crtc_state->pixel_multiplier = 1;
|
2013-06-01 17:16:21 +02:00
|
|
|
|
2013-07-21 21:37:09 +02:00
|
|
|
/* Fill in default crtc timings, allow encoders to overwrite them. */
|
2022-05-03 21:22:24 +03:00
|
|
|
drm_mode_set_crtcinfo(&crtc_state->hw.adjusted_mode,
|
2015-01-15 14:55:22 +02:00
|
|
|
CRTC_STEREO_DOUBLE);
|
2013-07-21 21:37:09 +02:00
|
|
|
|
2012-07-08 19:40:39 +02:00
|
|
|
/* Pass our mode to the connectors and the CRTC to give them a chance to
|
|
|
|
|
* adjust it according to limitations or connector properties, and also
|
|
|
|
|
* a chance to reject the mode entirely.
|
2010-12-03 15:37:31 +00:00
|
|
|
*/
|
2020-11-13 07:56:54 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
2020-01-15 21:08:13 +02:00
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(connector_state->best_encoder);
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
if (connector_state->crtc != &crtc->base)
|
2012-07-08 19:40:39 +02:00
|
|
|
continue;
|
2013-03-27 00:44:52 +01:00
|
|
|
|
2022-05-03 21:22:24 +03:00
|
|
|
ret = encoder->compute_config(encoder, crtc_state,
|
2019-01-15 15:08:00 -05:00
|
|
|
connector_state);
|
2021-09-30 13:41:31 +03:00
|
|
|
if (ret == -EDEADLK)
|
|
|
|
|
return ret;
|
2019-01-15 15:08:00 -05:00
|
|
|
if (ret < 0) {
|
2022-05-03 21:22:25 +03:00
|
|
|
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] config failure: %d\n",
|
|
|
|
|
encoder->base.base.id, encoder->base.name, ret);
|
2019-01-15 15:08:00 -05:00
|
|
|
return ret;
|
2012-07-08 19:40:39 +02:00
|
|
|
}
|
2012-04-20 17:11:53 +01:00
|
|
|
}
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2013-06-01 17:16:21 +02:00
|
|
|
/* Set default port clock if not overwritten by the encoder. Needs to be
|
|
|
|
|
* done afterwards in case the encoder adjusts the mode. */
|
2022-05-03 21:22:24 +03:00
|
|
|
if (!crtc_state->port_clock)
|
|
|
|
|
crtc_state->port_clock = crtc_state->hw.adjusted_mode.crtc_clock
|
|
|
|
|
* crtc_state->pixel_multiplier;
|
2013-06-01 17:16:21 +02:00
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
ret = intel_crtc_compute_config(state, crtc);
|
2018-11-07 23:35:20 +02:00
|
|
|
if (ret == -EDEADLK)
|
2018-11-07 23:35:21 +02:00
|
|
|
return ret;
|
2021-09-30 12:32:29 +03:00
|
|
|
if (ret == -EAGAIN) {
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN(&i915->drm, !retry,
|
2022-05-03 21:22:25 +03:00
|
|
|
"[CRTC:%d:%s] loop in pipe configuration computation\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name))
|
2018-11-07 23:35:21 +02:00
|
|
|
return -EINVAL;
|
drm/i915: implement fdi auto-dithering
So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
into this, among them the default 1080p mode.
The solution is to dither down the pipe a bit so that everything fits,
which this patch implements.
But ports compute their state under the assumption that the bpp they
pick will be the one selected, e.g. the display port bw computations
won't work otherwise. Now we could adjust our code to again up-dither
to the computed DP link parameters, but that's pointless.
So instead when the pipe needs to adjust parameters we need to retry
the pipe_config computation at the encoder stage. Furthermore we need
to inform encoders that they should not increase bandwidth
requirements if possible. This is required for the hdmi code, which
prefers the pipe to up-dither to either of the two possible hdmi bpc
values.
LVDS has a similar requirement, although that's probably only
theoretical in nature: It's unlikely that we'll ever see an 8bpc
high-res lvds panel (which is required to hit the 2 fdi lane limit).
eDP is the only thing which could increase the pipe_bpp setting again,
even when in the retry-loop. This could hit the WARN. Two reasons for
not bothering:
- On many eDP panels we'll get a black screen if the bpp settings
don't match vbt. So failing the modeset is the right thing to do.
But since that also means it's the only way to light up the panel,
it should work. So we shouldn't be able to hit this WARN.
- There are still opens around the eDP panel handling, and maybe we
need additional tricks. Before that happens it's imo no use trying
to be too clever.
Worst case we just need to kill that WARN or maybe fail the compute
config stage if the eDP connector can't get the bpp setting it wants.
And since this can only happen with an fdi link in between and so for
pch eDP panels it's rather unlikely to blow up, if ever.
v2: Rebased on top of a bikeshed from Paulo.
v3: Improve commit message around eDP handling with the stuff
things with Imre.
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
|
|
|
|
2022-05-03 21:22:25 +03:00
|
|
|
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] bw constrained, retrying\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
drm/i915: implement fdi auto-dithering
So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
into this, among them the default 1080p mode.
The solution is to dither down the pipe a bit so that everything fits,
which this patch implements.
But ports compute their state under the assumption that the bpp they
pick will be the one selected, e.g. the display port bw computations
won't work otherwise. Now we could adjust our code to again up-dither
to the computed DP link parameters, but that's pointless.
So instead when the pipe needs to adjust parameters we need to retry
the pipe_config computation at the encoder stage. Furthermore we need
to inform encoders that they should not increase bandwidth
requirements if possible. This is required for the hdmi code, which
prefers the pipe to up-dither to either of the two possible hdmi bpc
values.
LVDS has a similar requirement, although that's probably only
theoretical in nature: It's unlikely that we'll ever see an 8bpc
high-res lvds panel (which is required to hit the 2 fdi lane limit).
eDP is the only thing which could increase the pipe_bpp setting again,
even when in the retry-loop. This could hit the WARN. Two reasons for
not bothering:
- On many eDP panels we'll get a black screen if the bpp settings
don't match vbt. So failing the modeset is the right thing to do.
But since that also means it's the only way to light up the panel,
it should work. So we shouldn't be able to hit this WARN.
- There are still opens around the eDP panel handling, and maybe we
need additional tricks. Before that happens it's imo no use trying
to be too clever.
Worst case we just need to kill that WARN or maybe fail the compute
config stage if the eDP connector can't get the bpp setting it wants.
And since this can only happen with an fdi link in between and so for
pch eDP panels it's rather unlikely to blow up, if ever.
v2: Rebased on top of a bikeshed from Paulo.
v3: Improve commit message around eDP handling with the stuff
things with Imre.
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
|
|
|
retry = false;
|
|
|
|
|
goto encoder_retry;
|
|
|
|
|
}
|
2021-09-30 12:32:29 +03:00
|
|
|
if (ret < 0) {
|
2022-05-03 21:22:25 +03:00
|
|
|
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] config failure: %d\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name, ret);
|
2021-09-30 12:32:29 +03:00
|
|
|
return ret;
|
|
|
|
|
}
|
drm/i915: implement fdi auto-dithering
So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw
VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit
into this, among them the default 1080p mode.
The solution is to dither down the pipe a bit so that everything fits,
which this patch implements.
But ports compute their state under the assumption that the bpp they
pick will be the one selected, e.g. the display port bw computations
won't work otherwise. Now we could adjust our code to again up-dither
to the computed DP link parameters, but that's pointless.
So instead when the pipe needs to adjust parameters we need to retry
the pipe_config computation at the encoder stage. Furthermore we need
to inform encoders that they should not increase bandwidth
requirements if possible. This is required for the hdmi code, which
prefers the pipe to up-dither to either of the two possible hdmi bpc
values.
LVDS has a similar requirement, although that's probably only
theoretical in nature: It's unlikely that we'll ever see an 8bpc
high-res lvds panel (which is required to hit the 2 fdi lane limit).
eDP is the only thing which could increase the pipe_bpp setting again,
even when in the retry-loop. This could hit the WARN. Two reasons for
not bothering:
- On many eDP panels we'll get a black screen if the bpp settings
don't match vbt. So failing the modeset is the right thing to do.
But since that also means it's the only way to light up the panel,
it should work. So we shouldn't be able to hit this WARN.
- There are still opens around the eDP panel handling, and maybe we
need additional tricks. Before that happens it's imo no use trying
to be too clever.
Worst case we just need to kill that WARN or maybe fail the compute
config stage if the eDP connector can't get the bpp setting it wants.
And since this can only happen with an fdi link in between and so for
pch eDP panels it's rather unlikely to blow up, if ever.
v2: Rebased on top of a bikeshed from Paulo.
v3: Improve commit message around eDP handling with the stuff
things with Imre.
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-02-21 00:00:16 +01:00
|
|
|
|
2015-08-12 11:43:34 +02:00
|
|
|
/* Dithering seems to not pass-through bits correctly when it should, so
|
2017-01-24 08:21:49 -08:00
|
|
|
* only enable it on 6bpc panels and when its not a compliance
|
|
|
|
|
* test requesting 6bpc video pattern.
|
|
|
|
|
*/
|
2022-05-03 21:22:24 +03:00
|
|
|
crtc_state->dither = (crtc_state->pipe_bpp == 6*3) &&
|
|
|
|
|
!crtc_state->dither_force_disable;
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-05-03 21:22:25 +03:00
|
|
|
"[CRTC:%d:%s] hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name,
|
2022-05-03 21:22:24 +03:00
|
|
|
base_bpp, crtc_state->pipe_bpp, crtc_state->dither);
|
drm/i915: precompute pipe bpp before touching the hw
The procedure has now 3 steps:
1. Compute the bpp that the plane will output, this is done in
pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
this function clamps the pipe_bpp to whatever limit the EDID of any
connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
computed pipe_bpp.
There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
a 2nd change we now unconditionally force the lvds bpc value - this
shouldn't matter in reality when the panel setup is consistent, but
better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
what we actually want, since otherwise at least the pixelclock
computations are wrong (I'm not sure whether the port would accept
e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
the next higher bpc value, since otherwise there's no way to make
use of the 12 bpc mode (since the next patch will remove the 12bpc
plane format, it doesn't exist).
Both of these changes are due to the removal of the
pipe_bpp = min(display_bpp, plane_bpp);
statement.
Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
all available bpp values in an outer loop and the codeblock that
computes derived values (once a good configuration is found) has been
moved out of the for loop maze. This is prep work to allow us to
successively fall back on bpc values, and also correctly support bpc
values != 8 or 6.
v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.
v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.
v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.
v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.
v6: Fix spelling in a comment.
v7: Debug output improvements for the bpp computation.
v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!
v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.
v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.
v11: And g4x/vlv also lack 12bpc hdmi support, so only support high
depth on DP. Adjust the code.
v12: Rebased.
v13: Split out the introduction of pipe_config->dither|pipe_bpp, as
requested from Jesse Barnes.
v14: Split out the special 6BPC handling for DP, as requested by Jesse
Barnes.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-03-27 00:44:58 +01:00
|
|
|
|
2018-11-07 23:35:21 +02:00
|
|
|
return 0;
|
2012-04-20 17:11:53 +01:00
|
|
|
}
|
2010-12-03 15:37:31 +00:00
|
|
|
|
2020-02-14 03:41:24 -08:00
|
|
|
static int
|
2022-05-03 21:22:23 +03:00
|
|
|
intel_modeset_pipe_config_late(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2020-02-14 03:41:24 -08:00
|
|
|
{
|
2022-05-03 21:22:23 +03:00
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2020-02-14 03:41:24 -08:00
|
|
|
struct drm_connector_state *conn_state;
|
|
|
|
|
struct drm_connector *connector;
|
|
|
|
|
int i;
|
|
|
|
|
|
2022-02-23 15:13:15 +02:00
|
|
|
intel_bigjoiner_adjust_pipe_src(crtc_state);
|
|
|
|
|
|
2020-02-14 03:41:24 -08:00
|
|
|
for_each_new_connector_in_state(&state->base, connector,
|
|
|
|
|
conn_state, i) {
|
|
|
|
|
struct intel_encoder *encoder =
|
|
|
|
|
to_intel_encoder(conn_state->best_encoder);
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (conn_state->crtc != &crtc->base ||
|
|
|
|
|
!encoder->compute_config_late)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ret = encoder->compute_config_late(encoder, crtc_state,
|
|
|
|
|
conn_state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-24 19:40:27 +02:00
|
|
|
bool intel_fuzzy_clock_check(int clock1, int clock2)
|
2013-06-27 00:39:25 +03:00
|
|
|
{
|
2013-09-06 23:29:02 +03:00
|
|
|
int diff;
|
2013-06-27 00:39:25 +03:00
|
|
|
|
|
|
|
|
if (clock1 == clock2)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (!clock1 || !clock2)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
diff = abs(clock1 - clock2);
|
|
|
|
|
|
|
|
|
|
if (((((diff + clock1 + clock2) * 100)) / (clock1 + clock2)) < 105)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 12:17:40 +02:00
|
|
|
static bool
|
|
|
|
|
intel_compare_m_n(unsigned int m, unsigned int n,
|
|
|
|
|
unsigned int m2, unsigned int n2,
|
|
|
|
|
bool exact)
|
|
|
|
|
{
|
|
|
|
|
if (m == m2 && n == n2)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (exact || !m || !n || !m2 || !n2)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX);
|
|
|
|
|
|
2016-01-06 13:54:43 +01:00
|
|
|
if (n > n2) {
|
|
|
|
|
while (n > n2) {
|
2015-07-14 12:17:40 +02:00
|
|
|
m2 <<= 1;
|
|
|
|
|
n2 <<= 1;
|
|
|
|
|
}
|
2016-01-06 13:54:43 +01:00
|
|
|
} else if (n < n2) {
|
|
|
|
|
while (n < n2) {
|
2015-07-14 12:17:40 +02:00
|
|
|
m <<= 1;
|
|
|
|
|
n <<= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-06 13:54:43 +01:00
|
|
|
if (n != n2)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return intel_fuzzy_clock_check(m, m2);
|
2015-07-14 12:17:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
intel_compare_link_m_n(const struct intel_link_m_n *m_n,
|
2019-06-12 16:07:59 +03:00
|
|
|
const struct intel_link_m_n *m2_n2,
|
|
|
|
|
bool exact)
|
|
|
|
|
{
|
|
|
|
|
return m_n->tu == m2_n2->tu &&
|
2022-01-27 11:32:52 +02:00
|
|
|
intel_compare_m_n(m_n->data_m, m_n->data_n,
|
|
|
|
|
m2_n2->data_m, m2_n2->data_n, exact) &&
|
2019-06-12 16:07:59 +03:00
|
|
|
intel_compare_m_n(m_n->link_m, m_n->link_n,
|
|
|
|
|
m2_n2->link_m, m2_n2->link_n, exact);
|
2015-07-14 12:17:40 +02:00
|
|
|
}
|
|
|
|
|
|
2019-02-25 19:41:05 +02:00
|
|
|
static bool
|
|
|
|
|
intel_compare_infoframe(const union hdmi_infoframe *a,
|
|
|
|
|
const union hdmi_infoframe *b)
|
|
|
|
|
{
|
|
|
|
|
return memcmp(a, b, sizeof(*a)) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-14 09:07:27 +03:00
|
|
|
static bool
|
|
|
|
|
intel_compare_dp_vsc_sdp(const struct drm_dp_vsc_sdp *a,
|
|
|
|
|
const struct drm_dp_vsc_sdp *b)
|
|
|
|
|
{
|
|
|
|
|
return memcmp(a, b, sizeof(*a)) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-25 19:41:05 +02:00
|
|
|
static void
|
2019-06-12 16:08:00 +03:00
|
|
|
pipe_config_infoframe_mismatch(struct drm_i915_private *dev_priv,
|
|
|
|
|
bool fastset, const char *name,
|
|
|
|
|
const union hdmi_infoframe *a,
|
|
|
|
|
const union hdmi_infoframe *b)
|
2019-02-25 19:41:05 +02:00
|
|
|
{
|
2019-06-12 16:08:00 +03:00
|
|
|
if (fastset) {
|
2019-10-28 12:38:15 +02:00
|
|
|
if (!drm_debug_enabled(DRM_UT_KMS))
|
2019-02-25 19:41:05 +02:00
|
|
|
return;
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"fastset mismatch in %s infoframe\n", name);
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm, "expected:\n");
|
2019-02-25 19:41:05 +02:00
|
|
|
hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, a);
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "found:\n");
|
2019-02-25 19:41:05 +02:00
|
|
|
hdmi_infoframe_log(KERN_DEBUG, dev_priv->drm.dev, b);
|
|
|
|
|
} else {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm, "mismatch in %s infoframe\n", name);
|
|
|
|
|
drm_err(&dev_priv->drm, "expected:\n");
|
2019-02-25 19:41:05 +02:00
|
|
|
hdmi_infoframe_log(KERN_ERR, dev_priv->drm.dev, a);
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&dev_priv->drm, "found:\n");
|
2019-02-25 19:41:05 +02:00
|
|
|
hdmi_infoframe_log(KERN_ERR, dev_priv->drm.dev, b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-14 09:07:27 +03:00
|
|
|
static void
|
|
|
|
|
pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private *dev_priv,
|
|
|
|
|
bool fastset, const char *name,
|
|
|
|
|
const struct drm_dp_vsc_sdp *a,
|
|
|
|
|
const struct drm_dp_vsc_sdp *b)
|
|
|
|
|
{
|
|
|
|
|
if (fastset) {
|
|
|
|
|
if (!drm_debug_enabled(DRM_UT_KMS))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"fastset mismatch in %s dp sdp\n", name);
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm, "expected:\n");
|
|
|
|
|
drm_dp_vsc_sdp_log(KERN_DEBUG, dev_priv->drm.dev, a);
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm, "found:\n");
|
|
|
|
|
drm_dp_vsc_sdp_log(KERN_DEBUG, dev_priv->drm.dev, b);
|
|
|
|
|
} else {
|
|
|
|
|
drm_err(&dev_priv->drm, "mismatch in %s dp sdp\n", name);
|
|
|
|
|
drm_err(&dev_priv->drm, "expected:\n");
|
|
|
|
|
drm_dp_vsc_sdp_log(KERN_ERR, dev_priv->drm.dev, a);
|
|
|
|
|
drm_err(&dev_priv->drm, "found:\n");
|
|
|
|
|
drm_dp_vsc_sdp_log(KERN_ERR, dev_priv->drm.dev, b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-10 18:09:05 -07:00
|
|
|
static void __printf(4, 5)
|
|
|
|
|
pipe_config_mismatch(bool fastset, const struct intel_crtc *crtc,
|
|
|
|
|
const char *name, const char *format, ...)
|
2016-12-06 10:50:20 +00:00
|
|
|
{
|
2020-01-22 00:46:41 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2016-12-06 10:50:20 +00:00
|
|
|
struct va_format vaf;
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, format);
|
|
|
|
|
vaf.fmt = format;
|
|
|
|
|
vaf.va = &args;
|
|
|
|
|
|
2019-06-12 16:08:00 +03:00
|
|
|
if (fastset)
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] fastset mismatch in %s %pV\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name, name, &vaf);
|
2018-03-13 15:02:15 -07:00
|
|
|
else
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_err(&i915->drm, "[CRTC:%d:%s] mismatch in %s %pV\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name, name, &vaf);
|
2016-12-06 10:50:20 +00:00
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-24 14:01:14 +01:00
|
|
|
static bool fastboot_enabled(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
2020-06-18 18:04:02 +03:00
|
|
|
if (dev_priv->params.fastboot != -1)
|
|
|
|
|
return dev_priv->params.fastboot;
|
2019-01-24 14:01:14 +01:00
|
|
|
|
|
|
|
|
/* Enable fastboot by default on Skylake and newer */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9)
|
2019-01-29 15:22:37 +01:00
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* Enable fastboot by default on VLV and CHV */
|
|
|
|
|
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* Disabled by default on all others */
|
|
|
|
|
return false;
|
2019-01-24 14:01:14 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-16 12:48:15 +03:00
|
|
|
bool
|
2019-06-12 16:07:59 +03:00
|
|
|
intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|
|
|
|
const struct intel_crtc_state *pipe_config,
|
2019-06-12 16:08:00 +03:00
|
|
|
bool fastset)
|
2013-03-28 10:42:00 +01:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
|
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
2015-07-14 12:17:40 +02:00
|
|
|
bool ret = true;
|
2019-09-04 00:52:54 +05:30
|
|
|
u32 bp_gamma = 0;
|
2019-06-12 16:08:00 +03:00
|
|
|
bool fixup_inherited = fastset &&
|
2020-04-29 13:39:36 +03:00
|
|
|
current_config->inherited && !pipe_config->inherited;
|
2015-07-14 12:17:40 +02:00
|
|
|
|
2019-01-24 14:01:14 +01:00
|
|
|
if (fixup_inherited && !fastboot_enabled(dev_priv)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"initial modeset and fastboot not set\n");
|
2019-01-08 17:08:40 +01:00
|
|
|
ret = false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_X(name) do { \
|
2013-06-05 13:34:20 +02:00
|
|
|
if (current_config->name != pipe_config->name) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected 0x%08x, found 0x%08x)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name, \
|
|
|
|
|
pipe_config->name); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2013-06-05 13:34:20 +02:00
|
|
|
|
2021-05-14 16:22:45 -07:00
|
|
|
#define PIPE_CONF_CHECK_X_WITH_MASK(name, mask) do { \
|
|
|
|
|
if ((current_config->name & (mask)) != (pipe_config->name & (mask))) { \
|
|
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
|
|
|
|
"(expected 0x%08x, found 0x%08x)", \
|
|
|
|
|
current_config->name & (mask), \
|
|
|
|
|
pipe_config->name & (mask)); \
|
|
|
|
|
ret = false; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_I(name) do { \
|
2013-04-19 11:25:34 +02:00
|
|
|
if (current_config->name != pipe_config->name) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected %i, found %i)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name, \
|
|
|
|
|
pipe_config->name); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2015-07-14 12:17:40 +02:00
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_BOOL(name) do { \
|
2017-11-10 12:34:55 +01:00
|
|
|
if (current_config->name != pipe_config->name) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected %s, found %s)", \
|
2022-02-25 15:46:28 -08:00
|
|
|
str_yes_no(current_config->name), \
|
|
|
|
|
str_yes_no(pipe_config->name)); \
|
2017-11-10 12:34:55 +01:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2017-11-10 12:34:55 +01:00
|
|
|
|
2017-11-10 12:34:56 +01:00
|
|
|
/*
|
|
|
|
|
* Checks state where we only read out the enabling, but not the entire
|
|
|
|
|
* state itself (like full infoframes or ELD for audio). These states
|
|
|
|
|
* require a full modeset on bootup to fix up.
|
|
|
|
|
*/
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_BOOL_INCOMPLETE(name) do { \
|
2017-11-10 12:34:56 +01:00
|
|
|
if (!fixup_inherited || (!current_config->name && !pipe_config->name)) { \
|
|
|
|
|
PIPE_CONF_CHECK_BOOL(name); \
|
|
|
|
|
} else { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"unable to verify whether state matches exactly, forcing modeset (expected %s, found %s)", \
|
2022-02-25 15:46:28 -08:00
|
|
|
str_yes_no(current_config->name), \
|
|
|
|
|
str_yes_no(pipe_config->name)); \
|
2017-11-10 12:34:56 +01:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2017-11-10 12:34:56 +01:00
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_P(name) do { \
|
2016-03-08 17:46:18 +02:00
|
|
|
if (current_config->name != pipe_config->name) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected %p, found %p)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name, \
|
|
|
|
|
pipe_config->name); \
|
2016-03-08 17:46:18 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2016-03-08 17:46:18 +02:00
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_M_N(name) do { \
|
2015-07-14 12:17:40 +02:00
|
|
|
if (!intel_compare_link_m_n(¤t_config->name, \
|
|
|
|
|
&pipe_config->name,\
|
2019-06-12 16:08:00 +03:00
|
|
|
!fastset)) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2022-01-27 11:32:52 +02:00
|
|
|
"(expected tu %i data %i/%i link %i/%i, " \
|
|
|
|
|
"found tu %i, data %i/%i link %i/%i)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name.tu, \
|
2022-01-27 11:32:52 +02:00
|
|
|
current_config->name.data_m, \
|
|
|
|
|
current_config->name.data_n, \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name.link_m, \
|
|
|
|
|
current_config->name.link_n, \
|
|
|
|
|
pipe_config->name.tu, \
|
2022-01-27 11:32:52 +02:00
|
|
|
pipe_config->name.data_m, \
|
|
|
|
|
pipe_config->name.data_n, \
|
2019-06-12 16:08:00 +03:00
|
|
|
pipe_config->name.link_m, \
|
|
|
|
|
pipe_config->name.link_n); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2015-07-14 12:17:40 +02:00
|
|
|
|
2022-05-03 21:22:21 +03:00
|
|
|
#define PIPE_CONF_CHECK_TIMINGS(name) do { \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_htotal); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_hblank_start); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_hblank_end); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vtotal); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vblank_end); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2022-05-03 21:22:22 +03:00
|
|
|
#define PIPE_CONF_CHECK_RECT(name) do { \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.x1); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.x2); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.y1); \
|
|
|
|
|
PIPE_CONF_CHECK_I(name.y2); \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2016-03-30 11:34:36 +02:00
|
|
|
/* This is required for BDW+ where there is only one set of registers for
|
|
|
|
|
* switching between high and low RR.
|
|
|
|
|
* This macro can be used whenever a comparison has to be made between one
|
|
|
|
|
* hw state and multiple sw state variables.
|
|
|
|
|
*/
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
|
2015-07-14 12:17:40 +02:00
|
|
|
if (!intel_compare_link_m_n(¤t_config->name, \
|
2019-06-12 16:08:00 +03:00
|
|
|
&pipe_config->name, !fastset) && \
|
2015-07-14 12:17:40 +02:00
|
|
|
!intel_compare_link_m_n(¤t_config->alt_name, \
|
2019-06-12 16:08:00 +03:00
|
|
|
&pipe_config->name, !fastset)) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2022-01-27 11:32:52 +02:00
|
|
|
"(expected tu %i data %i/%i link %i/%i, " \
|
|
|
|
|
"or tu %i data %i/%i link %i/%i, " \
|
|
|
|
|
"found tu %i, data %i/%i link %i/%i)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name.tu, \
|
2022-01-27 11:32:52 +02:00
|
|
|
current_config->name.data_m, \
|
|
|
|
|
current_config->name.data_n, \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name.link_m, \
|
|
|
|
|
current_config->name.link_n, \
|
|
|
|
|
current_config->alt_name.tu, \
|
2022-01-27 11:32:52 +02:00
|
|
|
current_config->alt_name.data_m, \
|
|
|
|
|
current_config->alt_name.data_n, \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->alt_name.link_m, \
|
|
|
|
|
current_config->alt_name.link_n, \
|
|
|
|
|
pipe_config->name.tu, \
|
2022-01-27 11:32:52 +02:00
|
|
|
pipe_config->name.data_m, \
|
|
|
|
|
pipe_config->name.data_n, \
|
2019-06-12 16:08:00 +03:00
|
|
|
pipe_config->name.link_m, \
|
|
|
|
|
pipe_config->name.link_n); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2013-03-28 10:42:01 +01:00
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_FLAGS(name, mask) do { \
|
2013-04-29 21:56:12 +02:00
|
|
|
if ((current_config->name ^ pipe_config->name) & (mask)) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(%x) (expected %i, found %i)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
(mask), \
|
|
|
|
|
current_config->name & (mask), \
|
|
|
|
|
pipe_config->name & (mask)); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2013-04-29 21:56:12 +02:00
|
|
|
|
2018-03-16 20:36:25 +02:00
|
|
|
#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) do { \
|
2013-09-06 23:29:07 +03:00
|
|
|
if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected %i, found %i)", \
|
2019-06-12 16:08:00 +03:00
|
|
|
current_config->name, \
|
|
|
|
|
pipe_config->name); \
|
2015-07-14 12:17:40 +02:00
|
|
|
ret = false; \
|
2018-03-16 20:36:25 +02:00
|
|
|
} \
|
|
|
|
|
} while (0)
|
2013-09-06 23:29:07 +03:00
|
|
|
|
2019-02-25 19:41:05 +02:00
|
|
|
#define PIPE_CONF_CHECK_INFOFRAME(name) do { \
|
|
|
|
|
if (!intel_compare_infoframe(¤t_config->infoframes.name, \
|
|
|
|
|
&pipe_config->infoframes.name)) { \
|
2019-06-12 16:08:00 +03:00
|
|
|
pipe_config_infoframe_mismatch(dev_priv, fastset, __stringify(name), \
|
|
|
|
|
¤t_config->infoframes.name, \
|
|
|
|
|
&pipe_config->infoframes.name); \
|
2019-02-25 19:41:05 +02:00
|
|
|
ret = false; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2020-05-14 09:07:27 +03:00
|
|
|
#define PIPE_CONF_CHECK_DP_VSC_SDP(name) do { \
|
|
|
|
|
if (!current_config->has_psr && !pipe_config->has_psr && \
|
|
|
|
|
!intel_compare_dp_vsc_sdp(¤t_config->infoframes.name, \
|
|
|
|
|
&pipe_config->infoframes.name)) { \
|
|
|
|
|
pipe_config_dp_vsc_sdp_mismatch(dev_priv, fastset, __stringify(name), \
|
|
|
|
|
¤t_config->infoframes.name, \
|
|
|
|
|
&pipe_config->infoframes.name); \
|
|
|
|
|
ret = false; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2019-09-04 00:52:54 +05:30
|
|
|
#define PIPE_CONF_CHECK_COLOR_LUT(name1, name2, bit_precision) do { \
|
|
|
|
|
if (current_config->name1 != pipe_config->name1) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name1), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"(expected %i, found %i, won't compare lut values)", \
|
2019-09-04 00:52:54 +05:30
|
|
|
current_config->name1, \
|
|
|
|
|
pipe_config->name1); \
|
|
|
|
|
ret = false;\
|
|
|
|
|
} else { \
|
|
|
|
|
if (!intel_color_lut_equal(current_config->name2, \
|
|
|
|
|
pipe_config->name2, pipe_config->name1, \
|
|
|
|
|
bit_precision)) { \
|
2019-10-10 18:09:05 -07:00
|
|
|
pipe_config_mismatch(fastset, crtc, __stringify(name2), \
|
2019-10-10 18:09:04 -07:00
|
|
|
"hw_state doesn't match sw_state"); \
|
2019-09-04 00:52:54 +05:30
|
|
|
ret = false; \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
2019-02-25 19:41:05 +02:00
|
|
|
#define PIPE_CONF_QUIRK(quirk) \
|
2013-06-06 14:55:52 +02:00
|
|
|
((current_config->quirks | pipe_config->quirks) & (quirk))
|
|
|
|
|
|
2022-05-03 21:22:36 +03:00
|
|
|
PIPE_CONF_CHECK_I(hw.enable);
|
|
|
|
|
PIPE_CONF_CHECK_I(hw.active);
|
|
|
|
|
|
2013-05-22 00:50:22 +02:00
|
|
|
PIPE_CONF_CHECK_I(cpu_transcoder);
|
2022-05-03 21:22:36 +03:00
|
|
|
PIPE_CONF_CHECK_I(mst_master_transcoder);
|
2013-05-22 00:50:22 +02:00
|
|
|
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(has_pch_encoder);
|
2013-04-19 11:25:34 +02:00
|
|
|
PIPE_CONF_CHECK_I(fdi_lanes);
|
2015-07-14 12:17:40 +02:00
|
|
|
PIPE_CONF_CHECK_M_N(fdi_m_n);
|
2013-04-19 11:25:34 +02:00
|
|
|
|
2015-07-06 16:39:15 +03:00
|
|
|
PIPE_CONF_CHECK_I(lane_count);
|
2016-06-13 16:44:35 +03:00
|
|
|
PIPE_CONF_CHECK_X(lane_lat_optim_mask);
|
2014-08-05 07:51:23 -07:00
|
|
|
|
2022-01-28 12:37:56 +02:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) {
|
2015-07-14 12:17:40 +02:00
|
|
|
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
|
2022-01-28 12:37:56 +02:00
|
|
|
} else {
|
|
|
|
|
PIPE_CONF_CHECK_M_N(dp_m_n);
|
|
|
|
|
PIPE_CONF_CHECK_M_N(dp_m2_n2);
|
|
|
|
|
}
|
2013-09-10 17:02:54 +03:00
|
|
|
|
2016-06-22 21:57:01 +03:00
|
|
|
PIPE_CONF_CHECK_X(output_types);
|
2015-11-27 12:21:46 +02:00
|
|
|
|
2022-02-21 13:03:53 +02:00
|
|
|
PIPE_CONF_CHECK_I(framestart_delay);
|
2022-03-10 02:47:54 +02:00
|
|
|
PIPE_CONF_CHECK_I(msa_timing_delay);
|
2022-02-21 13:03:53 +02:00
|
|
|
|
2022-05-03 21:22:21 +03:00
|
|
|
PIPE_CONF_CHECK_TIMINGS(hw.pipe_mode);
|
|
|
|
|
PIPE_CONF_CHECK_TIMINGS(hw.adjusted_mode);
|
2021-10-22 13:33:04 +03:00
|
|
|
|
|
|
|
|
PIPE_CONF_CHECK_I(pixel_multiplier);
|
|
|
|
|
|
|
|
|
|
PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
|
|
|
|
|
DRM_MODE_FLAG_INTERLACE);
|
|
|
|
|
|
|
|
|
|
if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
|
2020-11-17 11:47:09 -08:00
|
|
|
PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
|
2021-10-22 13:33:04 +03:00
|
|
|
DRM_MODE_FLAG_PHSYNC);
|
|
|
|
|
PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
|
|
|
|
|
DRM_MODE_FLAG_NHSYNC);
|
|
|
|
|
PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
|
|
|
|
|
DRM_MODE_FLAG_PVSYNC);
|
|
|
|
|
PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
|
|
|
|
|
DRM_MODE_FLAG_NVSYNC);
|
2020-11-17 11:47:09 -08:00
|
|
|
}
|
|
|
|
|
|
2018-10-12 11:53:07 +05:30
|
|
|
PIPE_CONF_CHECK_I(output_format);
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(has_hdmi_sink);
|
2021-03-19 21:42:42 -07:00
|
|
|
if ((DISPLAY_VER(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
|
2016-10-14 10:13:44 +01:00
|
|
|
IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(limited_color_range);
|
drm/i915: enable scrambling
Geminilake platform sports a native HDMI 2.0 controller, and is
capable of driving pixel-clocks upto 594Mhz. HDMI 2.0 spec
mendates scrambling for these higher clocks, for reduced RF footprint.
This patch checks if the monitor supports scrambling, and if required,
enables it during the modeset.
V2: Addressed review comments from Ville:
- Do not track scrambling status in DRM layer, track somewhere in
driver like in intel_crtc_state.
- Don't talk to monitor at such a low layer, set monitor scrambling
in intel_enable_ddi() before enabling the port.
V3: Addressed review comments from Jani
- In comments, function names, use "sink" instead of "monitor",
so that the implementation could be close to the language of
HDMI spec.
V4: Addressed review comment from Maarten
- scrambling -> hdmi_scrambling
- high_tmds_clock_ratio -> hdmi_high_tmds_clock_ratio
V5: Addressed review comments from Ville and Ander
- Do not modifiy the crtc_state after compute_config. Move all
scrambling and tmds_clock_ratio calcutations to compute_config.
- While setting scrambling for source/sink, do not check the
conditions again, just go by the crtc_state flags. This will
simplyfy the condition checks.
V6: Addressed review comments from Ville
- Do not add IS_GLK check in disable/enable function, instead add it
in compute_config, while setting state flags.
- Remove unnecessary paranthesis.
- Simplyfy handle_sink_scrambling function as suggested.
- Add readout code for scrambling status in get_ddi_config and add a
check for the same in pipe_config_compare.
V7: Addressed review comments from Ander/Ville
- No separate function for source scrambling, make it inline
- Align the last line of the macro TRANS_DDI_HDMI_SCRAMBLING_MASK
- Do not add platform check while setting source scrambling
- Use pipe_config instead of crtc->config to set sink scrambling
- To readout scrambling status, Compare with SCRAMBLING_MASK
not any of its bits
- Remove platform check in intel_pipe_config_compare while checking
scrambling status
V8: Fixed mege conflict, Addressed review comments from Ander
- Remove the desciption/comment about scrambling fom the caller, move
it to the function
- Move the IS_GLK check into scrambling function
- Fix alignment
V9: Fixed review comments from Ville, Ander
- Pass the scrambling state variables as bool input to the sink_scrambling
function and let the disable call be unconditional.
- Fix alignments in function calls and debug messages.
- Add kernel doc for function intel_hdmi_handle_sink_scrambling
V10: Rebase
Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1489404244-16608-6-git-send-email-shashank.sharma@intel.com
2017-03-13 16:54:03 +05:30
|
|
|
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
|
|
|
|
|
PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
|
2019-06-12 16:08:01 +03:00
|
|
|
PIPE_CONF_CHECK_BOOL(has_infoframe);
|
2021-10-22 13:33:04 +03:00
|
|
|
PIPE_CONF_CHECK_BOOL(fec_enable);
|
2013-06-06 12:45:25 +02:00
|
|
|
|
2017-11-10 12:34:56 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
|
2014-04-24 23:54:52 +02:00
|
|
|
|
2015-09-03 21:50:16 +03:00
|
|
|
PIPE_CONF_CHECK_X(gmch_pfit.control);
|
2015-07-15 14:15:50 +02:00
|
|
|
/* pfit ratios are autocomputed by the hw on gen4+ */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 4)
|
2016-03-15 16:40:07 +02:00
|
|
|
PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios);
|
2015-09-03 21:50:16 +03:00
|
|
|
PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits);
|
2014-04-13 12:00:33 +02:00
|
|
|
|
2019-04-25 19:29:05 +03:00
|
|
|
/*
|
|
|
|
|
* Changing the EDP transcoder input mux
|
|
|
|
|
* (A_ONOFF vs. A_ON) requires a full modeset.
|
|
|
|
|
*/
|
2019-04-25 19:29:06 +03:00
|
|
|
PIPE_CONF_CHECK_BOOL(pch_pfit.force_thru);
|
2019-04-25 19:29:05 +03:00
|
|
|
|
2019-06-12 16:08:00 +03:00
|
|
|
if (!fastset) {
|
2022-05-03 21:22:22 +03:00
|
|
|
PIPE_CONF_CHECK_RECT(pipe_src);
|
2015-08-27 15:44:05 +02:00
|
|
|
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(pch_pfit.enabled);
|
2022-05-03 21:22:22 +03:00
|
|
|
PIPE_CONF_CHECK_RECT(pch_pfit.dst);
|
2013-05-07 23:34:16 +02:00
|
|
|
|
2015-09-14 11:30:10 +02:00
|
|
|
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
|
2021-10-22 13:33:04 +03:00
|
|
|
PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
|
2019-02-07 22:21:40 +02:00
|
|
|
|
|
|
|
|
PIPE_CONF_CHECK_X(gamma_mode);
|
2019-02-18 21:31:32 +02:00
|
|
|
if (IS_CHERRYVIEW(dev_priv))
|
|
|
|
|
PIPE_CONF_CHECK_X(cgm_mode);
|
|
|
|
|
else
|
|
|
|
|
PIPE_CONF_CHECK_X(csc_mode);
|
2019-02-07 22:39:13 +02:00
|
|
|
PIPE_CONF_CHECK_BOOL(gamma_enable);
|
2019-02-07 22:21:42 +02:00
|
|
|
PIPE_CONF_CHECK_BOOL(csc_enable);
|
2019-09-04 00:52:54 +05:30
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
PIPE_CONF_CHECK_I(linetime);
|
|
|
|
|
PIPE_CONF_CHECK_I(ips_linetime);
|
|
|
|
|
|
2019-09-04 00:52:54 +05:30
|
|
|
bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
|
|
|
|
|
if (bp_gamma)
|
2019-10-31 12:26:01 +01:00
|
|
|
PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
|
2021-05-14 16:22:44 -07:00
|
|
|
|
2021-09-22 14:52:42 -07:00
|
|
|
if (current_config->active_planes) {
|
|
|
|
|
PIPE_CONF_CHECK_BOOL(has_psr);
|
|
|
|
|
PIPE_CONF_CHECK_BOOL(has_psr2);
|
|
|
|
|
PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
|
|
|
|
|
PIPE_CONF_CHECK_I(dc3co_exitline);
|
|
|
|
|
}
|
2015-09-14 11:30:10 +02:00
|
|
|
}
|
2015-04-07 15:28:45 -07:00
|
|
|
|
2017-11-10 12:34:55 +01:00
|
|
|
PIPE_CONF_CHECK_BOOL(double_wide);
|
2013-09-04 18:30:03 +03:00
|
|
|
|
2021-10-22 13:33:04 +03:00
|
|
|
if (dev_priv->dpll.mgr) {
|
2021-07-21 15:30:37 -07:00
|
|
|
PIPE_CONF_CHECK_P(shared_dpll);
|
2020-11-17 11:47:09 -08:00
|
|
|
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.spll);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
|
2022-02-16 05:40:59 -08:00
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.div0);
|
2020-11-17 11:47:09 -08:00
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
|
|
|
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
|
2021-07-21 15:30:37 -07:00
|
|
|
}
|
2020-11-17 11:47:09 -08:00
|
|
|
|
2021-10-22 13:33:04 +03:00
|
|
|
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
|
|
|
|
|
PIPE_CONF_CHECK_X(dsi_pll.div);
|
2020-11-17 11:47:09 -08:00
|
|
|
|
2021-10-22 13:33:04 +03:00
|
|
|
if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5)
|
|
|
|
|
PIPE_CONF_CHECK_I(pipe_bpp);
|
2020-11-17 11:47:09 -08:00
|
|
|
|
2021-10-22 13:33:04 +03:00
|
|
|
PIPE_CONF_CHECK_CLOCK_FUZZY(hw.pipe_mode.crtc_clock);
|
|
|
|
|
PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
|
|
|
|
|
PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
|
2020-11-17 11:47:09 -08:00
|
|
|
|
2021-10-22 13:33:04 +03:00
|
|
|
PIPE_CONF_CHECK_I(min_voltage_level);
|
2017-10-24 12:52:14 +03:00
|
|
|
|
2021-09-22 14:52:42 -07:00
|
|
|
if (current_config->has_psr || pipe_config->has_psr)
|
2021-05-14 16:22:45 -07:00
|
|
|
PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable,
|
|
|
|
|
~intel_hdmi_infoframe_enable(DP_SDP_VSC));
|
|
|
|
|
else
|
|
|
|
|
PIPE_CONF_CHECK_X(infoframes.enable);
|
|
|
|
|
|
2019-02-25 19:41:05 +02:00
|
|
|
PIPE_CONF_CHECK_X(infoframes.gcp);
|
|
|
|
|
PIPE_CONF_CHECK_INFOFRAME(avi);
|
|
|
|
|
PIPE_CONF_CHECK_INFOFRAME(spd);
|
|
|
|
|
PIPE_CONF_CHECK_INFOFRAME(hdmi);
|
2019-05-16 19:40:17 +05:30
|
|
|
PIPE_CONF_CHECK_INFOFRAME(drm);
|
2020-05-14 09:07:27 +03:00
|
|
|
PIPE_CONF_CHECK_DP_VSC_SDP(vsc);
|
2019-02-25 19:41:05 +02:00
|
|
|
|
2020-01-15 21:08:12 +02:00
|
|
|
PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
|
2019-10-18 10:27:20 -07:00
|
|
|
PIPE_CONF_CHECK_I(master_transcoder);
|
2022-02-03 20:38:23 +02:00
|
|
|
PIPE_CONF_CHECK_X(bigjoiner_pipes);
|
2019-10-18 10:27:20 -07:00
|
|
|
|
2019-12-10 12:50:52 +02:00
|
|
|
PIPE_CONF_CHECK_I(dsc.compression_enable);
|
|
|
|
|
PIPE_CONF_CHECK_I(dsc.dsc_split);
|
|
|
|
|
PIPE_CONF_CHECK_I(dsc.compressed_bpp);
|
|
|
|
|
|
2021-03-02 13:03:00 +02:00
|
|
|
PIPE_CONF_CHECK_BOOL(splitter.enable);
|
|
|
|
|
PIPE_CONF_CHECK_I(splitter.link_count);
|
|
|
|
|
PIPE_CONF_CHECK_I(splitter.pixel_overlap);
|
|
|
|
|
|
2021-01-22 15:26:35 -08:00
|
|
|
PIPE_CONF_CHECK_BOOL(vrr.enable);
|
|
|
|
|
PIPE_CONF_CHECK_I(vrr.vmin);
|
|
|
|
|
PIPE_CONF_CHECK_I(vrr.vmax);
|
|
|
|
|
PIPE_CONF_CHECK_I(vrr.flipline);
|
|
|
|
|
PIPE_CONF_CHECK_I(vrr.pipeline_full);
|
2021-05-25 17:06:55 -07:00
|
|
|
PIPE_CONF_CHECK_I(vrr.guardband);
|
2021-01-22 15:26:35 -08:00
|
|
|
|
2013-06-05 13:34:20 +02:00
|
|
|
#undef PIPE_CONF_CHECK_X
|
2013-04-19 11:25:34 +02:00
|
|
|
#undef PIPE_CONF_CHECK_I
|
2017-11-10 12:34:55 +01:00
|
|
|
#undef PIPE_CONF_CHECK_BOOL
|
2017-11-10 12:34:56 +01:00
|
|
|
#undef PIPE_CONF_CHECK_BOOL_INCOMPLETE
|
2016-03-08 17:46:18 +02:00
|
|
|
#undef PIPE_CONF_CHECK_P
|
2013-04-29 21:56:12 +02:00
|
|
|
#undef PIPE_CONF_CHECK_FLAGS
|
2013-09-06 23:29:07 +03:00
|
|
|
#undef PIPE_CONF_CHECK_CLOCK_FUZZY
|
2019-09-04 00:52:54 +05:30
|
|
|
#undef PIPE_CONF_CHECK_COLOR_LUT
|
2022-05-03 21:22:21 +03:00
|
|
|
#undef PIPE_CONF_CHECK_TIMINGS
|
2022-05-03 21:22:22 +03:00
|
|
|
#undef PIPE_CONF_CHECK_RECT
|
2013-06-06 14:55:52 +02:00
|
|
|
#undef PIPE_CONF_QUIRK
|
2013-03-28 10:42:01 +01:00
|
|
|
|
2015-07-14 12:17:40 +02:00
|
|
|
return ret;
|
2013-03-28 10:42:00 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-17 21:19:17 +02:00
|
|
|
static void
|
|
|
|
|
intel_verify_planes(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
const struct intel_plane_state *plane_state;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane,
|
|
|
|
|
plane_state, i)
|
2019-09-20 13:42:20 +02:00
|
|
|
assert_plane(plane, plane_state->planar_slave ||
|
2019-10-31 12:26:08 +01:00
|
|
|
plane_state->uapi.visible);
|
2017-11-17 21:19:17 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-14 08:37:03 -07:00
|
|
|
int intel_modeset_all_pipes(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Add all pipes to the state, and force
|
|
|
|
|
* a modeset on all the active ones.
|
|
|
|
|
*/
|
|
|
|
|
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
|
|
|
|
struct intel_crtc_state *crtc_state;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
|
|
|
|
|
if (IS_ERR(crtc_state))
|
|
|
|
|
return PTR_ERR(crtc_state);
|
|
|
|
|
|
|
|
|
|
if (!crtc_state->hw.active ||
|
|
|
|
|
drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
crtc_state->uapi.mode_changed = true;
|
|
|
|
|
|
|
|
|
|
ret = drm_atomic_add_affected_connectors(&state->base,
|
|
|
|
|
&crtc->base);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
ret = intel_atomic_add_affected_planes(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
crtc_state->update_planes |= crtc_state->active_planes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state)
|
2014-05-15 20:23:23 +03:00
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2016-10-13 11:02:52 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
2022-02-18 12:03:59 +02:00
|
|
|
struct drm_display_mode adjusted_mode;
|
|
|
|
|
|
|
|
|
|
drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode);
|
2021-01-22 15:26:46 -08:00
|
|
|
|
|
|
|
|
if (crtc_state->vrr.enable) {
|
|
|
|
|
adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax;
|
|
|
|
|
adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax;
|
|
|
|
|
adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
|
|
|
|
|
crtc->vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state);
|
|
|
|
|
}
|
2019-10-07 14:49:43 +03:00
|
|
|
|
2021-01-22 15:26:46 -08:00
|
|
|
drm_calc_timestamping_constants(&crtc->base, &adjusted_mode);
|
2014-05-15 20:23:23 +03:00
|
|
|
|
2020-04-29 13:39:04 +03:00
|
|
|
crtc->mode_flags = crtc_state->mode_flags;
|
|
|
|
|
|
2014-05-15 20:23:23 +03:00
|
|
|
/*
|
|
|
|
|
* The scanline counter increments at the leading edge of hsync.
|
|
|
|
|
*
|
|
|
|
|
* On most platforms it starts counting from vtotal-1 on the
|
|
|
|
|
* first active line. That means the scanline counter value is
|
|
|
|
|
* always one less than what we would expect. Ie. just after
|
|
|
|
|
* start of vblank, which also occurs at start of hsync (on the
|
|
|
|
|
* last active line), the scanline counter will read vblank_start-1.
|
|
|
|
|
*
|
|
|
|
|
* On gen2 the scanline counter starts counting from 1 instead
|
|
|
|
|
* of vtotal-1, so we have to subtract one (or rather add vtotal-1
|
|
|
|
|
* to keep the value positive), instead of adding one.
|
|
|
|
|
*
|
|
|
|
|
* On HSW+ the behaviour of the scanline counter depends on the output
|
|
|
|
|
* type. For DP ports it behaves like most other platforms, but on HDMI
|
|
|
|
|
* there's an extra 1 line difference. So we need to add two instead of
|
|
|
|
|
* one to the value.
|
2016-12-15 19:47:34 +02:00
|
|
|
*
|
|
|
|
|
* On VLV/CHV DSI the scanline counter would appear to increment
|
|
|
|
|
* approx. 1/3 of a scanline before start of vblank. Unfortunately
|
|
|
|
|
* that means we can't tell whether we're in vblank or not while
|
|
|
|
|
* we're on that particular line. We must still set scanline_offset
|
|
|
|
|
* to 1 so that the vblank timestamps come out correct when we query
|
|
|
|
|
* the scanline counter from within the vblank interrupt handler.
|
|
|
|
|
* However if queried just before the start of vblank we'll get an
|
|
|
|
|
* answer that's slightly in the future.
|
2014-05-15 20:23:23 +03:00
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2) {
|
2014-05-15 20:23:23 +03:00
|
|
|
int vtotal;
|
|
|
|
|
|
2021-01-22 15:26:46 -08:00
|
|
|
vtotal = adjusted_mode.crtc_vtotal;
|
|
|
|
|
if (adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
2014-05-15 20:23:23 +03:00
|
|
|
vtotal /= 2;
|
|
|
|
|
|
|
|
|
|
crtc->scanline_offset = vtotal - 1;
|
2016-10-13 11:02:52 +01:00
|
|
|
} else if (HAS_DDI(dev_priv) &&
|
2018-10-11 12:04:52 +02:00
|
|
|
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
|
2014-05-15 20:23:23 +03:00
|
|
|
crtc->scanline_offset = 2;
|
2019-10-07 14:49:43 +03:00
|
|
|
} else {
|
2014-05-15 20:23:23 +03:00
|
|
|
crtc->scanline_offset = 1;
|
2019-10-07 14:49:43 +03:00
|
|
|
}
|
2014-05-15 20:23:23 +03:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 22:31:22 +03:00
|
|
|
static void intel_modeset_clear_plls(struct intel_atomic_state *state)
|
2015-01-29 16:55:08 +02:00
|
|
|
{
|
2019-06-28 17:36:28 +03:00
|
|
|
struct intel_crtc_state *new_crtc_state;
|
2019-05-17 22:31:22 +03:00
|
|
|
struct intel_crtc *crtc;
|
2015-04-21 17:13:04 +03:00
|
|
|
int i;
|
2015-01-29 16:55:08 +02:00
|
|
|
|
2019-06-28 17:36:28 +03:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state))
|
2015-04-02 14:47:57 +03:00
|
|
|
continue;
|
|
|
|
|
|
2019-06-28 17:36:28 +03:00
|
|
|
intel_release_shared_dplls(state, crtc);
|
2015-06-15 12:33:42 +02:00
|
|
|
}
|
2015-01-29 16:55:08 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-01 12:50:09 +02:00
|
|
|
/*
|
|
|
|
|
* This implements the workaround described in the "notes" section of the mode
|
|
|
|
|
* set sequence documentation. When going from no pipes or single pipe to
|
|
|
|
|
* multiple pipes, and planes are enabled after the pipe, we need to wait at
|
|
|
|
|
* least 2 vblanks on the first pipe before enabling planes on the second pipe.
|
|
|
|
|
*/
|
2019-12-24 00:40:05 -08:00
|
|
|
static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state)
|
2015-06-01 12:50:09 +02:00
|
|
|
{
|
2019-05-17 22:31:23 +03:00
|
|
|
struct intel_crtc_state *crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
2015-06-01 12:50:09 +02:00
|
|
|
struct intel_crtc_state *first_crtc_state = NULL;
|
|
|
|
|
struct intel_crtc_state *other_crtc_state = NULL;
|
|
|
|
|
enum pipe first_pipe = INVALID_PIPE, enabled_pipe = INVALID_PIPE;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* look at all crtc's that are going to be enabled in during modeset */
|
2019-05-17 22:31:23 +03:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
2019-10-31 12:26:02 +01:00
|
|
|
if (!crtc_state->hw.active ||
|
2020-12-21 11:04:45 +02:00
|
|
|
!intel_crtc_needs_modeset(crtc_state))
|
2015-06-01 12:50:09 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (first_crtc_state) {
|
2019-05-17 22:31:23 +03:00
|
|
|
other_crtc_state = crtc_state;
|
2015-06-01 12:50:09 +02:00
|
|
|
break;
|
|
|
|
|
} else {
|
2019-05-17 22:31:23 +03:00
|
|
|
first_crtc_state = crtc_state;
|
|
|
|
|
first_pipe = crtc->pipe;
|
2015-06-01 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* No workaround needed? */
|
|
|
|
|
if (!first_crtc_state)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* w/a possibly needed, check how many crtc's are already enabled. */
|
2019-05-17 22:31:23 +03:00
|
|
|
for_each_intel_crtc(state->base.dev, crtc) {
|
|
|
|
|
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
|
|
|
|
|
if (IS_ERR(crtc_state))
|
|
|
|
|
return PTR_ERR(crtc_state);
|
2015-06-01 12:50:09 +02:00
|
|
|
|
2019-05-17 22:31:23 +03:00
|
|
|
crtc_state->hsw_workaround_pipe = INVALID_PIPE;
|
2015-06-01 12:50:09 +02:00
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (!crtc_state->hw.active ||
|
2020-12-21 11:04:45 +02:00
|
|
|
intel_crtc_needs_modeset(crtc_state))
|
2015-06-01 12:50:09 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* 2 or more enabled crtcs means no need for w/a */
|
|
|
|
|
if (enabled_pipe != INVALID_PIPE)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2019-05-17 22:31:23 +03:00
|
|
|
enabled_pipe = crtc->pipe;
|
2015-06-01 12:50:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (enabled_pipe != INVALID_PIPE)
|
|
|
|
|
first_crtc_state->hsw_workaround_pipe = enabled_pipe;
|
|
|
|
|
else if (other_crtc_state)
|
|
|
|
|
other_crtc_state->hsw_workaround_pipe = first_pipe;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-20 19:47:26 +02:00
|
|
|
u8 intel_calc_active_pipes(struct intel_atomic_state *state,
|
|
|
|
|
u8 active_pipes)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_crtc_state *crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
|
|
|
|
if (crtc_state->hw.active)
|
|
|
|
|
active_pipes |= BIT(crtc->pipe);
|
|
|
|
|
else
|
|
|
|
|
active_pipes &= ~BIT(crtc->pipe);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return active_pipes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 22:31:26 +03:00
|
|
|
static int intel_modeset_checks(struct intel_atomic_state *state)
|
2015-04-21 17:13:06 +03:00
|
|
|
{
|
2019-05-17 22:31:26 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2015-04-21 17:13:06 +03:00
|
|
|
|
2019-05-17 22:31:26 +03:00
|
|
|
state->modeset = true;
|
2019-10-15 22:30:24 +03:00
|
|
|
|
2015-12-10 12:33:57 +01:00
|
|
|
if (IS_HASWELL(dev_priv))
|
2019-12-24 00:40:05 -08:00
|
|
|
return hsw_mode_set_planes_workaround(state);
|
2015-06-01 12:50:09 +02:00
|
|
|
|
2015-06-15 12:33:42 +02:00
|
|
|
return 0;
|
2015-06-01 12:50:02 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-12 16:07:59 +03:00
|
|
|
static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state,
|
2019-06-12 20:24:23 +03:00
|
|
|
struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
2019-06-12 16:07:59 +03:00
|
|
|
if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
|
2019-06-12 20:24:23 +03:00
|
|
|
return;
|
|
|
|
|
|
2019-10-31 12:26:03 +01:00
|
|
|
new_crtc_state->uapi.mode_changed = false;
|
2019-06-12 20:24:23 +03:00
|
|
|
new_crtc_state->update_pipe = true;
|
2019-12-22 17:06:52 -08:00
|
|
|
}
|
2019-06-12 20:24:23 +03:00
|
|
|
|
2019-12-22 17:06:52 -08:00
|
|
|
static void intel_crtc_copy_fastset(const struct intel_crtc_state *old_crtc_state,
|
|
|
|
|
struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
2019-06-12 20:24:23 +03:00
|
|
|
/*
|
|
|
|
|
* If we're not doing the full modeset we want to
|
|
|
|
|
* keep the current M/N values as they may be
|
|
|
|
|
* sufficiently different to the computed values
|
|
|
|
|
* to cause problems.
|
|
|
|
|
*
|
|
|
|
|
* FIXME: should really copy more fuzzy state here
|
|
|
|
|
*/
|
|
|
|
|
new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n;
|
|
|
|
|
new_crtc_state->dp_m_n = old_crtc_state->dp_m_n;
|
|
|
|
|
new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2;
|
|
|
|
|
new_crtc_state->has_drrs = old_crtc_state->has_drrs;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-15 22:30:26 +03:00
|
|
|
static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc,
|
|
|
|
|
u8 plane_ids_mask)
|
2019-07-08 15:53:14 +03:00
|
|
|
{
|
2019-10-15 22:30:26 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
|
|
|
|
|
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
|
|
|
|
|
struct intel_plane_state *plane_state;
|
|
|
|
|
|
|
|
|
|
if ((plane_ids_mask & BIT(plane->id)) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
plane_state = intel_atomic_get_plane_state(state, plane);
|
|
|
|
|
if (IS_ERR(plane_state))
|
|
|
|
|
return PTR_ERR(plane_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-24 22:11:54 +02:00
|
|
|
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
|
|
|
|
|
return intel_crtc_add_planes_to_state(state, crtc,
|
|
|
|
|
old_crtc_state->enabled_planes |
|
|
|
|
|
new_crtc_state->enabled_planes);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-15 22:30:26 +03:00
|
|
|
static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
|
|
|
|
/* See {hsw,vlv,ivb}_plane_ratio() */
|
|
|
|
|
return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) ||
|
|
|
|
|
IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
|
2021-03-25 02:44:15 +02:00
|
|
|
IS_IVYBRIDGE(dev_priv);
|
2019-10-15 22:30:26 +03:00
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:11 -08:00
|
|
|
static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc *other)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_plane_state *plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
u8 plane_ids = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
|
|
|
|
if (plane->pipe == crtc->pipe)
|
|
|
|
|
plane_ids |= BIT(plane->id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return intel_crtc_add_planes_to_state(state, other, plane_ids);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
|
|
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2020-11-17 11:47:11 -08:00
|
|
|
const struct intel_crtc_state *crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc *other;
|
2020-11-17 11:47:11 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
|
|
|
|
|
crtc_state->bigjoiner_pipes) {
|
|
|
|
|
int ret;
|
2020-11-17 11:47:11 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
if (crtc == other)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ret = intel_crtc_add_bigjoiner_planes(state, crtc, other);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2020-11-17 11:47:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-19 16:11:12 +03:00
|
|
|
static int intel_atomic_check_planes(struct intel_atomic_state *state)
|
2019-10-15 22:30:26 +03:00
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
2019-07-08 15:53:14 +03:00
|
|
|
struct intel_plane_state *plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
2019-10-15 22:30:26 +03:00
|
|
|
struct intel_crtc *crtc;
|
2019-07-08 15:53:14 +03:00
|
|
|
int i, ret;
|
|
|
|
|
|
2019-10-15 22:30:26 +03:00
|
|
|
ret = icl_add_linked_planes(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2020-11-17 11:47:11 -08:00
|
|
|
ret = intel_bigjoiner_add_affected_planes(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2019-07-08 15:53:14 +03:00
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
|
|
|
|
ret = intel_plane_atomic_check(state, plane);
|
|
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_atomic(&dev_priv->drm,
|
|
|
|
|
"[PLANE:%d:%s] atomic driver check failed\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2019-07-08 15:53:14 +03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-15 22:30:26 +03:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
|
|
|
|
u8 old_active_planes, new_active_planes;
|
|
|
|
|
|
|
|
|
|
ret = icl_check_nv12_planes(new_crtc_state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* On some platforms the number of active planes affects
|
|
|
|
|
* the planes' minimum cdclk calculation. Add such planes
|
|
|
|
|
* to the state before we compute the minimum cdclk.
|
|
|
|
|
*/
|
|
|
|
|
if (!active_planes_affects_min_cdclk(dev_priv))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
|
|
|
|
new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
|
|
|
|
|
2021-03-25 02:44:15 +02:00
|
|
|
if (hweight8(old_active_planes) == hweight8(new_active_planes))
|
2019-10-15 22:30:26 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-19 16:11:12 +03:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 15:53:14 +03:00
|
|
|
static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc_state *crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
2020-01-22 00:46:41 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2020-09-25 15:17:49 +03:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = intel_crtc_atomic_check(state, crtc);
|
2019-07-08 15:53:14 +03:00
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_atomic(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] atomic driver check failed\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
2019-07-08 15:53:14 +03:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-15 21:08:09 +02:00
|
|
|
static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
|
|
|
|
|
u8 transcoders)
|
2019-12-22 17:06:53 -08:00
|
|
|
{
|
2020-01-15 21:08:09 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state;
|
2019-12-22 17:06:53 -08:00
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
2020-01-15 21:08:09 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
|
|
|
|
if (new_crtc_state->hw.enable &&
|
|
|
|
|
transcoders & BIT(new_crtc_state->cpu_transcoder) &&
|
2020-12-21 11:04:45 +02:00
|
|
|
intel_crtc_needs_modeset(new_crtc_state))
|
2020-01-15 21:08:09 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2019-12-22 17:06:53 -08:00
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
|
|
|
|
|
u8 pipes)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
|
|
|
|
if (new_crtc_state->hw.enable &&
|
|
|
|
|
pipes & BIT(crtc->pipe) &&
|
|
|
|
|
intel_crtc_needs_modeset(new_crtc_state))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:06 -08:00
|
|
|
static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
|
2022-02-03 20:38:16 +02:00
|
|
|
struct intel_crtc *master_crtc)
|
2020-11-17 11:47:06 -08:00
|
|
|
{
|
2022-01-24 21:26:36 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2022-02-03 20:38:16 +02:00
|
|
|
struct intel_crtc_state *master_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, master_crtc);
|
|
|
|
|
struct intel_crtc *slave_crtc;
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
if (!master_crtc_state->bigjoiner_pipes)
|
2020-11-17 11:47:06 -08:00
|
|
|
return 0;
|
|
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
/* sanity check */
|
|
|
|
|
if (drm_WARN_ON(&i915->drm,
|
|
|
|
|
master_crtc->pipe != bigjoiner_master_pipe(master_crtc_state)))
|
|
|
|
|
return -EINVAL;
|
2022-02-03 20:38:23 +02:00
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
if (master_crtc_state->bigjoiner_pipes & ~bigjoiner_pipes(i915)) {
|
2022-01-24 21:26:36 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-03 20:38:23 +02:00
|
|
|
"[CRTC:%d:%s] Cannot act as big joiner master "
|
2022-02-23 15:13:13 +02:00
|
|
|
"(need 0x%x as pipes, only 0x%x possible)\n",
|
2022-02-03 20:38:23 +02:00
|
|
|
master_crtc->base.base.id, master_crtc->base.name,
|
2022-02-23 15:13:13 +02:00
|
|
|
master_crtc_state->bigjoiner_pipes, bigjoiner_pipes(i915));
|
2020-11-17 11:47:06 -08:00
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
|
|
|
|
|
intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc_state *slave_crtc_state;
|
|
|
|
|
int ret;
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc);
|
|
|
|
|
if (IS_ERR(slave_crtc_state))
|
|
|
|
|
return PTR_ERR(slave_crtc_state);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
/* master being enabled, slave was already configured? */
|
|
|
|
|
if (slave_crtc_state->uapi.enable) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
|
|
|
|
|
"[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
|
|
|
|
|
slave_crtc->base.base.id, slave_crtc->base.name,
|
|
|
|
|
master_crtc->base.base.id, master_crtc->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
/*
|
|
|
|
|
* The state copy logic assumes the master crtc gets processed
|
|
|
|
|
* before the slave crtc during the main compute_config loop.
|
|
|
|
|
* This works because the crtcs are created in pipe order,
|
|
|
|
|
* and the hardware requires master pipe < slave pipe as well.
|
|
|
|
|
* Should that change we need to rethink the logic.
|
|
|
|
|
*/
|
|
|
|
|
if (WARN_ON(drm_crtc_index(&master_crtc->base) >
|
|
|
|
|
drm_crtc_index(&slave_crtc->base)))
|
|
|
|
|
return -EINVAL;
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] Used as slave for big joiner master [CRTC:%d:%s]\n",
|
|
|
|
|
slave_crtc->base.base.id, slave_crtc->base.name,
|
|
|
|
|
master_crtc->base.base.id, master_crtc->base.name);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
slave_crtc_state->bigjoiner_pipes =
|
2022-02-23 15:13:13 +02:00
|
|
|
master_crtc_state->bigjoiner_pipes;
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
return 0;
|
2020-11-17 11:47:06 -08:00
|
|
|
}
|
|
|
|
|
|
2020-11-24 22:11:56 +02:00
|
|
|
static void kill_bigjoiner_slave(struct intel_atomic_state *state,
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc *master_crtc)
|
2020-11-17 11:47:06 -08:00
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2022-02-04 09:20:49 +02:00
|
|
|
struct intel_crtc_state *master_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, master_crtc);
|
2022-02-03 20:38:23 +02:00
|
|
|
struct intel_crtc *slave_crtc;
|
|
|
|
|
|
|
|
|
|
for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
|
|
|
|
|
intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
|
|
|
|
|
struct intel_crtc_state *slave_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, slave_crtc);
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
slave_crtc_state->bigjoiner_pipes = 0;
|
2022-02-04 09:20:49 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
master_crtc_state->bigjoiner_pipes = 0;
|
2020-11-17 11:47:06 -08:00
|
|
|
}
|
|
|
|
|
|
2020-09-21 16:32:09 +05:30
|
|
|
/**
|
|
|
|
|
* DOC: asynchronous flip implementation
|
|
|
|
|
*
|
|
|
|
|
* Asynchronous page flip is the implementation for the DRM_MODE_PAGE_FLIP_ASYNC
|
|
|
|
|
* flag. Currently async flip is only supported via the drmModePageFlip IOCTL.
|
|
|
|
|
* Correspondingly, support is currently added for primary plane only.
|
|
|
|
|
*
|
|
|
|
|
* Async flip can only change the plane surface address, so anything else
|
2022-02-14 12:55:30 +02:00
|
|
|
* changing is rejected from the intel_async_flip_check_hw() function.
|
2020-09-21 16:32:09 +05:30
|
|
|
* Once this check is cleared, flip done interrupt is enabled using
|
2021-01-11 18:37:05 +02:00
|
|
|
* the intel_crtc_enable_flip_done() function.
|
2020-09-21 16:32:09 +05:30
|
|
|
*
|
|
|
|
|
* As soon as the surface address register is written, flip done interrupt is
|
|
|
|
|
* generated and the requested events are sent to the usersapce in the interrupt
|
|
|
|
|
* handler itself. The timestamp and sequence sent during the flip done event
|
|
|
|
|
* correspond to the last vblank and have no relation to the actual time when
|
|
|
|
|
* the flip done event was sent.
|
|
|
|
|
*/
|
2022-02-14 12:55:30 +02:00
|
|
|
static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_plane_state *old_plane_state;
|
|
|
|
|
struct intel_plane_state *new_plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!new_crtc_state->uapi.async_flip)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (!new_crtc_state->uapi.active) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] not active\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intel_crtc_needs_modeset(new_crtc_state)) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] modeset required\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
|
|
|
|
|
new_plane_state, i) {
|
|
|
|
|
if (plane->pipe != crtc->pipe)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* TODO: Async flip is only supported through the page flip IOCTL
|
|
|
|
|
* as of now. So support currently added for primary plane only.
|
|
|
|
|
* Support for other planes on platforms on which supports
|
|
|
|
|
* this(vlv/chv and icl+) should be added when async flip is
|
|
|
|
|
* enabled in the atomic IOCTL path.
|
|
|
|
|
*/
|
|
|
|
|
if (!plane->async_flip) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] async flip not supported\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] no old or new framebuffer\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct intel_crtc *crtc)
|
2020-09-21 16:32:05 +05:30
|
|
|
{
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
|
|
|
|
const struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
|
|
|
|
const struct intel_plane_state *new_plane_state, *old_plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
int i;
|
|
|
|
|
|
2021-10-29 13:24:32 -07:00
|
|
|
old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
|
2020-09-21 16:32:05 +05:30
|
|
|
|
2022-02-14 12:55:30 +02:00
|
|
|
if (!new_crtc_state->uapi.async_flip)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2022-02-14 12:55:32 +02:00
|
|
|
if (!new_crtc_state->hw.active) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] not active\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
2021-10-29 13:24:32 -07:00
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-14 12:55:32 +02:00
|
|
|
if (intel_crtc_needs_modeset(new_crtc_state)) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[CRTC:%d:%s] modeset required\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
2021-10-29 13:24:32 -07:00
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
2022-02-14 12:55:32 +02:00
|
|
|
|
2021-10-29 13:24:32 -07:00
|
|
|
if (old_crtc_state->active_planes != new_crtc_state->active_planes) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[CRTC:%d:%s] Active planes cannot be in async flip\n",
|
|
|
|
|
crtc->base.base.id, crtc->base.name);
|
2021-10-29 13:24:32 -07:00
|
|
|
return -EINVAL;
|
2020-09-21 16:32:05 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
|
|
|
|
|
new_plane_state, i) {
|
2021-10-29 13:24:32 -07:00
|
|
|
if (plane->pipe != crtc->pipe)
|
|
|
|
|
continue;
|
|
|
|
|
|
2020-09-21 16:32:05 +05:30
|
|
|
/*
|
2022-02-14 12:55:31 +02:00
|
|
|
* Only async flip capable planes should be in the state
|
|
|
|
|
* if we're really about to ask the hardware to perform
|
|
|
|
|
* an async flip. We should never get this far otherwise.
|
2020-09-21 16:32:05 +05:30
|
|
|
*/
|
2022-02-14 12:55:31 +02:00
|
|
|
if (drm_WARN_ON(&i915->drm,
|
|
|
|
|
new_crtc_state->do_async_flip && !plane->async_flip))
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
|
2022-02-14 12:55:31 +02:00
|
|
|
/*
|
|
|
|
|
* Only check async flip capable planes other planes
|
|
|
|
|
* may be involved in the initial commit due to
|
|
|
|
|
* the wm0/ddb optimization.
|
|
|
|
|
*
|
|
|
|
|
* TODO maybe should track which planes actually
|
|
|
|
|
* were requested to do the async flip...
|
|
|
|
|
*/
|
|
|
|
|
if (!plane->async_flip)
|
|
|
|
|
continue;
|
|
|
|
|
|
2020-09-21 16:32:05 +05:30
|
|
|
/*
|
|
|
|
|
* FIXME: This check is kept generic for all platforms.
|
2021-07-28 14:59:42 -07:00
|
|
|
* Need to verify this for all gen9 platforms to enable
|
2020-09-21 16:32:05 +05:30
|
|
|
* this selectively if required.
|
|
|
|
|
*/
|
|
|
|
|
switch (new_plane_state->hw.fb->modifier) {
|
|
|
|
|
case I915_FORMAT_MOD_X_TILED:
|
|
|
|
|
case I915_FORMAT_MOD_Y_TILED:
|
|
|
|
|
case I915_FORMAT_MOD_Yf_TILED:
|
2022-01-18 13:55:44 +02:00
|
|
|
case I915_FORMAT_MOD_4_TILED:
|
2020-09-21 16:32:05 +05:30
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Modifier does not support async flips\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-18 14:50:22 +03:00
|
|
|
if (new_plane_state->hw.fb->format->num_planes > 1) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Planar formats do not support async flips\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2021-10-18 14:50:22 +03:00
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 01:51:03 +03:00
|
|
|
if (old_plane_state->view.color_plane[0].mapping_stride !=
|
|
|
|
|
new_plane_state->view.color_plane[0].mapping_stride) {
|
2022-02-14 12:55:32 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] Stride cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.fb->modifier !=
|
|
|
|
|
new_plane_state->hw.fb->modifier) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Modifier cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.fb->format !=
|
|
|
|
|
new_plane_state->hw.fb->format) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Pixel format cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.rotation !=
|
|
|
|
|
new_plane_state->hw.rotation) {
|
2022-02-14 12:55:32 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] Rotation cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!drm_rect_equals(&old_plane_state->uapi.src, &new_plane_state->uapi.src) ||
|
|
|
|
|
!drm_rect_equals(&old_plane_state->uapi.dst, &new_plane_state->uapi.dst)) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Size/co-ordinates cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.alpha != new_plane_state->hw.alpha) {
|
2022-02-14 12:55:32 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANES:%d:%s] Alpha value cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.pixel_blend_mode !=
|
|
|
|
|
new_plane_state->hw.pixel_blend_mode) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Pixel blend mode cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.color_encoding != new_plane_state->hw.color_encoding) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
2022-02-14 12:55:32 +02:00
|
|
|
"[PLANE:%d:%s] Color encoding cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (old_plane_state->hw.color_range != new_plane_state->hw.color_range) {
|
2022-02-14 12:55:32 +02:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] Color range cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2020-09-21 16:32:05 +05:30
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
2021-09-24 12:14:48 -07:00
|
|
|
|
|
|
|
|
/* plane decryption is allow to change only in synchronous flips */
|
2022-02-14 12:55:32 +02:00
|
|
|
if (old_plane_state->decrypt != new_plane_state->decrypt) {
|
|
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
|
"[PLANE:%d:%s] Decryption cannot be changed in async flip\n",
|
|
|
|
|
plane->base.base.id, plane->base.name);
|
2021-09-24 12:14:48 -07:00
|
|
|
return -EINVAL;
|
2022-02-14 12:55:32 +02:00
|
|
|
}
|
2020-09-21 16:32:05 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:10 -08:00
|
|
|
static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
|
|
|
|
|
{
|
2022-02-03 20:38:23 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2020-11-24 22:11:55 +02:00
|
|
|
struct intel_crtc_state *crtc_state;
|
2020-11-17 11:47:10 -08:00
|
|
|
struct intel_crtc *crtc;
|
2022-02-03 20:38:23 +02:00
|
|
|
u8 affected_pipes = 0;
|
|
|
|
|
u8 modeset_pipes = 0;
|
2020-11-17 11:47:10 -08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
2022-02-03 20:38:23 +02:00
|
|
|
affected_pipes |= crtc_state->bigjoiner_pipes;
|
|
|
|
|
if (intel_crtc_needs_modeset(crtc_state))
|
|
|
|
|
modeset_pipes |= crtc_state->bigjoiner_pipes;
|
|
|
|
|
}
|
2020-11-17 11:47:10 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) {
|
|
|
|
|
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
|
|
|
|
|
if (IS_ERR(crtc_state))
|
|
|
|
|
return PTR_ERR(crtc_state);
|
|
|
|
|
}
|
2020-11-17 11:47:10 -08:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, modeset_pipes) {
|
|
|
|
|
int ret;
|
2020-11-24 22:11:55 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
|
2020-11-24 22:11:55 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
crtc_state->uapi.mode_changed = true;
|
2020-11-24 22:11:55 +02:00
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
|
2020-11-24 22:11:55 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2022-02-03 20:38:23 +02:00
|
|
|
ret = intel_atomic_add_affected_planes(state, crtc);
|
2020-11-24 22:11:55 +02:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2020-11-17 11:47:10 -08:00
|
|
|
}
|
|
|
|
|
|
2020-11-24 22:11:56 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
|
|
|
|
/* Kill old bigjoiner link, we may re-establish afterwards */
|
2020-12-21 11:04:45 +02:00
|
|
|
if (intel_crtc_needs_modeset(crtc_state) &&
|
2022-02-03 20:38:19 +02:00
|
|
|
intel_crtc_is_bigjoiner_master(crtc_state))
|
2022-02-04 09:20:49 +02:00
|
|
|
kill_bigjoiner_slave(state, crtc);
|
2020-11-24 22:11:56 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:10 -08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 16:30:30 +02:00
|
|
|
/**
|
|
|
|
|
* intel_atomic_check - validate state object
|
|
|
|
|
* @dev: drm device
|
2019-06-12 16:13:11 +01:00
|
|
|
* @_state: state to validate
|
2015-07-13 16:30:30 +02:00
|
|
|
*/
|
|
|
|
|
static int intel_atomic_check(struct drm_device *dev,
|
2019-05-17 22:31:27 +03:00
|
|
|
struct drm_atomic_state *_state)
|
2015-06-01 12:50:02 +02:00
|
|
|
{
|
2016-01-19 11:35:49 -02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2019-05-17 22:31:27 +03:00
|
|
|
struct intel_atomic_state *state = to_intel_atomic_state(_state);
|
|
|
|
|
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
2015-06-01 12:50:02 +02:00
|
|
|
int ret, i;
|
2019-10-15 22:30:24 +03:00
|
|
|
bool any_ms = false;
|
2015-06-01 12:50:02 +02:00
|
|
|
|
2019-05-17 22:31:27 +03:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-04-29 13:39:36 +03:00
|
|
|
if (new_crtc_state->inherited != old_crtc_state->inherited)
|
2019-10-31 12:26:03 +01:00
|
|
|
new_crtc_state->uapi.mode_changed = true;
|
2022-02-03 20:38:14 +02:00
|
|
|
|
|
|
|
|
if (new_crtc_state->uapi.scaling_filter !=
|
|
|
|
|
old_crtc_state->uapi.scaling_filter)
|
|
|
|
|
new_crtc_state->uapi.mode_changed = true;
|
2018-02-21 10:28:08 +01:00
|
|
|
}
|
|
|
|
|
|
2021-01-22 15:26:35 -08:00
|
|
|
intel_vrr_check_modeset(state);
|
|
|
|
|
|
2019-05-17 22:31:27 +03:00
|
|
|
ret = drm_atomic_helper_check_modeset(dev, &state->base);
|
2015-04-21 17:13:06 +03:00
|
|
|
if (ret)
|
2019-05-17 22:31:30 +03:00
|
|
|
goto fail;
|
2015-04-21 17:13:06 +03:00
|
|
|
|
2022-02-14 12:55:30 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
|
|
|
|
ret = intel_async_flip_check_uapi(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-17 11:47:10 -08:00
|
|
|
ret = intel_bigjoiner_add_affected_crtcs(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2019-05-17 22:31:27 +03:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state)) {
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
|
2022-02-04 09:20:49 +02:00
|
|
|
copy_bigjoiner_crtc_state_nomodeset(state, crtc);
|
|
|
|
|
else
|
|
|
|
|
intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
|
2015-06-01 12:50:02 +02:00
|
|
|
continue;
|
2019-10-31 12:26:04 +01:00
|
|
|
}
|
2015-06-01 12:50:02 +02:00
|
|
|
|
2022-02-17 12:32:21 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
|
|
|
|
|
drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable);
|
2020-11-17 11:47:06 -08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-04 09:20:49 +02:00
|
|
|
ret = intel_crtc_prepare_cleared_state(state, crtc);
|
2019-10-31 12:26:04 +01:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2022-02-17 12:32:21 +02:00
|
|
|
if (!new_crtc_state->hw.enable)
|
|
|
|
|
continue;
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
ret = intel_modeset_pipe_config(state, crtc);
|
2019-05-17 22:31:30 +03:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2020-11-17 11:47:06 -08:00
|
|
|
|
2022-02-03 20:38:16 +02:00
|
|
|
ret = intel_atomic_check_bigjoiner(state, crtc);
|
2020-11-17 11:47:06 -08:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2020-02-14 03:41:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state))
|
2020-02-14 03:41:24 -08:00
|
|
|
continue;
|
|
|
|
|
|
2022-05-03 21:22:23 +03:00
|
|
|
ret = intel_modeset_pipe_config_late(state, crtc);
|
2020-02-14 03:41:24 -08:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2015-06-01 12:50:02 +02:00
|
|
|
|
2019-06-12 20:24:23 +03:00
|
|
|
intel_crtc_check_fastset(old_crtc_state, new_crtc_state);
|
2019-12-22 17:06:52 -08:00
|
|
|
}
|
2015-07-15 14:15:52 +02:00
|
|
|
|
2019-12-22 17:06:53 -08:00
|
|
|
/**
|
|
|
|
|
* Check if fastset is allowed by external dependencies like other
|
|
|
|
|
* pipes and transcoders.
|
|
|
|
|
*
|
|
|
|
|
* Right now it only forces a fullmodeset when the MST master
|
|
|
|
|
* transcoder did not changed but the pipe of the master transcoder
|
2020-01-06 06:28:23 -08:00
|
|
|
* needs a fullmodeset so all slaves also needs to do a fullmodeset or
|
|
|
|
|
* in case of port synced crtcs, if one of the synced crtcs
|
|
|
|
|
* needs a full modeset, all other synced crtcs should be
|
|
|
|
|
* forced a full modeset.
|
2019-12-22 17:06:53 -08:00
|
|
|
*/
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!new_crtc_state->hw.enable || intel_crtc_needs_modeset(new_crtc_state))
|
2019-12-22 17:06:53 -08:00
|
|
|
continue;
|
|
|
|
|
|
2020-01-06 06:28:23 -08:00
|
|
|
if (intel_dp_mst_is_slave_trans(new_crtc_state)) {
|
|
|
|
|
enum transcoder master = new_crtc_state->mst_master_transcoder;
|
|
|
|
|
|
2020-01-15 21:08:09 +02:00
|
|
|
if (intel_cpu_transcoders_need_modeset(state, BIT(master))) {
|
2020-01-06 06:28:23 -08:00
|
|
|
new_crtc_state->uapi.mode_changed = true;
|
|
|
|
|
new_crtc_state->update_pipe = false;
|
|
|
|
|
}
|
2020-01-15 21:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_trans_port_sync_mode(new_crtc_state)) {
|
2020-01-22 16:24:14 -08:00
|
|
|
u8 trans = new_crtc_state->sync_mode_slaves_mask;
|
|
|
|
|
|
|
|
|
|
if (new_crtc_state->master_transcoder != INVALID_TRANSCODER)
|
|
|
|
|
trans |= BIT(new_crtc_state->master_transcoder);
|
2020-01-06 06:28:23 -08:00
|
|
|
|
2020-01-15 21:08:09 +02:00
|
|
|
if (intel_cpu_transcoders_need_modeset(state, trans)) {
|
|
|
|
|
new_crtc_state->uapi.mode_changed = true;
|
|
|
|
|
new_crtc_state->update_pipe = false;
|
|
|
|
|
}
|
2019-12-22 17:06:53 -08:00
|
|
|
}
|
2020-11-24 22:11:55 +02:00
|
|
|
|
2022-02-23 15:13:13 +02:00
|
|
|
if (new_crtc_state->bigjoiner_pipes) {
|
2022-02-03 20:38:23 +02:00
|
|
|
if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes)) {
|
2020-11-24 22:11:55 +02:00
|
|
|
new_crtc_state->uapi.mode_changed = true;
|
|
|
|
|
new_crtc_state->update_pipe = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-22 17:06:53 -08:00
|
|
|
}
|
|
|
|
|
|
2019-12-22 17:06:52 -08:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (intel_crtc_needs_modeset(new_crtc_state)) {
|
2015-07-15 14:15:52 +02:00
|
|
|
any_ms = true;
|
2019-12-22 17:06:52 -08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!new_crtc_state->update_pipe)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_crtc_copy_fastset(old_crtc_state, new_crtc_state);
|
2015-06-01 12:50:02 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-15 22:30:25 +03:00
|
|
|
if (any_ms && !check_digital_port_conflicts(state)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"rejecting conflicting digital port configuration\n");
|
2020-08-02 19:15:35 +08:00
|
|
|
ret = -EINVAL;
|
2019-10-15 22:30:25 +03:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 22:31:27 +03:00
|
|
|
ret = drm_dp_mst_atomic_check(&state->base);
|
drm/dp_mst: Start tracking per-port VCPI allocations
There has been a TODO waiting for quite a long time in
drm_dp_mst_topology.c:
/* We cannot rely on port->vcpi.num_slots to update
* topology_state->avail_slots as the port may not exist if the parent
* branch device was unplugged. This should be fixed by tracking
* per-port slot allocation in drm_dp_mst_topology_state instead of
* depending on the caller to tell us how many slots to release.
*/
That's not the only reason we should fix this: forcing the driver to
track the VCPI allocations throughout a state's atomic check is
error prone, because it means that extra care has to be taken with the
order that drm_dp_atomic_find_vcpi_slots() and
drm_dp_atomic_release_vcpi_slots() are called in in order to ensure
idempotency. Currently the only driver actually using these helpers,
i915, doesn't even do this correctly: multiple ->best_encoder() checks
with i915's current implementation would not be idempotent and would
over-allocate VCPI slots, something I learned trying to implement
fallback retraining in MST.
So: simplify this whole mess, and teach drm_dp_atomic_find_vcpi_slots()
and drm_dp_atomic_release_vcpi_slots() to track the VCPI allocations for
each port. This allows us to ensure idempotency without having to rely
on the driver as much. Additionally: the driver doesn't need to do any
kind of VCPI slot tracking anymore if it doesn't need it for it's own
internal state.
Additionally; this adds a new drm_dp_mst_atomic_check() helper which
must be used by atomic drivers to perform validity checks for the new
VCPI allocations incurred by a state.
Also: update the documentation and make it more obvious that these
/must/ be called by /all/ atomic drivers supporting MST.
Changes since v9:
* Add some missing changes that were requested by danvet that I forgot
about after I redid all of the kref stuff:
* Remove unnecessary state changes in intel_dp_mst_atomic_check
* Cleanup atomic check logic for VCPI allocations - all we need to check in
compute_config is whether or not this state disables a CRTC, then free
VCPI based off that
Changes since v8:
* Fix compile errors, whoops!
Changes since v7:
- Don't check for mixed stale/valid VCPI allocations, just rely on
connector registration to stop such erroneous modesets
Changes since v6:
- Keep a kref to all of the ports we have allocations on. This required
a good bit of changing to when we call drm_dp_find_vcpi_slots(),
mainly that we need to ensure that we only redo VCPI allocations on
actual mode or CRTC changes, not crtc_state->active changes.
Additionally, we no longer take the registration of the DRM connector
for each port into account because so long as we have a kref to the
port in the new or previous atomic state, the connector will stay
registered.
- Use the small changes to drm_dp_put_port() to add even more error
checking to make misusage of the helpers more obvious. I added this
after having to chase down various use-after-free conditions that
started popping up from the new helpers so no one else has to
troubleshoot that.
- Move some accidental DRM_DEBUG_KMS() calls to DRM_DEBUG_ATOMIC()
- Update documentation again, note that find/release() should both not be
called on the same port in a single atomic check phase (but multiple
calls to one or the other is OK)
Changes since v4:
- Don't skip the atomic checks for VCPI allocations if no new VCPI
allocations happen in a state. This makes the next change I'm about
to list here a lot easier to implement.
- Don't ignore VCPI allocations on destroyed ports, instead ensure that
when ports are destroyed and still have VCPI allocations in the
topology state, the only state changes allowed are releasing said
ports' VCPI. This prevents a state with a mix of VCPI allocations
from destroyed ports, and allocations from valid ports.
Changes since v3:
- Don't release VCPI allocations in the topology state immediately in
drm_dp_atomic_release_vcpi_slots(), instead mark them as 0 and skip
over them in drm_dp_mst_duplicate_state(). This makes it so
drm_dp_atomic_release_vcpi_slots() is still idempotent while also
throwing warnings if the driver messes up it's book keeping and tries
to release VCPI slots on a port that doesn't have any pre-existing
VCPI allocation - danvet
- Change mst_state/state in some debugging messages to "mst state"
Changes since v2:
- Use kmemdup() for duplicating MST state - danvet
- Move port validation out of duplicate state callback - danvet
- Handle looping through MST topology states in
drm_dp_mst_atomic_check() so the driver doesn't have to do it
- Fix documentation in drm_dp_atomic_find_vcpi_slots()
- Move the atomic check for each individual topology state into it's
own function, reduces indenting
- Don't consider "stale" MST ports when calculating the bandwidth
requirements. This is needed because originally we relied on the
state duplication functions to prune any stale ports from the new
state, which would prevent us from incorrectly considering their
bandwidth requirements alongside legitimate new payloads.
- Add function references in drm_dp_atomic_release_vcpi_slots() - danvet
- Annotate atomic VCPI and atomic check functions with __must_check
- danvet
Changes since v1:
- Don't use the now-removed ->atomic_check() for private objects hook,
just give drivers a function to call themselves
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@redhat.com>
Cc: Jerry Zuo <Jerry.Zuo@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Juston Li <juston.li@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190111005343.17443-19-lyude@redhat.com
2019-01-10 19:53:41 -05:00
|
|
|
if (ret)
|
2019-05-17 22:31:30 +03:00
|
|
|
goto fail;
|
drm/dp_mst: Start tracking per-port VCPI allocations
There has been a TODO waiting for quite a long time in
drm_dp_mst_topology.c:
/* We cannot rely on port->vcpi.num_slots to update
* topology_state->avail_slots as the port may not exist if the parent
* branch device was unplugged. This should be fixed by tracking
* per-port slot allocation in drm_dp_mst_topology_state instead of
* depending on the caller to tell us how many slots to release.
*/
That's not the only reason we should fix this: forcing the driver to
track the VCPI allocations throughout a state's atomic check is
error prone, because it means that extra care has to be taken with the
order that drm_dp_atomic_find_vcpi_slots() and
drm_dp_atomic_release_vcpi_slots() are called in in order to ensure
idempotency. Currently the only driver actually using these helpers,
i915, doesn't even do this correctly: multiple ->best_encoder() checks
with i915's current implementation would not be idempotent and would
over-allocate VCPI slots, something I learned trying to implement
fallback retraining in MST.
So: simplify this whole mess, and teach drm_dp_atomic_find_vcpi_slots()
and drm_dp_atomic_release_vcpi_slots() to track the VCPI allocations for
each port. This allows us to ensure idempotency without having to rely
on the driver as much. Additionally: the driver doesn't need to do any
kind of VCPI slot tracking anymore if it doesn't need it for it's own
internal state.
Additionally; this adds a new drm_dp_mst_atomic_check() helper which
must be used by atomic drivers to perform validity checks for the new
VCPI allocations incurred by a state.
Also: update the documentation and make it more obvious that these
/must/ be called by /all/ atomic drivers supporting MST.
Changes since v9:
* Add some missing changes that were requested by danvet that I forgot
about after I redid all of the kref stuff:
* Remove unnecessary state changes in intel_dp_mst_atomic_check
* Cleanup atomic check logic for VCPI allocations - all we need to check in
compute_config is whether or not this state disables a CRTC, then free
VCPI based off that
Changes since v8:
* Fix compile errors, whoops!
Changes since v7:
- Don't check for mixed stale/valid VCPI allocations, just rely on
connector registration to stop such erroneous modesets
Changes since v6:
- Keep a kref to all of the ports we have allocations on. This required
a good bit of changing to when we call drm_dp_find_vcpi_slots(),
mainly that we need to ensure that we only redo VCPI allocations on
actual mode or CRTC changes, not crtc_state->active changes.
Additionally, we no longer take the registration of the DRM connector
for each port into account because so long as we have a kref to the
port in the new or previous atomic state, the connector will stay
registered.
- Use the small changes to drm_dp_put_port() to add even more error
checking to make misusage of the helpers more obvious. I added this
after having to chase down various use-after-free conditions that
started popping up from the new helpers so no one else has to
troubleshoot that.
- Move some accidental DRM_DEBUG_KMS() calls to DRM_DEBUG_ATOMIC()
- Update documentation again, note that find/release() should both not be
called on the same port in a single atomic check phase (but multiple
calls to one or the other is OK)
Changes since v4:
- Don't skip the atomic checks for VCPI allocations if no new VCPI
allocations happen in a state. This makes the next change I'm about
to list here a lot easier to implement.
- Don't ignore VCPI allocations on destroyed ports, instead ensure that
when ports are destroyed and still have VCPI allocations in the
topology state, the only state changes allowed are releasing said
ports' VCPI. This prevents a state with a mix of VCPI allocations
from destroyed ports, and allocations from valid ports.
Changes since v3:
- Don't release VCPI allocations in the topology state immediately in
drm_dp_atomic_release_vcpi_slots(), instead mark them as 0 and skip
over them in drm_dp_mst_duplicate_state(). This makes it so
drm_dp_atomic_release_vcpi_slots() is still idempotent while also
throwing warnings if the driver messes up it's book keeping and tries
to release VCPI slots on a port that doesn't have any pre-existing
VCPI allocation - danvet
- Change mst_state/state in some debugging messages to "mst state"
Changes since v2:
- Use kmemdup() for duplicating MST state - danvet
- Move port validation out of duplicate state callback - danvet
- Handle looping through MST topology states in
drm_dp_mst_atomic_check() so the driver doesn't have to do it
- Fix documentation in drm_dp_atomic_find_vcpi_slots()
- Move the atomic check for each individual topology state into it's
own function, reduces indenting
- Don't consider "stale" MST ports when calculating the bandwidth
requirements. This is needed because originally we relied on the
state duplication functions to prune any stale ports from the new
state, which would prevent us from incorrectly considering their
bandwidth requirements alongside legitimate new payloads.
- Add function references in drm_dp_atomic_release_vcpi_slots() - danvet
- Annotate atomic VCPI and atomic check functions with __must_check
- danvet
Changes since v1:
- Don't use the now-removed ->atomic_check() for private objects hook,
just give drivers a function to call themselves
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
Cc: David Airlie <airlied@redhat.com>
Cc: Jerry Zuo <Jerry.Zuo@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Juston Li <juston.li@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190111005343.17443-19-lyude@redhat.com
2019-01-10 19:53:41 -05:00
|
|
|
|
2020-05-19 16:11:12 +03:00
|
|
|
ret = intel_atomic_check_planes(state);
|
2019-10-15 22:30:26 +03:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
ret = intel_compute_global_watermarks(state);
|
2019-05-24 18:36:14 +03:00
|
|
|
if (ret)
|
2019-05-17 22:31:30 +03:00
|
|
|
goto fail;
|
2019-05-24 18:36:14 +03:00
|
|
|
|
2019-05-17 22:31:27 +03:00
|
|
|
ret = intel_bw_atomic_check(state);
|
2019-05-24 18:36:14 +03:00
|
|
|
if (ret)
|
2019-05-17 22:31:30 +03:00
|
|
|
goto fail;
|
2019-05-24 18:36:14 +03:00
|
|
|
|
2021-12-09 18:51:22 +02:00
|
|
|
ret = intel_cdclk_atomic_check(state, &any_ms);
|
2020-05-19 16:11:12 +03:00
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2021-05-18 17:06:17 -07:00
|
|
|
if (intel_any_crtc_needs_modeset(state))
|
|
|
|
|
any_ms = true;
|
|
|
|
|
|
2020-05-19 16:11:11 +03:00
|
|
|
if (any_ms) {
|
2020-09-01 18:10:36 +03:00
|
|
|
ret = intel_modeset_checks(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2020-05-19 16:11:11 +03:00
|
|
|
ret = intel_modeset_calc_cdclk(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
intel_modeset_clear_plls(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = intel_atomic_check_crtcs(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2021-11-24 13:36:35 +02:00
|
|
|
ret = intel_fbc_atomic_check(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2019-05-17 22:31:28 +03:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2022-02-14 12:55:30 +02:00
|
|
|
ret = intel_async_flip_check_hw(state, crtc);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2020-09-21 16:32:05 +05:30
|
|
|
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state) &&
|
2019-05-17 22:31:28 +03:00
|
|
|
!new_crtc_state->update_pipe)
|
|
|
|
|
continue;
|
|
|
|
|
|
2022-06-16 12:48:16 +03:00
|
|
|
intel_crtc_state_dump(new_crtc_state, state,
|
|
|
|
|
intel_crtc_needs_modeset(new_crtc_state) ?
|
2022-06-16 12:48:17 +03:00
|
|
|
"modeset" : "fastset");
|
2019-05-17 22:31:28 +03:00
|
|
|
}
|
|
|
|
|
|
2019-05-24 18:36:14 +03:00
|
|
|
return 0;
|
2019-05-17 22:31:30 +03:00
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
if (ret == -EDEADLK)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* FIXME would probably be nice to know which crtc specifically
|
|
|
|
|
* caused the failure, in cases where we can pinpoint it.
|
|
|
|
|
*/
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i)
|
2022-06-16 12:48:17 +03:00
|
|
|
intel_crtc_state_dump(new_crtc_state, state, "failed");
|
2019-05-17 22:31:30 +03:00
|
|
|
|
|
|
|
|
return ret;
|
2015-04-21 17:13:06 +03:00
|
|
|
}
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
|
2015-08-18 13:40:05 +02:00
|
|
|
{
|
2020-05-20 18:37:37 +05:30
|
|
|
struct intel_crtc_state *crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
|
|
ret = drm_atomic_helper_prepare_planes(state->base.dev, &state->base);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
bool mode_changed = intel_crtc_needs_modeset(crtc_state);
|
2020-05-20 18:37:37 +05:30
|
|
|
|
|
|
|
|
if (mode_changed || crtc_state->update_pipe ||
|
|
|
|
|
crtc_state->uapi.color_mgmt_changed) {
|
|
|
|
|
intel_dsb_prepare(crtc_state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2015-08-18 13:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-04 13:34:56 +02:00
|
|
|
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
|
|
|
|
|
struct intel_crtc_state *crtc_state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) != 2 || crtc_state->active_planes)
|
2019-10-04 13:34:56 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
|
|
|
|
|
|
|
|
|
|
if (crtc_state->has_pch_encoder) {
|
|
|
|
|
enum pipe pch_transcoder =
|
|
|
|
|
intel_crtc_pch_transcoder(crtc);
|
|
|
|
|
|
|
|
|
|
intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state)
|
|
|
|
|
{
|
2019-10-31 12:26:03 +01:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
|
2019-10-04 13:34:56 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Update pipe size and adjust fitter if needed: the reason for this is
|
|
|
|
|
* that in compute_mode_changes we check the native mode (not the pfit
|
|
|
|
|
* mode) to see if we can flip rather than do a full mode set. In the
|
|
|
|
|
* fastboot case, we'll flip, but if we don't update the pipesrc and
|
|
|
|
|
* pfit state, we'll end up with a big fb scanned out into the wrong
|
|
|
|
|
* sized surface.
|
|
|
|
|
*/
|
|
|
|
|
intel_set_pipe_src_size(new_crtc_state);
|
|
|
|
|
|
|
|
|
|
/* on skylake this is done by detaching scalers */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9) {
|
2019-10-04 13:34:56 +02:00
|
|
|
if (new_crtc_state->pch_pfit.enabled)
|
2019-12-24 00:40:06 -08:00
|
|
|
skl_pfit_enable(new_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
} else if (HAS_PCH_SPLIT(dev_priv)) {
|
|
|
|
|
if (new_crtc_state->pch_pfit.enabled)
|
2019-12-24 00:40:09 -08:00
|
|
|
ilk_pfit_enable(new_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
else if (old_crtc_state->pch_pfit.enabled)
|
2019-12-24 00:40:09 -08:00
|
|
|
ilk_pfit_disable(old_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-20 19:47:12 +02:00
|
|
|
/*
|
|
|
|
|
* The register is supposedly single buffered so perhaps
|
|
|
|
|
* not 100% correct to do this here. But SKL+ calculate
|
|
|
|
|
* this based on the adjust pixel rate so pfit changes do
|
|
|
|
|
* affect it and so it must be updated for fastsets.
|
|
|
|
|
* HSW/BDW only really need this here for fastboot, after
|
|
|
|
|
* that the value should not change without a full modeset.
|
|
|
|
|
*/
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 ||
|
2020-01-20 19:47:12 +02:00
|
|
|
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
|
|
|
|
hsw_set_linetime_wm(new_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-06 10:38:36 +03:00
|
|
|
static void commit_pipe_pre_planes(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2019-10-04 13:34:56 +02:00
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2020-03-13 18:48:27 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2020-12-21 11:04:45 +02:00
|
|
|
bool modeset = intel_crtc_needs_modeset(new_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* During modesets pipe configuration was programmed as the
|
|
|
|
|
* CRTC was enabled.
|
|
|
|
|
*/
|
|
|
|
|
if (!modeset) {
|
2019-10-31 12:26:03 +01:00
|
|
|
if (new_crtc_state->uapi.color_mgmt_changed ||
|
2019-10-04 13:34:56 +02:00
|
|
|
new_crtc_state->update_pipe)
|
2022-02-24 18:51:02 +02:00
|
|
|
intel_color_commit_arm(new_crtc_state);
|
2019-10-04 13:34:56 +02:00
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
|
2019-10-04 13:34:56 +02:00
|
|
|
bdw_set_pipemisc(new_crtc_state);
|
|
|
|
|
|
|
|
|
|
if (new_crtc_state->update_pipe)
|
|
|
|
|
intel_pipe_fastset(old_crtc_state, new_crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-22 14:52:41 -07:00
|
|
|
intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
|
|
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_atomic_update_watermarks(state, crtc);
|
2019-10-04 13:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-06 10:38:36 +03:00
|
|
|
static void commit_pipe_post_planes(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Disable the scaler(s) after the plane(s) so that we don't
|
|
|
|
|
* get a catastrophic underrun even if the two operations
|
|
|
|
|
* end up happening in two different frames.
|
|
|
|
|
*/
|
|
|
|
|
if (DISPLAY_VER(dev_priv) >= 9 &&
|
|
|
|
|
!intel_crtc_needs_modeset(new_crtc_state))
|
|
|
|
|
skl_detach_scalers(new_crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
static void intel_enable_crtc(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
2016-08-24 07:48:09 +02:00
|
|
|
{
|
2019-10-04 13:34:56 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2020-03-13 18:48:27 +02:00
|
|
|
const struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2016-08-24 07:48:09 +02:00
|
|
|
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state))
|
2020-03-13 18:48:27 +02:00
|
|
|
return;
|
2019-10-07 14:49:43 +03:00
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
intel_crtc_update_active_timings(new_crtc_state);
|
2018-03-08 13:02:02 +01:00
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display->crtc_enable(state, crtc);
|
2020-03-13 18:48:27 +02:00
|
|
|
|
2022-02-03 20:38:19 +02:00
|
|
|
if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
|
2020-11-17 11:47:08 -08:00
|
|
|
return;
|
|
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
/* vblanks work again, re-enable pipe CRC. */
|
|
|
|
|
intel_crtc_enable_pipe_crc(crtc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_update_crtc(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
2022-02-02 13:16:13 +02:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2020-03-13 18:48:27 +02:00
|
|
|
const struct intel_crtc_state *old_crtc_state =
|
|
|
|
|
intel_atomic_get_old_crtc_state(state, crtc);
|
|
|
|
|
struct intel_crtc_state *new_crtc_state =
|
|
|
|
|
intel_atomic_get_new_crtc_state(state, crtc);
|
2020-12-21 11:04:45 +02:00
|
|
|
bool modeset = intel_crtc_needs_modeset(new_crtc_state);
|
2020-03-13 18:48:27 +02:00
|
|
|
|
|
|
|
|
if (!modeset) {
|
2019-10-30 21:08:15 +02:00
|
|
|
if (new_crtc_state->preload_luts &&
|
|
|
|
|
(new_crtc_state->uapi.color_mgmt_changed ||
|
|
|
|
|
new_crtc_state->update_pipe))
|
|
|
|
|
intel_color_load_luts(new_crtc_state);
|
|
|
|
|
|
2019-11-27 21:05:53 +02:00
|
|
|
intel_pre_plane_update(state, crtc);
|
2018-12-20 14:21:18 +01:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (new_crtc_state->update_pipe)
|
2019-11-18 18:44:21 +02:00
|
|
|
intel_encoders_update_pipe(state, crtc);
|
2022-02-02 13:16:13 +02:00
|
|
|
|
|
|
|
|
if (DISPLAY_VER(i915) >= 11 &&
|
|
|
|
|
new_crtc_state->update_pipe)
|
|
|
|
|
icl_set_pipe_chicken(new_crtc_state);
|
2016-08-24 07:48:09 +02:00
|
|
|
}
|
|
|
|
|
|
2021-07-02 23:45:57 +03:00
|
|
|
intel_fbc_update(state, crtc);
|
2016-08-24 07:48:09 +02:00
|
|
|
|
2022-02-24 18:51:02 +02:00
|
|
|
if (!modeset &&
|
|
|
|
|
(new_crtc_state->uapi.color_mgmt_changed ||
|
|
|
|
|
new_crtc_state->update_pipe))
|
|
|
|
|
intel_color_commit_noarm(new_crtc_state);
|
|
|
|
|
|
2022-02-17 01:28:04 +02:00
|
|
|
intel_crtc_planes_update_noarm(state, crtc);
|
2021-10-18 14:50:25 +03:00
|
|
|
|
2019-10-04 13:34:56 +02:00
|
|
|
/* Perform vblank evasion around commit operation */
|
|
|
|
|
intel_pipe_update_start(new_crtc_state);
|
|
|
|
|
|
2021-05-06 10:38:36 +03:00
|
|
|
commit_pipe_pre_planes(state, crtc);
|
2018-09-20 12:27:08 +02:00
|
|
|
|
2022-02-17 01:28:04 +02:00
|
|
|
intel_crtc_planes_update_arm(state, crtc);
|
2018-09-20 12:27:08 +02:00
|
|
|
|
2021-05-06 10:38:36 +03:00
|
|
|
commit_pipe_post_planes(state, crtc);
|
|
|
|
|
|
2019-10-04 13:34:56 +02:00
|
|
|
intel_pipe_update_end(new_crtc_state);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We usually enable FIFO underrun interrupts as part of the
|
|
|
|
|
* CRTC enable sequence during modesets. But when we inherit a
|
|
|
|
|
* valid pipe configuration from the BIOS we need to take care
|
|
|
|
|
* of enabling them on the CRTC's first fastset.
|
|
|
|
|
*/
|
|
|
|
|
if (new_crtc_state->update_pipe && !modeset &&
|
2020-04-29 13:39:36 +03:00
|
|
|
old_crtc_state->inherited)
|
2019-10-04 13:34:56 +02:00
|
|
|
intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
|
2016-08-24 07:48:09 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-28 15:47:01 -07:00
|
|
|
static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
|
|
|
|
|
struct intel_crtc_state *old_crtc_state,
|
|
|
|
|
struct intel_crtc_state *new_crtc_state,
|
|
|
|
|
struct intel_crtc *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We need to disable pipe CRC before disabling the pipe,
|
|
|
|
|
* or we race against vblank off.
|
|
|
|
|
*/
|
|
|
|
|
intel_crtc_disable_pipe_crc(crtc);
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display->crtc_disable(state, crtc);
|
2019-08-28 15:47:01 -07:00
|
|
|
crtc->active = false;
|
|
|
|
|
intel_fbc_disable(crtc);
|
|
|
|
|
intel_disable_shared_dpll(old_crtc_state);
|
|
|
|
|
|
|
|
|
|
/* FIXME unify this for all platforms */
|
2019-10-31 12:26:02 +01:00
|
|
|
if (!new_crtc_state->hw.active &&
|
2021-09-29 01:57:48 +03:00
|
|
|
!HAS_GMCH(dev_priv))
|
|
|
|
|
intel_initial_watermarks(state, crtc);
|
2019-08-28 15:47:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_commit_modeset_disables(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc_state *new_crtc_state, *old_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
2019-12-05 13:03:50 -08:00
|
|
|
u32 handled = 0;
|
2019-08-28 15:47:01 -07:00
|
|
|
int i;
|
|
|
|
|
|
2021-10-22 13:32:58 +03:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
|
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!old_crtc_state->hw.active)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_pre_plane_update(state, crtc);
|
|
|
|
|
intel_crtc_disable_planes(state, crtc);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-22 17:06:49 -08:00
|
|
|
/* Only disable port sync and MST slaves */
|
2019-12-05 13:03:50 -08:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2021-10-22 13:33:03 +03:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state))
|
2019-08-28 15:47:01 -07:00
|
|
|
continue;
|
|
|
|
|
|
2019-12-05 13:03:50 -08:00
|
|
|
if (!old_crtc_state->hw.active)
|
|
|
|
|
continue;
|
|
|
|
|
|
2019-10-18 10:27:25 -07:00
|
|
|
/* In case of Transcoder port Sync master slave CRTCs can be
|
|
|
|
|
* assigned in any order and we need to make sure that
|
|
|
|
|
* slave CRTCs are disabled first and then master CRTC since
|
|
|
|
|
* Slave vblanks are masked till Master Vblanks.
|
|
|
|
|
*/
|
2019-12-22 17:06:49 -08:00
|
|
|
if (!is_trans_port_sync_slave(old_crtc_state) &&
|
2021-10-22 13:33:03 +03:00
|
|
|
!intel_dp_mst_is_slave_trans(old_crtc_state) &&
|
2022-02-03 20:38:19 +02:00
|
|
|
!intel_crtc_is_bigjoiner_slave(old_crtc_state))
|
2019-12-05 13:03:50 -08:00
|
|
|
continue;
|
2019-08-28 15:47:01 -07:00
|
|
|
|
2019-12-05 13:03:50 -08:00
|
|
|
intel_old_crtc_state_disables(state, old_crtc_state,
|
|
|
|
|
new_crtc_state, crtc);
|
|
|
|
|
handled |= BIT(crtc->pipe);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disable everything else left on */
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state) ||
|
2021-10-22 13:33:03 +03:00
|
|
|
(handled & BIT(crtc->pipe)))
|
2019-12-05 13:03:50 -08:00
|
|
|
continue;
|
|
|
|
|
|
2021-10-22 13:33:03 +03:00
|
|
|
if (!old_crtc_state->hw.active)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_old_crtc_state_disables(state, old_crtc_state,
|
|
|
|
|
new_crtc_state, crtc);
|
2019-08-28 15:47:01 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 15:17:34 -07:00
|
|
|
static void intel_commit_modeset_enables(struct intel_atomic_state *state)
|
2016-08-24 07:48:09 +02:00
|
|
|
{
|
2020-03-13 18:48:27 +02:00
|
|
|
struct intel_crtc_state *new_crtc_state;
|
2019-06-28 10:55:13 +02:00
|
|
|
struct intel_crtc *crtc;
|
2016-08-24 07:48:09 +02:00
|
|
|
int i;
|
|
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2019-10-31 12:26:02 +01:00
|
|
|
if (!new_crtc_state->hw.active)
|
2016-08-24 07:48:09 +02:00
|
|
|
continue;
|
|
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
intel_enable_crtc(state, crtc);
|
|
|
|
|
intel_update_crtc(state, crtc);
|
2016-08-24 07:48:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 15:17:34 -07:00
|
|
|
static void skl_commit_modeset_enables(struct intel_atomic_state *state)
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
{
|
2019-06-28 10:55:13 +02:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
2018-11-01 17:05:59 +02:00
|
|
|
struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
|
2019-12-22 17:06:50 -08:00
|
|
|
u8 update_pipes = 0, modeset_pipes = 0;
|
2019-12-10 16:41:02 +02:00
|
|
|
int i;
|
2016-11-08 13:55:35 +01:00
|
|
|
|
2019-12-10 16:41:02 +02:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
2020-01-15 21:08:11 +02:00
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
2019-12-22 17:06:50 -08:00
|
|
|
if (!new_crtc_state->hw.active)
|
|
|
|
|
continue;
|
|
|
|
|
|
2016-11-08 13:55:35 +01:00
|
|
|
/* ignore allocations for crtc's that have been turned off. */
|
2020-12-21 11:04:45 +02:00
|
|
|
if (!intel_crtc_needs_modeset(new_crtc_state)) {
|
2020-01-15 21:08:11 +02:00
|
|
|
entries[pipe] = old_crtc_state->wm.skl.ddb;
|
|
|
|
|
update_pipes |= BIT(pipe);
|
2019-12-22 17:06:50 -08:00
|
|
|
} else {
|
2020-01-15 21:08:11 +02:00
|
|
|
modeset_pipes |= BIT(pipe);
|
2019-12-22 17:06:50 -08:00
|
|
|
}
|
2019-12-10 16:41:02 +02:00
|
|
|
}
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Whenever the number of active pipes changes, we need to make sure we
|
|
|
|
|
* update the pipes in the right order so that their ddb allocations
|
2019-12-22 17:06:50 -08:00
|
|
|
* never overlap with each other between CRTC updates. Otherwise we'll
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
* cause pipe underruns and other bad stuff.
|
2019-12-22 17:06:50 -08:00
|
|
|
*
|
|
|
|
|
* So first lets enable all pipes that do not need a fullmodeset as
|
|
|
|
|
* those don't have any external dependency.
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
*/
|
2019-12-22 17:06:50 -08:00
|
|
|
while (update_pipes) {
|
2019-12-10 16:41:02 +02:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2019-10-11 23:09:44 +03:00
|
|
|
enum pipe pipe = crtc->pipe;
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
|
2019-12-22 17:06:50 -08:00
|
|
|
if ((update_pipes & BIT(pipe)) == 0)
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
continue;
|
2016-11-08 13:55:35 +01:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
|
2020-02-24 18:10:04 +05:30
|
|
|
entries, I915_MAX_PIPES, pipe))
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
continue;
|
|
|
|
|
|
2020-01-15 21:08:11 +02:00
|
|
|
entries[pipe] = new_crtc_state->wm.skl.ddb;
|
2019-12-22 17:06:50 -08:00
|
|
|
update_pipes &= ~BIT(pipe);
|
|
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
intel_update_crtc(state, crtc);
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
|
2019-12-10 16:41:02 +02:00
|
|
|
/*
|
|
|
|
|
* If this is an already active pipe, it's DDB changed,
|
|
|
|
|
* and this isn't the last pipe that needs updating
|
|
|
|
|
* then we need to wait for a vblank to pass for the
|
|
|
|
|
* new ddb allocation to take effect.
|
|
|
|
|
*/
|
|
|
|
|
if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
|
|
|
|
|
&old_crtc_state->wm.skl.ddb) &&
|
2019-12-22 17:06:50 -08:00
|
|
|
(update_pipes | modeset_pipes))
|
2021-12-01 15:57:03 +02:00
|
|
|
intel_crtc_wait_for_next_vblank(crtc);
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
}
|
2019-12-10 16:41:02 +02:00
|
|
|
}
|
2018-04-26 19:55:16 +05:30
|
|
|
|
2020-03-13 18:48:29 +02:00
|
|
|
update_pipes = modeset_pipes;
|
|
|
|
|
|
2019-12-22 17:06:50 -08:00
|
|
|
/*
|
|
|
|
|
* Enable all pipes that needs a modeset and do not depends on other
|
|
|
|
|
* pipes
|
|
|
|
|
*/
|
2020-03-13 18:48:28 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2019-12-22 17:06:50 -08:00
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
|
|
|
|
if ((modeset_pipes & BIT(pipe)) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
|
2020-11-17 11:47:08 -08:00
|
|
|
is_trans_port_sync_master(new_crtc_state) ||
|
2022-02-03 20:38:19 +02:00
|
|
|
intel_crtc_is_bigjoiner_master(new_crtc_state))
|
2019-12-22 17:06:50 -08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
modeset_pipes &= ~BIT(pipe);
|
|
|
|
|
|
2020-03-13 18:48:31 +02:00
|
|
|
intel_enable_crtc(state, crtc);
|
2019-12-22 17:06:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2020-03-13 18:48:29 +02:00
|
|
|
* Then we enable all remaining pipes that depend on other
|
2020-11-17 11:47:08 -08:00
|
|
|
* pipes: MST slaves and port sync masters, big joiner master
|
2019-12-22 17:06:50 -08:00
|
|
|
*/
|
2020-03-13 18:48:27 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2019-12-22 17:06:50 -08:00
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
|
|
|
|
if ((modeset_pipes & BIT(pipe)) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
2020-03-13 18:48:29 +02:00
|
|
|
modeset_pipes &= ~BIT(pipe);
|
|
|
|
|
|
|
|
|
|
intel_enable_crtc(state, crtc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Finally we do the plane updates/etc. for all pipes that got enabled.
|
|
|
|
|
*/
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
|
|
|
|
enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
|
|
|
|
if ((update_pipes & BIT(pipe)) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
|
2020-02-24 18:10:04 +05:30
|
|
|
entries, I915_MAX_PIPES, pipe));
|
2019-12-22 17:06:50 -08:00
|
|
|
|
2020-01-15 21:08:11 +02:00
|
|
|
entries[pipe] = new_crtc_state->wm.skl.ddb;
|
2020-03-13 18:48:29 +02:00
|
|
|
update_pipes &= ~BIT(pipe);
|
2019-12-22 17:06:50 -08:00
|
|
|
|
2020-03-13 18:48:27 +02:00
|
|
|
intel_update_crtc(state, crtc);
|
2019-12-22 17:06:50 -08:00
|
|
|
}
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm, modeset_pipes);
|
2020-03-13 18:48:29 +02:00
|
|
|
drm_WARN_ON(&dev_priv->drm, update_pipes);
|
drm/i915/skl: Update DDB values atomically with wms/plane attrs
Now that we can hook into update_crtcs and control the order in which we
update CRTCs at each modeset, we can finish the final step of fixing
Skylake's watermark handling by performing DDB updates at the same time
as plane updates and watermark updates.
The first major change in this patch is skl_update_crtcs(), which
handles ensuring that we order each CRTC update in our atomic commits
properly so that they honor the DDB flush order.
The second major change in this patch is the order in which we flush the
pipes. While the previous order may have worked, it can't be used in
this approach since it no longer will do the right thing. For example,
using the old ddb flush order:
We have pipes A, B, and C enabled, and we're disabling C. Initial ddb
allocation looks like this:
| A | B |xxxxxxx|
Since we're performing the ddb updates after performing any CRTC
disablements in intel_atomic_commit_tail(), the space to the right of
pipe B is unallocated.
1. Flush pipes with new allocation contained into old space. None
apply, so we skip this
2. Flush pipes having their allocation reduced, but overlapping with a
previous allocation. None apply, so we also skip this
3. Flush pipes that got more space allocated. This applies to A and B,
giving us the following update order: A, B
This is wrong, since updating pipe A first will cause it to overlap with
B and potentially burst into flames. Our new order (see the code
comments for details) would update the pipes in the proper order: B, A.
As well, we calculate the order for each DDB update during the check
phase, and reference it later in the commit phase when we hit
skl_update_crtcs().
This long overdue patch fixes the rest of the underruns on Skylake.
Changes since v1:
- Add skl_ddb_entry_write() for cursor into skl_write_cursor_wm()
Changes since v2:
- Use the method for updating CRTCs that Ville suggested
- In skl_update_wm(), only copy the watermarks for the crtc that was
passed to us
Changes since v3:
- Small comment fix in skl_ddb_allocation_overlaps()
Changes since v4:
- Remove the second loop in intel_update_crtcs() and use Ville's
suggestion for updating the ddb allocations in the right order
- Get rid of the second loop and just use the ddb state as it updates
to determine what order to update everything in (thanks for the
suggestion Ville)
- Simplify skl_ddb_allocation_overlaps()
- Split actual overlap checking into it's own helper
Fixes: 0e8fb7ba7ca5 ("drm/i915/skl: Flush the WM configuration")
Fixes: 8211bd5bdf5e ("drm/i915/skl: Program the DDB allocation")
[omitting CC for stable, since this patch will need to be changed for
such backports first]
Testcase: kms_cursor_legacy
Testcase: plane-all-modeset-transition
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471961565-28540-2-git-send-email-cpaul@redhat.com
2016-08-24 07:48:10 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-02 20:47:41 +00:00
|
|
|
static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
|
|
|
|
struct intel_atomic_state *state, *next;
|
|
|
|
|
struct llist_node *freed;
|
|
|
|
|
|
|
|
|
|
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
|
|
|
|
|
llist_for_each_entry_safe(state, next, freed, freed)
|
|
|
|
|
drm_atomic_state_put(&state->base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_atomic_helper_free_state_worker(struct work_struct *work)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *dev_priv =
|
|
|
|
|
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
|
|
|
|
|
|
|
|
|
|
intel_atomic_helper_free_state(dev_priv);
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
|
|
|
|
|
{
|
|
|
|
|
struct wait_queue_entry wait_fence, wait_reset;
|
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev);
|
|
|
|
|
|
|
|
|
|
init_wait_entry(&wait_fence, 0);
|
|
|
|
|
init_wait_entry(&wait_reset, 0);
|
|
|
|
|
for (;;) {
|
|
|
|
|
prepare_to_wait(&intel_state->commit_ready.wait,
|
|
|
|
|
&wait_fence, TASK_UNINTERRUPTIBLE);
|
2021-12-14 21:33:33 +02:00
|
|
|
prepare_to_wait(bit_waitqueue(&to_gt(dev_priv)->reset.flags,
|
2019-07-12 20:29:53 +01:00
|
|
|
I915_RESET_MODESET),
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
&wait_reset, TASK_UNINTERRUPTIBLE);
|
|
|
|
|
|
|
|
|
|
|
2019-07-12 20:29:53 +01:00
|
|
|
if (i915_sw_fence_done(&intel_state->commit_ready) ||
|
2021-12-14 21:33:33 +02:00
|
|
|
test_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags))
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
schedule();
|
|
|
|
|
}
|
|
|
|
|
finish_wait(&intel_state->commit_ready.wait, &wait_fence);
|
2021-12-14 21:33:33 +02:00
|
|
|
finish_wait(bit_waitqueue(&to_gt(dev_priv)->reset.flags,
|
2019-07-12 20:29:53 +01:00
|
|
|
I915_RESET_MODESET),
|
|
|
|
|
&wait_reset);
|
drm/i915: More surgically unbreak the modeset vs reset deadlock
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest way to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
The lesser source of deadlocks is when we try to pin a new framebuffer
and run into a stall. There's a bunch of places this can happen, like
eviction, changing the caching mode, acquiring a fence on older
platforms. And we can't just break the depency loop and keep going,
the only way would be to break out and restart. But the problem with
that approach is that we must stall for the reset to complete before
we grab any locks, and with the atomic infrastructure that's a bit
tricky. The only place is the ioctl code, and we don't want to insert
code into e.g. the BUSY ioctl. Hence for that problem just create a
critical section, and if any code is in there, wedge the GPU. For the
steady-state this should never be a problem.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
v2: Rebase onto 4.13 with a s/wait_queue_t/struct wait_queue_entry/.
v3: Really emabarrassing fixup, I checked the wrong bit and broke the
unbreak/wakeup logic.
v4: Also handle deadlocks in pin_to_display.
v5: Review from Michel:
- Fixup the BUILD_BUG_ON
- Don't forget about the overlay
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v2)
Cc: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170808080828.23650-3-daniel.vetter@ffwll.ch
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
2017-08-08 10:08:28 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-20 18:37:37 +05:30
|
|
|
static void intel_cleanup_dsbs(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i)
|
|
|
|
|
intel_dsb_cleanup(old_crtc_state);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-23 11:39:51 +01:00
|
|
|
static void intel_atomic_cleanup_work(struct work_struct *work)
|
|
|
|
|
{
|
2020-05-20 18:37:37 +05:30
|
|
|
struct intel_atomic_state *state =
|
|
|
|
|
container_of(work, struct intel_atomic_state, base.commit_work);
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
2018-06-23 11:39:51 +01:00
|
|
|
|
2020-05-20 18:37:37 +05:30
|
|
|
intel_cleanup_dsbs(state);
|
|
|
|
|
drm_atomic_helper_cleanup_planes(&i915->drm, &state->base);
|
|
|
|
|
drm_atomic_helper_commit_cleanup_done(&state->base);
|
|
|
|
|
drm_atomic_state_put(&state->base);
|
2018-06-23 11:39:51 +01:00
|
|
|
|
|
|
|
|
intel_atomic_helper_free_state(i915);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-15 23:39:52 +02:00
|
|
|
static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
struct intel_plane_state *plane_state;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
|
|
|
|
struct drm_framebuffer *fb = plane_state->hw.fb;
|
2021-10-20 22:51:34 +03:00
|
|
|
int cc_plane;
|
2021-01-15 23:39:52 +02:00
|
|
|
int ret;
|
|
|
|
|
|
2021-10-20 22:51:34 +03:00
|
|
|
if (!fb)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
cc_plane = intel_fb_rc_ccs_cc_plane(fb);
|
|
|
|
|
if (cc_plane < 0)
|
2021-01-15 23:39:52 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The layout of the fast clear color value expected by HW
|
2022-04-11 17:34:05 +03:00
|
|
|
* (the DRM ABI requiring this value to be located in fb at
|
|
|
|
|
* offset 0 of cc plane, plane #2 previous generations or
|
|
|
|
|
* plane #1 for flat ccs):
|
2021-01-15 23:39:52 +02:00
|
|
|
* - 4 x 4 bytes per-channel value
|
|
|
|
|
* (in surface type specific float/int format provided by the fb user)
|
|
|
|
|
* - 8 bytes native color value used by the display
|
|
|
|
|
* (converted/written by GPU during a fast clear operation using the
|
|
|
|
|
* above per-channel values)
|
|
|
|
|
*
|
|
|
|
|
* The commit's FB prepare hook already ensured that FB obj is pinned and the
|
|
|
|
|
* caller made sure that the object is synced wrt. the related color clear value
|
|
|
|
|
* GPU write on it.
|
|
|
|
|
*/
|
|
|
|
|
ret = i915_gem_object_read_from_page(intel_fb_obj(fb),
|
2021-10-20 22:51:34 +03:00
|
|
|
fb->offsets[cc_plane] + 16,
|
2021-01-15 23:39:52 +02:00
|
|
|
&plane_state->ccval,
|
|
|
|
|
sizeof(plane_state->ccval));
|
|
|
|
|
/* The above could only fail if the FB obj has an unexpected backing store type. */
|
|
|
|
|
drm_WARN_ON(&i915->drm, ret);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
2012-07-02 09:56:42 +02:00
|
|
|
{
|
2019-06-28 10:55:13 +02:00
|
|
|
struct drm_device *dev = state->base.dev;
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2019-06-28 10:55:13 +02:00
|
|
|
struct intel_crtc_state *new_crtc_state, *old_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
2022-04-15 00:06:48 +03:00
|
|
|
struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_wakeref_t wakeref = 0;
|
2016-10-28 13:58:27 +01:00
|
|
|
int i;
|
2012-07-02 09:56:42 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
intel_atomic_commit_fence_wait(state);
|
2017-08-08 10:08:27 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
drm_atomic_helper_wait_for_dependencies(&state->base);
|
2016-06-13 16:13:46 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (state->modeset)
|
2019-01-14 14:21:24 +00:00
|
|
|
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
|
2015-12-10 12:33:57 +01:00
|
|
|
|
2021-01-15 23:39:52 +02:00
|
|
|
intel_atomic_prepare_plane_clear_colors(state);
|
|
|
|
|
|
2019-08-30 12:16:44 +02:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
if (intel_crtc_needs_modeset(new_crtc_state) ||
|
2019-06-28 10:55:13 +02:00
|
|
|
new_crtc_state->update_pipe) {
|
2022-06-17 12:48:16 +03:00
|
|
|
intel_modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
|
2016-05-24 17:13:53 +02:00
|
|
|
}
|
2013-03-27 00:44:50 +01:00
|
|
|
}
|
2012-07-08 19:40:39 +02:00
|
|
|
|
2019-08-28 15:47:01 -07:00
|
|
|
intel_commit_modeset_disables(state);
|
|
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
/* FIXME: Eventually get rid of our crtc->config pointer */
|
|
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
|
|
|
|
|
crtc->config = new_crtc_state;
|
2011-04-12 18:06:51 +01:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (state->modeset) {
|
|
|
|
|
drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);
|
2016-02-10 13:49:37 +01:00
|
|
|
|
2020-01-20 19:47:18 +02:00
|
|
|
intel_set_cdclk_pre_plane_update(state);
|
2016-03-23 14:58:07 +01:00
|
|
|
|
2019-06-28 10:55:14 +02:00
|
|
|
intel_modeset_verify_disabled(dev_priv, state);
|
2015-08-05 12:37:10 +02:00
|
|
|
}
|
2012-10-26 10:58:18 +02:00
|
|
|
|
2020-04-30 22:56:34 +03:00
|
|
|
intel_sagv_pre_plane_update(state);
|
|
|
|
|
|
2016-08-24 07:48:09 +02:00
|
|
|
/* Complete the events for pipes that have now been disabled */
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2020-12-21 11:04:45 +02:00
|
|
|
bool modeset = intel_crtc_needs_modeset(new_crtc_state);
|
2014-05-15 20:23:23 +03:00
|
|
|
|
2016-06-13 16:13:45 +02:00
|
|
|
/* Complete events for now disable pipes here. */
|
2019-10-31 12:26:03 +01:00
|
|
|
if (modeset && !new_crtc_state->hw.active && new_crtc_state->uapi.event) {
|
2016-06-13 16:13:45 +02:00
|
|
|
spin_lock_irq(&dev->event_lock);
|
2019-10-31 12:26:03 +01:00
|
|
|
drm_crtc_send_vblank_event(&crtc->base,
|
|
|
|
|
new_crtc_state->uapi.event);
|
2016-06-13 16:13:45 +02:00
|
|
|
spin_unlock_irq(&dev->event_lock);
|
|
|
|
|
|
2019-10-31 12:26:03 +01:00
|
|
|
new_crtc_state->uapi.event = NULL;
|
2016-06-13 16:13:45 +02:00
|
|
|
}
|
2016-03-04 15:59:39 -08:00
|
|
|
}
|
|
|
|
|
|
2021-11-15 20:11:21 +02:00
|
|
|
intel_encoders_update_prepare(state);
|
2019-06-28 17:36:32 +03:00
|
|
|
|
2020-02-25 19:11:15 +02:00
|
|
|
intel_dbuf_pre_plane_update(state);
|
2022-03-30 08:57:24 -07:00
|
|
|
intel_mbus_dbox_update(state);
|
2020-02-03 01:06:26 +02:00
|
|
|
|
2020-09-21 16:32:03 +05:30
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2022-02-14 12:55:31 +02:00
|
|
|
if (new_crtc_state->do_async_flip)
|
2021-01-11 18:37:05 +02:00
|
|
|
intel_crtc_enable_flip_done(state, crtc);
|
2020-09-21 16:32:03 +05:30
|
|
|
}
|
|
|
|
|
|
2016-08-24 07:48:09 +02:00
|
|
|
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display->commit_modeset_enables(state);
|
2016-08-24 07:48:09 +02:00
|
|
|
|
2021-11-15 20:11:21 +02:00
|
|
|
intel_encoders_update_complete(state);
|
2019-06-28 17:36:32 +03:00
|
|
|
|
2021-11-15 20:11:21 +02:00
|
|
|
if (state->modeset)
|
2020-01-20 19:47:18 +02:00
|
|
|
intel_set_cdclk_post_plane_update(state);
|
2019-03-27 12:13:21 +02:00
|
|
|
|
2021-10-21 01:33:38 +03:00
|
|
|
intel_wait_for_vblank_workers(state);
|
|
|
|
|
|
2016-06-14 18:01:00 +02:00
|
|
|
/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
|
|
|
|
|
* already, but still need the state for the delayed optimization. To
|
|
|
|
|
* fix this:
|
|
|
|
|
* - wrap the optimization/post_plane_update stuff into a per-crtc work.
|
|
|
|
|
* - schedule that vblank worker _before_ calling hw_done
|
|
|
|
|
* - at the start of commit_tail, cancel it _synchrously
|
|
|
|
|
* - switch over to the vblank wait helper in the core after that since
|
|
|
|
|
* we don't need out special handling any more.
|
|
|
|
|
*/
|
2019-06-28 10:55:13 +02:00
|
|
|
drm_atomic_helper_wait_for_flip_done(dev, &state->base);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
2022-02-14 12:55:31 +02:00
|
|
|
if (new_crtc_state->do_async_flip)
|
2021-01-11 18:37:05 +02:00
|
|
|
intel_crtc_disable_flip_done(state, crtc);
|
2019-02-05 18:08:41 +02:00
|
|
|
}
|
|
|
|
|
|
2016-05-24 17:13:53 +02:00
|
|
|
/*
|
|
|
|
|
* Now that the vblank has passed, we can go ahead and program the
|
|
|
|
|
* optimal watermarks on platforms that need two-step watermark
|
|
|
|
|
* programming.
|
|
|
|
|
*
|
|
|
|
|
* TODO: Move this (and other cleanup) to an async worker eventually.
|
|
|
|
|
*/
|
2019-11-27 21:05:54 +02:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
|
new_crtc_state, i) {
|
|
|
|
|
/*
|
|
|
|
|
* Gen2 reports pipe underruns whenever all planes are disabled.
|
|
|
|
|
* So re-enable underrun reporting after some planes get enabled.
|
|
|
|
|
*
|
|
|
|
|
* We do this before .optimize_watermarks() so that we have a
|
|
|
|
|
* chance of catching underruns with the intermediate watermarks
|
|
|
|
|
* vs. the new plane configuration.
|
|
|
|
|
*/
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) == 2 && planes_enabling(old_crtc_state, new_crtc_state))
|
2019-11-27 21:05:54 +02:00
|
|
|
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
|
|
|
|
|
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_optimize_watermarks(state, crtc);
|
2016-05-24 17:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-25 19:11:15 +02:00
|
|
|
intel_dbuf_post_plane_update(state);
|
2021-09-22 14:52:42 -07:00
|
|
|
intel_psr_post_plane_update(state);
|
2020-02-03 01:06:26 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
2019-11-27 21:05:53 +02:00
|
|
|
intel_post_plane_update(state, crtc);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2022-06-17 12:48:16 +03:00
|
|
|
intel_modeset_put_crtc_power_domains(crtc, &put_domains[crtc->pipe]);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2017-03-09 15:52:04 +01:00
|
|
|
intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
|
2020-05-20 18:37:37 +05:30
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* DSB cleanup is done in cleanup_work aligning with framebuffer
|
|
|
|
|
* cleanup. So copy and reset the dsb structure to sync with
|
|
|
|
|
* commit_done and later do dsb cleanup in cleanup_work.
|
|
|
|
|
*/
|
|
|
|
|
old_crtc_state->dsb = fetch_and_zero(&new_crtc_state->dsb);
|
2016-05-24 17:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
2019-11-27 21:05:54 +02:00
|
|
|
/* Underruns don't always raise interrupts, so check manually */
|
|
|
|
|
intel_check_cpu_fifo_underruns(dev_priv);
|
|
|
|
|
intel_check_pch_fifo_underruns(dev_priv);
|
|
|
|
|
|
2020-04-30 22:56:34 +03:00
|
|
|
if (state->modeset)
|
2019-06-28 10:55:13 +02:00
|
|
|
intel_verify_planes(state);
|
2017-11-17 21:19:17 +02:00
|
|
|
|
2020-04-30 22:56:34 +03:00
|
|
|
intel_sagv_post_plane_update(state);
|
drm/i915/skl: Add support for the SAGV, fix underrun hangs
Since the watermark calculations for Skylake are still broken, we're apt
to hitting underruns very easily under multi-monitor configurations.
While it would be lovely if this was fixed, it's not. Another problem
that's been coming from this however, is the mysterious issue of
underruns causing full system hangs. An easy way to reproduce this with
a skylake system:
- Get a laptop with a skylake GPU, and hook up two external monitors to
it
- Move the cursor from the built-in LCD to one of the external displays
as quickly as you can
- You'll get a few pipe underruns, and eventually the entire system will
just freeze.
After doing a lot of investigation and reading through the bspec, I
found the existence of the SAGV, which is responsible for adjusting the
system agent voltage and clock frequencies depending on how much power
we need. According to the bspec:
"The display engine access to system memory is blocked during the
adjustment time. SAGV defaults to enabled. Software must use the
GT-driver pcode mailbox to disable SAGV when the display engine is not
able to tolerate the blocking time."
The rest of the bspec goes on to explain that software can simply leave
the SAGV enabled, and disable it when we use interlaced pipes/have more
then one pipe active.
Sure enough, with this patchset the system hangs resulting from pipe
underruns on Skylake have completely vanished on my T460s. Additionally,
the bspec mentions turning off the SAGV with more then one pipe enabled
as a workaround for display underruns. While this patch doesn't entirely
fix that, it looks like it does improve the situation a little bit so
it's likely this is going to be required to make watermarks on Skylake
fully functional.
This will still need additional work in the future: we shouldn't be
enabling the SAGV if any of the currently enabled planes can't enable WM
levels that introduce latencies >= 30 µs.
Changes since v11:
- Add skl_can_enable_sagv()
- Make sure we don't enable SAGV when not all planes can enable
watermarks >= the SAGV engine block time. I was originally going to
save this for later, but I recently managed to run into a machine
that was having problems with a single pipe configuration + SAGV.
- Make comparisons to I915_SKL_SAGV_NOT_CONTROLLED explicit
- Change I915_SAGV_DYNAMIC_FREQ to I915_SAGV_ENABLE
- Move printks outside of mutexes
- Don't print error messages twice
Changes since v10:
- Apparently sandybridge_pcode_read actually writes values and reads
them back, despite it's misleading function name. This means we've
been doing this mostly wrong and have been writing garbage to the
SAGV control. Because of this, we no longer attempt to read the SAGV
status during initialization (since there are no helpers for this).
- mlankhorst noticed that this patch was breaking on some very early
pre-release Skylake machines, which apparently don't allow you to
disable the SAGV. To prevent machines from failing tests due to SAGV
errors, if the first time we try to control the SAGV results in the
mailbox indicating an invalid command, we just disable future attempts
to control the SAGV state by setting dev_priv->skl_sagv_status to
I915_SKL_SAGV_NOT_CONTROLLED and make a note of it in dmesg.
- Move mutex_unlock() a little higher in skl_enable_sagv(). This
doesn't actually fix anything, but lets us release the lock a little
sooner since we're finished with it.
Changes since v9:
- Only enable/disable sagv on Skylake
Changes since v8:
- Add intel_state->modeset guard to the conditional for
skl_enable_sagv()
Changes since v7:
- Remove GEN9_SAGV_LOW_FREQ, replace with GEN9_SAGV_IS_ENABLED (that's
all we use it for anyway)
- Use GEN9_SAGV_IS_ENABLED instead of 0x1 for clarification
- Fix a styling error that snuck past me
Changes since v6:
- Protect skl_enable_sagv() with intel_state->modeset conditional in
intel_atomic_commit_tail()
Changes since v5:
- Don't use is_power_of_2. Makes things confusing
- Don't use the old state to figure out whether or not to
enable/disable the sagv, use the new one
- Split the loop in skl_disable_sagv into it's own function
- Move skl_sagv_enable/disable() calls into intel_atomic_commit_tail()
Changes since v4:
- Use is_power_of_2 against active_crtcs to check whether we have > 1
pipe enabled
- Fix skl_sagv_get_hw_state(): (temp & 0x1) indicates disabled, 0x0
enabled
- Call skl_sagv_enable/disable() from pre/post-plane updates
Changes since v3:
- Use time_before() to compare timeout to jiffies
Changes since v2:
- Really apply minor style nitpicks to patch this time
Changes since v1:
- Added comments about this probably being one of the requirements to
fixing Skylake's watermark issues
- Minor style nitpicks from Matt Roper
- Disable these functions on Broxton, since it doesn't have an SAGV
Signed-off-by: Lyude <cpaul@redhat.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471463761-26796-3-git-send-email-cpaul@redhat.com
[mlankhorst: ENOSYS -> ENXIO, whitespace fixes]
2016-08-17 15:55:54 -04:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
drm_atomic_helper_commit_hw_done(&state->base);
|
2016-06-14 18:01:00 +02:00
|
|
|
|
2019-06-28 10:55:13 +02:00
|
|
|
if (state->modeset) {
|
2017-05-04 12:55:08 +01:00
|
|
|
/* As one of the primary mmio accessors, KMS has a high
|
|
|
|
|
* likelihood of triggering bugs in unclaimed access. After we
|
|
|
|
|
* finish modesetting, see if an error has been flagged, and if
|
|
|
|
|
* so enable debugging for the next modeset - and hope we catch
|
|
|
|
|
* the culprit.
|
|
|
|
|
*/
|
2019-03-25 14:49:34 -07:00
|
|
|
intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
|
2019-01-14 14:21:24 +00:00
|
|
|
intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
|
2017-05-04 12:55:08 +01:00
|
|
|
}
|
2019-06-28 10:55:13 +02:00
|
|
|
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
|
2016-05-24 17:13:53 +02:00
|
|
|
|
2018-06-23 11:39:51 +01:00
|
|
|
/*
|
|
|
|
|
* Defer the cleanup of the old state to a separate worker to not
|
|
|
|
|
* impede the current task (userspace for blocking modesets) that
|
|
|
|
|
* are executed inline. For out-of-line asynchronous modesets/flips,
|
|
|
|
|
* deferring to a new worker seems overkill, but we would place a
|
|
|
|
|
* schedule point (cond_resched()) here anyway to keep latencies
|
|
|
|
|
* down.
|
|
|
|
|
*/
|
2019-06-28 10:55:13 +02:00
|
|
|
INIT_WORK(&state->base.commit_work, intel_atomic_cleanup_work);
|
|
|
|
|
queue_work(system_highpri_wq, &state->base.commit_work);
|
2016-06-14 18:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void intel_atomic_commit_work(struct work_struct *work)
|
|
|
|
|
{
|
2019-06-28 10:55:13 +02:00
|
|
|
struct intel_atomic_state *state =
|
|
|
|
|
container_of(work, struct intel_atomic_state, base.commit_work);
|
2016-10-28 13:58:45 +01:00
|
|
|
|
2016-06-14 18:01:00 +02:00
|
|
|
intel_atomic_commit_tail(state);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 11:49:29 -08:00
|
|
|
static int
|
2016-10-28 13:58:45 +01:00
|
|
|
intel_atomic_commit_ready(struct i915_sw_fence *fence,
|
|
|
|
|
enum i915_sw_fence_notify notify)
|
|
|
|
|
{
|
|
|
|
|
struct intel_atomic_state *state =
|
|
|
|
|
container_of(fence, struct intel_atomic_state, commit_ready);
|
|
|
|
|
|
|
|
|
|
switch (notify) {
|
|
|
|
|
case FENCE_COMPLETE:
|
2017-08-08 10:08:27 +02:00
|
|
|
/* we do blocking waits in the worker, nothing to do here */
|
2016-10-28 13:58:45 +01:00
|
|
|
break;
|
|
|
|
|
case FENCE_FREE:
|
2017-01-23 21:29:39 +00:00
|
|
|
{
|
|
|
|
|
struct intel_atomic_helper *helper =
|
|
|
|
|
&to_i915(state->base.dev)->atomic_helper;
|
|
|
|
|
|
|
|
|
|
if (llist_add(&state->freed, &helper->free_list))
|
|
|
|
|
schedule_work(&helper->free_work);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-10-28 13:58:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NOTIFY_DONE;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-01 19:05:48 +03:00
|
|
|
static void intel_atomic_track_fbs(struct intel_atomic_state *state)
|
drm/i915: Move fb_bits updating later in atomic_commit
Currently it's part of prepare_fb, still in the first phase of
atomic_commit which might fail. Which means that we need to have some
heuristics in cleanup_fb to figure out whether things failed, or
whether we just clean up the old fbs.
That's fragile, and worse, once we start pipelining commits gets
confused: While the last commit is still getting cleanup up we already
hammer in the new one, and fb_bits aren't refcounted, resulting in
lost bits and WARN_ON galore. We could instead try to make cleanup_fb
more clever, but a simpler fix is to postpone the fb_bits tracking
past the point of no return, where we commit all the software state.
That also makes conceptually more sense, since fb_bits must be updated
synchronously from the ioctl (they track usage from userspace pov, not
from the hw pov), right before we're fully committed to the updated.
This fixes WARNING splats from track_fb with page_flip implemented
through atomic_commit.
Testcase: igt/kms_flip/flip-vs-rmfb
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465827229-1704-4-git-send-email-daniel.vetter@ffwll.ch
2016-06-13 16:13:48 +02:00
|
|
|
{
|
2019-07-01 19:05:48 +03:00
|
|
|
struct intel_plane_state *old_plane_state, *new_plane_state;
|
|
|
|
|
struct intel_plane *plane;
|
drm/i915: Move fb_bits updating later in atomic_commit
Currently it's part of prepare_fb, still in the first phase of
atomic_commit which might fail. Which means that we need to have some
heuristics in cleanup_fb to figure out whether things failed, or
whether we just clean up the old fbs.
That's fragile, and worse, once we start pipelining commits gets
confused: While the last commit is still getting cleanup up we already
hammer in the new one, and fb_bits aren't refcounted, resulting in
lost bits and WARN_ON galore. We could instead try to make cleanup_fb
more clever, but a simpler fix is to postpone the fb_bits tracking
past the point of no return, where we commit all the software state.
That also makes conceptually more sense, since fb_bits must be updated
synchronously from the ioctl (they track usage from userspace pov, not
from the hw pov), right before we're fully committed to the updated.
This fixes WARNING splats from track_fb with page_flip implemented
through atomic_commit.
Testcase: igt/kms_flip/flip-vs-rmfb
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465827229-1704-4-git-send-email-daniel.vetter@ffwll.ch
2016-06-13 16:13:48 +02:00
|
|
|
int i;
|
|
|
|
|
|
2019-07-01 19:05:48 +03:00
|
|
|
for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
|
|
|
|
|
new_plane_state, i)
|
2019-10-31 12:26:07 +01:00
|
|
|
intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb),
|
|
|
|
|
to_intel_frontbuffer(new_plane_state->hw.fb),
|
2019-08-16 08:46:35 +01:00
|
|
|
plane->frontbuffer_bit);
|
drm/i915: Move fb_bits updating later in atomic_commit
Currently it's part of prepare_fb, still in the first phase of
atomic_commit which might fail. Which means that we need to have some
heuristics in cleanup_fb to figure out whether things failed, or
whether we just clean up the old fbs.
That's fragile, and worse, once we start pipelining commits gets
confused: While the last commit is still getting cleanup up we already
hammer in the new one, and fb_bits aren't refcounted, resulting in
lost bits and WARN_ON galore. We could instead try to make cleanup_fb
more clever, but a simpler fix is to postpone the fb_bits tracking
past the point of no return, where we commit all the software state.
That also makes conceptually more sense, since fb_bits must be updated
synchronously from the ioctl (they track usage from userspace pov, not
from the hw pov), right before we're fully committed to the updated.
This fixes WARNING splats from track_fb with page_flip implemented
through atomic_commit.
Testcase: igt/kms_flip/flip-vs-rmfb
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465827229-1704-4-git-send-email-daniel.vetter@ffwll.ch
2016-06-13 16:13:48 +02:00
|
|
|
}
|
|
|
|
|
|
2016-06-14 18:01:00 +02:00
|
|
|
static int intel_atomic_commit(struct drm_device *dev,
|
2019-07-01 19:05:50 +03:00
|
|
|
struct drm_atomic_state *_state,
|
2016-06-14 18:01:00 +02:00
|
|
|
bool nonblock)
|
|
|
|
|
{
|
2019-07-01 19:05:50 +03:00
|
|
|
struct intel_atomic_state *state = to_intel_atomic_state(_state);
|
2016-07-04 11:34:36 +01:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
2016-06-14 18:01:00 +02:00
|
|
|
int ret = 0;
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
|
2019-05-28 08:53:54 +01:00
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
drm_atomic_state_get(&state->base);
|
|
|
|
|
i915_sw_fence_init(&state->commit_ready,
|
2016-10-28 13:58:45 +01:00
|
|
|
intel_atomic_commit_ready);
|
2016-06-14 18:01:00 +02:00
|
|
|
|
2017-03-29 17:21:23 +03:00
|
|
|
/*
|
|
|
|
|
* The intel_legacy_cursor_update() fast path takes care
|
|
|
|
|
* of avoiding the vblank waits for simple cursor
|
|
|
|
|
* movement and flips. For cursor on/off and size changes,
|
|
|
|
|
* we want to perform the vblank waits so that watermark
|
|
|
|
|
* updates happen during the correct frames. Gen9+ have
|
|
|
|
|
* double buffered watermarks and so shouldn't need this.
|
|
|
|
|
*
|
2017-09-19 14:14:18 +02:00
|
|
|
* Unset state->legacy_cursor_update before the call to
|
|
|
|
|
* drm_atomic_helper_setup_commit() because otherwise
|
|
|
|
|
* drm_atomic_helper_wait_for_flip_done() is a noop and
|
|
|
|
|
* we get FIFO underruns because we didn't wait
|
|
|
|
|
* for vblank.
|
2017-03-29 17:21:23 +03:00
|
|
|
*
|
|
|
|
|
* FIXME doing watermarks and fb cleanup from a vblank worker
|
|
|
|
|
* (assuming we had any) would solve these problems.
|
|
|
|
|
*/
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 9 && state->base.legacy_cursor_update) {
|
2017-09-19 14:14:19 +02:00
|
|
|
struct intel_crtc_state *new_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
|
2017-09-19 14:14:19 +02:00
|
|
|
if (new_crtc_state->wm.need_postvbl_update ||
|
|
|
|
|
new_crtc_state->update_wm_post)
|
2019-07-01 19:05:50 +03:00
|
|
|
state->base.legacy_cursor_update = false;
|
2017-09-19 14:14:19 +02:00
|
|
|
}
|
2017-03-29 17:21:23 +03:00
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
ret = intel_atomic_prepare_commit(state);
|
2017-09-19 14:14:18 +02:00
|
|
|
if (ret) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_atomic(&dev_priv->drm,
|
|
|
|
|
"Preparing state failed with %i\n", ret);
|
2019-07-01 19:05:50 +03:00
|
|
|
i915_sw_fence_commit(&state->commit_ready);
|
|
|
|
|
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
|
2017-09-19 14:14:18 +02:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
ret = drm_atomic_helper_setup_commit(&state->base, nonblock);
|
2017-09-19 14:14:18 +02:00
|
|
|
if (!ret)
|
2019-07-01 19:05:50 +03:00
|
|
|
ret = drm_atomic_helper_swap_state(&state->base, true);
|
2020-01-20 19:47:24 +02:00
|
|
|
if (!ret)
|
|
|
|
|
intel_atomic_swap_global_state(state);
|
2017-09-19 14:14:18 +02:00
|
|
|
|
2017-07-11 16:33:07 +02:00
|
|
|
if (ret) {
|
2020-05-20 18:37:37 +05:30
|
|
|
struct intel_crtc_state *new_crtc_state;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int i;
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
i915_sw_fence_commit(&state->commit_ready);
|
2017-07-11 16:33:07 +02:00
|
|
|
|
2020-05-20 18:37:37 +05:30
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
|
|
|
|
|
intel_dsb_cleanup(new_crtc_state);
|
|
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
drm_atomic_helper_cleanup_planes(dev, &state->base);
|
|
|
|
|
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
|
2017-07-11 16:33:07 +02:00
|
|
|
return ret;
|
|
|
|
|
}
|
2019-07-01 19:05:50 +03:00
|
|
|
intel_shared_dpll_swap_state(state);
|
|
|
|
|
intel_atomic_track_fbs(state);
|
2016-06-14 18:01:00 +02:00
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
drm_atomic_state_get(&state->base);
|
|
|
|
|
INIT_WORK(&state->base.commit_work, intel_atomic_commit_work);
|
2016-10-28 13:58:45 +01:00
|
|
|
|
2019-07-01 19:05:50 +03:00
|
|
|
i915_sw_fence_commit(&state->commit_ready);
|
|
|
|
|
if (nonblock && state->modeset) {
|
|
|
|
|
queue_work(dev_priv->modeset_wq, &state->base.commit_work);
|
2017-11-13 15:36:22 +02:00
|
|
|
} else if (nonblock) {
|
2019-09-10 15:13:47 +03:00
|
|
|
queue_work(dev_priv->flip_wq, &state->base.commit_work);
|
2017-11-13 15:36:22 +02:00
|
|
|
} else {
|
2019-07-01 19:05:50 +03:00
|
|
|
if (state->modeset)
|
2017-11-13 15:36:22 +02:00
|
|
|
flush_workqueue(dev_priv->modeset_wq);
|
2019-07-01 19:05:50 +03:00
|
|
|
intel_atomic_commit_tail(state);
|
2017-11-13 15:36:22 +02:00
|
|
|
}
|
2015-12-16 09:26:48 +02:00
|
|
|
|
2015-07-13 16:30:30 +02:00
|
|
|
return 0;
|
2014-11-05 14:26:06 -08:00
|
|
|
}
|
|
|
|
|
|
2014-12-04 10:27:42 -08:00
|
|
|
/**
|
2014-12-23 10:41:51 -08:00
|
|
|
* intel_plane_destroy - destroy a plane
|
|
|
|
|
* @plane: plane to destroy
|
2014-12-04 10:27:42 -08:00
|
|
|
*
|
2014-12-23 10:41:51 -08:00
|
|
|
* Common destruction function for all types of planes (primary, cursor,
|
|
|
|
|
* sprite).
|
2014-12-04 10:27:42 -08:00
|
|
|
*/
|
2014-12-23 10:41:51 -08:00
|
|
|
void intel_plane_destroy(struct drm_plane *plane)
|
2014-05-29 08:06:54 -07:00
|
|
|
{
|
|
|
|
|
drm_plane_cleanup(plane);
|
2016-05-27 20:59:22 +03:00
|
|
|
kfree(to_intel_plane(plane));
|
2014-05-29 08:06:54 -07:00
|
|
|
}
|
|
|
|
|
|
2020-02-26 22:05:17 +05:30
|
|
|
static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
|
|
|
|
|
{
|
|
|
|
|
struct intel_plane *plane;
|
|
|
|
|
|
|
|
|
|
for_each_intel_plane(&dev_priv->drm, plane) {
|
2021-12-01 15:57:04 +02:00
|
|
|
struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv,
|
|
|
|
|
plane->pipe);
|
2020-02-26 22:05:17 +05:30
|
|
|
|
|
|
|
|
plane->base.possible_crtcs = drm_crtc_mask(&crtc->base);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2018-02-07 18:48:41 +02:00
|
|
|
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
|
|
|
|
|
struct drm_file *file)
|
2009-04-29 14:43:54 -07:00
|
|
|
{
|
|
|
|
|
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
|
2014-07-17 23:30:04 -04:00
|
|
|
struct drm_crtc *drmmode_crtc;
|
2009-08-11 16:05:30 +02:00
|
|
|
struct intel_crtc *crtc;
|
2009-04-29 14:43:54 -07:00
|
|
|
|
2017-03-14 23:25:07 -07:00
|
|
|
drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
|
2016-06-24 14:00:24 +01:00
|
|
|
if (!drmmode_crtc)
|
2013-10-17 13:35:03 +03:00
|
|
|
return -ENOENT;
|
2009-04-29 14:43:54 -07:00
|
|
|
|
2014-07-17 23:30:04 -04:00
|
|
|
crtc = to_intel_crtc(drmmode_crtc);
|
2009-08-11 16:05:30 +02:00
|
|
|
pipe_from_crtc_id->pipe = crtc->pipe;
|
2009-04-29 14:43:54 -07:00
|
|
|
|
2009-08-11 16:05:30 +02:00
|
|
|
return 0;
|
2009-04-29 14:43:54 -07:00
|
|
|
}
|
|
|
|
|
|
2019-10-02 19:25:00 +03:00
|
|
|
static u32 intel_encoder_possible_clones(struct intel_encoder *encoder)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2012-07-12 20:08:18 +02:00
|
|
|
struct drm_device *dev = encoder->base.dev;
|
|
|
|
|
struct intel_encoder *source_encoder;
|
2019-10-02 19:25:00 +03:00
|
|
|
u32 possible_clones = 0;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2014-08-05 11:29:37 +01:00
|
|
|
for_each_intel_encoder(dev, source_encoder) {
|
2014-03-03 16:15:28 +02:00
|
|
|
if (encoders_cloneable(encoder, source_encoder))
|
2019-10-02 19:25:00 +03:00
|
|
|
possible_clones |= drm_encoder_mask(&source_encoder->base);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
2010-09-09 15:14:28 +01:00
|
|
|
|
2019-10-02 19:25:00 +03:00
|
|
|
return possible_clones;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 19:20:42 +03:00
|
|
|
static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder)
|
|
|
|
|
{
|
|
|
|
|
struct drm_device *dev = encoder->base.dev;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
u32 possible_crtcs = 0;
|
|
|
|
|
|
2022-02-03 20:38:21 +02:00
|
|
|
for_each_intel_crtc_in_pipe_mask(dev, crtc, encoder->pipe_mask)
|
|
|
|
|
possible_crtcs |= drm_crtc_mask(&crtc->base);
|
2019-07-08 19:20:42 +03:00
|
|
|
|
|
|
|
|
return possible_crtcs;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-22 10:23:05 +02:00
|
|
|
static bool ilk_has_edp_a(struct drm_i915_private *dev_priv)
|
2010-12-14 19:21:29 +00:00
|
|
|
{
|
2016-10-31 22:37:14 +02:00
|
|
|
if (!IS_MOBILE(dev_priv))
|
2010-12-14 19:21:29 +00:00
|
|
|
return false;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if ((intel_de_read(dev_priv, DP_A) & DP_DETECTED) == 0)
|
2010-12-14 19:21:29 +00:00
|
|
|
return false;
|
|
|
|
|
|
2021-03-19 21:42:40 -07:00
|
|
|
if (IS_IRONLAKE(dev_priv) && (intel_de_read(dev_priv, FUSE_STRAP) & ILK_eDP_A_DISABLE))
|
2010-12-14 19:21:29 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-22 10:23:01 +02:00
|
|
|
static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv)
|
2014-06-25 08:24:29 -07:00
|
|
|
{
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9)
|
2013-12-03 13:56:23 +00:00
|
|
|
return false;
|
|
|
|
|
|
2016-10-13 11:02:58 +01:00
|
|
|
if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
|
2014-06-25 08:24:29 -07:00
|
|
|
return false;
|
|
|
|
|
|
2016-10-13 11:02:52 +01:00
|
|
|
if (HAS_PCH_LPT_H(dev_priv) &&
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED)
|
2015-12-01 23:28:55 +02:00
|
|
|
return false;
|
|
|
|
|
|
2015-12-01 23:29:56 +02:00
|
|
|
/* DDI E can't be used if DDI A requires 4 lanes */
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
|
2015-12-01 23:29:56 +02:00
|
|
|
return false;
|
|
|
|
|
|
drm/i915: Check VBT for CRT port presence on HSW/BDW
Unfortunatey there appear to quite a few HSW/BDW machines (eg.
NUCs, Brix Pro) in the wild with LPT/WPT-H that have no physical
CRT connector and non-working FDI. FDI training fails every
single time on these machines. Dunno, maybe they just didn't
bother wiring it up or something?
Unfortunately all the fuse bits and whatnot are telling us that
the CRT connector is present. And so what we get from this is tons
of false positives from the CI systems due to VGA connector forcing.
I've not found any way to detect this purely from hardware, so we
have to resort to looking at the VBT int_crt_support bit. We used
to check this bit on all platforms, but that broke all the old
machines, so the check was then restricted to VLV only in
commit 84b4e042c470 ("drm/i915: only apply crt_present check on VLV")
Considering HSW and VLV VBT probably got defined around the same time,
it should be reasonably safe to assume that the bits is sane for
HSW/BDW as well. At least I have one copy of some VBT spec here that
says it's meant for both VLV and HSW, and it knows about the bit
(lists it being valid from version 155 onwards). Also I have two
desktop machines with actual CRT ports and both have
int_crt_support==1 in their VBTs.
Also we already trust VBT >= 155 to tell us various details about
the DDI ports, so trusting it a bit more seems reasonable.
As far as VLV goes, the added VBT version check should be fine. Even
if someone has some weird VLV machine with a very old VBT version,
it just means they'll end up with a shadow CRT connector. IIRC the
reason for eliminating the shadow CRT connector on VLV was to speed
up display probing rather than fixing something more serious.
v2: Move the platform checks into the VBT parsing code
Also check that the VBT version is at least 155
v3: Improve commit message (Paulo)
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1449005493-15487-1-git-send-email-ville.syrjala@linux.intel.com
2015-12-01 23:31:33 +02:00
|
|
|
if (!dev_priv->vbt.int_crt_support)
|
2014-06-25 08:24:29 -07:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-23 16:21:44 +02:00
|
|
|
static void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
2010-09-09 15:14:28 +01:00
|
|
|
struct intel_encoder *encoder;
|
2010-07-16 14:46:29 -04:00
|
|
|
bool dpd_is_edp = false;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2021-01-20 12:18:32 +02:00
|
|
|
intel_pps_unlock_regs_wa(dev_priv);
|
2016-08-10 14:07:29 +03:00
|
|
|
|
2020-09-10 19:42:56 +03:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
2018-08-15 21:12:07 +01:00
|
|
|
return;
|
|
|
|
|
|
2021-07-21 15:30:39 -07:00
|
|
|
if (IS_DG2(dev_priv)) {
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_D_XELPD);
|
2022-02-17 17:03:28 -08:00
|
|
|
intel_ddi_init(dev_priv, PORT_TC1);
|
2021-07-21 15:30:39 -07:00
|
|
|
} else if (IS_ALDERLAKE_P(dev_priv)) {
|
2021-05-18 17:06:12 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC1);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC2);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC3);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC4);
|
2021-08-26 11:18:11 +05:30
|
|
|
icl_dsi_init(dev_priv);
|
2021-05-18 17:06:12 -07:00
|
|
|
} else if (IS_ALDERLAKE_S(dev_priv)) {
|
2021-01-25 06:07:50 -08:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC1);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC2);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC3);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC4);
|
|
|
|
|
} else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) {
|
2020-06-03 14:15:19 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
2020-10-28 23:33:06 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_TC1);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC2);
|
2021-03-19 21:42:42 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) >= 12) {
|
2019-07-11 10:31:08 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
2020-10-28 23:33:06 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_TC1);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC2);
|
2020-11-04 03:00:00 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_TC3);
|
2020-10-28 23:33:06 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_TC4);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC5);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_TC6);
|
2019-07-30 13:06:47 +05:30
|
|
|
icl_dsi_init(dev_priv);
|
2020-10-14 00:59:48 +05:30
|
|
|
} else if (IS_JSL_EHL(dev_priv)) {
|
2019-03-22 10:58:45 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
2019-07-09 11:39:34 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_D);
|
2019-03-22 10:58:45 -07:00
|
|
|
icl_dsi_init(dev_priv);
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) == 11) {
|
2018-05-21 17:25:47 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_D);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_E);
|
2021-04-30 15:38:08 -07:00
|
|
|
intel_ddi_init(dev_priv, PORT_F);
|
2018-10-30 13:56:23 +02:00
|
|
|
icl_dsi_init(dev_priv);
|
2021-04-07 13:39:45 -07:00
|
|
|
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
2018-07-05 16:25:08 +03:00
|
|
|
vlv_dsi_init(dev_priv);
|
2021-07-22 16:29:22 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) >= 9) {
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_D);
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_E);
|
2016-10-13 11:02:52 +01:00
|
|
|
} else if (HAS_DDI(dev_priv)) {
|
2021-04-30 15:38:07 -07:00
|
|
|
u32 found;
|
2012-05-09 15:37:27 -03:00
|
|
|
|
2019-01-22 10:23:01 +02:00
|
|
|
if (intel_ddi_crt_present(dev_priv))
|
|
|
|
|
intel_crt_init(dev_priv);
|
|
|
|
|
|
2021-04-30 15:38:07 -07:00
|
|
|
/* Haswell uses DDI functions to detect digital outputs. */
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
found = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED;
|
2021-04-30 15:38:07 -07:00
|
|
|
if (found)
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_A);
|
2012-05-09 15:37:27 -03:00
|
|
|
|
2021-04-30 15:38:07 -07:00
|
|
|
found = intel_de_read(dev_priv, SFUSE_STRAP);
|
2012-05-09 15:37:27 -03:00
|
|
|
if (found & SFUSE_STRAP_DDIB_DETECTED)
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_B);
|
2012-05-09 15:37:27 -03:00
|
|
|
if (found & SFUSE_STRAP_DDIC_DETECTED)
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_C);
|
2012-05-09 15:37:27 -03:00
|
|
|
if (found & SFUSE_STRAP_DDID_DETECTED)
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_ddi_init(dev_priv, PORT_D);
|
2018-01-29 15:22:22 -08:00
|
|
|
if (found & SFUSE_STRAP_DDIF_DETECTED)
|
|
|
|
|
intel_ddi_init(dev_priv, PORT_F);
|
2016-10-13 11:02:53 +01:00
|
|
|
} else if (HAS_PCH_SPLIT(dev_priv)) {
|
2010-07-16 14:46:29 -04:00
|
|
|
int found;
|
2019-01-22 10:23:01 +02:00
|
|
|
|
2019-01-22 10:23:02 +02:00
|
|
|
/*
|
|
|
|
|
* intel_edp_init_connector() depends on this completing first,
|
|
|
|
|
* to prevent the registration of both eDP and LVDS and the
|
|
|
|
|
* incorrect sharing of the PPS.
|
|
|
|
|
*/
|
|
|
|
|
intel_lvds_init(dev_priv);
|
2019-01-22 10:23:07 +02:00
|
|
|
intel_crt_init(dev_priv);
|
2019-01-22 10:23:01 +02:00
|
|
|
|
2017-08-18 12:30:19 +03:00
|
|
|
dpd_is_edp = intel_dp_is_port_edp(dev_priv, PORT_D);
|
2012-10-27 15:52:05 +02:00
|
|
|
|
2019-01-22 10:23:05 +02:00
|
|
|
if (ilk_has_edp_a(dev_priv))
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, DP_A, PORT_A);
|
2010-07-16 14:46:29 -04:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, PCH_HDMIB) & SDVO_DETECTED) {
|
2010-03-30 15:11:33 +08:00
|
|
|
/* PCH SDVOB multiplex with HDMIB */
|
2016-11-23 16:21:44 +02:00
|
|
|
found = intel_sdvo_init(dev_priv, PCH_SDVOB, PORT_B);
|
2009-06-05 15:38:43 +08:00
|
|
|
if (!found)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, PCH_HDMIB, PORT_B);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (!found && (intel_de_read(dev_priv, PCH_DP_B) & DP_DETECTED))
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, PCH_DP_B, PORT_B);
|
2009-06-05 15:38:43 +08:00
|
|
|
}
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, PCH_HDMIC) & SDVO_DETECTED)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, PCH_HDMIC, PORT_C);
|
2009-06-05 15:38:43 +08:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (!dpd_is_edp && intel_de_read(dev_priv, PCH_HDMID) & SDVO_DETECTED)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, PCH_HDMID, PORT_D);
|
2009-06-05 15:38:43 +08:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, PCH_DP_C) & DP_DETECTED)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, PCH_DP_C, PORT_C);
|
2009-07-24 01:00:31 +08:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, PCH_DP_D) & DP_DETECTED)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, PCH_DP_D, PORT_D);
|
2016-10-14 10:13:44 +01:00
|
|
|
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
2016-06-03 12:17:43 +03:00
|
|
|
bool has_edp, has_port;
|
2016-06-01 08:27:50 +01:00
|
|
|
|
2019-01-22 10:23:01 +02:00
|
|
|
if (IS_VALLEYVIEW(dev_priv) && dev_priv->vbt.int_crt_support)
|
|
|
|
|
intel_crt_init(dev_priv);
|
|
|
|
|
|
2014-10-09 19:37:15 +03:00
|
|
|
/*
|
|
|
|
|
* The DP_DETECTED bit is the latched state of the DDC
|
|
|
|
|
* SDA pin at boot. However since eDP doesn't require DDC
|
|
|
|
|
* (no way to plug in a DP->HDMI dongle) the DDC pins for
|
|
|
|
|
* eDP ports may have been muxed to an alternate function.
|
|
|
|
|
* Thus we can't rely on the DP_DETECTED bit alone to detect
|
|
|
|
|
* eDP ports. Consult the VBT as well as DP_DETECTED to
|
|
|
|
|
* detect eDP ports.
|
2016-06-03 12:17:43 +03:00
|
|
|
*
|
|
|
|
|
* Sadly the straps seem to be missing sometimes even for HDMI
|
|
|
|
|
* ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
|
|
|
|
|
* and VBT for the presence of the port. Additionally we can't
|
|
|
|
|
* trust the port type the VBT declares as we've seen at least
|
|
|
|
|
* HDMI ports that the VBT claim are DP or eDP.
|
2014-10-09 19:37:15 +03:00
|
|
|
*/
|
2017-08-18 12:30:19 +03:00
|
|
|
has_edp = intel_dp_is_port_edp(dev_priv, PORT_B);
|
2016-06-03 12:17:43 +03:00
|
|
|
has_port = intel_bios_is_port_present(dev_priv, PORT_B);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, VLV_DP_B) & DP_DETECTED || has_port)
|
2021-03-18 18:10:15 +02:00
|
|
|
has_edp &= g4x_dp_init(dev_priv, VLV_DP_B, PORT_B);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if ((intel_de_read(dev_priv, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, VLV_HDMIB, PORT_B);
|
drm/i915: preserve dispaly init order on ByT
This patch changes HDMI port registration order for the BayTrail platform.
The story is that in kernel version 3.11 i915 supported only one HDMI port -
the HDMIB port. So this port ended up being HDMI-1 in user-space.
But commit '6f6005a drm/i915: expose HDMI connectors on port C on BYT'
introduced HDMIC port support. And added HDMIC registration prior to HDMIB,
so HDMIB became HDMI-2 and HDMIC became HDMI-1.
Well, this is fine as far as the kernel is concerned. i915 does not give any
guarantees to the numbering, and has never given them.
However, this breaks wayland setup in Tizen IVI. We have only one single HDMI
port on our hardware, and it is connected to HDMIB. Our configuration relies on
the fact that it is HDMI-1.
Well, certainly this is user-space problem which was exposed with Jesse's
patch. However, there is a reason why we have to do this assumption - we use
touchscreen monitors and we have to associate event devices with the monitors,
and this is not easy to do dynamically, so we just have a static setup.
Anyway, while the user-space setup will have to be fixed regardless, let's
chane the HDMI port registration order so that HDMIB stays HDMI-1, just like it
was in 3.11. Simply because there is no strong reason for changing the order in
the kernel, and it'll help setups like ours in sense that we'll have more time
for fixing the issue properly.
Also amend the commentary which looks a bit out-of-date.
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
[danvet: Drop the commment, SDVOC is gone and we have a proper HDMIC
define now.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2013-10-16 18:10:41 +03:00
|
|
|
|
2017-08-18 12:30:19 +03:00
|
|
|
has_edp = intel_dp_is_port_edp(dev_priv, PORT_C);
|
2016-06-03 12:17:43 +03:00
|
|
|
has_port = intel_bios_is_port_present(dev_priv, PORT_C);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, VLV_DP_C) & DP_DETECTED || has_port)
|
2021-03-18 18:10:15 +02:00
|
|
|
has_edp &= g4x_dp_init(dev_priv, VLV_DP_C, PORT_C);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if ((intel_de_read(dev_priv, VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, VLV_HDMIC, PORT_C);
|
2012-09-27 19:13:07 +05:30
|
|
|
|
2016-10-14 10:13:44 +01:00
|
|
|
if (IS_CHERRYVIEW(dev_priv)) {
|
2016-06-03 12:17:43 +03:00
|
|
|
/*
|
|
|
|
|
* eDP not supported on port D,
|
|
|
|
|
* so no need to worry about it
|
|
|
|
|
*/
|
|
|
|
|
has_port = intel_bios_is_port_present(dev_priv, PORT_D);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, CHV_DP_D) & DP_DETECTED || has_port)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, CHV_DP_D, PORT_D);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, CHV_HDMID) & SDVO_DETECTED || has_port)
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, CHV_HDMID, PORT_D);
|
2014-04-09 13:28:56 +03:00
|
|
|
}
|
|
|
|
|
|
2018-07-05 16:25:08 +03:00
|
|
|
vlv_dsi_init(dev_priv);
|
2019-01-22 10:23:01 +02:00
|
|
|
} else if (IS_PINEVIEW(dev_priv)) {
|
2019-01-22 10:23:02 +02:00
|
|
|
intel_lvds_init(dev_priv);
|
2019-01-22 10:23:07 +02:00
|
|
|
intel_crt_init(dev_priv);
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
} else if (IS_DISPLAY_VER(dev_priv, 3, 4)) {
|
2009-08-24 13:50:23 +08:00
|
|
|
bool found = false;
|
2009-01-02 13:33:00 -08:00
|
|
|
|
2019-01-22 10:23:03 +02:00
|
|
|
if (IS_MOBILE(dev_priv))
|
|
|
|
|
intel_lvds_init(dev_priv);
|
2019-01-22 10:23:02 +02:00
|
|
|
|
2019-01-22 10:23:07 +02:00
|
|
|
intel_crt_init(dev_priv);
|
2019-01-22 10:23:01 +02:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "probing SDVOB\n");
|
2016-11-23 16:21:44 +02:00
|
|
|
found = intel_sdvo_init(dev_priv, GEN3_SDVOB, PORT_B);
|
2016-10-13 11:03:06 +01:00
|
|
|
if (!found && IS_G4X(dev_priv)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"probing HDMI on SDVOB\n");
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, GEN4_HDMIB, PORT_B);
|
2009-12-11 11:07:17 -08:00
|
|
|
}
|
2009-08-24 13:50:23 +08:00
|
|
|
|
2016-10-13 11:03:06 +01:00
|
|
|
if (!found && IS_G4X(dev_priv))
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, DP_B, PORT_B);
|
2009-01-22 13:01:02 -08:00
|
|
|
}
|
2009-03-13 15:42:14 -04:00
|
|
|
|
|
|
|
|
/* Before G4X SDVOC doesn't have its own detect register */
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "probing SDVOC\n");
|
2016-11-23 16:21:44 +02:00
|
|
|
found = intel_sdvo_init(dev_priv, GEN3_SDVOC, PORT_C);
|
2009-12-11 11:07:17 -08:00
|
|
|
}
|
2009-08-24 13:50:23 +08:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (!found && (intel_de_read(dev_priv, GEN3_SDVOC) & SDVO_DETECTED)) {
|
2009-08-24 13:50:23 +08:00
|
|
|
|
2016-10-13 11:03:06 +01:00
|
|
|
if (IS_G4X(dev_priv)) {
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"probing HDMI on SDVOC\n");
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_hdmi_init(dev_priv, GEN4_HDMIC, PORT_C);
|
2009-12-11 11:07:17 -08:00
|
|
|
}
|
2016-10-13 11:03:06 +01:00
|
|
|
if (IS_G4X(dev_priv))
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, DP_C, PORT_C);
|
2009-01-22 13:01:02 -08:00
|
|
|
}
|
2009-08-24 13:50:23 +08:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
if (IS_G4X(dev_priv) && (intel_de_read(dev_priv, DP_D) & DP_DETECTED))
|
2021-03-18 18:10:15 +02:00
|
|
|
g4x_dp_init(dev_priv, DP_D, PORT_D);
|
2019-01-22 10:23:04 +02:00
|
|
|
|
|
|
|
|
if (SUPPORTS_TV(dev_priv))
|
|
|
|
|
intel_tv_init(dev_priv);
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) == 2) {
|
2019-01-22 10:23:06 +02:00
|
|
|
if (IS_I85X(dev_priv))
|
2019-01-22 10:23:03 +02:00
|
|
|
intel_lvds_init(dev_priv);
|
2019-01-22 10:23:02 +02:00
|
|
|
|
2019-01-22 10:23:07 +02:00
|
|
|
intel_crt_init(dev_priv);
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_dvo_init(dev_priv);
|
2019-01-22 10:23:01 +02:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2016-11-23 16:21:44 +02:00
|
|
|
for_each_intel_encoder(&dev_priv->drm, encoder) {
|
2019-07-08 19:20:42 +03:00
|
|
|
encoder->base.possible_crtcs =
|
|
|
|
|
intel_encoder_possible_crtcs(encoder);
|
2010-09-09 15:14:28 +01:00
|
|
|
encoder->base.possible_clones =
|
2019-10-02 19:25:00 +03:00
|
|
|
intel_encoder_possible_clones(encoder);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
2011-01-11 17:06:04 +00:00
|
|
|
|
2016-11-23 16:21:44 +02:00
|
|
|
intel_init_pch_refclk(dev_priv);
|
2012-10-27 15:52:05 +02:00
|
|
|
|
2016-11-23 16:21:44 +02:00
|
|
|
drm_helper_move_panel_connectors_to_head(&dev_priv->drm);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-11-14 20:32:58 +02:00
|
|
|
static enum drm_mode_status
|
|
|
|
|
intel_mode_valid(struct drm_device *dev,
|
|
|
|
|
const struct drm_display_mode *mode)
|
|
|
|
|
{
|
2018-06-15 20:44:05 +03:00
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
|
|
|
int hdisplay_max, htotal_max;
|
|
|
|
|
int vdisplay_max, vtotal_max;
|
|
|
|
|
|
2018-05-24 15:54:03 +03:00
|
|
|
/*
|
|
|
|
|
* Can't reject DBLSCAN here because Xorg ddxen can add piles
|
|
|
|
|
* of DBLSCAN modes to the output's mode list when they detect
|
|
|
|
|
* the scaling mode property on the connector. And they don't
|
|
|
|
|
* ask the kernel to validate those modes in any way until
|
|
|
|
|
* modeset time at which point the client gets a protocol error.
|
|
|
|
|
* So in order to not upset those clients we silently ignore the
|
|
|
|
|
* DBLSCAN flag on such connectors. For other connectors we will
|
|
|
|
|
* reject modes with the DBLSCAN flag in encoder->compute_config().
|
|
|
|
|
* And we always reject DBLSCAN modes in connector->mode_valid()
|
|
|
|
|
* as we never want such modes on the connector's mode list.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-11-14 20:32:58 +02:00
|
|
|
if (mode->vscan > 1)
|
|
|
|
|
return MODE_NO_VSCAN;
|
|
|
|
|
|
|
|
|
|
if (mode->flags & DRM_MODE_FLAG_HSKEW)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
if (mode->flags & (DRM_MODE_FLAG_CSYNC |
|
|
|
|
|
DRM_MODE_FLAG_NCSYNC |
|
|
|
|
|
DRM_MODE_FLAG_PCSYNC))
|
|
|
|
|
return MODE_HSYNC;
|
|
|
|
|
|
|
|
|
|
if (mode->flags & (DRM_MODE_FLAG_BCAST |
|
|
|
|
|
DRM_MODE_FLAG_PIXMUX |
|
|
|
|
|
DRM_MODE_FLAG_CLKDIV2))
|
|
|
|
|
return MODE_BAD;
|
|
|
|
|
|
2019-09-18 18:07:07 +03:00
|
|
|
/* Transcoder timing limits */
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 11) {
|
2019-07-12 13:22:13 -07:00
|
|
|
hdisplay_max = 16384;
|
|
|
|
|
vdisplay_max = 8192;
|
|
|
|
|
htotal_max = 16384;
|
|
|
|
|
vtotal_max = 8192;
|
2021-03-19 21:42:42 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) >= 9 ||
|
2019-07-12 13:22:13 -07:00
|
|
|
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) {
|
2018-06-15 20:44:05 +03:00
|
|
|
hdisplay_max = 8192; /* FDI max 4096 handled elsewhere */
|
|
|
|
|
vdisplay_max = 4096;
|
|
|
|
|
htotal_max = 8192;
|
|
|
|
|
vtotal_max = 8192;
|
2021-03-19 21:42:42 -07:00
|
|
|
} else if (DISPLAY_VER(dev_priv) >= 3) {
|
2018-06-15 20:44:05 +03:00
|
|
|
hdisplay_max = 4096;
|
|
|
|
|
vdisplay_max = 4096;
|
|
|
|
|
htotal_max = 8192;
|
|
|
|
|
vtotal_max = 8192;
|
|
|
|
|
} else {
|
|
|
|
|
hdisplay_max = 2048;
|
|
|
|
|
vdisplay_max = 2048;
|
|
|
|
|
htotal_max = 4096;
|
|
|
|
|
vtotal_max = 4096;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode->hdisplay > hdisplay_max ||
|
|
|
|
|
mode->hsync_start > htotal_max ||
|
|
|
|
|
mode->hsync_end > htotal_max ||
|
|
|
|
|
mode->htotal > htotal_max)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
if (mode->vdisplay > vdisplay_max ||
|
|
|
|
|
mode->vsync_start > vtotal_max ||
|
|
|
|
|
mode->vsync_end > vtotal_max ||
|
|
|
|
|
mode->vtotal > vtotal_max)
|
|
|
|
|
return MODE_V_ILLEGAL;
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 5) {
|
2019-07-18 17:43:40 +03:00
|
|
|
if (mode->hdisplay < 64 ||
|
|
|
|
|
mode->htotal - mode->hdisplay < 32)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
if (mode->vtotal - mode->vdisplay < 5)
|
|
|
|
|
return MODE_V_ILLEGAL;
|
|
|
|
|
} else {
|
|
|
|
|
if (mode->htotal - mode->hdisplay < 32)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
if (mode->vtotal - mode->vdisplay < 3)
|
|
|
|
|
return MODE_V_ILLEGAL;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-30 13:41:33 +03:00
|
|
|
/*
|
|
|
|
|
* Cantiga+ cannot handle modes with a hsync front porch of 0.
|
|
|
|
|
* WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
|
|
|
|
|
*/
|
|
|
|
|
if ((DISPLAY_VER(dev_priv) > 4 || IS_G4X(dev_priv)) &&
|
|
|
|
|
mode->hsync_start == mode->hdisplay)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
2017-11-14 20:32:58 +02:00
|
|
|
return MODE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-18 18:07:07 +03:00
|
|
|
enum drm_mode_status
|
|
|
|
|
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
|
2020-11-17 11:47:05 -08:00
|
|
|
const struct drm_display_mode *mode,
|
|
|
|
|
bool bigjoiner)
|
2019-09-18 18:07:07 +03:00
|
|
|
{
|
|
|
|
|
int plane_width_max, plane_height_max;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* intel_mode_valid() should be
|
|
|
|
|
* sufficient on older platforms.
|
|
|
|
|
*/
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) < 9)
|
2019-09-18 18:07:07 +03:00
|
|
|
return MODE_OK;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Most people will probably want a fullscreen
|
|
|
|
|
* plane so let's not advertize modes that are
|
|
|
|
|
* too big for that.
|
|
|
|
|
*/
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 11) {
|
2020-11-17 11:47:05 -08:00
|
|
|
plane_width_max = 5120 << bigjoiner;
|
2019-09-18 18:07:07 +03:00
|
|
|
plane_height_max = 4320;
|
|
|
|
|
} else {
|
|
|
|
|
plane_width_max = 5120;
|
|
|
|
|
plane_height_max = 4096;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mode->hdisplay > plane_width_max)
|
|
|
|
|
return MODE_H_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
if (mode->vdisplay > plane_height_max)
|
|
|
|
|
return MODE_V_ILLEGAL;
|
|
|
|
|
|
|
|
|
|
return MODE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
static const struct drm_mode_config_funcs intel_mode_funcs = {
|
|
|
|
|
.fb_create = intel_user_framebuffer_create,
|
2021-10-20 22:51:29 +03:00
|
|
|
.get_format_info = intel_fb_get_format_info,
|
2013-10-08 17:44:49 +02:00
|
|
|
.output_poll_changed = intel_fbdev_output_poll_changed,
|
2017-11-14 20:32:58 +02:00
|
|
|
.mode_valid = intel_mode_valid,
|
2015-01-21 16:35:44 -08:00
|
|
|
.atomic_check = intel_atomic_check,
|
|
|
|
|
.atomic_commit = intel_atomic_commit,
|
2015-06-04 10:21:28 +02:00
|
|
|
.atomic_state_alloc = intel_atomic_state_alloc,
|
|
|
|
|
.atomic_state_clear = intel_atomic_state_clear,
|
2016-12-05 14:29:39 +00:00
|
|
|
.atomic_state_free = intel_atomic_state_free,
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
};
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
static const struct intel_display_funcs skl_display_funcs = {
|
2021-09-29 01:58:06 +03:00
|
|
|
.get_pipe_config = hsw_get_pipe_config,
|
|
|
|
|
.crtc_enable = hsw_crtc_enable,
|
|
|
|
|
.crtc_disable = hsw_crtc_disable,
|
|
|
|
|
.commit_modeset_enables = skl_commit_modeset_enables,
|
|
|
|
|
.get_initial_plane_config = skl_get_initial_plane_config,
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
static const struct intel_display_funcs ddi_display_funcs = {
|
2021-09-29 01:58:06 +03:00
|
|
|
.get_pipe_config = hsw_get_pipe_config,
|
|
|
|
|
.crtc_enable = hsw_crtc_enable,
|
|
|
|
|
.crtc_disable = hsw_crtc_disable,
|
|
|
|
|
.commit_modeset_enables = intel_commit_modeset_enables,
|
|
|
|
|
.get_initial_plane_config = i9xx_get_initial_plane_config,
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
static const struct intel_display_funcs pch_split_display_funcs = {
|
2021-09-29 01:58:06 +03:00
|
|
|
.get_pipe_config = ilk_get_pipe_config,
|
|
|
|
|
.crtc_enable = ilk_crtc_enable,
|
|
|
|
|
.crtc_disable = ilk_crtc_disable,
|
|
|
|
|
.commit_modeset_enables = intel_commit_modeset_enables,
|
|
|
|
|
.get_initial_plane_config = i9xx_get_initial_plane_config,
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
static const struct intel_display_funcs vlv_display_funcs = {
|
2021-09-29 01:58:06 +03:00
|
|
|
.get_pipe_config = i9xx_get_pipe_config,
|
|
|
|
|
.crtc_enable = valleyview_crtc_enable,
|
|
|
|
|
.crtc_disable = i9xx_crtc_disable,
|
|
|
|
|
.commit_modeset_enables = intel_commit_modeset_enables,
|
|
|
|
|
.get_initial_plane_config = i9xx_get_initial_plane_config,
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-24 16:15:27 +03:00
|
|
|
static const struct intel_display_funcs i9xx_display_funcs = {
|
2021-09-29 01:58:06 +03:00
|
|
|
.get_pipe_config = i9xx_get_pipe_config,
|
|
|
|
|
.crtc_enable = i9xx_crtc_enable,
|
|
|
|
|
.crtc_disable = i9xx_crtc_disable,
|
|
|
|
|
.commit_modeset_enables = intel_commit_modeset_enables,
|
|
|
|
|
.get_initial_plane_config = i9xx_get_initial_plane_config,
|
|
|
|
|
};
|
|
|
|
|
|
2016-03-16 13:38:53 +02:00
|
|
|
/**
|
|
|
|
|
* intel_init_display_hooks - initialize the display modesetting hooks
|
|
|
|
|
* @dev_priv: device private
|
|
|
|
|
*/
|
|
|
|
|
void intel_init_display_hooks(struct drm_i915_private *dev_priv)
|
2009-09-21 10:42:27 -07:00
|
|
|
{
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
|
|
|
|
return;
|
|
|
|
|
|
2017-02-07 20:33:05 +02:00
|
|
|
intel_init_cdclk_hooks(dev_priv);
|
2021-11-04 18:18:58 +02:00
|
|
|
intel_audio_hooks_init(dev_priv);
|
2017-02-07 20:33:05 +02:00
|
|
|
|
2021-01-14 13:13:46 +02:00
|
|
|
intel_dpll_init_clock_hook(dev_priv);
|
|
|
|
|
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 9) {
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display = &skl_display_funcs;
|
2016-03-16 13:38:53 +02:00
|
|
|
} else if (HAS_DDI(dev_priv)) {
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display = &ddi_display_funcs;
|
2016-03-16 13:38:53 +02:00
|
|
|
} else if (HAS_PCH_SPLIT(dev_priv)) {
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display = &pch_split_display_funcs;
|
2021-01-14 13:13:46 +02:00
|
|
|
} else if (IS_CHERRYVIEW(dev_priv) ||
|
|
|
|
|
IS_VALLEYVIEW(dev_priv)) {
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display = &vlv_display_funcs;
|
2016-03-22 15:35:23 +02:00
|
|
|
} else {
|
2022-08-24 16:15:27 +03:00
|
|
|
dev_priv->display.funcs.display = &i9xx_display_funcs;
|
2011-03-30 13:01:02 -07:00
|
|
|
}
|
2009-09-21 10:42:27 -07:00
|
|
|
|
2021-01-14 13:13:47 +02:00
|
|
|
intel_fdi_init_hook(dev_priv);
|
2009-09-21 10:42:27 -07:00
|
|
|
}
|
|
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
void intel_modeset_init_hw(struct drm_i915_private *i915)
|
2012-04-10 15:50:11 +02:00
|
|
|
{
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
struct intel_cdclk_state *cdclk_state;
|
|
|
|
|
|
|
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state);
|
2020-01-20 19:47:19 +02:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_update_cdclk(i915);
|
2022-01-21 15:00:37 +02:00
|
|
|
intel_cdclk_dump_config(i915, &i915->cdclk.hw, "Current CDCLK");
|
2020-01-20 19:47:19 +02:00
|
|
|
cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw;
|
2012-04-10 15:50:11 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-22 22:43:29 +02:00
|
|
|
static int sanitize_watermarks_add_affected(struct drm_atomic_state *state)
|
|
|
|
|
{
|
|
|
|
|
struct drm_plane *plane;
|
2020-04-29 13:39:04 +03:00
|
|
|
struct intel_crtc *crtc;
|
2020-01-22 22:43:29 +02:00
|
|
|
|
2020-04-29 13:39:04 +03:00
|
|
|
for_each_intel_crtc(state->dev, crtc) {
|
|
|
|
|
struct intel_crtc_state *crtc_state;
|
2020-01-22 22:43:29 +02:00
|
|
|
|
2020-04-29 13:39:04 +03:00
|
|
|
crtc_state = intel_atomic_get_crtc_state(state, crtc);
|
2020-01-22 22:43:29 +02:00
|
|
|
if (IS_ERR(crtc_state))
|
|
|
|
|
return PTR_ERR(crtc_state);
|
2020-04-29 13:39:04 +03:00
|
|
|
|
|
|
|
|
if (crtc_state->hw.active) {
|
|
|
|
|
/*
|
|
|
|
|
* Preserve the inherited flag to avoid
|
|
|
|
|
* taking the full modeset path.
|
|
|
|
|
*/
|
2020-04-29 13:39:36 +03:00
|
|
|
crtc_state->inherited = true;
|
2020-04-29 13:39:04 +03:00
|
|
|
}
|
2020-01-22 22:43:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drm_for_each_plane(plane, state->dev) {
|
|
|
|
|
struct drm_plane_state *plane_state;
|
|
|
|
|
|
|
|
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
|
|
|
if (IS_ERR(plane_state))
|
|
|
|
|
return PTR_ERR(plane_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-03 11:37:41 -08:00
|
|
|
/*
|
|
|
|
|
* Calculate what we think the watermarks should be for the state we've read
|
|
|
|
|
* out of the hardware and then immediately program those watermarks so that
|
|
|
|
|
* we ensure the hardware settings match our internal state.
|
|
|
|
|
*
|
|
|
|
|
* We can calculate what we think WM's should be by creating a duplicate of the
|
|
|
|
|
* current state (which was constructed during hardware readout) and running it
|
|
|
|
|
* through the atomic check code to calculate new watermark values in the
|
|
|
|
|
* state object.
|
|
|
|
|
*/
|
2020-01-22 22:43:29 +02:00
|
|
|
static void sanitize_watermarks(struct drm_i915_private *dev_priv)
|
2015-12-03 11:37:41 -08:00
|
|
|
{
|
|
|
|
|
struct drm_atomic_state *state;
|
2016-11-08 13:55:32 +01:00
|
|
|
struct intel_atomic_state *intel_state;
|
2019-06-28 10:55:15 +02:00
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
struct intel_crtc_state *crtc_state;
|
2015-12-03 11:37:41 -08:00
|
|
|
struct drm_modeset_acquire_ctx ctx;
|
|
|
|
|
int ret;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Only supported on platforms that use atomic watermark design */
|
2022-08-24 16:15:31 +03:00
|
|
|
if (!dev_priv->display.funcs.wm->optimize_watermarks)
|
2015-12-03 11:37:41 -08:00
|
|
|
return;
|
|
|
|
|
|
2020-01-22 22:43:29 +02:00
|
|
|
state = drm_atomic_state_alloc(&dev_priv->drm);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
if (drm_WARN_ON(&dev_priv->drm, !state))
|
2020-01-22 22:43:29 +02:00
|
|
|
return;
|
2015-12-03 11:37:41 -08:00
|
|
|
|
2016-11-08 13:55:32 +01:00
|
|
|
intel_state = to_intel_atomic_state(state);
|
|
|
|
|
|
2020-01-22 22:43:29 +02:00
|
|
|
drm_modeset_acquire_init(&ctx, 0);
|
|
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
state->acquire_ctx = &ctx;
|
|
|
|
|
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
/*
|
|
|
|
|
* Hardware readout is the only time we don't want to calculate
|
|
|
|
|
* intermediate watermarks (since we don't trust the current
|
|
|
|
|
* watermarks).
|
|
|
|
|
*/
|
2019-02-04 14:25:38 -08:00
|
|
|
if (!HAS_GMCH(dev_priv))
|
2017-03-02 19:15:02 +02:00
|
|
|
intel_state->skip_intermediate_wm = true;
|
drm/i915: Add two-stage ILK-style watermark programming (v11)
In addition to calculating final watermarks, let's also pre-calculate a
set of intermediate watermark values at atomic check time. These
intermediate watermarks are a combination of the watermarks for the old
state and the new state; they should satisfy the requirements of both
states which means they can be programmed immediately when we commit the
atomic state (without waiting for a vblank). Once the vblank does
happen, we can then re-program watermarks to the more optimal final
value.
v2: Significant rebasing/rewriting.
v3:
- Move 'need_postvbl_update' flag to CRTC state (Daniel)
- Don't forget to check intermediate watermark values for validity
(Maarten)
- Don't due async watermark optimization; just do it at the end of the
atomic transaction, after waiting for vblanks. We do want it to be
async eventually, but adding that now will cause more trouble for
Maarten's in-progress work. (Maarten)
- Don't allocate space in crtc_state for intermediate watermarks on
platforms that don't need it (gen9+).
- Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit
now that ilk_update_wm is gone.
v4:
- Add a wm_mutex to cover updates to intel_crtc->active and the
need_postvbl_update flag. Since we don't have async yet it isn't
terribly important yet, but might as well add it now.
- Change interface to program watermarks. Platforms will now expose
.initial_watermarks() and .optimize_watermarks() functions to do
watermark programming. These should lock wm_mutex, copy the
appropriate state values into intel_crtc->active, and then call
the internal program watermarks function.
v5:
- Skip intermediate watermark calculation/check during initial hardware
readout since we don't trust the existing HW values (and don't have
valid values of our own yet).
- Don't try to call .optimize_watermarks() on platforms that don't have
atomic watermarks yet. (Maarten)
v6:
- Rebase
v7:
- Further rebase
v8:
- A few minor indentation and line length fixes
v9:
- Yet another rebase since Maarten's patches reworked a bunch of the
code (wm_pre, wm_post, etc.) that this was previously based on.
v10:
- Move wm_mutex to dev_priv to protect against racing commits against
disjoint CRTC sets. (Maarten)
- Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten)
v11:
- Now that we've moved to atomic watermark updates, make sure we call
the proper function to program watermarks in
{ironlake,haswell}_crtc_enable(); the failure to do so on the
previous patch iteration led to us not actually programming the
watermarks before turning on the CRTC, which was the cause of the
underruns that the CI system was seeing.
- Fix inverted logic for determining when to optimize watermarks. We
were needlessly optimizing when the intermediate/optimal values were
the same (harmless), but not actually optimizing when they differed
(also harmless, but wasteful from a power/bandwidth perspective).
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456276813-5689-1-git-send-email-matthew.d.roper@intel.com
2016-02-23 17:20:13 -08:00
|
|
|
|
2020-01-22 22:43:29 +02:00
|
|
|
ret = sanitize_watermarks_add_affected(state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
ret = intel_atomic_check(&dev_priv->drm, state);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto fail;
|
2015-12-03 11:37:41 -08:00
|
|
|
|
|
|
|
|
/* Write calculated watermark values back */
|
2019-06-28 10:55:15 +02:00
|
|
|
for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
|
|
|
|
|
crtc_state->wm.need_postvbl_update = true;
|
2021-09-29 01:57:48 +03:00
|
|
|
intel_optimize_watermarks(intel_state, crtc);
|
2017-11-10 12:34:53 +01:00
|
|
|
|
2019-06-28 10:55:15 +02:00
|
|
|
to_intel_crtc_state(crtc->base.state)->wm = crtc_state->wm;
|
2015-12-03 11:37:41 -08:00
|
|
|
}
|
|
|
|
|
|
2016-01-12 07:13:37 -08:00
|
|
|
fail:
|
2020-01-22 22:43:29 +02:00
|
|
|
if (ret == -EDEADLK) {
|
|
|
|
|
drm_atomic_state_clear(state);
|
|
|
|
|
drm_modeset_backoff(&ctx);
|
|
|
|
|
goto retry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If we fail here, it means that the hardware appears to be
|
|
|
|
|
* programmed in a way that shouldn't be possible, given our
|
|
|
|
|
* understanding of watermark requirements. This might mean a
|
|
|
|
|
* mistake in the hardware readout code or a mistake in the
|
|
|
|
|
* watermark calculations for a given platform. Raise a WARN
|
|
|
|
|
* so that this is noticeable.
|
|
|
|
|
*
|
|
|
|
|
* If this actually happens, we'll have to just leave the
|
|
|
|
|
* BIOS-programmed watermarks untouched and hope for the best.
|
|
|
|
|
*/
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN(&dev_priv->drm, ret,
|
|
|
|
|
"Could not determine valid watermarks for inherited state\n");
|
2020-01-22 22:43:29 +02:00
|
|
|
|
|
|
|
|
drm_atomic_state_put(state);
|
|
|
|
|
|
2015-12-03 11:37:41 -08:00
|
|
|
drm_modeset_drop_locks(&ctx);
|
|
|
|
|
drm_modeset_acquire_fini(&ctx);
|
|
|
|
|
}
|
|
|
|
|
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
static int intel_initial_commit(struct drm_device *dev)
|
|
|
|
|
{
|
|
|
|
|
struct drm_atomic_state *state = NULL;
|
|
|
|
|
struct drm_modeset_acquire_ctx ctx;
|
2019-10-31 12:25:59 +01:00
|
|
|
struct intel_crtc *crtc;
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
state = drm_atomic_state_alloc(dev);
|
|
|
|
|
if (!state)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
drm_modeset_acquire_init(&ctx, 0);
|
|
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
state->acquire_ctx = &ctx;
|
|
|
|
|
|
2019-10-31 12:25:59 +01:00
|
|
|
for_each_intel_crtc(dev, crtc) {
|
|
|
|
|
struct intel_crtc_state *crtc_state =
|
|
|
|
|
intel_atomic_get_crtc_state(state, crtc);
|
|
|
|
|
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
if (IS_ERR(crtc_state)) {
|
|
|
|
|
ret = PTR_ERR(crtc_state);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 12:26:02 +01:00
|
|
|
if (crtc_state->hw.active) {
|
2020-10-06 00:53:10 +03:00
|
|
|
struct intel_encoder *encoder;
|
|
|
|
|
|
2020-04-29 13:39:04 +03:00
|
|
|
/*
|
|
|
|
|
* We've not yet detected sink capabilities
|
|
|
|
|
* (audio,infoframes,etc.) and thus we don't want to
|
|
|
|
|
* force a full state recomputation yet. We want that to
|
|
|
|
|
* happen only for the first real commit from userspace.
|
|
|
|
|
* So preserve the inherited flag for the time being.
|
|
|
|
|
*/
|
2020-04-29 13:39:36 +03:00
|
|
|
crtc_state->inherited = true;
|
2020-04-29 13:39:04 +03:00
|
|
|
|
2019-10-31 12:25:59 +01:00
|
|
|
ret = drm_atomic_add_affected_planes(state, &crtc->base);
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
if (ret)
|
|
|
|
|
goto out;
|
2018-11-20 15:54:49 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* FIXME hack to force a LUT update to avoid the
|
|
|
|
|
* plane update forcing the pipe gamma on without
|
|
|
|
|
* having a proper LUT loaded. Remove once we
|
|
|
|
|
* have readout for pipe gamma enable.
|
|
|
|
|
*/
|
2019-10-31 12:26:03 +01:00
|
|
|
crtc_state->uapi.color_mgmt_changed = true;
|
2020-02-13 16:04:11 +02:00
|
|
|
|
2020-10-06 00:53:10 +03:00
|
|
|
for_each_intel_encoder_mask(dev, encoder,
|
|
|
|
|
crtc_state->uapi.encoder_mask) {
|
|
|
|
|
if (encoder->initial_fastset_check &&
|
|
|
|
|
!encoder->initial_fastset_check(encoder, crtc_state)) {
|
|
|
|
|
ret = drm_atomic_add_affected_connectors(state,
|
|
|
|
|
&crtc->base);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
2020-02-13 16:04:11 +02:00
|
|
|
}
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = drm_atomic_commit(state);
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (ret == -EDEADLK) {
|
|
|
|
|
drm_atomic_state_clear(state);
|
|
|
|
|
drm_modeset_backoff(&ctx);
|
|
|
|
|
goto retry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drm_atomic_state_put(state);
|
|
|
|
|
|
|
|
|
|
drm_modeset_drop_locks(&ctx);
|
|
|
|
|
drm_modeset_acquire_fini(&ctx);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-20 21:54:20 +03:00
|
|
|
static void intel_mode_config_init(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
struct drm_mode_config *mode_config = &i915->drm.mode_config;
|
|
|
|
|
|
|
|
|
|
drm_mode_config_init(&i915->drm);
|
2020-01-20 19:47:24 +02:00
|
|
|
INIT_LIST_HEAD(&i915->global_obj_list);
|
2019-09-20 21:54:20 +03:00
|
|
|
|
|
|
|
|
mode_config->min_width = 0;
|
|
|
|
|
mode_config->min_height = 0;
|
|
|
|
|
|
|
|
|
|
mode_config->preferred_depth = 24;
|
|
|
|
|
mode_config->prefer_shadow = 1;
|
|
|
|
|
|
|
|
|
|
mode_config->funcs = &intel_mode_funcs;
|
|
|
|
|
|
2021-08-23 15:25:32 +03:00
|
|
|
mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
|
2020-09-21 16:32:10 +05:30
|
|
|
|
2019-09-20 21:54:20 +03:00
|
|
|
/*
|
|
|
|
|
* Maximum framebuffer dimensions, chosen to match
|
|
|
|
|
* the maximum render engine surface size on gen4+.
|
|
|
|
|
*/
|
2021-03-19 21:42:42 -07:00
|
|
|
if (DISPLAY_VER(i915) >= 7) {
|
2019-09-20 21:54:20 +03:00
|
|
|
mode_config->max_width = 16384;
|
|
|
|
|
mode_config->max_height = 16384;
|
2021-03-19 21:42:42 -07:00
|
|
|
} else if (DISPLAY_VER(i915) >= 4) {
|
2019-09-20 21:54:20 +03:00
|
|
|
mode_config->max_width = 8192;
|
|
|
|
|
mode_config->max_height = 8192;
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-12 22:09:53 -07:00
|
|
|
} else if (DISPLAY_VER(i915) == 3) {
|
2019-09-20 21:54:20 +03:00
|
|
|
mode_config->max_width = 4096;
|
|
|
|
|
mode_config->max_height = 4096;
|
|
|
|
|
} else {
|
|
|
|
|
mode_config->max_width = 2048;
|
|
|
|
|
mode_config->max_height = 2048;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IS_I845G(i915) || IS_I865G(i915)) {
|
|
|
|
|
mode_config->cursor_width = IS_I845G(i915) ? 64 : 512;
|
|
|
|
|
mode_config->cursor_height = 1023;
|
2019-10-28 13:30:32 +02:00
|
|
|
} else if (IS_I830(i915) || IS_I85X(i915) ||
|
|
|
|
|
IS_I915G(i915) || IS_I915GM(i915)) {
|
2019-09-20 21:54:20 +03:00
|
|
|
mode_config->cursor_width = 64;
|
|
|
|
|
mode_config->cursor_height = 64;
|
|
|
|
|
} else {
|
|
|
|
|
mode_config->cursor_width = 256;
|
|
|
|
|
mode_config->cursor_height = 256;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-20 19:47:24 +02:00
|
|
|
static void intel_mode_config_cleanup(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
intel_atomic_global_obj_cleanup(i915);
|
|
|
|
|
drm_mode_config_cleanup(&i915->drm);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-24 14:08:28 +02:00
|
|
|
/* part #1: call before irq install */
|
|
|
|
|
int intel_modeset_init_noirq(struct drm_i915_private *i915)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
drm/i915: Fix assert_plane() warning on bootup with external display
On KBL, WHL RVPs, booting up with an external display connected, triggers
below warning, when the BiOS brings up the external display too.
This warning is not seen during hotplug.
[ 3.615226] ------------[ cut here ]------------
[ 3.619829] plane 1A assertion failure (expected on, current off)
[ 3.632039] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.633920] iwlwifi 0000:00:14.3: loaded firmware version 38.c0e03d94.0 op_mode iwlmvm
[ 3.647157] Modules linked in: iwlwifi cfg80211 btusb btrtl btbcm btintel bluetooth ecdh_generic
[ 3.647163] CPU: 2 PID: 354 Comm: frecon Not tainted 4.17.0-rc7-50176-g655af12d39c2 #3
[ 3.647165] Hardware name: Intel Corporation CoffeeLake Client Platform/WhiskeyLake U DDR4 ERB, BIOS CNLSFWR1.R00.X140.B00.1804040304 04/04/2018
[ 3.684509] RIP: 0010:assert_plane+0x71/0xbb
[ 3.764451] Call Trace:
[ 3.766888] intel_atomic_commit_tail+0xa97/0xb77
[ 3.771569] intel_atomic_commit+0x26a/0x279
[ 3.771572] drm_atomic_helper_set_config+0x5c/0x76
[ 3.780670] __drm_mode_set_config_internal+0x66/0x109
[ 3.780672] drm_mode_setcrtc+0x4c9/0x5cc
[ 3.780674] ? drm_mode_getcrtc+0x162/0x162
[ 3.789774] ? drm_mode_getcrtc+0x162/0x162
[ 3.798108] drm_ioctl_kernel+0x8d/0xe4
[ 3.801926] drm_ioctl+0x27d/0x368
[ 3.805311] ? drm_mode_getcrtc+0x162/0x162
[ 3.805314] ? selinux_file_ioctl+0x14e/0x199
[ 3.805317] vfs_ioctl+0x21/0x2f
[ 3.813812] do_vfs_ioctl+0x491/0x4b4
[ 3.813813] ? security_file_ioctl+0x37/0x4b
[ 3.813816] ksys_ioctl+0x55/0x75
[ 3.820672] __x64_sys_ioctl+0x1a/0x1e
[ 3.820674] do_syscall_64+0x51/0x5f
[ 3.820678] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 3.828221] RIP: 0033:0x7b5e04953967
[ 3.835504] RSP: 002b:00007fff2eafb6f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 3.835505] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007b5e04953967
[ 3.835505] RDX: 00007fff2eafb730 RSI: 00000000c06864a2 RDI: 000000000000000f
[ 3.835506] RBP: 00007fff2eafb720 R08: 0000000000000000 R09: 0000000000000000
[ 3.835507] R10: 0000000000000070 R11: 0000000000000246 R12: 000000000000000f
[ 3.879988] R13: 000056bc9dd7d210 R14: 00007fff2eafb730 R15: 00000000c06864a2
[ 3.887081] Code: 48 c7 c7 06 71 a5 be 84 c0 48 c7 c2 06 fd a3 be 48 89 f9 48 0f 44 ca 84 db 48 0f 45 d7 48 c7 c7 df d3 a4 be 31 c0 e8 af a0 c0 ff <0f> 0b eb 2b 48 c7 c7 06 fd a3 be 84 c0 48 c7 c2 06 71 a5 be 48
[ 3.905845] WARNING: CPU: 2 PID: 354 at drivers/gpu/drm/i915/intel_display.c:1294 assert_plane+0x71/0xbb
[ 3.920964] ---[ end trace dac692f4ac46391a ]---
The warning is seen when mode_setcrtc() is called for pipeB
during bootup and before we get a mode_setcrtc() for pipeA,
while doing update_crtcs() in intel_atomic_commit_tail().
Now since, plane1A is still active after commit, update_crtcs()
is done for pipeA and eventually update_plane() for plane1A.
intel_plane_state->ctl for plane1A is not updated since set_modecrtc() is
called for pipeB. So intel_plane_state->ctl for plane 1A will be 0x0.
So doing an update_plane() for plane1A, will result in clearing
PLANE_CTL_ENABLE bit, and hence the warning.
To fix this warning, force all active planes to recompute their states
in probe.
Changes in v8:
- Actually add Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Changes in v7:
- Move call to intel_initial_commit() after sanitize_watermarks()
Otherwise the plane update will still consult potentially bogus
watermarks we read out from the hardware. (Ville)
- Carry Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
from v6
Changes in v6:
- Handle EDEADLK for drm_atomic_get_crtc_state() and
drm_atomic_add_affected_planes()
- Remove optimization of calling intel_initial_commit()
only when there is more than one active pipe in probe.
- Avoid using intel_ types.
Changes in v5:
- Drop drm_modeset_lock_all_ctx() since locks will be taken later.
Changes in v4:
- Handle locking in intel_initial_commit()
- Move the for loop inside intel_initial_commit() so that
drm_atomic_commit() is called only once
- Call intel_initial_commit() only for more than one active crtc on boot.
- Save the return value of intel_initial_commit() and print a message in
case of an error
Changes in v3:
- Add comments
Changes in v2:
- Force all planes to recompute their states.(Ville Syrjälä)
- Update the commit message
Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1530902250-44583-1-git-send-email-azhar.shaikh@intel.com
2018-07-06 11:37:30 -07:00
|
|
|
int ret;
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2020-09-02 17:30:21 +03:00
|
|
|
if (i915_inject_probe_failure(i915))
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
2020-09-10 00:38:23 +03:00
|
|
|
if (HAS_DISPLAY(i915)) {
|
2020-09-02 17:30:21 +03:00
|
|
|
ret = drm_vblank_init(&i915->drm,
|
|
|
|
|
INTEL_NUM_PIPES(i915));
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intel_bios_init(i915);
|
|
|
|
|
|
|
|
|
|
ret = intel_vga_register(i915);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto cleanup_bios;
|
|
|
|
|
|
|
|
|
|
/* FIXME: completely on the wrong abstraction layer */
|
|
|
|
|
intel_power_domains_init_hw(i915, false);
|
|
|
|
|
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2021-05-18 14:34:43 -07:00
|
|
|
intel_dmc_ucode_init(i915);
|
2020-09-02 17:30:21 +03:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
i915->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0);
|
|
|
|
|
i915->flip_wq = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
|
|
|
|
WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
|
2017-11-13 15:36:22 +02:00
|
|
|
|
2021-05-25 17:06:55 -07:00
|
|
|
i915->window2_delay = 0; /* No DSB so no window2 delay */
|
|
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_mode_config_init(i915);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
2020-01-21 16:03:53 +02:00
|
|
|
ret = intel_cdclk_init(i915);
|
|
|
|
|
if (ret)
|
2021-05-18 14:34:43 -07:00
|
|
|
goto cleanup_vga_client_pw_domain_dmc;
|
2020-01-21 16:03:53 +02:00
|
|
|
|
2020-02-25 19:11:13 +02:00
|
|
|
ret = intel_dbuf_init(i915);
|
|
|
|
|
if (ret)
|
2021-05-18 14:34:43 -07:00
|
|
|
goto cleanup_vga_client_pw_domain_dmc;
|
2020-02-25 19:11:13 +02:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
ret = intel_bw_init(i915);
|
2019-05-24 18:36:14 +03:00
|
|
|
if (ret)
|
2021-05-18 14:34:43 -07:00
|
|
|
goto cleanup_vga_client_pw_domain_dmc;
|
2019-05-24 18:36:14 +03:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
init_llist_head(&i915->atomic_helper.free_list);
|
|
|
|
|
INIT_WORK(&i915->atomic_helper.free_work,
|
2017-02-02 20:47:41 +00:00
|
|
|
intel_atomic_helper_free_state_worker);
|
2017-01-23 21:29:39 +00:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_init_quirks(i915);
|
2010-07-19 13:53:12 -07:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_fbc_init(i915);
|
2018-11-07 16:16:45 -08:00
|
|
|
|
2020-02-24 14:08:28 +02:00
|
|
|
return 0;
|
2020-09-02 17:30:21 +03:00
|
|
|
|
2021-05-18 14:34:43 -07:00
|
|
|
cleanup_vga_client_pw_domain_dmc:
|
|
|
|
|
intel_dmc_ucode_fini(i915);
|
2020-09-02 17:30:21 +03:00
|
|
|
intel_power_domains_driver_remove(i915);
|
|
|
|
|
intel_vga_unregister(i915);
|
|
|
|
|
cleanup_bios:
|
|
|
|
|
intel_bios_driver_remove(i915);
|
|
|
|
|
|
|
|
|
|
return ret;
|
2020-02-24 14:08:28 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-02 17:30:20 +03:00
|
|
|
/* part #2: call after irq install, but before gem init */
|
|
|
|
|
int intel_modeset_init_nogem(struct drm_i915_private *i915)
|
2020-02-24 14:08:28 +02:00
|
|
|
{
|
|
|
|
|
struct drm_device *dev = &i915->drm;
|
|
|
|
|
enum pipe pipe;
|
|
|
|
|
struct intel_crtc *crtc;
|
|
|
|
|
int ret;
|
|
|
|
|
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_init_pm(i915);
|
2012-04-18 15:29:26 -03:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_panel_sanitize_ssc(i915);
|
drm/i915: Preserve SSC earlier
Commit 92122789b2d6 ("drm/i915: preserve SSC if previously set v3")
added code to intel_modeset_gem_init to override the SSC status read
from VBT with the SSC status set by BIOS.
However, intel_modeset_gem_init is invoked *after* intel_modeset_init,
which calls intel_setup_outputs, which *modifies* SSC status by way of
intel_init_pch_refclk. So unlike advertised, intel_modeset_gem_init
doesn't preserve the SSC status set by BIOS but whatever
intel_init_pch_refclk decided on.
This is a problem on dual gpu laptops such as the MacBook Pro which
require either a handler to switch DDC lines, or the discrete gpu
to proxy DDC/AUX communication: Both the handler and the discrete
gpu may initialize after the i915 driver, and consequently, an LVDS
connector may initially seem disconnected and the SSC therefore
is disabled by intel_init_pch_refclk, but on reprobe the connector
may turn out to be connected and the SSC must then be enabled.
Due to 92122789b2d6 however, the SSC is not enabled on reprobe since
it is assumed BIOS disabled it while in fact it was disabled by
intel_init_pch_refclk.
Also, because the SSC status is preserved so late, the preserved value
only ever gets used on resume but not on panel initialization:
intel_modeset_init calls intel_init_display which indirectly calls
intel_panel_use_ssc via multiple subroutines, *before* the BIOS value
overrides the VBT value in intel_modeset_gem_init (intel_panel_use_ssc
is the sole user of dev_priv->vbt.lvds_use_ssc).
Fix this by moving the code introduced by 92122789b2d6 from
intel_modeset_gem_init to intel_modeset_init before the invocation
of intel_setup_outputs and intel_init_display.
Add a DRM_DEBUG_KMS as suggested way back by Jani:
http://lists.freedesktop.org/archives/intel-gfx/2014-June/046666.html
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Tested-by: Paul Hordiienko <pvt.gord@gmail.com>
[MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina]
Tested-by: William Brown <william@blackhats.net.au>
[MBP 8,2 2011 intel SNB + amd turks pre-retina]
Tested-by: Lukas Wunner <lukas@wunner.de>
[MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina]
Tested-by: Bruno Bierbaumer <bruno@bierbaumer.net>
[MBP 11,3 2013 intel HSW + nvidia GK107 retina -- work in progress]
Fixes: 92122789b2d6 ("drm/i915: preserve SSC if previously set v3")
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2015-07-15 13:57:35 +02:00
|
|
|
|
2021-01-20 12:18:32 +02:00
|
|
|
intel_pps_setup(i915);
|
|
|
|
|
|
2019-10-04 15:20:19 +03:00
|
|
|
intel_gmbus_setup(i915);
|
|
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&i915->drm, "%d display pipe%s available.\n",
|
|
|
|
|
INTEL_NUM_PIPES(i915),
|
|
|
|
|
INTEL_NUM_PIPES(i915) > 1 ? "s" : "");
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
for_each_pipe(i915, pipe) {
|
|
|
|
|
ret = intel_crtc_init(i915, pipe);
|
|
|
|
|
if (ret) {
|
|
|
|
|
intel_mode_config_cleanup(i915);
|
|
|
|
|
return ret;
|
2016-10-25 18:58:02 +03:00
|
|
|
}
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2020-02-26 22:05:17 +05:30
|
|
|
intel_plane_possible_crtcs_init(i915);
|
2022-03-25 14:31:54 +02:00
|
|
|
intel_shared_dpll_init(i915);
|
2021-08-25 18:47:48 +03:00
|
|
|
intel_fdi_pll_freq_update(i915);
|
2012-04-20 17:11:53 +01:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_update_czclk(i915);
|
|
|
|
|
intel_modeset_init_hw(i915);
|
2021-02-25 18:12:25 +02:00
|
|
|
intel_dpll_update_ref_clks(i915);
|
2017-02-20 16:04:43 +02:00
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_hdcp_component_init(i915);
|
2019-02-16 23:06:51 +05:30
|
|
|
|
2019-09-20 21:54:21 +03:00
|
|
|
if (i915->max_cdclk_freq == 0)
|
|
|
|
|
intel_update_max_cdclk(i915);
|
2016-05-13 23:41:27 +03:00
|
|
|
|
2020-07-16 15:05:50 -07:00
|
|
|
/*
|
|
|
|
|
* If the platform has HTI, we need to find out whether it has reserved
|
|
|
|
|
* any display resources before we create our display outputs.
|
|
|
|
|
*/
|
|
|
|
|
if (INTEL_INFO(i915)->display.has_hti)
|
|
|
|
|
i915->hti_state = intel_de_read(i915, HDPORT_STATE);
|
|
|
|
|
|
2010-08-13 15:11:26 -07:00
|
|
|
/* Just disable it once at startup */
|
2019-10-01 18:25:06 +03:00
|
|
|
intel_vga_disable(i915);
|
2019-09-20 21:54:21 +03:00
|
|
|
intel_setup_outputs(i915);
|
2012-11-15 11:32:20 +00:00
|
|
|
|
drm: Split connection_mutex out of mode_config.mutex (v3)
After the split-out of crtc locks from the big mode_config.mutex
there's still two major areas it protects:
- Various connector probe states, like connector->status, EDID
properties, probed mode lists and similar information.
- The links from connector->encoder and encoder->crtc and other
modeset-relevant connector state (e.g. properties which control the
panel fitter).
The later is used by modeset operations. But they don't really care
about the former since it's allowed to e.g. enable a disconnected VGA
output or with a mode not in the probed list.
Thus far this hasn't been a problem, but for the atomic modeset
conversion Rob Clark needs to convert all modeset relevant locks into
w/w locks. This is required because the order of acquisition is
determined by how userspace supplies the atomic modeset data. This has
run into troubles in the detect path since the i915 load detect code
needs _both_ protections offered by the mode_config.mutex: It updates
probe state and it needs to change the modeset configuration to enable
the temporary load detect pipe.
The big deal here is that for the probe/detect users of this lock a
plain mutex fits best, but for atomic modesets we really want a w/w
mutex. To fix this lets split out a new connection_mutex lock for the
modeset relevant parts.
For simplicity I've decided to only add one additional lock for all
connector/encoder links and modeset configuration states. We have
piles of different modeset objects in addition to those (like bridges
or panels), so adding per-object locks would be much more effort.
Also, we're guaranteed (at least for now) to do a full modeset if we
need to acquire this lock. Which means that fine-grained locking is
fairly irrelevant compared to the amount of time the full modeset will
take.
I've done a full audit, and there's just a few things that justify
special focus:
- Locking in drm_sysfs.c is almost completely absent. We should
sprinkle mode_config.connection_mutex over this file a bit, but
since it already lacks mode_config.mutex this patch wont make the
situation any worse. This is material for a follow-up patch.
- omap has a omap_framebuffer_flush function which walks the
connector->encoder->crtc links and is called from many contexts.
Some look like they don't acquire mode_config.mutex, so this is
already racy. Again fixing this is material for a separate patch.
- The radeon hot_plug function to retrain DP links looks at
connector->dpms. Currently this happens without any locking, so is
already racy. I think radeon_hotplug_work_func should gain
mutex_lock/unlock calls for the mode_config.connection_mutex.
- Same applies to i915's intel_dp_hot_plug. But again, this is already
racy.
- i915 load_detect code needs to acquire this lock. Which means the
w/w dance due to Rob's work will be nicely contained to _just_ this
function.
I've added fixme comments everywhere where it looks suspicious but in
the sysfs code. After a quick irc discussion with Dave Airlie it
sounds like the lack of locking in there is due to sysfs cleanup fun
at module unload.
v1: original (only compile tested)
v2: missing mutex_init(), etc (from Rob Clark)
v3: i915 needs more care in the conversion:
- Protect the edp pp logic with the connection_mutex.
- Use connection_mutex in the backlight code due to
get_pipe_from_connector.
- Use drm_modeset_lock_all in suspend/resume paths.
- Update lock checks in the overlay code.
Cc: Alex Deucher <alexdeucher@gmail.com>
Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
|
|
|
drm_modeset_lock_all(dev);
|
2022-06-17 12:48:17 +03:00
|
|
|
intel_modeset_setup_hw_state(i915, dev->mode_config.acquire_ctx);
|
2021-08-17 23:51:58 +02:00
|
|
|
intel_acpi_assign_connector_fwnodes(i915);
|
drm: Split connection_mutex out of mode_config.mutex (v3)
After the split-out of crtc locks from the big mode_config.mutex
there's still two major areas it protects:
- Various connector probe states, like connector->status, EDID
properties, probed mode lists and similar information.
- The links from connector->encoder and encoder->crtc and other
modeset-relevant connector state (e.g. properties which control the
panel fitter).
The later is used by modeset operations. But they don't really care
about the former since it's allowed to e.g. enable a disconnected VGA
output or with a mode not in the probed list.
Thus far this hasn't been a problem, but for the atomic modeset
conversion Rob Clark needs to convert all modeset relevant locks into
w/w locks. This is required because the order of acquisition is
determined by how userspace supplies the atomic modeset data. This has
run into troubles in the detect path since the i915 load detect code
needs _both_ protections offered by the mode_config.mutex: It updates
probe state and it needs to change the modeset configuration to enable
the temporary load detect pipe.
The big deal here is that for the probe/detect users of this lock a
plain mutex fits best, but for atomic modesets we really want a w/w
mutex. To fix this lets split out a new connection_mutex lock for the
modeset relevant parts.
For simplicity I've decided to only add one additional lock for all
connector/encoder links and modeset configuration states. We have
piles of different modeset objects in addition to those (like bridges
or panels), so adding per-object locks would be much more effort.
Also, we're guaranteed (at least for now) to do a full modeset if we
need to acquire this lock. Which means that fine-grained locking is
fairly irrelevant compared to the amount of time the full modeset will
take.
I've done a full audit, and there's just a few things that justify
special focus:
- Locking in drm_sysfs.c is almost completely absent. We should
sprinkle mode_config.connection_mutex over this file a bit, but
since it already lacks mode_config.mutex this patch wont make the
situation any worse. This is material for a follow-up patch.
- omap has a omap_framebuffer_flush function which walks the
connector->encoder->crtc links and is called from many contexts.
Some look like they don't acquire mode_config.mutex, so this is
already racy. Again fixing this is material for a separate patch.
- The radeon hot_plug function to retrain DP links looks at
connector->dpms. Currently this happens without any locking, so is
already racy. I think radeon_hotplug_work_func should gain
mutex_lock/unlock calls for the mode_config.connection_mutex.
- Same applies to i915's intel_dp_hot_plug. But again, this is already
racy.
- i915 load_detect code needs to acquire this lock. Which means the
w/w dance due to Rob's work will be nicely contained to _just_ this
function.
I've added fixme comments everywhere where it looks suspicious but in
the sysfs code. After a quick irc discussion with Dave Airlie it
sounds like the lack of locking in there is due to sysfs cleanup fun
at module unload.
v1: original (only compile tested)
v2: missing mutex_init(), etc (from Rob Clark)
v3: i915 needs more care in the conversion:
- Protect the edp pp logic with the connection_mutex.
- Use connection_mutex in the backlight code due to
get_pipe_from_connector.
- Use drm_modeset_lock_all in suspend/resume paths.
- Update lock checks in the overlay code.
Cc: Alex Deucher <alexdeucher@gmail.com>
Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Rob Clark <robdclark@gmail.com>
2014-05-29 23:54:47 +02:00
|
|
|
drm_modeset_unlock_all(dev);
|
2014-03-07 08:57:48 -08:00
|
|
|
|
2014-05-13 23:32:22 +01:00
|
|
|
for_each_intel_crtc(dev, crtc) {
|
2020-11-17 11:47:09 -08:00
|
|
|
if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
|
2014-03-07 08:57:48 -08:00
|
|
|
continue;
|
2021-10-12 14:34:57 +10:00
|
|
|
intel_crtc_initial_plane_config(crtc);
|
2014-03-07 08:57:48 -08:00
|
|
|
}
|
2015-12-03 11:37:41 -08:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Make sure hardware watermarks really match the state we read out.
|
|
|
|
|
* Note that we need to do this after reconstructing the BIOS fb's
|
|
|
|
|
* since the watermark calculation done here will use pstate->fb.
|
|
|
|
|
*/
|
2019-09-20 21:54:21 +03:00
|
|
|
if (!HAS_GMCH(i915))
|
2020-01-22 22:43:29 +02:00
|
|
|
sanitize_watermarks(i915);
|
2016-10-25 18:58:02 +03:00
|
|
|
|
|
|
|
|
return 0;
|
2011-03-29 10:40:27 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-02 17:30:20 +03:00
|
|
|
/* part #3: call after gem init */
|
|
|
|
|
int intel_modeset_init(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
2020-09-10 00:38:23 +03:00
|
|
|
if (!HAS_DISPLAY(i915))
|
2020-09-02 17:30:20 +03:00
|
|
|
return 0;
|
|
|
|
|
|
2020-11-25 19:30:32 +00:00
|
|
|
/*
|
|
|
|
|
* Force all active planes to recompute their states. So that on
|
|
|
|
|
* mode_setcrtc after probe, all the intel_plane_state variables
|
|
|
|
|
* are already calculated and there is no assert_plane warnings
|
|
|
|
|
* during bootup.
|
|
|
|
|
*/
|
|
|
|
|
ret = intel_initial_commit(&i915->drm);
|
|
|
|
|
if (ret)
|
2020-12-10 23:07:41 +00:00
|
|
|
drm_dbg_kms(&i915->drm, "Initial modeset failed, %d\n", ret);
|
2020-11-25 19:30:32 +00:00
|
|
|
|
2020-11-06 14:55:27 -08:00
|
|
|
intel_overlay_setup(i915);
|
|
|
|
|
|
2020-09-02 17:30:20 +03:00
|
|
|
ret = intel_fbdev_init(&i915->drm);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
/* Only enable hotplug handling once the fbdev is fully set up. */
|
|
|
|
|
intel_hpd_init(i915);
|
2020-10-13 21:11:37 +03:00
|
|
|
intel_hpd_poll_disable(i915);
|
2020-09-02 17:30:20 +03:00
|
|
|
|
|
|
|
|
intel_init_ipc(i915);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-01 17:36:16 +03:00
|
|
|
void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
|
|
|
{
|
2021-12-01 15:57:04 +02:00
|
|
|
struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
|
2017-06-01 17:36:16 +03:00
|
|
|
/* 640x480@60Hz, ~25175 kHz */
|
|
|
|
|
struct dpll clock = {
|
|
|
|
|
.m1 = 18,
|
|
|
|
|
.m2 = 7,
|
|
|
|
|
.p1 = 13,
|
|
|
|
|
.p2 = 4,
|
|
|
|
|
.n = 2,
|
|
|
|
|
};
|
|
|
|
|
u32 dpll, fp;
|
|
|
|
|
int i;
|
|
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
|
|
|
|
i9xx_calc_dpll_params(48000, &clock) != 25154);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
|
"enabling pipe %c due to force quirk (vco=%d dot=%d)\n",
|
|
|
|
|
pipe_name(pipe), clock.vco, clock.dot);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
|
|
|
|
fp = i9xx_dpll_compute_fp(&clock);
|
2019-03-05 21:24:00 +02:00
|
|
|
dpll = DPLL_DVO_2X_MODE |
|
2017-06-01 17:36:16 +03:00
|
|
|
DPLL_VGA_MODE_DIS |
|
|
|
|
|
((clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT) |
|
|
|
|
|
PLL_P2_DIVIDE_BY_4 |
|
|
|
|
|
PLL_REF_INPUT_DREFCLK |
|
|
|
|
|
DPLL_VCO_ENABLE;
|
|
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, HTOTAL(pipe), (640 - 1) | ((800 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, HBLANK(pipe), (640 - 1) | ((800 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, HSYNC(pipe), (656 - 1) | ((752 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, VTOTAL(pipe), (480 - 1) | ((525 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, VBLANK(pipe), (480 - 1) | ((525 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, VSYNC(pipe), (490 - 1) | ((492 - 1) << 16));
|
|
|
|
|
intel_de_write(dev_priv, PIPESRC(pipe), ((640 - 1) << 16) | (480 - 1));
|
2017-06-01 17:36:16 +03:00
|
|
|
|
2022-03-21 21:50:04 +02:00
|
|
|
intel_de_write(dev_priv, FP0(pipe), fp);
|
|
|
|
|
intel_de_write(dev_priv, FP1(pipe), fp);
|
|
|
|
|
|
2017-06-01 17:36:16 +03:00
|
|
|
/*
|
|
|
|
|
* Apparently we need to have VGA mode enabled prior to changing
|
|
|
|
|
* the P1/P2 dividers. Otherwise the DPLL will keep using the old
|
|
|
|
|
* dividers, even though the register value does change.
|
|
|
|
|
*/
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, DPLL(pipe), dpll & ~DPLL_VGA_MODE_DIS);
|
|
|
|
|
intel_de_write(dev_priv, DPLL(pipe), dpll);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
|
|
|
|
/* Wait for the clocks to stabilize. */
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_posting_read(dev_priv, DPLL(pipe));
|
2017-06-01 17:36:16 +03:00
|
|
|
udelay(150);
|
|
|
|
|
|
|
|
|
|
/* The pixel multiplier can only be updated once the
|
|
|
|
|
* DPLL is enabled and the clocks are stable.
|
|
|
|
|
*
|
|
|
|
|
* So write it again.
|
|
|
|
|
*/
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, DPLL(pipe), dpll);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
|
|
|
|
/* We do this three times for luck */
|
|
|
|
|
for (i = 0; i < 3 ; i++) {
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, DPLL(pipe), dpll);
|
|
|
|
|
intel_de_posting_read(dev_priv, DPLL(pipe));
|
2017-06-01 17:36:16 +03:00
|
|
|
udelay(150); /* wait for warmup */
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-12 21:38:08 +02:00
|
|
|
intel_de_write(dev_priv, PIPECONF(pipe), PIPECONF_ENABLE);
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_posting_read(dev_priv, PIPECONF(pipe));
|
2017-11-29 17:37:31 +02:00
|
|
|
|
|
|
|
|
intel_wait_for_pipe_scanline_moving(crtc);
|
2017-06-01 17:36:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
|
|
|
{
|
2021-12-01 15:57:04 +02:00
|
|
|
struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
|
2017-11-29 17:37:30 +02:00
|
|
|
|
2020-01-22 00:46:41 +03:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "disabling pipe %c due to force quirk\n",
|
|
|
|
|
pipe_name(pipe));
|
2017-06-01 17:36:16 +03:00
|
|
|
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
2022-01-21 13:30:31 +02:00
|
|
|
intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
2022-01-21 13:30:31 +02:00
|
|
|
intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
2022-01-21 13:30:31 +02:00
|
|
|
intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
2021-12-01 17:25:49 +02:00
|
|
|
intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE_MASK);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&dev_priv->drm,
|
2021-12-01 17:25:49 +02:00
|
|
|
intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE_MASK);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, PIPECONF(pipe), 0);
|
|
|
|
|
intel_de_posting_read(dev_priv, PIPECONF(pipe));
|
2017-06-01 17:36:16 +03:00
|
|
|
|
2017-11-29 17:37:30 +02:00
|
|
|
intel_wait_for_pipe_scanline_stopped(crtc);
|
2017-06-01 17:36:16 +03:00
|
|
|
|
drm/i915/display: use intel_de_*() functions for register access
The implicit "dev_priv" local variable use has been a long-standing pain
point in the register access macros I915_READ(), I915_WRITE(),
POSTING_READ(), I915_READ_FW(), and I915_WRITE_FW().
Replace them with the corresponding new display engine register
accessors intel_de_read(), intel_de_write(), intel_de_posting_read(),
intel_de_read_fw(), and intel_de_write_fw().
No functional changes.
Generated using the following semantic patch:
@@
expression REG, OFFSET;
@@
- I915_READ(REG)
+ intel_de_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- POSTING_READ(REG)
+ intel_de_posting_read(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE(REG, OFFSET)
+ intel_de_write(dev_priv, REG, OFFSET)
@@
expression REG;
@@
- I915_READ_FW(REG)
+ intel_de_read_fw(dev_priv, REG)
@@
expression REG, OFFSET;
@@
- I915_WRITE_FW(REG, OFFSET)
+ intel_de_write_fw(dev_priv, REG, OFFSET)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Acked-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/41b937d632edb59ca2ddecefd9ac613c2f998d58.1580149467.git.jani.nikula@intel.com
2020-01-27 20:26:06 +02:00
|
|
|
intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
|
|
|
|
|
intel_de_posting_read(dev_priv, DPLL(pipe));
|
2017-06-01 17:36:16 +03:00
|
|
|
}
|
|
|
|
|
|
2015-07-13 16:30:25 +02:00
|
|
|
void intel_display_resume(struct drm_device *dev)
|
|
|
|
|
{
|
2022-06-16 12:48:20 +03:00
|
|
|
struct drm_i915_private *i915 = to_i915(dev);
|
|
|
|
|
struct drm_atomic_state *state = i915->modeset_restore_state;
|
2016-02-16 10:06:14 +01:00
|
|
|
struct drm_modeset_acquire_ctx ctx;
|
2015-07-13 16:30:25 +02:00
|
|
|
int ret;
|
2013-04-11 20:22:50 +02:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
if (!HAS_DISPLAY(i915))
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
return;
|
|
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
i915->modeset_restore_state = NULL;
|
2016-08-05 23:28:27 +03:00
|
|
|
if (state)
|
|
|
|
|
state->acquire_ctx = &ctx;
|
2015-07-13 16:30:25 +02:00
|
|
|
|
2016-02-16 10:06:14 +01:00
|
|
|
drm_modeset_acquire_init(&ctx, 0);
|
2015-07-13 16:30:25 +02:00
|
|
|
|
2016-08-05 23:28:27 +03:00
|
|
|
while (1) {
|
|
|
|
|
ret = drm_modeset_lock_all_ctx(dev, &ctx);
|
|
|
|
|
if (ret != -EDEADLK)
|
|
|
|
|
break;
|
2015-07-13 16:30:25 +02:00
|
|
|
|
2016-02-16 10:06:14 +01:00
|
|
|
drm_modeset_backoff(&ctx);
|
|
|
|
|
}
|
2015-07-13 16:30:25 +02:00
|
|
|
|
2016-08-05 23:28:27 +03:00
|
|
|
if (!ret)
|
2022-06-16 12:48:20 +03:00
|
|
|
ret = __intel_display_resume(i915, state, &ctx);
|
2016-08-05 23:28:27 +03:00
|
|
|
|
2022-06-16 12:48:20 +03:00
|
|
|
intel_enable_ipc(i915);
|
2016-02-16 10:06:14 +01:00
|
|
|
drm_modeset_drop_locks(&ctx);
|
|
|
|
|
drm_modeset_acquire_fini(&ctx);
|
2015-07-13 16:30:25 +02:00
|
|
|
|
2016-10-14 13:18:18 +01:00
|
|
|
if (ret)
|
2022-06-16 12:48:20 +03:00
|
|
|
drm_err(&i915->drm,
|
2020-01-22 00:46:41 +03:00
|
|
|
"Restoring old state failed with %i\n", ret);
|
2017-01-15 12:58:25 +00:00
|
|
|
if (state)
|
|
|
|
|
drm_atomic_state_put(state);
|
2011-03-29 10:40:27 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
static void intel_hpd_poll_fini(struct drm_i915_private *i915)
|
2017-10-26 14:52:00 -07:00
|
|
|
{
|
|
|
|
|
struct intel_connector *connector;
|
|
|
|
|
struct drm_connector_list_iter conn_iter;
|
|
|
|
|
|
2017-11-28 11:01:47 +00:00
|
|
|
/* Kill all the work that may have been queued by hpd. */
|
2019-09-20 21:54:18 +03:00
|
|
|
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
|
2017-10-26 14:52:00 -07:00
|
|
|
for_each_intel_connector_iter(connector, &conn_iter) {
|
|
|
|
|
if (connector->modeset_retry_work.func)
|
|
|
|
|
cancel_work_sync(&connector->modeset_retry_work);
|
2018-10-29 15:15:46 +05:30
|
|
|
if (connector->hdcp.shim) {
|
|
|
|
|
cancel_delayed_work_sync(&connector->hdcp.check_work);
|
|
|
|
|
cancel_work_sync(&connector->hdcp.prop_work);
|
2018-01-08 14:55:39 -05:00
|
|
|
}
|
2017-10-26 14:52:00 -07:00
|
|
|
}
|
|
|
|
|
drm_connector_list_iter_end(&conn_iter);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-14 15:50:57 +02:00
|
|
|
/* part #1: call before irq uninstall */
|
2019-09-20 21:54:18 +03:00
|
|
|
void intel_modeset_driver_remove(struct drm_i915_private *i915)
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
{
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return;
|
|
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
flush_workqueue(i915->flip_wq);
|
|
|
|
|
flush_workqueue(i915->modeset_wq);
|
2018-07-10 10:44:20 +01:00
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
flush_work(&i915->atomic_helper.free_work);
|
drm/i915/display/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200220165507.16823-4-pankaj.laxminarayan.bharadiya@intel.com
2020-02-20 22:25:02 +05:30
|
|
|
drm_WARN_ON(&i915->drm, !llist_empty(&i915->atomic_helper.free_list));
|
2020-02-14 15:50:57 +02:00
|
|
|
}
|
2017-01-23 21:29:39 +00:00
|
|
|
|
2020-02-14 15:50:57 +02:00
|
|
|
/* part #2: call after irq uninstall */
|
|
|
|
|
void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
|
|
|
|
|
{
|
drm/i915: skip display initialization when there is no display
Display features should not be initialized or de-initialized when there
is no display. Skip modeset initialization, output setup, plane, crtc,
encoder, connector registration, display cdclk and rawclk
initialization, display core initialization, etc.
Skip the functionality at as high level as possible, and remove any
redundant checks. If the functionality is conditional to *other* display
checks, do not add more. If the un-initialization has checks for
initialization, do not add more.
We explicitly do not care about any GMCH/VLV/CHV code paths, as they've
always had and will have display.
Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408203150.237947-3-jose.souza@intel.com
2021-04-08 13:31:50 -07:00
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return;
|
|
|
|
|
|
2013-04-24 11:13:35 +02:00
|
|
|
/*
|
|
|
|
|
* Due to the hpd irq storm handling the hotplug work can re-arm the
|
|
|
|
|
* poll handlers. Hence disable polling after hpd handling is shut down.
|
|
|
|
|
*/
|
2019-09-20 21:54:18 +03:00
|
|
|
intel_hpd_poll_fini(i915);
|
2013-04-24 11:13:35 +02:00
|
|
|
|
2019-11-26 18:16:09 -08:00
|
|
|
/*
|
|
|
|
|
* MST topology needs to be suspended so we don't have any calls to
|
|
|
|
|
* fbdev after it's finalized. MST will be destroyed later as part of
|
|
|
|
|
* drm_mode_config_cleanup()
|
|
|
|
|
*/
|
|
|
|
|
intel_dp_mst_suspend(i915);
|
|
|
|
|
|
2017-07-15 00:46:55 +02:00
|
|
|
/* poll work can call into fbdev, hence clean that up afterwards */
|
2019-09-20 21:54:18 +03:00
|
|
|
intel_fbdev_fini(i915);
|
2017-07-15 00:46:55 +02:00
|
|
|
|
2010-10-07 16:01:13 -07:00
|
|
|
intel_unregister_dsm_handler();
|
|
|
|
|
|
2011-07-08 12:22:42 +01:00
|
|
|
/* flush any delayed tasks or pending work */
|
|
|
|
|
flush_scheduled_work();
|
|
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
intel_hdcp_component_fini(i915);
|
2019-02-16 23:06:51 +05:30
|
|
|
|
2020-01-20 19:47:24 +02:00
|
|
|
intel_mode_config_cleanup(i915);
|
2012-12-18 15:24:37 +01:00
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
intel_overlay_cleanup(i915);
|
2014-03-31 15:10:44 +03:00
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
intel_gmbus_teardown(i915);
|
2017-11-13 15:36:22 +02:00
|
|
|
|
2019-09-20 21:54:18 +03:00
|
|
|
destroy_workqueue(i915->flip_wq);
|
|
|
|
|
destroy_workqueue(i915->modeset_wq);
|
2018-11-07 16:16:45 -08:00
|
|
|
|
2021-11-04 16:45:19 +02:00
|
|
|
intel_fbc_cleanup(i915);
|
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs.
Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are
supported. HDMI, DisplayPort and additional SDVO output support will
follow.
Support for the mode setting code is controlled by the new 'modeset'
module option. A new config option, CONFIG_DRM_I915_KMS controls the
default behavior, and whether a PCI ID list is built into the module for
use by user level module utilities.
Note that if mode setting is enabled, user level drivers that access
display registers directly or that don't use the kernel graphics memory
manager will likely corrupt kernel graphics memory, disrupt output
configuration (possibly leading to hangs and/or blank displays), and
prevent panic/oops messages from appearing. So use caution when
enabling this code; be sure your user level code supports the new
interfaces.
A new SysRq key, 'g', provides emergency support for switching back to
the kernel's framebuffer console; which is useful for testing.
Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-11-07 14:24:08 -08:00
|
|
|
}
|
|
|
|
|
|
2020-09-02 17:30:22 +03:00
|
|
|
/* part #3: call after gem init */
|
|
|
|
|
void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915)
|
|
|
|
|
{
|
2021-05-18 14:34:43 -07:00
|
|
|
intel_dmc_ucode_fini(i915);
|
2020-09-02 17:30:22 +03:00
|
|
|
|
|
|
|
|
intel_power_domains_driver_remove(i915);
|
|
|
|
|
|
|
|
|
|
intel_vga_unregister(i915);
|
|
|
|
|
|
|
|
|
|
intel_bios_driver_remove(i915);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 22:23:21 +02:00
|
|
|
bool intel_modeset_probe_defer(struct pci_dev *pdev)
|
|
|
|
|
{
|
2021-10-05 22:23:22 +02:00
|
|
|
struct drm_privacy_screen *privacy_screen;
|
|
|
|
|
|
2021-10-05 22:23:21 +02:00
|
|
|
/*
|
|
|
|
|
* apple-gmux is needed on dual GPU MacBook Pro
|
|
|
|
|
* to probe the panel if we're the inactive GPU.
|
|
|
|
|
*/
|
|
|
|
|
if (vga_switcheroo_client_probe_defer(pdev))
|
|
|
|
|
return true;
|
|
|
|
|
|
2021-10-05 22:23:22 +02:00
|
|
|
/* If the LCD panel has a privacy-screen, wait for it */
|
|
|
|
|
privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL);
|
|
|
|
|
if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
drm_privacy_screen_put(privacy_screen);
|
|
|
|
|
|
2021-10-05 22:23:21 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 20:27:55 -08:00
|
|
|
void intel_display_driver_register(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
intel_display_debugfs_register(i915);
|
|
|
|
|
|
|
|
|
|
/* Must be done after probing outputs */
|
|
|
|
|
intel_opregion_register(i915);
|
|
|
|
|
acpi_video_register();
|
|
|
|
|
|
|
|
|
|
intel_audio_init(i915);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Some ports require correctly set-up hpd registers for
|
|
|
|
|
* detection to work properly (leading to ghost connected
|
|
|
|
|
* connector status), e.g. VGA on gm45. Hence we can only set
|
|
|
|
|
* up the initial fbdev config after hpd irqs are fully
|
|
|
|
|
* enabled. We do it last so that the async config cannot run
|
|
|
|
|
* before the connectors are registered.
|
|
|
|
|
*/
|
|
|
|
|
intel_fbdev_initial_config_async(&i915->drm);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We need to coordinate the hotplugs with the asynchronous
|
|
|
|
|
* fbdev configuration, for which we use the
|
|
|
|
|
* fbdev->async_cookie.
|
|
|
|
|
*/
|
|
|
|
|
drm_kms_helper_poll_init(&i915->drm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void intel_display_driver_unregister(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
if (!HAS_DISPLAY(i915))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
intel_fbdev_unregister(i915);
|
|
|
|
|
intel_audio_deinit(i915);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* After flushing the fbdev (incl. a late async config which
|
|
|
|
|
* will have delayed queuing of a hotplug event), then flush
|
|
|
|
|
* the hotplug events.
|
|
|
|
|
*/
|
|
|
|
|
drm_kms_helper_poll_fini(&i915->drm);
|
|
|
|
|
drm_atomic_helper_shutdown(&i915->drm);
|
|
|
|
|
|
|
|
|
|
acpi_video_unregister();
|
|
|
|
|
intel_opregion_unregister(i915);
|
|
|
|
|
}
|
2022-03-29 10:02:04 +01:00
|
|
|
|
|
|
|
|
bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915)
|
|
|
|
|
{
|
|
|
|
|
return DISPLAY_VER(i915) >= 6 && i915_vtd_active(i915);
|
|
|
|
|
}
|