Noticed that I wasn't paying close enough attention the last time I looked
at our audio callbacks, as I completely missed the fact that we were
figuring out which audio-enabled connector goes to each encoder by checking
it's state, but without grabbing any of the appropriate modesetting locks
to do so.
That being said however: trying to grab modesetting locks in our audio
callbacks would be very painful due to the potential for locking inversion
between HDA and DRM. So, let's instead just copy what i915 does again - add
our own audio lock to protect audio related state, and store each audio
enabled connector in each nouveau_encoder struct so that we don't need to
check any atomic states.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Just to be more consistent with the order of args that DRM helpers like
drm_atomic_get_new_crtc_state() use.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This is another bit that we never implemented for nouveau: dongle
detection. When a "dongle", e.g. an active display adaptor, is hooked up
to the system and causes an HPD to be fired, we don't actually know
whether or not there's anything plugged into the dongle without checking
the sink count. As a result, plugging in a dongle without anything
plugged into it currently results in a bogus EDID retrieval error in the kernel log.
Additionally, most dongles won't send another long HPD signal if the
user suddenly plugs something in, they'll only send a short HPD IRQ with
the expectation that the source will check the sink count and reprobe
the connector if it's changed - something we don't actually do. As a
result, nothing will happen if the user plugs the dongle in before
plugging something into the dongle.
So, let's fix this by checking the sink count in both
nouveau_dp_probe_dpcd() and nouveau_dp_irq(), and reprobing the
connector if things change.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-18-lyude@redhat.com
This adds support for querying the maximum clock rate of a downstream
port on a DisplayPort connection. Generally, downstream ports refer to
active dongles which can have their own pixel clock limits.
Note as well, we also start marking the connector as disconnected if we
can't read the DPCD, since we wouldn't be able to do anything without
DPCD access anyway.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-15-lyude@redhat.com
First some backstory here: Currently, we keep track of whether or not
we've enabled MST or not by trying to piggy-back off the MST helpers.
This means that in order to check whether MST is enabled or not, we
actually need to grab drm_dp_mst_topology_mgr.lock.
Back when I originally wrote this, I did this piggy-backing with the
intention that I'd eventually be teaching our MST helpers how to recover
when an MST device has stopped responding, which in turn would require
the MST helpers having a way of disabling MST independently of the
driver. Note that this was before I reworked locking in the MST helpers,
so at the time we were sticking random things under &mgr->lock - which
grabbing this lock was meant to protect against.
This never came to fruition because doing such a reset safely turned out
to be a lot more painful and impossible then it sounds, and also just
risks us working around issues with our MST handlers that should be
properly fixed instead. Even if it did though, simply calling
drm_dp_mst_topology_mgr_set_mst() from the MST helpers (with the
exception of when we're tearing down our MST managers, that's always OK)
wouldn't have been a bad idea, since drivers like nouveau and i915 need
to do their own book keeping immediately after disabling MST.
So-implementing that would likely require adding a hook for
helper-triggered MST disables anyway.
So, fast forward to now - we want to start adding support for all of the
miscellaneous bits of the DP protocol (for both SST and MST) we're
missing before moving on to supporting more complicated features like
supporting different BPP values on MST, DSC, etc. Since many of these
features only exist on SST and make use of DP HPD IRQs, we want to be
able to atomically check whether we're servicing an MST IRQ or SST IRQ
in nouveau_connector_hotplug(). Currently we literally don't do this at
all, and just handle any kind of possible DP IRQ we could get including
ESIs - even if MST isn't actually enabled.
This would be very complicated and difficult to fix if we need to hold
&mgr->lock while handling SST IRQs to ensure that the MST topology
state doesn't change under us. What we really want here is to do our own
tracking of whether MST is enabled or not, similar to drivers like i915,
and define our own locking order to decomplicate things and avoid
hitting locking issues in the future.
So, let's do this by refactoring our MST probing/enabling code to use
our own MST bookkeeping, along with adding a lock for protecting DP
state that needs to be checked outside of our connector probing
functions. While we're at it, we also remove a bunch of unneeded steps
we perform when probing/enabling MST:
* Enabling bits in MSTM_CTRL before calling drm_dp_mst_topology_mgr_set_mst().
I don't think these ever actually did anything, since the nvif methods
for enabling MST don't actually do anything DPCD related and merely
indicate to nvkm that we've turned on MST.
* Checking the MSTM_CTRL bit is intact when checking the state of an
enabled MST topology in nv50_mstm_detect(). I just added this to be safe
originally, but now that we try reading the DPCD when probing DP
connectors it shouldn't be needed as that will abort our hotplug probing
if the device was removed well before we start checking for MST..
* All of the duplicate DPCD version checks.
This leaves us with much nicer looking code, a much more sensible
locking scheme, and an easy way of checking whether MST is enabled or
not for handling DP HPD IRQs.
v2:
* Get rid of accidental newlines
v4:
* Fix uninitialized usage of mstm in nv50_mstm_detect() - thanks kernel
bot!
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-9-lyude@redhat.com
While the way we find the associated connector for an encoder is just
fine for legacy modesetting, it's not correct for nv50+ since that uses
atomic modesetting. For reference, see the drm_encoder kdocs.
Fix this by removing nouveau_encoder_connector_get(), and replacing it
with nv04_encoder_get_connector(), nv50_outp_get_old_connector(), and
nv50_outp_get_new_connector().
v2:
* Don't line-wrap for_each_(old|new)_connector_in_state in
nv50_outp_get_(old|new)_connector() - sravn
v3:
* Fix potential uninitialized usage of nv_connector (needs to be
initialized to NULL at the start). Thanks kernel test robot!
v4:
* Actually fix uninitialized nv_connector usage in
nv50_audio_component_get_eld(). The previous fix wouldn't have worked
since we would have started out with nv_connector == NULL, but
wouldn't clear it after a single drm_for_each_encoder() iteration.
Thanks again Kernel bot!
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-7-lyude@redhat.com
Noticed this while going through our DP code - we use an open-coded
version of drm_dp_read_desc() instead of just using the helper, so
change that. This will also let us use quirks in the future if we end up
needing them.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-3-lyude@redhat.com
The audio driver can call into nouveau right while we're in the middle
of re-fetching the EDID, and decide it no longer needs to be awake.
Stop depending on EDID in the audio component get_eld() callback, and
instead cache whether audio support is present from the prior modeset.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Currently, the nv50_mstc_mode_valid() function is happy to take any and
all modes, even the ones we can't actually support sometimes like
interlaced modes.
Luckily, the only difference between the mode validation that needs to
be performed for MST vs. SST is that eventually we'll need to check the
minimum PBN against the MSTB's full PBN capabilities (remember-we don't
care about the current bw state here). Otherwise, all of the other code
can be shared.
So, we move all of the common mode validation in
nouveau_connector_mode_valid() into a separate helper,
nv50_dp_mode_valid(), and use that from both nv50_mstc_mode_valid() and
nouveau_connector_mode_valid(). Note that we allow for returning the
calculated clock that nv50_dp_mode_valid() came up with, since we'll
eventually want to use that for PBN calculation in
nv50_mstc_mode_valid().
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Right now, we make the mistake of allowing interlacing on all
connectors. Nvidia hardware does not always support interlacing with DP
though, so we need to make sure that we don't allow interlaced modes to
be set in such situations as otherwise we'll end up accidentally hanging
the display HW.
This fixes some hangs with Turing, which would be caused by attempting
to set an interlaced mode on hardware that doesn't support it. This
patch likely fixes other hardware hanging in the same way as well.
Note that we say we probe PIOR caps, but they don't actually have any
interlacing caps. So, the get_caps() function for PIORs just sets
interlacing support to true.
Changes since v1:
* Actually probe caps correctly this time, both on EVO and NVDisplay.
Changes since v2:
* Fix probing for < GF119
* Use vfunc table, in prep for adding more caps in the future.
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
These exist to give NVKM information on the set of display paths that
the DD needs to be active at any given time.
Previously, the supervisor attempted to determine this solely from OR
state, but there's a few configurations where this information on its
own isn't enough to determine the specific display paths in question:
- ANX9805, where the PIOR protocol for both DP and TMDS is TMDS.
- On a device using DCB Switched Outputs.
- On GM20x and newer, with a crossbar between the SOR and macro links.
After this commit, the DD tells NVKM *exactly* which display path it's
attempting a modeset on.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Just a shuffle of blocks into an order consistent with the rest of the
code, renaming hdmi/audio funtions for atomic, and removal of unused
code.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Sometimes we load with a sink already in MST mode. If, however, we can't
or don't want to use MST, we need to be able to switch it back to SST.
This commit instantiates a stub topology manager for any output path that
we believe (the detection of this could use some improvement) has support
for MST, and adds the connector detect() logic for detecting sink support
and switching between modes.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Nouveau is the only user, and atomic drivers should do state
save/restoring differently. So move it into noveau.
Saves me typing some kerneldoc, too ;-)
v2: Move misplaced hunk into earlier nouveau patch.
Cc: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1449245647-1315-1-git-send-email-daniel.vetter@ffwll.ch
Reviewed-by: Thierry Reding <treding@nvidia.com>
The namespace of NVKM is being changed to nvkm_ instead of nouveau_,
which will be used for the DRM part of the driver. This is being
done in order to make it very clear as to what part of the driver a
given symbol belongs to, and as a minor step towards splitting the
DRM driver out to be able to stand on its own (for virt).
Because there's already a large amount of churn here anyway, this is
as good a time as any to also switch to NVIDIA's device and chipset
naming to ease collaboration with them.
A comparison of objdump disassemblies proves no code changes.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
It'd be pretty awesome if someone would care enough to port this all
properly to a class interface, perhaps submitting a command stream to
the core via a sw object on PFIFO (emulating how EVO works basically,
and also what nvidia have done forever..)..
But, this seems unlikely given how old this hardware is now, so, lets
just hide it away.
There's a heap of other bits and pieces laying around that are still
tangled. I'll (re)move them in pieces.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This is about to become somewhat more complicated to determine in a
number of cases, so store the "common" case (DDC/AUX) directly inside
the encoder structure.
Pre-nv50 code not touched except to fill the pointer, don't care.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Pull drm merge (part 1) from Dave Airlie:
"So first of all my tree and uapi stuff has a conflict mess, its my
fault as the nouveau stuff didn't hit -next as were trying to rebase
regressions out of it before we merged.
Highlights:
- SH mobile modesetting driver and associated helpers
- some DRM core documentation
- i915 modesetting rework, haswell hdmi, haswell and vlv fixes, write
combined pte writing, ilk rc6 support,
- nouveau: major driver rework into a hw core driver, makes features
like SLI a lot saner to implement,
- psb: add eDP/DP support for Cedarview
- radeon: 2 layer page tables, async VM pte updates, better PLL
selection for > 2 screens, better ACPI interactions
The rest is general grab bag of fixes.
So why part 1? well I have the exynos pull req which came in a bit
late but was waiting for me to do something they shouldn't have and it
looks fairly safe, and David Howells has some more header cleanups
he'd like me to pull, that seem like a good idea, but I'd like to get
this merge out of the way so -next dosen't get blocked."
Tons of conflicts mostly due to silly include line changes, but mostly
mindless. A few other small semantic conflicts too, noted from Dave's
pre-merged branch.
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (447 commits)
drm/nv98/crypt: fix fuc build with latest envyas
drm/nouveau/devinit: fixup various issues with subdev ctor/init ordering
drm/nv41/vm: fix and enable use of "real" pciegart
drm/nv44/vm: fix and enable use of "real" pciegart
drm/nv04/dmaobj: fixup vm target handling in preparation for nv4x pcie
drm/nouveau: store supported dma mask in vmmgr
drm/nvc0/ibus: initial implementation of subdev
drm/nouveau/therm: add support for fan-control modes
drm/nouveau/hwmon: rename pwm0* to pmw1* to follow hwmon's rules
drm/nouveau/therm: calculate the pwm divisor on nv50+
drm/nouveau/fan: rewrite the fan tachometer driver to get more precision, faster
drm/nouveau/therm: move thermal-related functions to the therm subdev
drm/nouveau/bios: parse the pwm divisor from the perf table
drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices
drm/nouveau/therm: rework thermal table parsing
drm/nouveau/gpio: expose the PWM/TOGGLE parameter found in the gpio vbios table
drm/nouveau: fix pm initialization order
drm/nouveau/bios: check that fixed tvdac gpio data is valid before using it
drm/nouveau: log channel debug/error messages from client object rather than drm client
drm/nouveau: have drm debugging macros build on top of core macros
...
v2/v3: Ben Skeggs <bskeggs@redhat.com>
- fix typo in default bus selection
- fix accidental loss of destructor
v4: Dmitry Eremin-Solenikov <dmitry_eremin@mentor.com>
- fix typo causing incorrect default i2c port settings when no BMP data
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Convert #include "..." to #include <path/...> in drivers/gpu/.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Dave Jones <davej@redhat.com>
Off-chip encoders (which we don't support yet anyway), and newer chipsets
(such as NVD9...), will need their own code for this.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Not used currently, but it will be used in preference to pre-determined
lane/bandwidth numbers at a later point.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
I'm sure that out there somewhere, someone will need this. We currently
haven't seen an example of LVDS being on a non-0 SOR so far though.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
sil164 and friends are the most common, usually they just need to be
poked once because a fixed configuration is enough for any modes and
clocks, so they worked without this patch if the BIOS had done a good
job on POST. Display couldn't survive a suspend/resume cycle though.
Unfortunately, BIOS scripts are useless here.
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Allows us to remove a driver hack that used to be necessary to disable
encoders in certain situations before setting up a mode. The DRM has
better knowledge of when this is needed than the driver does.
This fixes a number of display switching issues.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Create connectors before encoders to avoid having to do another loop across
encoder list whenever we create a new connector. This allows us to pass
the connector to the encoder creation functions, and avoid using a
create_resources() callback since we can now call it directly.
This can also potentially modify the connector ordering on nv50. On cards
where the DCB connector and encoder tables are in the same order, things
will be unchanged. However, there's some cards where the ordering between
the tables differ, and in one case, leads us to naming the connectors
"wrongly".
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This value interacts with some registers we don't currently know how to
program properly ourselves. The default of 5 that we were using matches
what the VBIOS on early DP cards do, but later ones use 6, which would
cause nouveau to program an incorrect mode on these chips.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This adds a drm/kms staging non-API stable driver for GPUs from NVIDIA.
This driver is a KMS-based driver and requires a compatible nouveau
userspace libdrm and nouveau X.org driver.
This driver requires firmware files not available in this kernel tree,
interested parties can find them via the nouveau project git archive.
This driver is reverse engineered, and is in no way supported by nVidia.
Support for nearly the complete range of nvidia hw from nv04->g80 (nv50)
is available, and the kms driver should support driving nearly all
output types (displayport is under development still) along with supporting
suspend/resume.
This work is all from the upstream nouveau project found at
nouveau.freedesktop.org.
The original authors list from nouveau git tree is:
Anssi Hannula <anssi.hannula@iki.fi>
Ben Skeggs <bskeggs@redhat.com>
Francisco Jerez <currojerez@riseup.net>
Maarten Maathuis <madman2003@gmail.com>
Marcin Kościelnicki <koriakin@0x04.net>
Matthew Garrett <mjg@redhat.com>
Matt Parnell <mparnell@gmail.com>
Patrice Mandin <patmandin@gmail.com>
Pekka Paalanen <pq@iki.fi>
Xavier Chantry <shiningxc@gmail.com>
along with project founder Stephane Marchesin <marchesin@icps.u-strasbg.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>