Jani Nikula [Wed, 11 Dec 2024 12:54:30 +0000 (14:54 +0200)]
drm/i915/dp: add g4x_dp_compute_config()
Add g4x_dp_compute_config() instead of using intel_dp_compute_config()
directly, in order to slightly reduce the clutter in the latter wrt
->has_pch_encoder.
Jani Nikula [Thu, 5 Dec 2024 09:49:33 +0000 (11:49 +0200)]
drm/print: add drm_print_hex_dump()
Add a helper to print a hex dump to a struct drm_printer. There's no
fancy formatting stuff, just 16 space-separated bytes per line, with an
optional prefix.
Jani Nikula [Mon, 25 Nov 2024 15:19:33 +0000 (17:19 +0200)]
drm/i915/mst: add beginnings of DP MST documentation
Add a little bit of documentation around DP MST. This is nowhere near
complete nor does it have enough detail. But it's better than nothing,
and hopefully gives people a basic grasp of what's going on.
Suraj Kandpal [Tue, 3 Dec 2024 08:47:04 +0000 (14:17 +0530)]
drm/i915/display: Refactor DPKGC code to call it from atomic_commit_tail
Refactor the code to check the fixed refresh rate condition in the dpkgc
function itself and call it from intel_atomic_commit_tail so that we
have all the required values specially linetime which is computed after
intel_wm_compute, this will also help implement some WA's which requires
linetime. This also avoid writing into any of the registers while we are
in compute_config phase.
Suraj Kandpal [Tue, 3 Dec 2024 08:47:03 +0000 (14:17 +0530)]
drm/i915/wm: Use intel_display structure in DPKGC code
Use intel_display for DPKGC code wherever we can. While we are
at it also use intel_de_rmw instead of intel_uncore_rmw as we
really don't need the internal uncore_rmw_function.
Suraj Kandpal [Tue, 3 Dec 2024 08:47:02 +0000 (14:17 +0530)]
drm/i915/wm: Refactor dpkgc value prepration
Refactor the value getting prepped to be written into the PKG_C_LATENCY
register by ORing the REG_FIELD_PREP values instead of having val
getting operated on twice.
We dont need the clear and val variables to be initialized.
Jani Nikula [Fri, 29 Nov 2024 10:25:03 +0000 (12:25 +0200)]
drm/i915/display: replace dig_port->saved_port_bits with flags
dig_port->saved_port_bits is used to permanently store two DDI_BUF_CTL
bits, DDI_BUF_PORT_REVERSAL and DDI_A_4_LANES. Store them separately as
bools to make their use more logical and less about storing state as
register bits.
Jani Nikula [Thu, 28 Nov 2024 15:38:23 +0000 (17:38 +0200)]
drm/i915/display: convert high level power interfaces to struct intel_display
Going forward, struct intel_display is the main device data structure
for display. Convert the high level interfaces (init, cleanup, suspend,
resume, etc.) of intel_display_power.c over to it. The actual power
get/put etc. are left for follow-up.
Jani Nikula [Thu, 28 Nov 2024 15:38:22 +0000 (17:38 +0200)]
drm/i915/display: convert power domain code internally to struct intel_display
Going forward, struct intel_display is the main device data structure
for display. Convert intel_display_power.c internally first, leaving
external interfaces for follow-up.
Suraj Kandpal [Mon, 2 Dec 2024 06:04:10 +0000 (11:34 +0530)]
drm/i915/hdcp: Remove log for HDMI HDCP LIC check
We don't need to shout out loud if there is a Link Integrity
Failure. This does not mean HDCP has failed, it is expected and
taken into account in the HDCP Spec. The real failure happens when
we are not able to reauthenticate and get HDCP running again for
which we already have the right logging.
Gustavo Sousa [Fri, 29 Nov 2024 16:37:56 +0000 (13:37 -0300)]
drm/xe/display: Flush DMC wakelock release work on runtime suspend
We currently are not calling display runtime suspend functions when
D3cold is not allowed. Because of that, we end up not disabling dynamic
DC states (and do not go to DC9). With dynamic DC states enabled, we
will also have DMC wakelock enabled. Since we use a delayed work to
release the DMC wakelock, the work might get executed a little too late
(after the PCI device has been put to D3hot) and we get a timeout
warning ("DMC wakelock release timed out") because the MMIO for
releasing the wakelock will be invalid after that point.
To fix that, make sure we flush the release work at the end of
xe_display_pm_runtime_suspend_late(). We can do that unconditionally
because, if there is no pending work, that turns into a no-op.
The current behavior for the runtime suspend case is that
xe_display_pm_suspend_late() is only called when D3cold is allowed.
Let's incorporate that behavior into a function specific to runtime PM
and call it xe_display_pm_runtime_suspend_late().
With that, we keep stuff a bit more self-contained and allow having a
place for adding more "late display runtime suspend"-related logic that
isn't dependent on the "D3cold allowed" state.
v2:
- Fix typo in that caused xe_display_pm_runtime_suspend_late() to call
itself instead of xe_display_pm_suspend_late().
- Add the empty version of xe_display_pm_runtime_suspend_late() for
the !CONFIG_DRM_XE_DISPLAY case.
We will need to flush the release work from outside in an upcoming
change. Let's put that into a public interface and call it
intel_dmc_wl_flush_release_work().
Ville Syrjälä [Wed, 6 Nov 2024 21:58:56 +0000 (23:58 +0200)]
drm/i915/pps: Spell out the eDP spec power sequencing delays a bit more clearly
We determine the "spec" eDP power sequencing delays
by referencing some max values from the eDP spec.
Write out each number from the spec explicitly instead
of precomputing the final number (that's the job of
the computer). Makes it a bit easier to see what the
supposed spec defined numbers actually are.
Ville Syrjälä [Wed, 6 Nov 2024 21:58:55 +0000 (23:58 +0200)]
drm/i915/lvds: Use struct intel_pps_delays for LVDS power sequencing
Reuse struct intel_pps_delays for the LVDS power
sequencing delays instead of hand rolling it all.
Perhaps in the future we could reuse some of the
same PPS code for both LVDS and eDP (assuming we
can decouple the PPS code from intel_dp...).
Ville Syrjälä [Wed, 6 Nov 2024 21:58:54 +0000 (23:58 +0200)]
drm/i915/pps: Rename intel_pps_delay members
Stop using the semi-random eDP spec T1,T3,... names for the
power sequencing delays, and instead call them by their human
readable names. Much easier to keep track what delay goes
where when you don't have to constantly cross reference against
the eDP spec.
Ville Syrjälä [Wed, 6 Nov 2024 21:58:53 +0000 (23:58 +0200)]
drm/i915/pps: Decouple pps delays from VBT struct definition
We currently lack a proper struct definition for the VBT power
squencing delays, and instead we use the same struct definition
(in intel_bios.h) for both the VBT layout and our driver side
state. Decouple those two things by moving the current struct
into intel_vbt_defs.h and adding a new one for the driver's use.
Ville Syrjälä [Wed, 6 Nov 2024 21:58:52 +0000 (23:58 +0200)]
drm/i915/pps: Store the power cycle delay without the +1
The code initializing the power sequencing delays is a bit
hard to follow. One confusing thing is that we keep doing the
+/-1 adjustment for the hardware register value in several places.
Simplify this a bit by doing the adjustment only when reading or
writing the actual register.
Ville Syrjälä [Wed, 20 Nov 2024 16:41:22 +0000 (18:41 +0200)]
drm/i915/dsb: Nuke the MMIO->indexed register write logic
We've determined that indexed DSB writes are only faster
than MMIO writes when writing the same register ~5 or more
times. That seems very unlikely to happen in any other case
than when using indexed LUT registers. Simplify the code
by removing the MMIO->indexed write conversion logic and
just emit the instruction as an indexed write from the get go.
Ville Syrjälä [Wed, 20 Nov 2024 16:41:21 +0000 (18:41 +0200)]
drm/i915/color: Stop using non-posted DSB writes for legacy LUT
DSB LUT register writes vs. palette anti-collision logic
appear to interact in interesting ways:
- posted DSB writes simply vanish into thin air while
anti-collision is active
- non-posted DSB writes actually get blocked by the anti-collision
logic, but unfortunately this ends up hogging the bus for
long enough that unrelated parallel CPU MMIO accesses start
to disappear instead
Even though we are updating the LUT during vblank we aren't
immune to the anti-collision logic because it kicks in briefly
for pipe prefill (initiated at frame start). The safe time
window for performing the LUT update is thus between the
undelayed vblank and frame start. Turns out that with low
enough CDCLK frequency (DSB execution speed depends on CDCLK)
we can exceed that.
As we are currently using non-posted writes for the legacy LUT
updates, in which case we can hit the far more severe failure
mode. The problem is exacerbated by the fact that non-posted
writes are much slower than posted writes (~4x it seems).
To mititage the problem let's switch to using posted DSB
writes for legacy LUT updates (which will involve using the
double write approach to avoid other problems with DSB
vs. legacy LUT writes). Despite writing each register twice
this will in fact make the legacy LUT update faster when
compared to the non-posted write approach, making the
problem less likely to appear. The failure mode is also
less severe.
This isn't the 100% solution we need though. That will involve
estimating how long the LUT update will take, and pushing
frame start and/or delayed vblank forward to guarantee that
the update will have finished by the time the pipe prefill
starts...
Cc: stable@vger.kernel.org Fixes: 34d8311f4a1c ("drm/i915/dsb: Re-instate DSB for LUT updates") Fixes: 25ea3411bd23 ("drm/i915/dsb: Use non-posted register writes for legacy LUT") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12494 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241120164123.12706-3-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Ville Syrjälä [Wed, 20 Nov 2024 16:41:20 +0000 (18:41 +0200)]
drm/i915/dsb: Don't use indexed register writes needlessly
Turns out the DSB indexed register write command has
rather significant initial overhead compared to the normal
MMIO write command. Based on some quick experiments on TGL
you have to write the register at least ~5 times for the
indexed write command to come out ahead. If you write the
register less times than that the MMIO write is faster.
So it seems my automagic indexed write logic was a bit
misguided. Go back to the original approach only use
indexed writes for the cases we know will benefit from
it (indexed LUT register updates).
Currently we shouldn't have any cases where this truly
matters (just some rare double writes to the precision
LUT index registers), but we will need to switch the
legacy LUT updates to write each LUT register twice (to
avoid some palette anti-collision logic troubles).
This would be close to the worst case for using indexed
writes (two writes per register, and 256 separate registers).
Using the MMIO write command should shave off around 30%
of the execution time compared to using the indexed write
command.
Cc: stable@vger.kernel.org Fixes: 34d8311f4a1c ("drm/i915/dsb: Re-instate DSB for LUT updates") Fixes: 25ea3411bd23 ("drm/i915/dsb: Use non-posted register writes for legacy LUT") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241120164123.12706-2-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Ville Syrjälä [Wed, 27 Nov 2024 06:11:16 +0000 (08:11 +0200)]
drm/i915/dpt: Evict all DPT VMAs on suspend
Currently intel_dpt_resume() tries to blindly rewrite all the
PTEs for currently bound DPT VMAs. That is problematic because
the CPU mapping for the DPT is only really guaranteed to exist
while the DPT object has been pinned. In the past we worked
around this issue by making DPT objects unshrinkable, but that
is undesirable as it'll waste physical RAM.
Let's instead forcefully evict all the DPT VMAs on suspend,
thus guaranteeing that intel_dpt_resume() has nothing to do.
To guarantee that all the DPT VMAs are evictable by
intel_dpt_suspend() we need to flush the cleanup workqueue
after the display output has been shut down.
And for good measure throw in a few extra WARNs to catch
any mistakes.
Ville Syrjälä [Wed, 27 Nov 2024 06:11:15 +0000 (08:11 +0200)]
drm/i915: Intruduce display.wq.cleanup
Introduce a dedicated workqueue for the commit cleanup work.
In the future we'll need this to guarantee all the cleanup
works have finished at a specific point during suspend.
Ville Syrjälä [Wed, 27 Nov 2024 06:11:14 +0000 (08:11 +0200)]
drm/i915: Don't reuse commit_work for the cleanup
Currently we reuse the commit_work for a later cleanup step.
Let's not do that so that atomic ioctl handler won't accidentally
wait for the cleanup work when it really wants to just wait on the
commit_tail() part. We'll just add another work struct for the
cleanup.
Jani Nikula [Mon, 25 Nov 2024 12:09:59 +0000 (14:09 +0200)]
drm/i915/ddi: clarify intel_ddi_connector_get_hw_state() for DP MST
encoder->get_hw_state() returns false for DP MST, and currently always
interprets 128b/132b as MST. Therefore the DDI MST mode checks in
intel_ddi_connector_get_hw_state() are redundant.
Prepare for future, and handle 128b/132b SST and warn on 8b/10b MST.
Jani Nikula [Wed, 20 Nov 2024 11:30:32 +0000 (13:30 +0200)]
drm/i915/irq: hide display_irqs_enabled access
Move the check for display_irqs_enabled within vlv_display_irq_reset()
and vlv_display_irq_postinstall() to avoid looking at struct
intel_display members within i915 core irq code.
Within display irq code, vlv_display_irq_reset() may need to be called
with !display_irqs_enabled, so add a small wrapper.
Jani Nikula [Wed, 20 Nov 2024 11:30:30 +0000 (13:30 +0200)]
drm/i915/overlay: add intel_overlay_available() and use it
Avoid accessing struct intel_display members directly from
i915_getparam_ioctl(). Add intel_overlay_available() function to provide
the information for I915_PARAM_HAS_OVERLAY.
Jani Nikula [Wed, 20 Nov 2024 12:43:17 +0000 (14:43 +0200)]
drm/i915/ddi: split up intel_ddi_read_func_ctl() by output type
The function has become quite long, and the switch-case statement quite
complex with the fallthrougs. Simplify by splitting to individual
functions and an if-ladder.
This highlights how TRANS_DDI_MODE_SELECT_FDI_OR_128B132B works on
different platforms.
Jani Nikula [Wed, 20 Nov 2024 12:43:15 +0000 (14:43 +0200)]
drm/i915/dp: refactor clear/wait for act sent
Move clear_act_sent() and wait_for_act_sent() to intel_ddi.[ch] and make
independent of DP MST. They'll be needed for 128b/132b SST
operation. Rename accordingly.
Jani Nikula [Wed, 20 Nov 2024 12:43:10 +0000 (14:43 +0200)]
drm/i915/mst: unify MST connector function naming to mst_connector_*
Similar to commit 5674e700d43e ("drm/i915/mst: change naming from fake
encoders to MST stream encoders"), name all MST connector related
functions to mst_connector_*.
Jani Nikula [Wed, 20 Nov 2024 12:43:09 +0000 (14:43 +0200)]
drm/i915/mst: pass intel_dp around in mst stream helpers
All of the functions in question operate on the primary encoder, and
more specifically the primary intel_dp, so pass it around instead of the
encoder for less ambiguity.
Ankit Nautiyal [Wed, 13 Nov 2024 11:55:31 +0000 (17:25 +0530)]
drm/i915/display/xe3lpd: Avoid setting YUV420_MODE in PIPE_MISC
For Xe3_LPD the PIPE_MISC YUV420 Enable (bit 27), already implies enabling
full blend YUV420 mode and YUV420 Mode (bit 26) is removed.
Therefore, avoid setting YUV420 Mode for Xe3_LPD+ while programming
PIPE_MISC for YCbCr420 output format.
Animesh Manna [Tue, 5 Nov 2024 10:39:16 +0000 (16:09 +0530)]
drm/i915/psr: Disable psr1 if setup_time > vblank
Issue is seen when PSR enabled with setup frames and when try to disable
PSR at SRDONACK State (0x1). PSR FSM is stuck at SRDONACK(0x1) for more
than 5 seconds. Issue not seen with Setup frames disabled. Currently
disable psr1 if setuptime > vblank to workaround the above issue.
Imre Deak [Mon, 18 Nov 2024 13:10:44 +0000 (15:10 +0200)]
drm/i915/dp_mst: Fix connector initialization in intel_dp_add_mst_connector()
The connector initialization in intel_dp_add_mst_connector() depends on
the device pointer in connector to be valid, at least by connector
debug printing. The device pointer is initialized by drm_connector_init(),
however that function also exposes the connector to in-kernel users,
which can't be done before the connector is fully initialized. For now
make sure the device pointer is valid before it's used, until a
follow-up change moving this to DRM core.
This issue was revealed by the commit in the Fixes: line below, before
which the above debug printing checked and handled a NULL device pointer
gracefully in DRM core.
Cc: Jani Nikula <jani.nikula@intel.com> Fixes: 529798bd786a ("drm/i915/mst: convert to struct intel_display") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12799 Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241118131044.1278028-1-imre.deak@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drm/i915/dp: Include the time taken by AUX Tx for timeout
As per DP spec the timeout for LANE_CHANNEL_EQ_DONE is 400ms. But this
timeout value is exclusively for the Aux RD Interval and excludes the
time consumed for the AUX Tx (i.e reading/writing FFE presets). Add
another 50ms for these AUX Tx to the 400ms timeout.
Ref: "Figure 3-52: 128b132b DP DPTC LANEx_CHANNEL_EQ_DONE Sequence" of
DP2.1a spec.
Co-developed-by: Srikanth V NagaVenkata <nagavenkata.srikanth.v@intel.com> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com> Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com> Acked-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925034432.1777029-4-arun.r.murthy@intel.com
Arun R Murthy [Fri, 11 Oct 2024 04:58:25 +0000 (10:28 +0530)]
drm/i915/dp: read Aux RD interval just before setting the FFE preset
Figure 3-52: 128b132b DP DPTC LANEx_CHANNEL_EQ_DONE Sequence of
DP2.1a spec.
After reading LANEx_CHANNEL_EQ_DONE, read the FFE presets.
AUX_RD_INTERVAL and then write the new FFE presets.
v4: Read AUX_RD_INTERVAL before get/set TX FFE preset (Jani)
drm/i915/dp: use fsleep instead of usleep_range for LT
Sleeping for < 10us use udelay, for 10us to 20ms use usleep_range() and
for > 10ms use msleep. flseep() will call the particular API based on
the above condition. (Documentation/timers/timers-howto.rst)
Aux RD Interval value depends on the value read from the dpcd register
which is updated from the sink device, hence use flseep.
Rodrigo Vivi [Wed, 13 Nov 2024 22:50:16 +0000 (17:50 -0500)]
drm/{i915, xe}: Move power_domains suspend/resume to display_power
Move intel_power_domains_{suspend,resume} to inside
intel_display_power_{suspend_late, resume_early}.
With this also change the VLV suspend failure to call
the intel_display_power_resume_early. In the end, the only
function executed there for VLV is the intel_power_domains_resume.
Besides make the code more consistency give the call that was
immediately before: intel_display_power_suspend_late.
Rodrigo Vivi [Wed, 13 Nov 2024 22:50:11 +0000 (17:50 -0500)]
drm/i915/display: Convert i915_suspend into i9xx_display_sr
These save & restore functions inside i915_suspend are old display
functions to save and restore a bunch of display related registers.
Move it under display and rename accordantly. Just don't move it
entirely towards intel_display struct yet because it depends
on drm_i915_private for the IS_MOBILE.
While doing this conversion also update the MIT header using
the new SPDX ones.
v2: Fix Makefile and include (Jani)
Removed vga and gmbus (Jani, Ville)
Ankit Nautiyal [Wed, 30 Oct 2024 08:41:00 +0000 (14:11 +0530)]
drm/i915/dp: Limit max compressed bpp to 18 when forcing DSC
While forcing DSC when it is not actually required, the max compressed
bpp from the source gets picked for compression for some pipe bpps.
Apparently, when DSC is not required, forcing DSC to the maximum compressed
bpp seems to cause underruns.
To avoid this, limit the max compressed bpp to 18 while forcing DSC. This
value works across platforms with different pipe bpps and prevents
underruns.
Jani Nikula [Tue, 12 Nov 2024 11:10:44 +0000 (13:10 +0200)]
drm/i915/dp: add comments about hooks called from MST stream encoders
It would be best to have self-explanatory code, but lacking that, add
some comments about the way the DDI encoder hooks get called from DP MST
stream encoders.
Jani Nikula [Tue, 12 Nov 2024 11:10:43 +0000 (13:10 +0200)]
drm/i915/mst: change naming from fake encoders to MST stream encoders
The fake encoders pretty much match individual MST streams. The encoders
remain as fake as ever, but change the naming to MST stream
encoders. Rename all the encoder hooks and related functions called from
them to mst_stream_* to clarify what type of encoders the hooks are
called on.
Jani Nikula [Tue, 12 Nov 2024 11:10:42 +0000 (13:10 +0200)]
drm/i915/mst: convert to struct intel_display
struct intel_display will replace struct drm_i915_private as the main
display device data structure. Convert the DP MST code to struct
intel_display as much as possible.
Jani Nikula [Tue, 12 Nov 2024 11:10:41 +0000 (13:10 +0200)]
drm/i915/display: make CHICKEN_TRANS() display version aware
Making register macros platform or display version aware is not exactly
something I want to promote widely, but in this case it's the lesser of
two evils. hsw_chicken_trans_reg() is not pretty, and it doesn't have a
suitable home.
Jani Nikula [Tue, 12 Nov 2024 11:10:39 +0000 (13:10 +0200)]
drm/i915/mst: introduce to_primary_encoder() and to_primary_dp()
Add helpers to_primary_encoder() and to_primary_dp() to convert fake MST
encoder pointers to primary encoder and DP pointers, respectively, and
use them.
The main point is to highlight the primary encoder and DP usage. Very
few places actually need the struct intel_dp_mst_encoder pointer, or the
primary struct intel_digital_port, so ditch them where possible for
clarity.
Jani Nikula [Tue, 12 Nov 2024 11:10:37 +0000 (13:10 +0200)]
drm/i915/mst: pass primary encoder to primary encoder hooks
Pass the primary encoder to the primary encoder hooks. This is
pedantically correct, but intel_ddi_post_pll_disable() also works with
the fake encoder by coincidence.
Jani Nikula [Mon, 11 Nov 2024 10:34:04 +0000 (12:34 +0200)]
drm/i915/display: add mobile platform group
Identify mobile platforms separately in display, using the platform
group mechanism. This enables dropping the dependency on i915_drv.h
IS_MOBILE() from display code.
Jani Nikula [Mon, 11 Nov 2024 10:34:03 +0000 (12:34 +0200)]
drm/i915/display: pass struct pci_dev * to intel_display_device_probe()
Convert intel_display_device_probe() to accept struct pci_dev * instead
of struct drm_i915_private *. Return struct intel_display * in
preparation of allocating the memory of it later.
Jani Nikula [Mon, 11 Nov 2024 10:34:02 +0000 (12:34 +0200)]
drm/i915/display: convert display device identification to struct intel_display
Convert intel_display_device.[ch] to struct intel_display, including
callers, but excluding intel_display_device_probe() which will be
handled in follow-up.