mirror of
git://nv-tegra.nvidia.com/tegra/kernel-src/nv-kernel-display-driver.git
synced 2025-12-24 10:41:52 +03:00
Compare commits
9 Commits
rel-36-lws
...
rel-36
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdcd6ec921 | ||
|
|
cfdc1a1644 | ||
|
|
c46a1b24d6 | ||
|
|
ad05f6ecb9 | ||
|
|
95cde7ef1c | ||
|
|
d1aa84175b | ||
|
|
d137833257 | ||
|
|
7296f7cc89 | ||
|
|
6475e2b9c3 |
@@ -1,7 +1,7 @@
|
||||
# NVIDIA Linux Open GPU Kernel Module Source
|
||||
|
||||
This is the source release of the NVIDIA Linux open GPU kernel modules,
|
||||
version 540.3.2.
|
||||
version 540.5.0.
|
||||
|
||||
|
||||
## How to Build
|
||||
@@ -17,7 +17,7 @@ as root:
|
||||
|
||||
Note that the kernel modules built here must be used with GSP
|
||||
firmware and user-space NVIDIA GPU driver components from a corresponding
|
||||
540.3.2 driver release. This can be achieved by installing
|
||||
540.5.0 driver release. This can be achieved by installing
|
||||
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
|
||||
option. E.g.,
|
||||
|
||||
@@ -180,7 +180,7 @@ software applications.
|
||||
## Compatible GPUs
|
||||
|
||||
The open-gpu-kernel-modules can be used on any Turing or later GPU
|
||||
(see the table below). However, in the 540.3.2 release,
|
||||
(see the table below). However, in the 540.5.0 release,
|
||||
GeForce and Workstation support is still considered alpha-quality.
|
||||
|
||||
To enable use of the open kernel modules on GeForce and Workstation GPUs,
|
||||
@@ -188,7 +188,7 @@ set the "NVreg_OpenRmEnableUnsupportedGpus" nvidia.ko kernel module
|
||||
parameter to 1. For more details, see the NVIDIA GPU driver end user
|
||||
README here:
|
||||
|
||||
https://us.download.nvidia.com/XFree86/Linux-x86_64/540.3.2/README/kernel_open.html
|
||||
https://us.download.nvidia.com/XFree86/Linux-x86_64/540.5.0/README/kernel_open.html
|
||||
|
||||
In the below table, if three IDs are listed, the first is the PCI Device
|
||||
ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI
|
||||
|
||||
200
commitFile.txt
200
commitFile.txt
@@ -5,12 +5,12 @@ d13779dbbab1c776db15f462cd46b29f2c0f8c7c - Makefile
|
||||
5728867ce2e96b63b29367be6aa1c0e47bcafc8f - SECURITY.md
|
||||
6b73bf6a534ddc0f64e8ba88739381c3b7fb4b5c - nv-compiler.sh
|
||||
ac7f91dfb6c5c469d2d8196c6baebe46ede5aee0 - CHANGELOG.md
|
||||
e232781c94c96872c1404d4affff50acebd871bd - README.md
|
||||
fb30136834a37c3b273df8352db5bcc1f46b3d7d - README.md
|
||||
ec5f1eb408e0b650158e0310fb1ddd8e9b323a6f - CONTRIBUTING.md
|
||||
af3ee56442f16029cb9b13537477c384226b22fc - CODE_OF_CONDUCT.md
|
||||
61d353ba0c79a1eae91f759efb8508f3eef0cfd5 - kernel-open/Kbuild
|
||||
e3d628e13e13e8f4b886c88d8b22adfbf3217a54 - kernel-open/Kbuild
|
||||
4f4410c3c8db46e5a98d7a35f7d909a49de6cb43 - kernel-open/Makefile
|
||||
6a9b31e3d157dea5790b05752f5521d2870f88bc - kernel-open/conftest.sh
|
||||
3f1d791899ab2db1d55cc73ec56fc11c9bef67cb - kernel-open/conftest.sh
|
||||
0b1508742a1c5a04b6c3a4be1b48b506f4180848 - kernel-open/dkms.conf
|
||||
19a5da412ce1557b721b8550a4a80196f6162ba6 - kernel-open/common/inc/os_dsi_panel_props.h
|
||||
4750735d6f3b334499c81d499a06a654a052713d - kernel-open/common/inc/nv-caps.h
|
||||
@@ -33,7 +33,8 @@ d7ab0ee225361daacd280ff98848851933a10a98 - kernel-open/common/inc/nv-list-helper
|
||||
b02c378ac0521c380fc2403f0520949f785b1db6 - kernel-open/common/inc/nv-dmabuf.h
|
||||
689d6be9302d488000e57a329373feeb14e93798 - kernel-open/common/inc/nv-procfs-utils.h
|
||||
b417d06ed1845f5ed69181d8eb9de6b6a87fa973 - kernel-open/common/inc/nv-firmware.h
|
||||
e6c1a783642af932b1ed8e35810c768de492c070 - kernel-open/common/inc/nv-platform.h
|
||||
d5253e7e4abd3ad8d72375260aa80037adcd8973 - kernel-open/common/inc/nv_dpy_id.h
|
||||
a69cfed9725a8ade97036a1cb795e9144be1836d - kernel-open/common/inc/nv-platform.h
|
||||
b986bc6591ba17a74ad81ec4c93347564c6d5165 - kernel-open/common/inc/nvkms-format.h
|
||||
fa267c903e9c449e62dbb6945906400d43417eff - kernel-open/common/inc/nvlimits.h
|
||||
143051f69a53db0e7c5d2f846a9c14d666e264b4 - kernel-open/common/inc/nv-kref.h
|
||||
@@ -53,12 +54,13 @@ d25291d32caef187daf3589ce4976e4fa6bec70d - kernel-open/common/inc/nv-time.h
|
||||
4856fe869a5f3141e5d7f7d1b0a6affad94cbc31 - kernel-open/common/inc/nv-pci.h
|
||||
95bf694a98ba78d5a19e66463b8adda631e6ce4c - kernel-open/common/inc/nvstatus.h
|
||||
b15c5fe5d969414640a2cb374b707c230e7597e4 - kernel-open/common/inc/nv-hash.h
|
||||
36c20e9c111e66601b025802f840e7b87d09cdde - kernel-open/common/inc/nvkms-kapi.h
|
||||
61a60660761e90aa622af2fda482d69473ab40d4 - kernel-open/common/inc/nvkms-kapi.h
|
||||
f428218ee6f5d0289602495a1cfb287db4fb0823 - kernel-open/common/inc/nv_uvm_interface.h
|
||||
1e7eec6561b04d2d21c3515987aaa116e9401c1f - kernel-open/common/inc/nv-kernel-interface-api.h
|
||||
d51449fa2fd19748007f2e98f0233c92b45f9572 - kernel-open/common/inc/nvkms-api-types.h
|
||||
de6913c5e5092a417530ac9f818497824eab7946 - kernel-open/common/inc/os-interface.h
|
||||
b3d26ddf643e0bd98847ee56b930c14d06cadf89 - kernel-open/common/inc/nvkms-api-types.h
|
||||
c9120c6a33932c7514608601f82ea85d2386b84f - kernel-open/common/inc/os-interface.h
|
||||
ceac0fe7333f3a67b8fb63de42ab567dd905949f - kernel-open/common/inc/nv-ioctl-numa.h
|
||||
995d8447f8539bd736cc09d62983ae8ebc7e3436 - kernel-open/common/inc/nv_common_utils.h
|
||||
c75bfc368c6ce3fc2c1a0c5062834e90d822b365 - kernel-open/common/inc/nv-memdbg.h
|
||||
1d17329caf26cdf931122b3c3b7edf4932f43c38 - kernel-open/common/inc/nv-msi.h
|
||||
3b12d770f8592b94a8c7774c372e80ad08c5774c - kernel-open/common/inc/nvi2c.h
|
||||
@@ -77,15 +79,15 @@ b8d361216db85fe897cbced2a9600507b7708c61 - kernel-open/nvidia/libspdm_hkdf_sha.c
|
||||
4e5a330fa40dab218821976ac1b530c649d48994 - kernel-open/nvidia/libspdm_ecc.c
|
||||
94c406f36836c3396b0ca08b4ff71496666b9c43 - kernel-open/nvidia/os-usermap.c
|
||||
7ac10bc4b3b1c5a261388c3f5f9ce0e9b35d7b44 - kernel-open/nvidia/nv-usermap.c
|
||||
5ac10d9b20ccd37e1e24d4a81b8ac8f83db981e4 - kernel-open/nvidia/nv-vtophys.c
|
||||
7af675f85642229b7e7de05dcadd622550fe7ad7 - kernel-open/nvidia/nv-vtophys.c
|
||||
d11ab03a617b29efcf00f85e24ebce60f91cf82c - kernel-open/nvidia/nv-backlight.c
|
||||
ef8fd76c55625aeaa71c9b789c4cf519ef6116b2 - kernel-open/nvidia/libspdm_hkdf.c
|
||||
cf90d9ea3abced81d182ab3c4161e1b5d3ad280d - kernel-open/nvidia/nv-rsync.h
|
||||
6710f4603a9d3e14bcaefdf415b1cfff9ec9b7ec - kernel-open/nvidia/libspdm_aead.c
|
||||
d68af9144d3d487308e73d0a52f4474f8047d6ca - kernel-open/nvidia/nv-gpio.c
|
||||
fc22bea3040ae178492cb9c7a62f1d0012b1c113 - kernel-open/nvidia/nv-procfs.c
|
||||
e7a9eb87524d092f9785e35806ef03d96aa3aff7 - kernel-open/nvidia/nv.c
|
||||
e0aff92ee8ddec261d8f0d81c41f837503c4b571 - kernel-open/nvidia/nv-dsi-parse-panel-props.c
|
||||
aa6cf0ed774330e4afe4eaa55b3463ed31a2f7ae - kernel-open/nvidia/nv.c
|
||||
6047676c00c8396d7c9f5192b873377a42bb8988 - kernel-open/nvidia/nv-dsi-parse-panel-props.c
|
||||
9104dc5f36a825aaf1208b54b167965625d4a433 - kernel-open/nvidia/nv_uvm_interface.c
|
||||
fbae5663e3c278d8206d07ec6446ca4c2781795f - kernel-open/nvidia/nv-ibmnpu.h
|
||||
ab04c42e0e8e7f48f1a7074885278bbb6006d65f - kernel-open/nvidia/nv-bpmp.c
|
||||
@@ -95,7 +97,7 @@ dc39c4ee87f4dc5f5ccc179a98e07ddb82bb8bce - kernel-open/nvidia/nv-modeset-interfa
|
||||
70a9117dce7471a07178d9456b146a033d6b544b - kernel-open/nvidia/nv-dma.c
|
||||
0a3ad5cdacfe156b02f53c0087bdc0ec9509cd6a - kernel-open/nvidia/nv-ipc-soc.c
|
||||
06e7ec77cd21c43f900984553a4960064753e444 - kernel-open/nvidia/nv-platform-pm.c
|
||||
c1ebcfec42f7898dd9d909eacd439d288b80523f - kernel-open/nvidia/os-mlock.c
|
||||
04596e9a57955df30de2f21122aa7e38f3c8825a - kernel-open/nvidia/os-mlock.c
|
||||
646e6b03521587cc1a02617afd697183e5d1a83a - kernel-open/nvidia/nv-kthread-q.c
|
||||
94344ec0af21bd9c7c7ab912f7bd3a8668a3e0aa - kernel-open/nvidia/os-pci.c
|
||||
6e669fe32e4b69dcdbc9739dc8a45fb800547d53 - kernel-open/nvidia/nv-p2p.c
|
||||
@@ -105,7 +107,7 @@ e8daae4e6106429378673988293aaa1fcd80f0eb - kernel-open/nvidia/nv-pci.c
|
||||
8c9fd9590d7e3ad333ae03d5f22b72ffbdbe6e70 - kernel-open/nvidia/nv-dmabuf.c
|
||||
6d4fbea733fdcd92fc6a8a5884e8bb359f9e8abd - kernel-open/nvidia/rmp2pdefines.h
|
||||
b71bf4426322ab59e78e2a1500509a5f4b2b71ab - kernel-open/nvidia/nv-pat.h
|
||||
e1f18e92457844913b9b6613d2f6dca73fc233c3 - kernel-open/nvidia/os-interface.c
|
||||
bb4b87fbfa85a21af5b3ed26cc8ff5cbaae78266 - kernel-open/nvidia/os-interface.c
|
||||
ce537a7d786bd11a4429bf7c59836d5373a66f61 - kernel-open/nvidia/nv-i2c.c
|
||||
8bedc7374d7a43250e49fb09139c511b489d45e3 - kernel-open/nvidia/nv-pci-table.h
|
||||
c7f1aaa6a5f3a3cdf1e5f80adf40b3c9f185fb94 - kernel-open/nvidia/nv-report-err.c
|
||||
@@ -113,7 +115,7 @@ c7f1aaa6a5f3a3cdf1e5f80adf40b3c9f185fb94 - kernel-open/nvidia/nv-report-err.c
|
||||
dd9e367cba9e0672c998ec6d570be38084a365ab - kernel-open/nvidia/libspdm_rand.c
|
||||
37654472e65659be229b5e35c6f25c0724929511 - kernel-open/nvidia/nv-frontend.c
|
||||
8f87a475c202458948025d1521968677fc11dd50 - kernel-open/nvidia/nv-msi.c
|
||||
e5d6dfa062d2d9533760f883bdd36a669d79b759 - kernel-open/nvidia/nv-platform.c
|
||||
45cdfeaf7b31b7891b19840f17a996b382806f1c - kernel-open/nvidia/nv-platform.c
|
||||
dd819a875c584bc469082fcf519779ea00b1d952 - kernel-open/nvidia/libspdm_aead_aes_gcm.c
|
||||
69f203ad21e643f7b7c85e7e86bd4b674a3536de - kernel-open/nvidia/nv-acpi.c
|
||||
cf98395acb4430a7c105218f7a4b5f7e810b39cf - kernel-open/nvidia/os-registry.c
|
||||
@@ -126,14 +128,14 @@ cf98395acb4430a7c105218f7a4b5f7e810b39cf - kernel-open/nvidia/os-registry.c
|
||||
9883eb32e5d4377c3dce1c7cb54d0e05c05e128b - kernel-open/nvidia/nv-mmap.c
|
||||
68d781e929d103e6fa55fa92b5d4f933fbfb6526 - kernel-open/nvidia/nv-report-err.h
|
||||
95ae148b016e4111122c2d9f8f004b53e78998f3 - kernel-open/nvidia/nv-memdbg.c
|
||||
e3806f50e77b4d6e854c4e84631a1d5fc0f4b710 - kernel-open/nvidia/nvidia.Kbuild
|
||||
4de56ccb102fd148feaaa08002db0a5ea129a61a - kernel-open/nvidia/nvidia.Kbuild
|
||||
6060392eec4e707ac61ebca3995b6a966eba7fc1 - kernel-open/nvidia/nv-p2p.h
|
||||
7b1bd10726481626dd51f4eebb693794561c20f6 - kernel-open/nvidia/nv-host1x.c
|
||||
11778961efc78ef488be5387fa3de0c1b761c0d9 - kernel-open/nvidia/libspdm_sha.c
|
||||
02b1936dd9a9e30141245209d79b8304b7f12eb9 - kernel-open/nvidia/nv-cray.c
|
||||
2f6e4c6ee6f809097c8b07a7b698e8614bf25e57 - kernel-open/nvidia/nv-caps.c
|
||||
9b701fe42a0e87d62c58b15c553086a608e89f7b - kernel-open/nvidia/nv-frontend.h
|
||||
e2da77ff1bc25c0b1de69af7c09e0bde26c34e30 - kernel-open/nvidia/libspdm_shash.c
|
||||
d2ce61cd7fc2c0d384f9caa40e98bdeb032bab86 - kernel-open/nvidia/libspdm_shash.c
|
||||
fa178a7209f56008e67b553a2c5ad1b2dd383aac - kernel-open/nvidia/hal/library/cryptlib/cryptlib_rng.h
|
||||
34de62da6f880ba8022299c77eddbb11d7fc68d2 - kernel-open/nvidia/hal/library/cryptlib/cryptlib_hash.h
|
||||
95b97f5a3ddcf73ed5d7fa0be9e27aec776d7c13 - kernel-open/nvidia/hal/library/cryptlib/cryptlib_rsa.h
|
||||
@@ -148,52 +150,52 @@ c276be3eb63bb451edfe9ed13859c251530743e6 - kernel-open/nvidia/hal/library/cryptl
|
||||
d5ddc354e191d6178625b0df8e8b34e8c3e4c474 - kernel-open/nvidia/library/spdm_lib_config.h
|
||||
19b5d633f4560d545f622ada0dd352d5aa02c651 - kernel-open/nvidia/library/cryptlib.h
|
||||
7398ff33b24fa58315cc40776bc3451e090aa437 - kernel-open/nvidia/internal/libspdm_lib_config.h
|
||||
487db563f4e5153ffc976fc2aa26636ebb4cd534 - kernel-open/nvidia-drm/nvidia-drm-crtc.h
|
||||
1f0cdee2468f842c06bb84aceef60e0723023084 - kernel-open/nvidia-drm/nvidia-drm-linux.c
|
||||
44b9140286d2917ff7896b98f02d2d87bce58ee2 - kernel-open/nvidia-drm/nvidia-drm-crtc.h
|
||||
7c1eb7d5d928bb5677634cedde4a234266d4344d - kernel-open/nvidia-drm/nvidia-drm-linux.c
|
||||
8b2063f0cc2e328f4f986c2ce556cfb626c89810 - kernel-open/nvidia-drm/nvidia-drm-utils.c
|
||||
6d65ea9f067e09831a8196022bfe00a145bec270 - kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.h
|
||||
79bcf373ff7d728740716acde5e2d44e924efefa - kernel-open/nvidia-drm/nvidia-drm-gem-nvkms-memory.c
|
||||
fe9132110f104ff7ebba922ce6dd66a2d08a998d - kernel-open/nvidia-drm/nvidia-drm-modeset.c
|
||||
f454b9ae53a2c308d6909d197c2b9a6543f7d8c3 - kernel-open/nvidia-drm/nvidia-drm-gem-nvkms-memory.c
|
||||
e1895532cf6ec0edc4b73eb169b33b8477151364 - kernel-open/nvidia-drm/nvidia-drm-modeset.c
|
||||
23586447526d9ffedd7878b6cf5ba00139fadb5e - kernel-open/nvidia-drm/nvidia-drm-gem-user-memory.h
|
||||
99642b76e9a84b5a1d2e2f4a8c7fb7bcd77a44fd - kernel-open/nvidia-drm/nvidia-drm.h
|
||||
66b33e4ac9abe09835635f6776c1222deefad741 - kernel-open/nvidia-drm/nvidia-drm-fb.h
|
||||
2eba218d75f3802d7bab34d0dd6320f872b2d604 - kernel-open/nvidia-drm/nvidia-drm-gem-nvkms-memory.h
|
||||
c52acdbc07f16aa78570d9e6a7f62e493264fde1 - kernel-open/nvidia-drm/nvidia-drm-helper.c
|
||||
dc0fe38909e2f38e919495b7b4f21652a035a3ee - kernel-open/nvidia-drm/nvidia-drm.c
|
||||
4b68b6cb0f98116376be36733f5ae60eec85d78d - kernel-open/nvidia-drm/nvidia-drm-ioctl.h
|
||||
ae6efc1bbec8a5e948b7244f4801f0b4b398f203 - kernel-open/nvidia-drm/nvidia-drm.c
|
||||
86666530006fc4446d7e3bbe175ce9d3350d8d81 - kernel-open/nvidia-drm/nvidia-drm-ioctl.h
|
||||
511ea7cd9e7778c6adc028ae13377c1a8856b72a - kernel-open/nvidia-drm/nvidia-drm-format.c
|
||||
9a882b31b2acc9e1ad3909c0061eee536e648aae - kernel-open/nvidia-drm/nvidia-drm-drv.h
|
||||
b91df730fba3c2f9401321557bb1bc2e64bbf980 - kernel-open/nvidia-drm/nvidia-drm-connector.h
|
||||
aedc8183ac255b270f74899cf9fd1c974fdbf00b - kernel-open/nvidia-drm/nvidia-drm-drv.h
|
||||
3a1e3e14eeda27330da9fb54f798556994b8953e - kernel-open/nvidia-drm/nvidia-drm-connector.h
|
||||
646e6b03521587cc1a02617afd697183e5d1a83a - kernel-open/nvidia-drm/nv-kthread-q.c
|
||||
d9221522e02e18b037b8929fbc075dc3c1e58654 - kernel-open/nvidia-drm/nv-pci-table.c
|
||||
eb98761cdc99141ad937966e5533c57189db376a - kernel-open/nvidia-drm/nvidia-drm-fence.h
|
||||
eca70b3b8146903ec678a60eebb0462e6ccf4569 - kernel-open/nvidia-drm/nvidia-drm-encoder.h
|
||||
b1bc97e6e0564f1526dedaf8bb68d081fc509cc7 - kernel-open/nvidia-drm/nvidia-drm-helper.h
|
||||
273d0cafeb0f21bf9b7d189f2dc6278e1a3c9672 - kernel-open/nvidia-drm/nvidia-drm-os-interface.h
|
||||
55e26337c0d52b5ec4f6ab403e9306417d2893f8 - kernel-open/nvidia-drm/nvidia-drm-gem-user-memory.c
|
||||
f92b90d05b58d7097b6762016b351a300eaf93cc - kernel-open/nvidia-drm/nvidia-drm-drv.c
|
||||
6dfbbc39799b6578fb1f16357e8e29c14dcf455a - kernel-open/nvidia-drm/nvidia-drm-encoder.h
|
||||
2529ef49fee3a01717aaabea530d94017d5c31cc - kernel-open/nvidia-drm/nvidia-drm-helper.h
|
||||
2a48c9643c836a1b0a0c133afa9439b4f5ce0feb - kernel-open/nvidia-drm/nvidia-drm-os-interface.h
|
||||
b83e4c3ba825a75233eaedb0ac33feed74a53ab7 - kernel-open/nvidia-drm/nvidia-drm-gem-user-memory.c
|
||||
21c629706f242599f6a81380155dd00bb0d994e7 - kernel-open/nvidia-drm/nvidia-drm-drv.c
|
||||
203295380efca7e422746805437b05ce22505424 - kernel-open/nvidia-drm/nvidia-drm-gem.c
|
||||
672afea77ca2c2575f278d9e182ba1188e35e971 - kernel-open/nvidia-drm/nvidia-drm-encoder.c
|
||||
cd987993109f7c020e296bf397905190a866d4ff - kernel-open/nvidia-drm/nvidia-drm-encoder.c
|
||||
8bedc7374d7a43250e49fb09139c511b489d45e3 - kernel-open/nvidia-drm/nv-pci-table.h
|
||||
044071d60c8cc8ea66c6caaf1b70fe01c4081ad3 - kernel-open/nvidia-drm/nvidia-drm-conftest.h
|
||||
9df641d3a2ee920c4fc68bfe19e8a11b085af03b - kernel-open/nvidia-drm/nvidia-drm-conftest.h
|
||||
ec550cba2bebff2c5054b6e12fc43d81e37ade48 - kernel-open/nvidia-drm/nvidia-dma-fence-helper.h
|
||||
e362c64aa67b47becdbf5c8ba2a245e135adeedf - kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.c
|
||||
492a1b0b02dcd2d60f05ac670daeeddcaa4b0da5 - kernel-open/nvidia-drm/nvidia-dma-resv-helper.h
|
||||
61c61f91d1a29d6f7794a67eac337152b58aaac0 - kernel-open/nvidia-drm/nvidia-drm-connector.c
|
||||
05d56aa5e69b2332dba36ed15703865533976681 - kernel-open/nvidia-drm/nvidia-drm-connector.c
|
||||
97b6c56b1407de976898e0a8b5a8f38a5211f8bb - kernel-open/nvidia-drm/nvidia-drm-format.h
|
||||
c1af941dd5144b05995dcf5721652a4f126e175f - kernel-open/nvidia-drm/nvidia-drm-priv.h
|
||||
62b38738a83f67d0ea336cfadff1db5a5eaa8521 - kernel-open/nvidia-drm/nvidia-drm-priv.h
|
||||
deb00fa4d1de972d93d8e72355d81ba87044c86f - kernel-open/nvidia-drm/nvidia-drm-fence.c
|
||||
8a8b431f45bd0fe477759c1527d792cb9a1fa3f5 - kernel-open/nvidia-drm/nvidia-drm-gem.h
|
||||
6528efa1f8061678b8543c5c0be8761cab860858 - kernel-open/nvidia-drm/nvidia-drm-modeset.h
|
||||
c4e015832f97c367b0717fce6cd56e5619ce712c - kernel-open/nvidia-drm/nvidia-drm.Kbuild
|
||||
1b7c0e4bc236101b930a9a95a622c0031c56978d - kernel-open/nvidia-drm/nvidia-drm-modeset.h
|
||||
fa3bcbf2d4b25dc6e2337bcd9d04b0c1413be3da - kernel-open/nvidia-drm/nvidia-drm.Kbuild
|
||||
40b5613d1fbbe6b74bff67a5d07974ad321f75f0 - kernel-open/nvidia-drm/nvidia-drm-utils.h
|
||||
8da06bd922850e840c94ed380e3b92c63aecbf70 - kernel-open/nvidia-drm/nvidia-drm-fb.c
|
||||
c14c141137ddcf2b9fff0c66213098b2dbb7e868 - kernel-open/nvidia-drm/nvidia-drm-crtc.c
|
||||
50dd67b47a78026eb087020dadb9f706cdaa94d2 - kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h
|
||||
5c05b2b133edb91665fbf937d8cea3a92089aa33 - kernel-open/nvidia-modeset/nvidia-modeset-linux.c
|
||||
252660f72b80add6f6071dd0b86288dda8dbb168 - kernel-open/nvidia-modeset/nvkms.h
|
||||
71560a9be3b3c2cd1c85f5d781524aadb6869eed - kernel-open/nvidia-drm/nvidia-drm-crtc.c
|
||||
372ea4c8e7bbc0bdeb899e6f163c8f20c663ad22 - kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h
|
||||
e02497b93f0f13d8e1624ff2effe417ec63bc2b0 - kernel-open/nvidia-modeset/nvidia-modeset-linux.c
|
||||
0a0650835e8835d32418891a2fd25031f5d8770e - kernel-open/nvidia-modeset/nvkms.h
|
||||
646e6b03521587cc1a02617afd697183e5d1a83a - kernel-open/nvidia-modeset/nv-kthread-q.c
|
||||
7dbe6f8405e47c1380c6151c7c7d12b0b02ef7f4 - kernel-open/nvidia-modeset/nvidia-modeset.Kbuild
|
||||
180e72402720a8cc52eb3c0354723a5db3a3bcd3 - kernel-open/nvidia-modeset/nvidia-modeset.Kbuild
|
||||
2ea1436104463c5e3d177e8574c3b4298976d37e - kernel-open/nvidia-modeset/nvkms-ioctl.h
|
||||
36f9753dbbef7dd5610312d5b14bffac1a93cee4 - nouveau/nouveau_firmware_layout.ods
|
||||
7ad4bb8aebd57a9be26329a611b14c5a70ccf2b7 - nouveau/extract-firmware-nouveau.py
|
||||
@@ -252,7 +254,7 @@ f968cd35ce1d1d8e3bc2f669025e6b1042b35354 - src/common/sdk/nvidia/inc/class/cl00d
|
||||
941a031920c0b3bb16473a6a3d4ba8c52c1259d7 - src/common/sdk/nvidia/inc/class/cl917e.h
|
||||
cb610aaae807d182b4a2ee46b9b43ebfa4a49a08 - src/common/sdk/nvidia/inc/class/clc57e.h
|
||||
9e1d2f90d77e23f1d2163a8f8d8d747058e21947 - src/common/sdk/nvidia/inc/class/cl9010.h
|
||||
7c8e1f1055f9522cfb2935ea0aae612ef172c26e - src/common/sdk/nvidia/inc/class/clc370_notification.h
|
||||
5f4e91808d6289265c73f07072eb9cd028e87428 - src/common/sdk/nvidia/inc/class/clc370_notification.h
|
||||
36c6162356ac39346c8900b1e0074e4b614d4b5a - src/common/sdk/nvidia/inc/class/clc370.h
|
||||
5df0ce4eb733554e963eb3c7938396f58f2dd4d5 - src/common/sdk/nvidia/inc/class/cl2081.h
|
||||
2e3d5c71793820d90973d547d8afdf41ff989f89 - src/common/sdk/nvidia/inc/class/clc67a.h
|
||||
@@ -363,7 +365,7 @@ e0c551dc47bc06f8dff5884affdeb05eb118609f - src/common/sdk/nvidia/inc/ctrl/ctrl00
|
||||
7edd8cdb8061ec137bc29d0dbbfbb5d169c0fd35 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080perf.h
|
||||
ccba5f12df1bce4b4235eed5a1c7a0cd2612c2ce - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080internal.h
|
||||
a3328cf6633f9b04258eff05ce30e66cc6930310 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080cipher.h
|
||||
316494234df96c6af34cc0bd2b1c791dc42ac92b - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080unix.h
|
||||
a427892e601a4ca4f88cc5778ff78895324f3728 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080unix.h
|
||||
92ff82d1045933baa79958a9f6efd451b0123e95 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080bsp.h
|
||||
ec7b09fe14c31c175e0abfcfa85dee20d57d02b4 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080clk.h
|
||||
68bdc682ee42784c09409cd581bb991f7fc1bf41 - src/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080msenc.h
|
||||
@@ -381,8 +383,8 @@ d2992c1a9aac5b1b5cfefcca72e9a2401190158c - src/common/sdk/nvidia/inc/ctrl/ctrl00
|
||||
456707a5de78815fc6a33f2da7e2a2a45ccc4884 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073internal.h
|
||||
abed22b35137e2d40399eb4ed01724aa789cb635 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073event.h
|
||||
505860d3cd6f7d5144f97195b9fb32dd5b8f74aa - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h
|
||||
f9f404124a718ace14803ebe84efe752fcef816b - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h
|
||||
ff78c1bb58b1946f3e75e053be9f2b5de443e2f4 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h
|
||||
f32b4e3e8efc0b39538df2b141e3e8845eed553c - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h
|
||||
8e807c3771f3d37885d4066d95ec71c05234b5ec - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h
|
||||
52f251090780737f14eb993150f3ae73be303921 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dpu.h
|
||||
77eb4fab61225663a3f49b868c983d5d532ca184 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073svp.h
|
||||
6ca26c7149455e43f32e8b83b74f4a34a24a2d29 - src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073base.h
|
||||
@@ -490,7 +492,7 @@ e670ffdd499c13e5025aceae5541426ab2ab0925 - src/common/inc/gps.h
|
||||
5257e84f2048b01258c78cec70987f158f6b0c44 - src/common/inc/nvlog_inc.h
|
||||
b58ed1b4372a5c84d5f3755b7090b196179a2729 - src/common/inc/nv_speculation_barrier.h
|
||||
d877f4b99ae7d18cc5c78b85e89c0a7e3f3e8418 - src/common/inc/nvPNPVendorIds.h
|
||||
b777cb738d82ba6f28169fcc7e28d12288642016 - src/common/inc/nvUnixVersion.h
|
||||
6e212afa22e8348eedf1b15bd4bd7f7fd698c3b2 - src/common/inc/nvUnixVersion.h
|
||||
1fc95a17ddb619570063f6707d6a395684bfa884 - src/common/inc/displayport/dpcd20.h
|
||||
90998aac8685a403fdec9ff875f7436373d76f71 - src/common/inc/displayport/dpcd14.h
|
||||
669268ea1660e9e5b876f90da003599ba01356bb - src/common/inc/displayport/displayport.h
|
||||
@@ -504,7 +506,7 @@ bbcecae47807b4578baa460da4147328140ecfcd - src/common/inc/swref/published/nv_ref
|
||||
64c123c90018c5ee122b02b02cbccfcd5ec32cab - src/common/inc/swref/published/t23x/t234/dev_fuse.h
|
||||
4de33a60116ce3fa3f440db105561eddc21ce375 - src/common/shared/nvstatus/nvstatus.c
|
||||
750ecc85242882a9e428d5a5cf1a64f418d59c5f - src/common/displayport/inc/dp_object.h
|
||||
72f91aac76264d34ce778489f5ce839e03833db8 - src/common/displayport/inc/dp_messages.h
|
||||
a6ff1a7aee138f6771c5b0bbedb593a2641e1114 - src/common/displayport/inc/dp_messages.h
|
||||
80380945c76c58648756446435d615f74630f2da - src/common/displayport/inc/dp_timeout.h
|
||||
cdb1e7797c250b0a7c0449e2df5ce71e42b83432 - src/common/displayport/inc/dp_merger.h
|
||||
070b4f6216f19feebb6a67cbb9c3eb22dc60cf74 - src/common/displayport/inc/dp_buffer.h
|
||||
@@ -513,58 +515,60 @@ cdb1e7797c250b0a7c0449e2df5ce71e42b83432 - src/common/displayport/inc/dp_merger.
|
||||
e27519c72e533a69f7433638a1d292fb9df8772e - src/common/displayport/inc/dp_crc.h
|
||||
325818d0a4d1b15447923e2ed92c938d293dc079 - src/common/displayport/inc/dp_hostimp.h
|
||||
29ee5f4ef6670f06e96c07b36c11e3bad8bee6aa - src/common/displayport/inc/dp_address.h
|
||||
36e80dd13c5adc64c3adc9a931d5ebbf922e9502 - src/common/displayport/inc/dp_groupimpl.h
|
||||
f9149d441628fb2ad4fa630f74b9ca43ce710ba7 - src/common/displayport/inc/dp_groupimpl.h
|
||||
8d8a5f0160922b6630fa796789c5d59cce94d9e0 - src/common/displayport/inc/dp_configcaps.h
|
||||
e70068249ebb59040a3e3be1fc4248d714550e61 - src/common/displayport/inc/dp_evoadapter.h
|
||||
570d78b90c470b48d47592a76404c190a0480023 - src/common/displayport/inc/dp_evoadapter.h
|
||||
01f1dd58ed5bb12503fa45be7a6657cde0a857e2 - src/common/displayport/inc/dp_guid.h
|
||||
cca426d571c6b01f7953180e2e550e55c629f0f4 - src/common/displayport/inc/dp_auxretry.h
|
||||
11487c992494f502d1c48ff00982998504336800 - src/common/displayport/inc/dp_internal.h
|
||||
f6e1b0850f5ed0f23f263d4104523d9290bb8669 - src/common/displayport/inc/dp_vrr.h
|
||||
2f134665b274bb223c3f74e0ec5c6a0392fa6387 - src/common/displayport/inc/dp_discovery.h
|
||||
07d22f84e6a386dad251761278a828dab64b6dd5 - src/common/displayport/inc/dp_bitstream.h
|
||||
2a81681efef7ffced62c6d64cfdbc455d85fdb0a - src/common/displayport/inc/dp_mainlink.h
|
||||
9a0aa25938adf3bda9451aeab67fb04e266d771d - src/common/displayport/inc/dp_deviceimpl.h
|
||||
6617a20b016f0cd3278e37617d093b900a6b6afd - src/common/displayport/inc/dp_mainlink.h
|
||||
96f8faea51e03cb6dd421e8c2b0a80d5a6ba8b93 - src/common/displayport/inc/dp_deviceimpl.h
|
||||
eb9cdbb0a907926b1afd2a551ec19830f06ae205 - src/common/displayport/inc/dp_splitter.h
|
||||
5bd3706ceea585df76a75dda7f9581b91ee8f998 - src/common/displayport/inc/dp_tracing.h
|
||||
4a098c4d09dedc33b86748d5fe9a30d097675e9f - src/common/displayport/inc/dp_list.h
|
||||
7b7d9a137027fbbedfc041465987fa4ed4198ce4 - src/common/displayport/inc/dp_edid.h
|
||||
379d3933c90eaf9c35a0bad2bd6af960a321465f - src/common/displayport/inc/dp_wardatabase.h
|
||||
d876d77caef3541ae05f310857f3d32e642fba04 - src/common/displayport/inc/dp_auxdefs.h
|
||||
800e4cb73c649c3c5ad56a8116a8de66aedd487c - src/common/displayport/inc/dp_auxdefs.h
|
||||
e2075486b392d6b231f2f133922ac096ca4bc095 - src/common/displayport/inc/dp_ringbuffer.h
|
||||
d0b72ca2db108478bba75393c7255356da0e8233 - src/common/displayport/inc/dp_regkeydatabase.h
|
||||
36d3c602cbbf0a52d574f841ba1b75125ec3b24a - src/common/displayport/inc/dp_linkconfig.h
|
||||
2c60a5ee5d2a248e51a0ea740395f377d2e51e25 - src/common/displayport/inc/dp_regkeydatabase.h
|
||||
cd9d3f57a9212166eba32b25cebc866a8d5bc026 - src/common/displayport/inc/dp_qse.h
|
||||
72711e7f688ee25510fca0e7eef6a4a99bb0aff3 - src/common/displayport/inc/dp_linkconfig.h
|
||||
e02e5621eaea52a2266a86dcd587f4714680caf4 - src/common/displayport/inc/dp_linkedlist.h
|
||||
2067e2ca3b86014c3e6dfc51d6574d87ae12d907 - src/common/displayport/inc/dp_timer.h
|
||||
a3fc03562a3fa0968ab8d4a50424465174392f0e - src/common/displayport/inc/dp_connectorimpl.h
|
||||
34e808f745eaaff13aeb4e6cde1a8ce35f7b9def - src/common/displayport/inc/dp_connector.h
|
||||
c2f5f82ddf1d0b5c976264ceb14fe9b67bf12851 - src/common/displayport/inc/dp_messagecodings.h
|
||||
5a0d4df6d025eb24ae8af408416378d1e9e2f17a - src/common/displayport/inc/dp_connectorimpl.h
|
||||
4a445c98d9541a53f77af2ffa154501793c01fe4 - src/common/displayport/inc/dp_connector.h
|
||||
660ba146cf1242947eac3e2ded50ef4387ca8f35 - src/common/displayport/inc/dp_messagecodings.h
|
||||
df11366a5bcfb641025f12cddf9b5e8c2ed008de - src/common/displayport/inc/dp_watermark.h
|
||||
020194b85245bad5de4dfe372a7ccb0c247d6ede - src/common/displayport/inc/dptestutil/dp_testmessage.h
|
||||
d2b00a849a81f6c6092e3b2c4e7ed20fcee62b39 - src/common/displayport/inc/dptestutil/dp_testmessage.h
|
||||
70b155b0da07a92ede884a9cec715f67e6b5c3e8 - src/common/displayport/src/dp_list.cpp
|
||||
37eabb1ab51cb38660eb24e294c63c8320750b96 - src/common/displayport/src/dp_sst_edid.cpp
|
||||
fea946e5320e7de8e9229bca8d4a6a14b9e8db59 - src/common/displayport/src/dp_crc.cpp
|
||||
fbd877bac2efc8ee33e4e108e61c961e1fc42f44 - src/common/displayport/src/dp_messagecodings.cpp
|
||||
d199166ebfe00628b9c4894a97c3bb9f09d355e5 - src/common/displayport/src/dp_messagecodings.cpp
|
||||
aa2e56f6c66bf91c2b4a6030de2d29480f69710e - src/common/displayport/src/dp_wardatabase.cpp
|
||||
de264916d0e3e873a4c624f237ea228469d0a980 - src/common/displayport/src/dp_watermark.cpp
|
||||
e874ffeaeb6deec57605bf91eaa2af116a9762bd - src/common/displayport/src/dp_bitstream.cpp
|
||||
818efd113374de206a36ccf2bf594b4e433a0b85 - src/common/displayport/src/dp_evoadapter.cpp
|
||||
6b2384144feb749a974ca794ff74031e13ed6610 - src/common/displayport/src/dp_evoadapter.cpp
|
||||
56ee9318a7b51a04baa1d25d7d9a798c733dc1bc - src/common/displayport/src/dp_vrr.cpp
|
||||
d991afdb694634e9df756184b5951739fc3fd0ab - src/common/displayport/src/dp_auxretry.cpp
|
||||
554e6b7dadbb68ac0f3d2e368ca3fd90832ea254 - src/common/displayport/src/dp_discovery.cpp
|
||||
45da2aabdaf6b5b2bf17a3deeb045feed1545415 - src/common/displayport/src/dp_messages.cpp
|
||||
719d2ddbfb8555636496cb5dd74ee6776059db92 - src/common/displayport/src/dp_timer.cpp
|
||||
ca92fed27d4c5ca5e9495df08e63d5f446e7f24b - src/common/displayport/src/dp_deviceimpl.cpp
|
||||
1923346b4f1209a8ceaf30d240f1b05717149be4 - src/common/displayport/src/dp_deviceimpl.cpp
|
||||
98cec6b663cf630c789e9823675cbb4948e1ba5e - src/common/displayport/src/dp_edid.cpp
|
||||
f4493ab7efc7030b4cd17bf792981a9dca497e29 - src/common/displayport/src/dp_groupimpl.cpp
|
||||
9fc1b9ae59805ea96879de1960149398bfe8dccd - src/common/displayport/src/dp_groupimpl.cpp
|
||||
e10ed809c1ddb7e67f0d7caf88802f291c8567ef - src/common/displayport/src/dp_qse.cpp
|
||||
4803cde0fffcf89fed46d6deaeba5c96c669a908 - src/common/displayport/src/dp_messageheader.cpp
|
||||
9f31213ab8037d7bb18c96a67d2630d61546544a - src/common/displayport/src/dp_mst_edid.cpp
|
||||
f56f92e32710b0342805b785d34ba1a9f2a54ed3 - src/common/displayport/src/dp_guid.cpp
|
||||
d2f8d43d650d9c0b4a8d9b8070087f13efdaac79 - src/common/displayport/src/dp_connectorimpl.cpp
|
||||
656cf635f5268df416d746378d25e773bde24758 - src/common/displayport/src/dp_connectorimpl.cpp
|
||||
f83b3c17e9f26651f12c8835a682abdd66aed3a2 - src/common/displayport/src/dp_splitter.cpp
|
||||
1543bbaba8f3e149239cf44be3c0d080c624d5ba - src/common/displayport/src/dp_buffer.cpp
|
||||
fa4f4869d3d63c0180f30ae3736600a6627284c6 - src/common/displayport/src/dp_merger.cpp
|
||||
b18924b1d50232b92223355f608fcca1b6d7ff46 - src/common/displayport/src/dp_configcaps.cpp
|
||||
fe8007b3d98dad71b17595ecb67af77b198827a0 - src/common/displayport/src/dptestutil/dp_testmessage.cpp
|
||||
a0b68fce10eb0b95518cfd291e2d282872225295 - src/common/displayport/src/dptestutil/dp_testmessage.cpp
|
||||
54c516f23671ec703a4e000f700c16dce640367a - src/common/modeset/timing/nvt_dmt.c
|
||||
890d8c2898a3277b0fed360301c2dc2688724f47 - src/common/modeset/timing/nvt_util.c
|
||||
cc04c12ebe4e2f7e31d0619ddd16db0c46b9db9e - src/common/modeset/timing/nvtiming.h
|
||||
@@ -596,7 +600,7 @@ a1f52f0f78eec1d98b30b0f08bc1c5e88ae3d396 - src/common/modeset/hdmipacket/nvhdmip
|
||||
67db549636b67a32d646fb7fc6c8db2f13689ecc - src/common/modeset/hdmipacket/nvhdmipkt_9271.c
|
||||
e6d500269128cbd93790fe68fbcad5ba45c2ba7d - src/common/modeset/hdmipacket/nvhdmipkt_C371.c
|
||||
f2b434ed8bdd7624143654b7b3953d8c92e5a8e2 - src/common/modeset/hdmipacket/nvhdmipkt_common.h
|
||||
b882497ae393bf66a728dae395b64ac53602a1a5 - src/common/softfloat/nvidia/nv-softfloat.h
|
||||
33a5c7cd8cf4ecb7d9a76c9b623372949b538fc8 - src/common/softfloat/nvidia/nv-softfloat.h
|
||||
be9407a273620c0ba619b53ed72d59d52620c3e4 - src/common/softfloat/nvidia/platform.h
|
||||
f6d98979ab2d1e2b0d664333104130af6abbcad5 - src/common/softfloat/source/f64_to_i64_r_minMag.c
|
||||
21a6232d93734b01692689258a3fdfbbf4ff089d - src/common/softfloat/source/s_roundToUI32.c
|
||||
@@ -705,7 +709,7 @@ ae7d5cb2c57beeea12724e09d957e233a71c12a1 - src/nvidia/arch/nvalloc/unix/include/
|
||||
1e89b4a52a5cdc6cac511ff148c7448d53cf5d5c - src/nvidia/arch/nvalloc/unix/include/os_custom.h
|
||||
499e72dad20bcc283ee307471f8539b315211da4 - src/nvidia/arch/nvalloc/unix/include/nv-unix-nvos-params-wrappers.h
|
||||
5f2a30347378f2ed028c9fb7c8abea9b6032141c - src/nvidia/arch/nvalloc/unix/include/osapi.h
|
||||
de6913c5e5092a417530ac9f818497824eab7946 - src/nvidia/arch/nvalloc/unix/include/os-interface.h
|
||||
c9120c6a33932c7514608601f82ea85d2386b84f - src/nvidia/arch/nvalloc/unix/include/os-interface.h
|
||||
ddfedb3b81feb09ea9daadf1a7f63f6309ee6e3b - src/nvidia/arch/nvalloc/unix/include/rmobjexportimport.h
|
||||
9c7b09c55aabbd670c860bdaf8ec9e8ff254b5e9 - src/nvidia/arch/nvalloc/unix/include/nv-kernel-rmapi-ops.h
|
||||
1d8b347e4b92c340a0e9eac77e0f63b9fb4ae977 - src/nvidia/arch/nvalloc/unix/include/nv-ioctl-numbers.h
|
||||
@@ -715,11 +719,11 @@ ddfedb3b81feb09ea9daadf1a7f63f6309ee6e3b - src/nvidia/arch/nvalloc/unix/include/
|
||||
63edc719390a814eb70290e709634d133ad198cc - src/nvidia/arch/nvalloc/unix/src/osmemdesc.c
|
||||
11c6d988bccbdf49ac241d77e6363c7843a0191f - src/nvidia/arch/nvalloc/unix/src/power-management-tegra.c
|
||||
6ca29f3d6b38fb5d05ff222cd1b79ade811a74b2 - src/nvidia/arch/nvalloc/unix/src/osunix.c
|
||||
ff839a6e0535caf19fb52ec24d33f7368aada796 - src/nvidia/arch/nvalloc/unix/src/unix_console.c
|
||||
7ce04b5b6d90c9a433af667c8644b8e328af9968 - src/nvidia/arch/nvalloc/unix/src/unix_console.c
|
||||
b5b409625fde1b640e4e93276e35248f0fccfa4c - src/nvidia/arch/nvalloc/unix/src/gcc_helper.c
|
||||
16e1482d8a9287bc2fd3da28dd62066e4e3ff92b - src/nvidia/arch/nvalloc/unix/src/exports-stubs.c
|
||||
15920addb99f39201a7a7cc9c4e7a9e22c13d118 - src/nvidia/arch/nvalloc/unix/src/osinit.c
|
||||
4971626589ae66cc273ad11b80f0ab875fb39c05 - src/nvidia/arch/nvalloc/unix/src/osapi.c
|
||||
b7f20cd0a65957e5f5639cb561ca14893ee024cb - src/nvidia/arch/nvalloc/unix/src/osapi.c
|
||||
eccfc4f261fd8531254eb2961120073aac9847db - src/nvidia/arch/nvalloc/unix/src/rmobjexportimport.c
|
||||
690927567b5344c8030e2c52d91f824bb94e956c - src/nvidia/arch/nvalloc/unix/src/registry.c
|
||||
a28937330829b4f27a9da5e2c3776ceb293b6085 - src/nvidia/arch/nvalloc/unix/src/os-hypervisor-stubs.c
|
||||
@@ -835,7 +839,7 @@ c5021789fed61a37794ade5a3632a8eb37c0c27f - src/nvidia/generated/g_kern_disp_nvoc
|
||||
8b5821085e5aabc00408e7a90e78b2471de6797e - src/nvidia/generated/g_os_nvoc.h
|
||||
87c14e1c1a8f37f139f6a99efaf7752d6db48db5 - src/nvidia/generated/g_kern_disp_nvoc.c
|
||||
a97bf85ce6681aae086e0415aecaebf0208bfebb - src/nvidia/generated/g_tmr_nvoc.h
|
||||
779103a57f68832641a7616ea8c5608780cfc155 - src/nvidia/generated/g_disp_objs_nvoc.h
|
||||
d44164b90bdf5ed4a2ce9a5d13f680b8a997a5cb - src/nvidia/generated/g_disp_objs_nvoc.h
|
||||
3b08d4bb1612bb193cd2f26229b119cc43284879 - src/nvidia/generated/g_rs_server_nvoc.h
|
||||
ddc0ac4e1d8b8aef15e147f1f85f8df37c196763 - src/nvidia/generated/g_hal_register.h
|
||||
aac848bd48955659eb5e07fcac70e6fe3c3a137a - src/nvidia/generated/g_hal_nvoc.c
|
||||
@@ -848,7 +852,7 @@ c8d6ddc934e0c4ae3fd2d2dc81d0d1a91c8b8d52 - src/nvidia/generated/g_disp_inst_mem_
|
||||
76b1f545e3712a2f8e7c31b101acd9dd682c52f8 - src/nvidia/generated/g_traceable_nvoc.c
|
||||
c0750d49486dcf1718083d5deaef16c718b9a909 - src/nvidia/generated/g_eng_desc_nvoc.h
|
||||
ad695d35b837b970b8f50a280d400ffed5067c0f - src/nvidia/generated/g_os_desc_mem_nvoc.c
|
||||
e3078050c80bf14c9f91f12b43eab48af94c9ec5 - src/nvidia/generated/g_disp_objs_nvoc.c
|
||||
b114f65bcee6bda607f4549827ccb298f7449c03 - src/nvidia/generated/g_disp_objs_nvoc.c
|
||||
b0089bee11caa0d8994b39eaecfb42ca3507de37 - src/nvidia/generated/g_syncpoint_mem_nvoc.h
|
||||
b30dc7b4114007f7649e18a7be2d829a3752447a - src/nvidia/generated/g_mem_nvoc.c
|
||||
06094e14a41e58c8a687bc8b64197a73c0c2b61a - src/nvidia/generated/g_system_nvoc.h
|
||||
@@ -1069,7 +1073,7 @@ fc39cb6ac6e9d73bd1ab98890e6b253217d6cc90 - src/nvidia/src/kernel/diagnostics/nvl
|
||||
1fad27934185df50c1d91b5536d0df437618382f - src/nvidia/src/kernel/os/os_init.c
|
||||
c8c4af5a28740f1e66ff4e6e9c47fc6c981ce46b - src/nvidia/src/kernel/os/os_timer.c
|
||||
0e0c1b862bdba245297ffd4f725001fa2439cddf - src/nvidia/src/kernel/os/os_sanity.c
|
||||
1dc0be7577b4f7914743379943bcf0d5e236eb0b - src/nvidia/src/kernel/os/os_stubs.c
|
||||
0f10f992879cdea2a2e3d5f19589ad66b518a872 - src/nvidia/src/kernel/os/os_stubs.c
|
||||
b4dc306ae4d4f8850571e2fbbed0114d63f1ba93 - src/nvidia/src/kernel/rmapi/entry_points.c
|
||||
bac6ef63d11e87f9a4af3318d5be6860f861a0b9 - src/nvidia/src/kernel/rmapi/rpc_common.c
|
||||
96f763eef08f1954d3f07639053db2cde2a01e39 - src/nvidia/src/kernel/rmapi/rmapi.c
|
||||
@@ -1149,7 +1153,7 @@ c6e78a54a1b8d4ca6fe4b01d83e3199ea41606d7 - src/nvidia/src/kernel/gpu/mem_mgr/con
|
||||
f30ae0e8e1e32d0adb7e52b8995c277637b6bc2a - src/nvidia/src/kernel/gpu/mem_mgr/mem_utils.c
|
||||
3c463773f2f970b1764edb231d349164fe4341fc - src/nvidia/src/kernel/gpu/mem_mgr/mem_desc.c
|
||||
2bb921b462c4b50d1f42b39b4728374c7433c8cb - src/nvidia/src/kernel/gpu/mem_mgr/arch/turing/mem_mgr_tu102_base.c
|
||||
5a053caaa8eb655d9e0f7ab42ec1b3f0b72fb787 - src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c
|
||||
cc1249dcc4c4530c59f0aa314dbcd8f7a69be009 - src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c
|
||||
7f9874d9af6b937dac888a3ebb55a82c2a5de71b - src/nvidia/src/kernel/gpu/dce_client/dce_client.c
|
||||
d5d8ff429d3bda7103bafcb2dca94678efc8ddd8 - src/nvidia/src/kernel/gpu_mgr/gpu_group.c
|
||||
719d890f8160efe57e4c3267db65885ebb66cd03 - src/nvidia/src/kernel/gpu_mgr/gpu_db.c
|
||||
@@ -1178,7 +1182,7 @@ d81ef382635d0c4de47dfa3d709e0702f371ceb7 - src/nvidia/interface/rmapi/src/g_finn
|
||||
c3ab6005d7083e90145cac66addf815c4f93d9a0 - src/nvidia-modeset/lib/nvkms-format.c
|
||||
b8854261256a801af52d1201081afa9c17486a96 - src/nvidia-modeset/include/nvkms-3dvision.h
|
||||
ebafc51b2b274cd1818e471850a5efa9618eb17d - src/nvidia-modeset/include/nvkms-prealloc.h
|
||||
8a0ced82697c32b97a80fa3366704014879610e7 - src/nvidia-modeset/include/nvkms-flip-workarea.h
|
||||
712798f7ead59ecab66551630967fe54472f2f9f - src/nvidia-modeset/include/nvkms-flip-workarea.h
|
||||
fa829f1cd3b73f194f39879c48962b703f640b65 - src/nvidia-modeset/include/nvkms-vrr.h
|
||||
49af4a8fa95d0e595deacadbca5360f097722e7f - src/nvidia-modeset/include/nvkms-evo1.h
|
||||
496b94af536dd912866a05f7b2da53050b50c2f5 - src/nvidia-modeset/include/nvkms-prealloc-types.h
|
||||
@@ -1191,8 +1195,8 @@ a79cfb74026085b0aa612c0ae6789083e196bbc2 - src/nvidia-modeset/include/nvkms-evo-
|
||||
6e3681d5caa36312804c91630eaaf510eda897d2 - src/nvidia-modeset/include/nvkms-dma.h
|
||||
eb5248c4b0b51e7aecd2de87e496253b3b235c70 - src/nvidia-modeset/include/nvkms-utils-flip.h
|
||||
377dd4a29b2ea5937a9b8fc3fba0c9e4ef92992e - src/nvidia-modeset/include/nvkms-cursor.h
|
||||
ec1374d339746b73bc7c7614695fde68c156074a - src/nvidia-modeset/include/nvkms-rm.h
|
||||
d57ae79509c667e8d16a4756d85e3564c1b1ac34 - src/nvidia-modeset/include/nvkms-modeset.h
|
||||
7347dc4c3d89053efaac4e7c64fb35cfdeaf305a - src/nvidia-modeset/include/nvkms-rm.h
|
||||
0449c65467d54097b65d60eec670450b126b07c1 - src/nvidia-modeset/include/nvkms-modeset.h
|
||||
be6e0e97c1e7ffc0daa2f14ef7b05b9f9c11dc16 - src/nvidia-modeset/include/nvkms-attributes.h
|
||||
07ac47b52b1b42c143501c4a95a88a3f86f5be03 - src/nvidia-modeset/include/nvkms-hdmi.h
|
||||
6b21a68e254becdd2641bc456f194f54c23abe51 - src/nvidia-modeset/include/nvkms-framelock.h
|
||||
@@ -1200,15 +1204,15 @@ c90e4393f568d96bc98cb52a93bfc3fdea10658d - src/nvidia-modeset/include/nvkms-mode
|
||||
ae03509966df56d98fa72b7528ab43ec2b258381 - src/nvidia-modeset/include/nvkms-utils.h
|
||||
f5f3b11c78a8b0eef40c09e1751615a47f516edb - src/nvidia-modeset/include/nvkms-hal.h
|
||||
d05ef9a837f2927fe387e7d157ea76c7ef567807 - src/nvidia-modeset/include/nvkms-lut.h
|
||||
1b75646c99c748f9070208eb58f0082812eabbd9 - src/nvidia-modeset/include/nvkms-private.h
|
||||
15dddd9307fa7ac201bd9ebc1e35e6ac0d2cf6c9 - src/nvidia-modeset/include/nvkms-evo.h
|
||||
2b720811867a06d24b22f03d098fe6d9fea423a0 - src/nvidia-modeset/include/nvkms-private.h
|
||||
6fa4708e4f6dfe63f149a1c70fa84bf9df01026a - src/nvidia-modeset/include/nvkms-evo.h
|
||||
4a94381bd8c24b09193577d3f05d6d61f178e1cf - src/nvidia-modeset/include/nvkms-ctxdma.h
|
||||
11bae7c491bbb0ba4cad94b645d47c384191fa5c - src/nvidia-modeset/include/nvkms-flip.h
|
||||
c869ccfcda419d80b6691d3667c4e9196493065e - src/nvidia-modeset/include/nvkms-modeset-types.h
|
||||
260b6ef87c755e55a803adad4ce49f2d57315f9a - src/nvidia-modeset/include/nvkms-event.h
|
||||
00d2f2fa1f7c96757f67b9ca3ff1c2699a493bd0 - src/nvidia-modeset/include/nvkms-modeset-types.h
|
||||
4f85782f39355e10576f21bee44a942c9317664c - src/nvidia-modeset/include/nvkms-event.h
|
||||
35fa1444c57f7adbbddddc612237f3ad38cdd78f - src/nvidia-modeset/include/nvkms-rmapi.h
|
||||
118d0ea84ff81de16fbdc2c7daf249ee5c82ed6e - src/nvidia-modeset/include/nvkms-modepool.h
|
||||
691731826d6daa3bb5a3847a3dd2424d513113c4 - src/nvidia-modeset/include/nvkms-types.h
|
||||
fd0c300efa7a76783847cfc809242d304fe4435c - src/nvidia-modeset/include/nvkms-types.h
|
||||
4a33d410f090fd4f4dfc9a6de285f8e8fb1c9ced - src/nvidia-modeset/include/nvkms-surface.h
|
||||
b0d407b0413453ec71481f84cc448d090b90d609 - src/nvidia-modeset/include/nvkms-evo3.h
|
||||
8c7e0e15c1038fe518e98d8f86fafb250b10a1d2 - src/nvidia-modeset/include/nvkms-stereo.h
|
||||
@@ -1218,36 +1222,36 @@ c386632dbdc0e89019d5618f132dbcb3dff4dafb - src/nvidia-modeset/include/dp/nvdp-de
|
||||
a8fbb7a071c0e7b326f384fed7547e7b6ec81c3e - src/nvidia-modeset/include/dp/nvdp-timer.h
|
||||
ae43c46687d16b93189047d9eeed933a67e5571f - src/nvidia-modeset/include/dp/nvdp-connector.h
|
||||
727bd77cfbc9ac4989c2ab7eec171ceb516510aa - src/nvidia-modeset/kapi/include/nvkms-kapi-notifiers.h
|
||||
27612b72a77ac67cd468ac7f15948d2ad78defed - src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h
|
||||
67fe73dc7149daf807194bd9a0f96252cb452179 - src/nvidia-modeset/kapi/src/nvkms-kapi.c
|
||||
d77e520819f0fa8a775542f493af03f9f2aafc47 - src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h
|
||||
ff51857b54672bd80d740213e9b20f35bcdeed89 - src/nvidia-modeset/kapi/src/nvkms-kapi.c
|
||||
01d943d6edb0c647c2b8dbc44460948665b03e7a - src/nvidia-modeset/kapi/src/nvkms-kapi-notifiers.c
|
||||
ce42ceac4c4cf9d249d66ab57ae2f435cd9623fc - src/nvidia-modeset/kapi/src/nvkms-kapi-sync.c
|
||||
80c2c9a2a05beb0202239db8b0dd7080ff21c194 - src/nvidia-modeset/kapi/interface/nvkms-kapi-private.h
|
||||
36c20e9c111e66601b025802f840e7b87d09cdde - src/nvidia-modeset/kapi/interface/nvkms-kapi.h
|
||||
fd64ffbcc1efd446fb3352ceaa8bd4221b23a1d2 - src/nvidia-modeset/src/nvkms-modeset.c
|
||||
b7232f4b4b8f0d4c395c241c451fc17b6ab84d7f - src/nvidia-modeset/src/nvkms-evo.c
|
||||
7d0e38f9d79e0c928bdc67276b8ecb0c18470b88 - src/nvidia-modeset/src/nvkms-hw-flip.c
|
||||
61a60660761e90aa622af2fda482d69473ab40d4 - src/nvidia-modeset/kapi/interface/nvkms-kapi.h
|
||||
26144f7b6e9358a5418735c5c357c964047b52ca - src/nvidia-modeset/src/nvkms-modeset.c
|
||||
5f559582336ab0e252f25039d43b114a6630758c - src/nvidia-modeset/src/nvkms-evo.c
|
||||
7262999494048226f8a94492899609fbecd729d8 - src/nvidia-modeset/src/nvkms-hw-flip.c
|
||||
6a35b80a6995777dc9500cac9659e6f0f0c12d23 - src/nvidia-modeset/src/nvkms-cursor3.c
|
||||
710b38a93fee94fa4659309451bd4e7baa7ff0d6 - src/nvidia-modeset/src/nvkms-rm.c
|
||||
7326c2e84f81abbe6d8df0ce2632a83682fbd5dc - src/nvidia-modeset/src/nvkms-rm.c
|
||||
30ad7839985dea46e6b6d43499210a3056da51ad - src/nvidia-modeset/src/nvkms-utils-flip.c
|
||||
96296baa35ea2367f1fd6ee2c99fa0107c126849 - src/nvidia-modeset/src/nvkms-evo3.c
|
||||
b13bd89b5ac60ceab56e9c2398cf7668375ab7ad - src/nvidia-modeset/src/nvkms-flip.c
|
||||
2ff0dded5029b1284268ee9358f576828d073285 - src/nvidia-modeset/src/nvkms-evo3.c
|
||||
0343d2f40978b0780b0dae54b22f366f723ff08e - src/nvidia-modeset/src/nvkms-flip.c
|
||||
3e723edf2a0a2f4f93032feb4aeaaf7fd0acddfa - src/nvidia-modeset/src/g_nvkms-evo-states.c
|
||||
761c8540278a1ffb9fe4aa0adb1b4ee95524787a - src/nvidia-modeset/src/nvkms-hal.c
|
||||
9e4d3e3505a84d8634a2ef2307628a8fe551a4c3 - src/nvidia-modeset/src/nvkms-surface.c
|
||||
bd2e4a6102432d4ac1faf92b5d3db29e9e3cfafc - src/nvidia-modeset/src/nvkms-utils.c
|
||||
6d41c9f84cc9ce2d16812e94a3fba055b3fc7308 - src/nvidia-modeset/src/nvkms-conf.c
|
||||
9a8746ee4a4e772b8ac13f06dc0de8a250fdb4c7 - src/nvidia-modeset/src/nvkms-ctxdma.c
|
||||
eb99e694dc088194091e33ed73c01b745c3b939e - src/nvidia-modeset/src/nvkms-hdmi.c
|
||||
e7a717712eb5f710df2c735013f27b0c03ae276c - src/nvidia-modeset/src/nvkms-hdmi.c
|
||||
2fa9d9b3cbeeb9406f2dd51a4f4a5d53844a31c9 - src/nvidia-modeset/src/nvkms-dpy.c
|
||||
a49319a235d8746b771a7c418277e168a291259f - src/nvidia-modeset/src/nvkms.c
|
||||
f92ae2b0ba77cf14cbe966a0c66fe6ca02a7e73e - src/nvidia-modeset/src/nvkms.c
|
||||
dff88ceaf95239b51b60af915f92e389bb844425 - src/nvidia-modeset/src/nvkms-cursor.c
|
||||
2b304663f2a005b5ccdecfafb69a3407f2feeb18 - src/nvidia-modeset/src/nvkms-evo2.c
|
||||
94e9c19b7b6a5e56fd46b0885e7dd6fe698fe2df - src/nvidia-modeset/src/nvkms-prealloc.c
|
||||
54b41301663dc9fdc45d24c7a43ad4a980821f9d - src/nvidia-modeset/src/nvkms-attributes.c
|
||||
795ddaec1aa05d152eedd28a3bc82ca49e44a72f - src/nvidia-modeset/src/nvkms-attributes.c
|
||||
65b02b48caff2a9100b8c5614f91d42fb20da9c0 - src/nvidia-modeset/src/nvkms-dpy-override.c
|
||||
9fea40b7b55d6ebf3f73b5d469751c873ffbe7c0 - src/nvidia-modeset/src/nvkms-dma.c
|
||||
da726d20eea99a96af4c10aace88f419e8ee2a34 - src/nvidia-modeset/src/nvkms-event.c
|
||||
7e16c9cc7e4a9a8329347133663f29aaa4ec7446 - src/nvidia-modeset/src/nvkms-event.c
|
||||
2fabe1c14116a2b07f24d01710394ee84a6e3914 - src/nvidia-modeset/src/nvkms-3dvision.c
|
||||
3261fd9a1eb14f7f3fb0917757b1e2704d4abbd2 - src/nvidia-modeset/src/nvkms-hw-states.c
|
||||
c799d52bdc792efc377fb5cd307b0eb445c44d6a - src/nvidia-modeset/src/nvkms-cursor2.c
|
||||
@@ -1256,23 +1260,23 @@ df59641109db4529eed62cf156b1815a3e67ba05 - src/nvidia-modeset/src/nvkms-vrr.c
|
||||
05ca4acdfeb9b99eccc7e222846fc688473322ae - src/nvidia-modeset/src/nvkms-rmapi-dgpu.c
|
||||
f754a27436fd1e1fa103de6110224c21ad7ea9f4 - src/nvidia-modeset/src/nvkms-pow.c
|
||||
f4a02d5b6cb1fa5d461514b21e13002ad9cfa1a4 - src/nvidia-modeset/src/nvkms-evo1.c
|
||||
6f2eb25d57d2dc3c1e5db869cfbdf556878d3332 - src/nvidia-modeset/src/nvkms-console-restore.c
|
||||
3b4843e97ce186b05df6b6f19b463818d769bfcb - src/nvidia-modeset/src/nvkms-console-restore.c
|
||||
933829ff39c6d1fe41bd82a5af177f5059b4b69e - src/nvidia-modeset/src/nvkms-modepool.c
|
||||
403e6dbff0a607c2aecf3204c56633bd7b612ae2 - src/nvidia-modeset/src/nvkms-stereo.c
|
||||
bf1b007fceaa1c38771f9e7d1130f9c0c3eddd80 - src/nvidia-modeset/src/nvkms-lut.c
|
||||
93ab81a362c4ba29ed817dd14fbd75f2b36b62b8 - src/nvidia-modeset/src/nvkms-lut.c
|
||||
f96cd982b4c05351faa31d04ac30d6fa7c866bcb - src/nvidia-modeset/src/dp/nvdp-timer.cpp
|
||||
6b985fc50b5040ce1a81418bed73a60edb5d3289 - src/nvidia-modeset/src/dp/nvdp-timer.hpp
|
||||
a90b2c295271631b4c3abe6afb8dfd92d6b429c8 - src/nvidia-modeset/src/dp/nvdp-connector.cpp
|
||||
535ce9f743903eb83a341eef1be812f4e4b50887 - src/nvidia-modeset/src/dp/nvdp-evo-interface.cpp
|
||||
c19775aebdaaaee3500378d47af6ff0b8eb486b8 - src/nvidia-modeset/src/dp/nvdp-device.cpp
|
||||
a2a4b7063fa903cc434163ebceb7c8d48f703c33 - src/nvidia-modeset/src/dp/nvdp-connector-event-sink.cpp
|
||||
98046832ecc2cad21e727fecf2b9626dd212d95c - src/nvidia-modeset/src/dp/nvdp-connector-event-sink.cpp
|
||||
51af3c1ee6b74ee0c9add3fb7d50cbc502980789 - src/nvidia-modeset/src/dp/nvdp-evo-interface.hpp
|
||||
110ac212ee8832c3fa3c4f45d6d33eed0301e992 - src/nvidia-modeset/src/dp/nvdp-host.cpp
|
||||
69fed95ab3954dd5cb26590d02cd8ba09cdff1ac - src/nvidia-modeset/src/dp/nvdp-connector-event-sink.hpp
|
||||
50dd67b47a78026eb087020dadb9f706cdaa94d2 - src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h
|
||||
252660f72b80add6f6071dd0b86288dda8dbb168 - src/nvidia-modeset/os-interface/include/nvkms.h
|
||||
4da2125966732a80fc154cea4b18b2372b12501e - src/nvidia-modeset/interface/nvkms-api.h
|
||||
372ea4c8e7bbc0bdeb899e6f163c8f20c663ad22 - src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h
|
||||
0a0650835e8835d32418891a2fd25031f5d8770e - src/nvidia-modeset/os-interface/include/nvkms.h
|
||||
beebcd654ab4db41c38a2d2e9c1575415a0ed815 - src/nvidia-modeset/interface/nvkms-api.h
|
||||
b986bc6591ba17a74ad81ec4c93347564c6d5165 - src/nvidia-modeset/interface/nvkms-format.h
|
||||
2ea1436104463c5e3d177e8574c3b4298976d37e - src/nvidia-modeset/interface/nvkms-ioctl.h
|
||||
d51449fa2fd19748007f2e98f0233c92b45f9572 - src/nvidia-modeset/interface/nvkms-api-types.h
|
||||
b3d26ddf643e0bd98847ee56b930c14d06cadf89 - src/nvidia-modeset/interface/nvkms-api-types.h
|
||||
8e3e74d2b3f45381e7b0012d930cf451cbd1728f - src/nvidia-modeset/interface/nvkms-sync.h
|
||||
|
||||
@@ -72,7 +72,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc
|
||||
EXTRA_CFLAGS += -I$(src)
|
||||
EXTRA_CFLAGS += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args
|
||||
EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM
|
||||
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"540.3.2\"
|
||||
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"540.5.0\"
|
||||
|
||||
ifneq ($(SYSSRCHOST1X),)
|
||||
EXTRA_CFLAGS += -I$(SYSSRCHOST1X)
|
||||
@@ -212,6 +212,8 @@ $(obj)/conftest/patches.h: $(NV_CONFTEST_SCRIPT)
|
||||
# corresponding #define will be generated in conftest/headers.h.
|
||||
NV_HEADER_PRESENCE_TESTS = \
|
||||
asm/system.h \
|
||||
drm/display/drm_hdcp.h \
|
||||
drm/display/drm_hdcp_helper.h \
|
||||
drm/drmP.h \
|
||||
drm/drm_aperture.h \
|
||||
drm/drm_auth.h \
|
||||
@@ -290,7 +292,6 @@ NV_HEADER_PRESENCE_TESTS = \
|
||||
linux/of_platform.h \
|
||||
linux/of_device.h \
|
||||
linux/of_gpio.h \
|
||||
linux/of_clk.h \
|
||||
linux/gpio.h \
|
||||
linux/gpio/consumer.h \
|
||||
linux/interconnect.h \
|
||||
|
||||
@@ -35,6 +35,4 @@ int nv_platform_count_devices(void);
|
||||
int nv_soc_register_irqs(nv_state_t *nv);
|
||||
void nv_soc_free_irqs(nv_state_t *nv);
|
||||
|
||||
int nv_disable_simplefb_clocks(void);
|
||||
|
||||
#endif
|
||||
|
||||
120
kernel-open/common/inc/nv_common_utils.h
Normal file
120
kernel-open/common/inc/nv_common_utils.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
#ifndef __NV_COMMON_UTILS_H__
|
||||
#define __NV_COMMON_UTILS_H__
|
||||
|
||||
#include "nvtypes.h"
|
||||
#include "nvmisc.h"
|
||||
|
||||
#if !defined(TRUE)
|
||||
#define TRUE NV_TRUE
|
||||
#endif
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE NV_FALSE
|
||||
#endif
|
||||
|
||||
#define NV_IS_UNSIGNED(x) ((__typeof__(x))-1 > 0)
|
||||
|
||||
/* Get the length of a statically-sized array. */
|
||||
#define ARRAY_LEN(_arr) (sizeof(_arr) / sizeof(_arr[0]))
|
||||
|
||||
#define NV_INVALID_HEAD 0xFFFFFFFF
|
||||
|
||||
#define NV_INVALID_CONNECTOR_PHYSICAL_INFORMATION (~0)
|
||||
|
||||
#if !defined(NV_MIN)
|
||||
# define NV_MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#define NV_MIN3(a,b,c) NV_MIN(NV_MIN(a, b), c)
|
||||
#define NV_MIN4(a,b,c,d) NV_MIN3(NV_MIN(a,b),c,d)
|
||||
|
||||
#if !defined(NV_MAX)
|
||||
# define NV_MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#define NV_MAX3(a,b,c) NV_MAX(NV_MAX(a, b), c)
|
||||
#define NV_MAX4(a,b,c,d) NV_MAX3(NV_MAX(a,b),c,d)
|
||||
|
||||
static inline int NV_LIMIT_VAL_TO_MIN_MAX(int val, int min, int max)
|
||||
{
|
||||
if (val < min) {
|
||||
return min;
|
||||
}
|
||||
if (val > max) {
|
||||
return max;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
#define NV_ROUNDUP_DIV(x,y) ((x) / (y) + (((x) % (y)) ? 1 : 0))
|
||||
|
||||
/*
|
||||
* Macros used for computing palette entries:
|
||||
*
|
||||
* NV_UNDER_REPLICATE(val, source_size, result_size) expands a value
|
||||
* of source_size bits into a value of target_size bits by shifting
|
||||
* the source value into the high bits and replicating the high bits
|
||||
* of the value into the low bits of the result.
|
||||
*
|
||||
* PALETTE_DEPTH_SHIFT(val, w) maps a colormap entry for a component
|
||||
* that has w bits to an appropriate entry in a LUT of 256 entries.
|
||||
*/
|
||||
static inline unsigned int NV_UNDER_REPLICATE(unsigned short val,
|
||||
int source_size,
|
||||
int result_size)
|
||||
{
|
||||
return (val << (result_size - source_size)) |
|
||||
(val >> ((source_size << 1) - result_size));
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned short PALETTE_DEPTH_SHIFT(unsigned short val, int depth)
|
||||
{
|
||||
return NV_UNDER_REPLICATE(val, depth, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use __builtin_ffs where it is supported, or provide an equivalent
|
||||
* implementation for platforms like riscv where it is not.
|
||||
*/
|
||||
#if defined(__GNUC__) && !NVCPU_IS_RISCV64
|
||||
static inline int nv_ffs(int x)
|
||||
{
|
||||
return __builtin_ffs(x);
|
||||
}
|
||||
#else
|
||||
static inline int nv_ffs(int x)
|
||||
{
|
||||
if (x == 0)
|
||||
return 0;
|
||||
|
||||
LOWESTBITIDX_32(x);
|
||||
|
||||
return 1 + x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NV_COMMON_UTILS_H__ */
|
||||
370
kernel-open/common/inc/nv_dpy_id.h
Normal file
370
kernel-open/common/inc/nv_dpy_id.h
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2014 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
/*
|
||||
* This header file defines the types NVDpyId and NVDpyIdList, as well
|
||||
* as inline functions to manipulate these types. NVDpyId and
|
||||
* NVDpyIdList should be treated as opaque by includers of this header
|
||||
* file.
|
||||
*/
|
||||
|
||||
#ifndef __NV_DPY_ID_H__
|
||||
#define __NV_DPY_ID_H__
|
||||
|
||||
#include "nvtypes.h"
|
||||
#include "nvmisc.h"
|
||||
#include "nv_common_utils.h"
|
||||
#include <nvlimits.h> /* NV_MAX_SUBDEVICES */
|
||||
|
||||
typedef struct {
|
||||
NvU32 opaqueDpyId;
|
||||
} NVDpyId;
|
||||
|
||||
typedef struct {
|
||||
NvU32 opaqueDpyIdList;
|
||||
} NVDpyIdList;
|
||||
|
||||
#define NV_DPY_ID_MAX_SUBDEVICES NV_MAX_SUBDEVICES
|
||||
#define NV_DPY_ID_MAX_DPYS_IN_LIST 32
|
||||
|
||||
/*
|
||||
* For use in combination with nvDpyIdToPrintFormat(); e.g.,
|
||||
*
|
||||
* printf("dpy id: " NV_DPY_ID_PRINT_FORMAT "\n",
|
||||
* nvDpyIdToPrintFormat(dpyId));
|
||||
*
|
||||
* The includer should not make assumptions about the return type of
|
||||
* nvDpyIdToPrintFormat().
|
||||
*/
|
||||
#define NV_DPY_ID_PRINT_FORMAT "0x%08x"
|
||||
|
||||
/* functions to return an invalid DpyId and empty DpyIdList */
|
||||
|
||||
static inline NVDpyId nvInvalidDpyId(void)
|
||||
{
|
||||
NVDpyId dpyId = { 0 };
|
||||
return dpyId;
|
||||
}
|
||||
|
||||
static inline NVDpyIdList nvEmptyDpyIdList(void)
|
||||
{
|
||||
NVDpyIdList dpyIdList = { 0 };
|
||||
return dpyIdList;
|
||||
}
|
||||
|
||||
static inline NVDpyIdList nvAllDpyIdList(void)
|
||||
{
|
||||
NVDpyIdList dpyIdList = { ~0U };
|
||||
return dpyIdList;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvEmptyDpyIdListSubDeviceArray(NVDpyIdList dpyIdList[NV_DPY_ID_MAX_SUBDEVICES])
|
||||
{
|
||||
int dispIndex;
|
||||
for (dispIndex = 0; dispIndex < NV_DPY_ID_MAX_SUBDEVICES; dispIndex++) {
|
||||
dpyIdList[dispIndex] = nvEmptyDpyIdList();
|
||||
}
|
||||
}
|
||||
|
||||
/* set operations on DpyIds and DpyIdLists: Add, Subtract, Intersect, Xor */
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvAddDpyIdToDpyIdList(NVDpyId dpyId, NVDpyIdList dpyIdList)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdList.opaqueDpyIdList |
|
||||
dpyId.opaqueDpyId;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
/* Passing an invalid display ID makes this function return an empty list. */
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvAddDpyIdToEmptyDpyIdList(NVDpyId dpyId)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyId.opaqueDpyId;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvAddDpyIdListToDpyIdList(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdListB.opaqueDpyIdList |
|
||||
dpyIdListA.opaqueDpyIdList;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
/* Returns: dpyIdList - dpyId */
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvDpyIdListMinusDpyId(NVDpyIdList dpyIdList, NVDpyId dpyId)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdList.opaqueDpyIdList &
|
||||
(~dpyId.opaqueDpyId);
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
/* Returns: dpyIdListA - dpyIdListB */
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvDpyIdListMinusDpyIdList(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdListA.opaqueDpyIdList &
|
||||
(~dpyIdListB.opaqueDpyIdList);
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvIntersectDpyIdAndDpyIdList(NVDpyId dpyId, NVDpyIdList dpyIdList)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdList.opaqueDpyIdList &
|
||||
dpyId.opaqueDpyId;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvIntersectDpyIdListAndDpyIdList(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdListA.opaqueDpyIdList &
|
||||
dpyIdListB.opaqueDpyIdList;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvXorDpyIdAndDpyIdList(NVDpyId dpyId, NVDpyIdList dpyIdList)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdList.opaqueDpyIdList ^
|
||||
dpyId.opaqueDpyId;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyIdList nvXorDpyIdListAndDpyIdList(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
NVDpyIdList tmpDpyIdList;
|
||||
tmpDpyIdList.opaqueDpyIdList = dpyIdListA.opaqueDpyIdList ^
|
||||
dpyIdListB.opaqueDpyIdList;
|
||||
return tmpDpyIdList;
|
||||
}
|
||||
|
||||
|
||||
/* boolean checks */
|
||||
|
||||
static inline NvBool nvDpyIdIsInDpyIdList(NVDpyId dpyId,
|
||||
NVDpyIdList dpyIdList)
|
||||
{
|
||||
return !!(dpyIdList.opaqueDpyIdList & dpyId.opaqueDpyId);
|
||||
}
|
||||
|
||||
static inline NvBool nvDpyIdIsInvalid(NVDpyId dpyId)
|
||||
{
|
||||
return (dpyId.opaqueDpyId == 0);
|
||||
}
|
||||
|
||||
static inline NvBool nvDpyIdListIsEmpty(NVDpyIdList dpyIdList)
|
||||
{
|
||||
return (dpyIdList.opaqueDpyIdList == 0);
|
||||
}
|
||||
|
||||
static inline NvBool
|
||||
nvDpyIdListSubDeviceArrayIsEmpty(NVDpyIdList
|
||||
dpyIdList[NV_DPY_ID_MAX_SUBDEVICES])
|
||||
{
|
||||
int dispIndex;
|
||||
for (dispIndex = 0; dispIndex < NV_DPY_ID_MAX_SUBDEVICES; dispIndex++) {
|
||||
if (!nvDpyIdListIsEmpty(dpyIdList[dispIndex])) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
}
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static inline NvBool nvDpyIdsAreEqual(NVDpyId dpyIdA, NVDpyId dpyIdB)
|
||||
{
|
||||
return (dpyIdA.opaqueDpyId == dpyIdB.opaqueDpyId);
|
||||
}
|
||||
|
||||
static inline NvBool nvDpyIdListsAreEqual(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
return (dpyIdListA.opaqueDpyIdList == dpyIdListB.opaqueDpyIdList);
|
||||
}
|
||||
|
||||
static inline NvBool nvDpyIdListIsASubSetofDpyIdList(NVDpyIdList dpyIdListA,
|
||||
NVDpyIdList dpyIdListB)
|
||||
{
|
||||
NVDpyIdList intersectedDpyIdList =
|
||||
nvIntersectDpyIdListAndDpyIdList(dpyIdListA, dpyIdListB);
|
||||
|
||||
return nvDpyIdListsAreEqual(intersectedDpyIdList, dpyIdListA);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* retrieve the individual dpyIds from dpyIdList; if dpyId is invalid,
|
||||
* start at the beginning of the list; otherwise, start at the dpyId
|
||||
* after the specified dpyId
|
||||
*/
|
||||
|
||||
static inline __attribute__ ((warn_unused_result))
|
||||
NVDpyId nvNextDpyIdInDpyIdListUnsorted(NVDpyId dpyId, NVDpyIdList dpyIdList)
|
||||
{
|
||||
if (nvDpyIdIsInvalid(dpyId)) {
|
||||
dpyId.opaqueDpyId = 1;
|
||||
} else {
|
||||
dpyId.opaqueDpyId <<= 1;
|
||||
}
|
||||
|
||||
while (dpyId.opaqueDpyId) {
|
||||
|
||||
if (nvDpyIdIsInDpyIdList(dpyId, dpyIdList)) {
|
||||
return dpyId;
|
||||
}
|
||||
|
||||
dpyId.opaqueDpyId <<= 1;
|
||||
}
|
||||
|
||||
/* no dpyIds left in dpyIdlist; return the invalid dpyId */
|
||||
|
||||
return nvInvalidDpyId();
|
||||
}
|
||||
|
||||
#define FOR_ALL_DPY_IDS(_dpyId, _dpyIdList) \
|
||||
for ((_dpyId) = nvNextDpyIdInDpyIdListUnsorted(nvInvalidDpyId(), \
|
||||
(_dpyIdList)); \
|
||||
!nvDpyIdIsInvalid(_dpyId); \
|
||||
(_dpyId) = nvNextDpyIdInDpyIdListUnsorted((_dpyId), \
|
||||
(_dpyIdList)))
|
||||
|
||||
/* report how many dpyIds are in the dpyIdList */
|
||||
|
||||
static inline int nvCountDpyIdsInDpyIdList(NVDpyIdList dpyIdList)
|
||||
{
|
||||
return nvPopCount32(dpyIdList.opaqueDpyIdList);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nvCountDpyIdsInDpyIdListSubDeviceArray(NVDpyIdList
|
||||
dpyIdList[NV_DPY_ID_MAX_SUBDEVICES])
|
||||
{
|
||||
int dispIndex, n = 0;
|
||||
|
||||
for (dispIndex = 0; dispIndex < NV_DPY_ID_MAX_SUBDEVICES; dispIndex++) {
|
||||
n += nvCountDpyIdsInDpyIdList(dpyIdList[dispIndex]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* convert between dpyId/dpyIdList and NV-CONTROL values */
|
||||
|
||||
static inline int nvDpyIdToNvControlVal(NVDpyId dpyId)
|
||||
{
|
||||
return (int) dpyId.opaqueDpyId;
|
||||
}
|
||||
|
||||
static inline int nvDpyIdListToNvControlVal(NVDpyIdList dpyIdList)
|
||||
{
|
||||
return (int) dpyIdList.opaqueDpyIdList;
|
||||
}
|
||||
|
||||
static inline NVDpyId nvNvControlValToDpyId(int val)
|
||||
{
|
||||
NVDpyId dpyId;
|
||||
dpyId.opaqueDpyId = (val == 0) ? 0 : 1 << (nv_ffs(val)-1);
|
||||
return dpyId;
|
||||
}
|
||||
|
||||
static inline NVDpyIdList nvNvControlValToDpyIdList(int val)
|
||||
{
|
||||
NVDpyIdList dpyIdList;
|
||||
dpyIdList.opaqueDpyIdList = val;
|
||||
return dpyIdList;
|
||||
}
|
||||
|
||||
|
||||
/* convert between dpyId and NvU32 */
|
||||
|
||||
static inline NVDpyId nvNvU32ToDpyId(NvU32 val)
|
||||
{
|
||||
NVDpyId dpyId;
|
||||
dpyId.opaqueDpyId = (val == 0) ? 0 : 1 << (nv_ffs(val)-1);
|
||||
return dpyId;
|
||||
}
|
||||
|
||||
static inline NVDpyIdList nvNvU32ToDpyIdList(NvU32 val)
|
||||
{
|
||||
NVDpyIdList dpyIdList;
|
||||
dpyIdList.opaqueDpyIdList = val;
|
||||
return dpyIdList;
|
||||
}
|
||||
|
||||
static inline NvU32 nvDpyIdToNvU32(NVDpyId dpyId)
|
||||
{
|
||||
return dpyId.opaqueDpyId;
|
||||
}
|
||||
|
||||
static inline NvU32 nvDpyIdListToNvU32(NVDpyIdList dpyIdList)
|
||||
{
|
||||
return dpyIdList.opaqueDpyIdList;
|
||||
}
|
||||
|
||||
/* Return the bit position of dpyId: a number in the range [0..31]. */
|
||||
static inline NvU32 nvDpyIdToIndex(NVDpyId dpyId)
|
||||
{
|
||||
return nv_ffs(dpyId.opaqueDpyId) - 1;
|
||||
}
|
||||
|
||||
/* Return a display ID that is not in the list passed in. */
|
||||
|
||||
static inline NVDpyId nvNewDpyId(NVDpyIdList excludeList)
|
||||
{
|
||||
NVDpyId dpyId;
|
||||
if (~excludeList.opaqueDpyIdList == 0) {
|
||||
return nvInvalidDpyId();
|
||||
}
|
||||
dpyId.opaqueDpyId =
|
||||
1U << (nv_ffs(~excludeList.opaqueDpyIdList) - 1);
|
||||
return dpyId;
|
||||
}
|
||||
|
||||
/* See comment for NV_DPY_ID_PRINT_FORMAT. */
|
||||
static inline NvU32 nvDpyIdToPrintFormat(NVDpyId dpyId)
|
||||
{
|
||||
return nvDpyIdToNvU32(dpyId);
|
||||
}
|
||||
|
||||
/* Prevent usage of opaque values. */
|
||||
#define opaqueDpyId __ERROR_ACCESS_ME_VIA_NV_DPY_ID_H
|
||||
#define opaqueDpyIdList __ERROR_ACCESS_ME_VIA_NV_DPY_ID_H
|
||||
|
||||
#endif /* __NV_DPY_ID_H__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -55,6 +55,7 @@ typedef NvU32 NvKmsFrameLockHandle;
|
||||
typedef NvU32 NvKmsDeferredRequestFifoHandle;
|
||||
typedef NvU32 NvKmsSwapGroupHandle;
|
||||
typedef NvU32 NvKmsVblankSyncObjectHandle;
|
||||
typedef NvU32 NvKmsVblankIntrCallbackHandle;
|
||||
|
||||
struct NvKmsSize {
|
||||
NvU16 width;
|
||||
@@ -179,6 +180,8 @@ enum NvKmsEventType {
|
||||
NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED,
|
||||
NVKMS_EVENT_TYPE_FRAMELOCK_ATTRIBUTE_CHANGED,
|
||||
NVKMS_EVENT_TYPE_FLIP_OCCURRED,
|
||||
NVKMS_EVENT_TYPE_DPY_CP_CHANGED,
|
||||
NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -545,6 +548,36 @@ enum NvKmsInputColorRange {
|
||||
NVKMS_INPUT_COLORRANGE_FULL = 2,
|
||||
};
|
||||
|
||||
enum NvKmsOutputColorimetry {
|
||||
NVKMS_OUTPUT_COLORIMETRY_DEFAULT = 0,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_SRGB = 1,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT601 = 2,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT709 = 3,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT2020 = 4,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT2100 = 5,
|
||||
};
|
||||
|
||||
/*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE attribute. */
|
||||
enum NvKmsDpyAttributeRequestedColorSpaceValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr422 = 1,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr444 = 2,
|
||||
};
|
||||
|
||||
/*!
|
||||
* * Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE and
|
||||
* * NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE attributes.
|
||||
* */
|
||||
enum NvKmsDpyAttributeColorRangeValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED = 1,
|
||||
};
|
||||
|
||||
enum NvKmsInputColorSpace {
|
||||
/* Unknown colorspace; no de-gamma will be applied */
|
||||
NVKMS_INPUT_COLORSPACE_NONE = 0,
|
||||
@@ -554,6 +587,21 @@ enum NvKmsInputColorSpace {
|
||||
|
||||
/* PQ, Rec.2020 unity */
|
||||
NVKMS_INPUT_COLORSPACE_BT2100_PQ = 2,
|
||||
|
||||
/* sRGB colorspace with sRGB gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_SRGB = 3,
|
||||
|
||||
/* Rec601 colorspace with Rec601 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT601 = 4,
|
||||
|
||||
/* Rec709 colorspace with Rec709 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT709 = 5,
|
||||
|
||||
/* Rec709 colorspace with linear (identity) gamma */
|
||||
NVKMS_INPUT_COLORSPACE_BT709_LINEAR = 6,
|
||||
|
||||
/* Rec2020 colorspace with Rec2020 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT2020 = 7,
|
||||
};
|
||||
|
||||
enum NvKmsOutputTf {
|
||||
@@ -644,4 +692,33 @@ struct NvKmsSuperframeInfo {
|
||||
} view[NVKMS_MAX_SUPERFRAME_VIEWS];
|
||||
};
|
||||
|
||||
typedef void (*NVVBlankIntrCallbackProc)(NvU64 param1, NvU64 param2);
|
||||
|
||||
enum NvKmsContentProtection {
|
||||
NVKMS_CP_OFF = 0,
|
||||
NVKMS_CP_HDCP1X_ON = 1,
|
||||
NVKMS_CP_HDCP2X_TYPE0_ON = 2,
|
||||
NVKMS_CP_HDCP2X_TYPE1_ON = 3,
|
||||
};
|
||||
|
||||
#define HDCP_TOPOLOGY_MAX_LINK_COUNT (2)
|
||||
#define HDCP_TOPOLOGY_MAX_DEV_COUNT (255)
|
||||
#define HDCP_TOPOLOGY_KSV_SIZE (5)
|
||||
|
||||
struct NvKmsHdcpTopology {
|
||||
NvBool isHdcpCapable;
|
||||
NvBool isHdcpAuthOn;
|
||||
NvBool isHdcpRp;
|
||||
NvBool isHdcp2X;
|
||||
NvBool maxCascadeExceeded;
|
||||
NvBool maxDeviceExceeded;
|
||||
NvBool isHdcp1DevDownstream;
|
||||
NvBool isHdcp2LegacyDevDownstream;
|
||||
NvU8 cascadeDepth;
|
||||
NvU8 linkCount;
|
||||
NvU8 bksv[HDCP_TOPOLOGY_MAX_LINK_COUNT * HDCP_TOPOLOGY_KSV_SIZE];
|
||||
NvU8 numOfBksv;
|
||||
NvU8 bksvList[HDCP_TOPOLOGY_MAX_DEV_COUNT * HDCP_TOPOLOGY_KSV_SIZE];
|
||||
};
|
||||
|
||||
#endif /* NVKMS_API_TYPES_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nvtypes.h"
|
||||
|
||||
#include "nv-gpu-info.h"
|
||||
#include "nv_dpy_id.h"
|
||||
#include "nvkms-api-types.h"
|
||||
#include "nvkms-format.h"
|
||||
|
||||
@@ -190,6 +191,7 @@ struct NvKmsKapiConnectorInfo {
|
||||
NvU32 numIncompatibleConnectors;
|
||||
NvKmsKapiConnector incompatibleConnectorHandles[NVKMS_KAPI_MAX_CONNECTORS];
|
||||
|
||||
NVDpyIdList dynamicDpyIdList;
|
||||
};
|
||||
|
||||
struct NvKmsKapiStaticDisplayInfo {
|
||||
@@ -208,6 +210,8 @@ struct NvKmsKapiStaticDisplayInfo {
|
||||
NvKmsKapiDisplay possibleCloneHandles[NVKMS_KAPI_MAX_CLONE_DISPLAYS];
|
||||
|
||||
NvU32 headMask;
|
||||
|
||||
NvBool isDpMST;
|
||||
};
|
||||
|
||||
struct NvKmsKapiSyncpt {
|
||||
@@ -248,6 +252,9 @@ struct NvKmsKapiLayerConfig {
|
||||
NvU16 dstWidth, dstHeight;
|
||||
|
||||
enum NvKmsInputColorSpace inputColorSpace;
|
||||
enum NvKmsInputColorRange inputColorRange;
|
||||
struct NvKmsCscMatrix csc;
|
||||
NvBool cscUseMain;
|
||||
};
|
||||
|
||||
struct NvKmsKapiLayerRequestedConfig {
|
||||
@@ -258,6 +265,7 @@ struct NvKmsKapiLayerRequestedConfig {
|
||||
NvBool srcWHChanged : 1;
|
||||
NvBool dstXYChanged : 1;
|
||||
NvBool dstWHChanged : 1;
|
||||
NvBool cscChanged : 1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
@@ -301,6 +309,10 @@ struct NvKmsKapiHeadModeSetConfig {
|
||||
struct NvKmsKapiDisplayMode mode;
|
||||
|
||||
NvBool vrrEnabled;
|
||||
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
};
|
||||
|
||||
struct NvKmsKapiHeadRequestedConfig {
|
||||
@@ -309,6 +321,8 @@ struct NvKmsKapiHeadRequestedConfig {
|
||||
NvBool activeChanged : 1;
|
||||
NvBool displaysChanged : 1;
|
||||
NvBool modeChanged : 1;
|
||||
NvBool colorrangeChanged: 1;
|
||||
NvBool colorimetryChanged : 1;
|
||||
} flags;
|
||||
|
||||
struct NvKmsKapiCursorRequestedConfig cursorRequestedConfig;
|
||||
@@ -341,6 +355,16 @@ struct NvKmsKapiEventDisplayChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDisplayCpChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
enum NvKmsContentProtection cp;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDisplayCpTopologyChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
struct NvKmsHdcpTopology *topology;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDynamicDisplayConnected {
|
||||
NvKmsKapiDisplay display;
|
||||
};
|
||||
@@ -372,6 +396,8 @@ struct NvKmsKapiEvent {
|
||||
struct NvKmsKapiEventDisplayChanged displayChanged;
|
||||
struct NvKmsKapiEventDynamicDisplayConnected dynamicDisplayConnected;
|
||||
struct NvKmsKapiEventFlipOccurred flipOccurred;
|
||||
struct NvKmsKapiEventDisplayCpChanged displayCpChanged;
|
||||
struct NvKmsKapiEventDisplayCpTopologyChanged displayCpTopologyChanged;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -411,6 +437,14 @@ struct NvKmsKapiDynamicDisplayParams {
|
||||
NvBool forceDisconnected;
|
||||
};
|
||||
|
||||
struct NvKmsKapiVtFbParams {
|
||||
/* [OUT] VT framebuffer memory base address */
|
||||
NvU64 baseAddress;
|
||||
|
||||
/* [OUT] VT framebuffer memory size */
|
||||
NvU64 size;
|
||||
};
|
||||
|
||||
struct NvKmsKapiCreateSurfaceParams {
|
||||
|
||||
/* [IN] Parameter of each plane */
|
||||
@@ -455,6 +489,8 @@ typedef enum NvKmsKapiRegisterWaiterResultRec {
|
||||
NVKMS_KAPI_REG_WAITER_ALREADY_SIGNALLED,
|
||||
} NvKmsKapiRegisterWaiterResult;
|
||||
|
||||
typedef void NvKmsKapiSuspendResumeCallbackFunc(NvBool suspend);
|
||||
|
||||
struct NvKmsKapiFunctionsTable {
|
||||
|
||||
/*!
|
||||
@@ -540,8 +576,8 @@ struct NvKmsKapiFunctionsTable {
|
||||
);
|
||||
|
||||
/*!
|
||||
* Revoke permissions previously granted. Only one (dispIndex, head,
|
||||
* display) is currently supported.
|
||||
* Revoke modeset permissions previously granted. Only one (dispIndex,
|
||||
* head, display) is currently supported.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
@@ -558,6 +594,34 @@ struct NvKmsKapiFunctionsTable {
|
||||
NvKmsKapiDisplay display
|
||||
);
|
||||
|
||||
/*!
|
||||
* Grant modeset sub-owner permissions to fd. This is used by clients to
|
||||
* convert drm 'master' permissions into nvkms sub-owner permission.
|
||||
*
|
||||
* \param [in] fd fd from opening /dev/nvidia-modeset.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*grantSubOwnership)
|
||||
(
|
||||
NvS32 fd,
|
||||
struct NvKmsKapiDevice *device
|
||||
);
|
||||
|
||||
/*!
|
||||
* Revoke sub-owner permissions previously granted.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*revokeSubOwnership)
|
||||
(
|
||||
struct NvKmsKapiDevice *device
|
||||
);
|
||||
|
||||
/*!
|
||||
* Registers for notification, via
|
||||
* NvKmsKapiAllocateDeviceParams::eventCallback, of the events specified
|
||||
@@ -679,6 +743,20 @@ struct NvKmsKapiFunctionsTable {
|
||||
struct NvKmsKapiDynamicDisplayParams *params
|
||||
);
|
||||
|
||||
/*!
|
||||
* Get VT framebuffer information.
|
||||
*
|
||||
* \param [out] params Parameters containing the base address and size
|
||||
* of VT framebuffer memory
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*getVtFbInfo)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiVtFbParams *params
|
||||
);
|
||||
|
||||
/*!
|
||||
* Allocate some unformatted video memory of the specified size.
|
||||
*
|
||||
@@ -1336,6 +1414,27 @@ struct NvKmsKapiFunctionsTable {
|
||||
NvU64 index,
|
||||
NvU64 new_value
|
||||
);
|
||||
|
||||
/*!
|
||||
* Set the callback function for suspending and resuming the display system.
|
||||
*/
|
||||
void
|
||||
(*setSuspendResumeCallback)
|
||||
(
|
||||
NvKmsKapiSuspendResumeCallbackFunc *function
|
||||
);
|
||||
|
||||
struct NvKmsKapiVblankIntrCallback*
|
||||
(*RegisterVblankIntrCallback)(struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
NVVBlankIntrCallbackProc pCallback,
|
||||
NvU64 param1,
|
||||
NvU64 param2);
|
||||
|
||||
void (*UnregisterVblankIntrCallback)(
|
||||
struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
struct NvKmsKapiVblankIntrCallback *pCallback);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -162,7 +162,7 @@ NvBool NV_API_CALL os_is_vgx_hyper (void);
|
||||
NV_STATUS NV_API_CALL os_inject_vgx_msi (NvU16, NvU64, NvU32);
|
||||
NvBool NV_API_CALL os_is_grid_supported (void);
|
||||
NvU32 NV_API_CALL os_get_grid_csp_support (void);
|
||||
void NV_API_CALL os_get_screen_info (NvU64 *, NvU32 *, NvU32 *, NvU32 *, NvU32 *, NvU64, NvU64);
|
||||
void NV_API_CALL os_get_screen_info (NvU64 *, NvU32 *, NvU32 *, NvU32 *, NvU32 *, NvU64 *, NvU64, NvU64);
|
||||
void NV_API_CALL os_bug_check (NvU32, const char *);
|
||||
NV_STATUS NV_API_CALL os_lock_user_pages (void *, NvU64, void **, NvU32);
|
||||
NV_STATUS NV_API_CALL os_lookup_user_io_memory (void *, NvU64, NvU64 **, void**);
|
||||
|
||||
283
kernel-open/conftest.sh
Executable file → Normal file
283
kernel-open/conftest.sh
Executable file → Normal file
@@ -1390,6 +1390,23 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_DRM_DEV_UNREF_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
drm_sysfs_connector_property_event)
|
||||
#
|
||||
# Determine if drm_sysfs_connector_property_event() is present.
|
||||
#
|
||||
# Commit 0cf8d292ba5e ("drm/sysfs: rename drm_sysfs_connector_status_event()")
|
||||
# renamed drm_sysfs_connector_status_event() to
|
||||
# drm_sysfs_connector_property_event() in Linux v6.5.
|
||||
#
|
||||
CODE="
|
||||
#include <drm/drm_sysfs.h>
|
||||
void conftest_drm_sysfs_connector_property_event(void) {
|
||||
drm_sysfs_connector_property_event();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_SYSFS_CONNECTOR_PROPERTY_EVENT_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
pde_data)
|
||||
#
|
||||
# Determine if the pde_data() function is present.
|
||||
@@ -1652,22 +1669,6 @@ compile_test() {
|
||||
fi
|
||||
;;
|
||||
|
||||
of_clk_get_parent_count)
|
||||
#
|
||||
# Determine if the of_clk_get_parent_count function is present.
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_LINUX_OF_CLK_H_PRESENT)
|
||||
#include <linux/of_clk.h>
|
||||
#endif
|
||||
void conftest_of_clk_get_parent_count(void)
|
||||
{
|
||||
of_clk_get_parent_count();
|
||||
}
|
||||
"
|
||||
compile_check_conftest "$CODE" "NV_OF_CLK_GET_PARENT_COUNT_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
of_node_to_nid)
|
||||
#
|
||||
# Determine if of_node_to_nid is present
|
||||
@@ -5106,20 +5107,22 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_PCI_CLASS_MULTIMEDIA_HD_AUDIO_PRESENT" "" "generic"
|
||||
;;
|
||||
|
||||
unsafe_follow_pfn)
|
||||
follow_pfn)
|
||||
#
|
||||
# Determine if unsafe_follow_pfn() is present.
|
||||
# Determine if follow_pfn() is present.
|
||||
#
|
||||
# unsafe_follow_pfn() was added by commit 69bacee7f9ad
|
||||
# ("mm: Add unsafe_follow_pfn") in v5.13-rc1.
|
||||
# follow_pfn() was added by commit 3b6748e2dd69
|
||||
# ("mm: introduce follow_pfn()") in v2.6.31-rc1, and removed
|
||||
# by commit 233eb0bf3b94 ("mm: remove follow_pfn")
|
||||
# from linux-next 233eb0bf3b94.
|
||||
#
|
||||
CODE="
|
||||
#include <linux/mm.h>
|
||||
void conftest_unsafe_follow_pfn(void) {
|
||||
unsafe_follow_pfn();
|
||||
void conftest_follow_pfn(void) {
|
||||
follow_pfn();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_UNSAFE_FOLLOW_PFN_PRESENT" "" "functions"
|
||||
compile_check_conftest "$CODE" "NV_FOLLOW_PFN_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
drm_plane_atomic_check_has_atomic_state_arg)
|
||||
@@ -5301,6 +5304,31 @@ compile_test() {
|
||||
fi
|
||||
;;
|
||||
|
||||
of_property_for_each_u32_has_internal_args)
|
||||
#
|
||||
# Determine if the internal arguments for the macro
|
||||
# of_property_for_each_u32() are present.
|
||||
#
|
||||
# Commit 9722c3b66e21 ("of: remove internal arguments from
|
||||
# of_property_for_each_u32()") removes two arguments from
|
||||
# of_property_for_each_u32() which are used internally within
|
||||
# the macro and so do not need to be passed. This change was
|
||||
# made for Linux v6.11.
|
||||
#
|
||||
CODE="
|
||||
#include <linux/of.h>
|
||||
void conftest_of_property_for_each_u32(struct device_node *np,
|
||||
char *propname) {
|
||||
struct property *iparam1;
|
||||
const __be32 *iparam2;
|
||||
u32 val;
|
||||
|
||||
of_property_for_each_u32(np, propname, iparam1, iparam2, val);
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_OF_PROPERTY_FOR_EACH_U32_HAS_INTERNAL_ARGS" "" "types"
|
||||
;;
|
||||
|
||||
of_property_read_variable_u8_array)
|
||||
#
|
||||
# Determine if of_property_read_variable_u8_array is present
|
||||
@@ -5781,24 +5809,6 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_MM_PASID_SET_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
drm_crtc_state_has_no_vblank)
|
||||
#
|
||||
# Determine if the 'drm_crtc_state' structure has 'no_vblank'.
|
||||
#
|
||||
# drm_crtc_state::no_vblank was added by commit b25c60af7a877
|
||||
# ("drm/crtc: Add a generic infrastructure to fake VBLANK events")
|
||||
# in 4.18.0-rc3 (2018-07-03).
|
||||
#
|
||||
CODE="
|
||||
#include <drm/drm_crtc.h>
|
||||
void conftest_drm_crtc_state_has_no_vblank(void) {
|
||||
struct drm_crtc_state foo;
|
||||
(void)foo.no_vblank;
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_CRTC_STATE_HAS_NO_VBLANK" "" "types"
|
||||
;;
|
||||
|
||||
drm_mode_config_has_allow_fb_modifiers)
|
||||
#
|
||||
# Determine if the 'drm_mode_config' structure has
|
||||
@@ -6405,6 +6415,29 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_DRM_FBDEV_GENERIC_SETUP_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
drm_output_poll_changed)
|
||||
#
|
||||
# Determine whether drm_mode_config_funcs.output_poll_changed
|
||||
# callback is present
|
||||
#
|
||||
# Removed by commit 446d0f4849b1 ("drm: Remove struct
|
||||
# drm_mode_config_funcs.output_poll_changed") in v6.12. Hotplug
|
||||
# event support is handled through the fbdev emulation interface
|
||||
# going forward.
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRM_MODE_CONFIG_H_PRESENT)
|
||||
#include <drm/drm_mode_config.h>
|
||||
#else
|
||||
#include <drm/drm_crtc.h>
|
||||
#endif
|
||||
int conftest_drm_output_poll_changed_available(void) {
|
||||
return offsetof(struct drm_mode_config_funcs, output_poll_changed);
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_OUTPUT_POLL_CHANGED_PRESENT" "" "types"
|
||||
;;
|
||||
|
||||
drm_aperture_remove_conflicting_pci_framebuffers)
|
||||
#
|
||||
# Determine whether drm_aperture_remove_conflicting_pci_framebuffers is present.
|
||||
@@ -6459,6 +6492,21 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_HAS_DRIVER_ARG" "" "types"
|
||||
;;
|
||||
|
||||
crypto_tfm_ctx_aligned)
|
||||
# Determine if 'crypto_tfm_ctx_aligned' is defined.
|
||||
#
|
||||
# Removed by commit 25c74a39e0f6 ("crypto: hmac - remove unnecessary
|
||||
# alignment logic") in v6.7.
|
||||
#
|
||||
CODE="
|
||||
#include <crypto/algapi.h>
|
||||
void conftest_crypto_tfm_ctx_aligned(void) {
|
||||
(void)crypto_tfm_ctx_aligned();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_CRYPTO_TFM_CTX_ALIGNED_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
crypto)
|
||||
#
|
||||
# Determine if we support various crypto functions.
|
||||
@@ -6485,6 +6533,159 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_CRYPTO_PRESENT" "" "symbols"
|
||||
;;
|
||||
|
||||
drm_aperture_remove_conflicting_framebuffers)
|
||||
#
|
||||
# Determine whether drm_aperture_remove_conflicting_framebuffers is present.
|
||||
#
|
||||
# drm_aperture_remove_conflicting_framebuffers was added in commit 2916059147ea
|
||||
# ("drm/aperture: Add infrastructure for aperture ownership) in
|
||||
# v5.14-rc1 (2021-04-12)
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRM_APERTURE_H_PRESENT)
|
||||
#include <drm/drm_aperture.h>
|
||||
#endif
|
||||
void conftest_drm_aperture_remove_conflicting_framebuffers(void) {
|
||||
drm_aperture_remove_conflicting_framebuffers();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_APERTURE_REMOVE_CONFLICTING_FRAMEBUFFERS_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
drm_aperture_remove_conflicting_framebuffers_has_driver_arg)
|
||||
#
|
||||
# Determine whether drm_aperture_remove_conflicting_framebuffers
|
||||
# takes a struct drm_driver * as its fourth argument.
|
||||
#
|
||||
# Prior to commit 97c9bfe3f6605d41eb8f1206e6e0f62b31ba15d6, the
|
||||
# second argument was a char * pointer to the driver's name.
|
||||
#
|
||||
# To test if drm_aperture_remove_conflicting_framebuffers() has
|
||||
# a req_driver argument, define a function with the expected
|
||||
# signature and then define the corresponding function
|
||||
# implementation with the expected signature. Successful compilation
|
||||
# indicates that this function has the expected signature.
|
||||
#
|
||||
# This change occurred in commit 97c9bfe3f660 ("drm/aperture: Pass
|
||||
# DRM driver structure instead of driver name") in v5.15
|
||||
# (2021-06-29).
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRM_DRV_H_PRESENT)
|
||||
#include <drm/drm_drv.h>
|
||||
#endif
|
||||
#if defined(NV_DRM_DRM_APERTURE_H_PRESENT)
|
||||
#include <drm/drm_aperture.h>
|
||||
#endif
|
||||
typeof(drm_aperture_remove_conflicting_framebuffers) conftest_drm_aperture_remove_conflicting_framebuffers;
|
||||
int conftest_drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
|
||||
bool primary, const struct drm_driver *req_driver)
|
||||
{
|
||||
return 0;
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_APERTURE_REMOVE_CONFLICTING_FRAMEBUFFERS_HAS_DRIVER_ARG" "" "types"
|
||||
;;
|
||||
|
||||
drm_aperture_remove_conflicting_framebuffers_has_no_primary_arg)
|
||||
#
|
||||
# Determine whether drm_aperture_remove_conflicting_framebuffers
|
||||
# has its third argument as a bool.
|
||||
#
|
||||
# Prior to commit 62aeaeaa1b267c5149abee6b45967a5df3feed58, the
|
||||
# third argument was a bool for figuring out whether the legacy vga
|
||||
# stuff should be nuked, but it's only for pci devices and not
|
||||
# really needed in this function.
|
||||
#
|
||||
# To test if drm_aperture_remove_conflicting_framebuffers() has
|
||||
# a bool primary argument, define a function with the expected
|
||||
# signature and then define the corresponding function
|
||||
# implementation with the expected signature. Successful compilation
|
||||
# indicates that this function has the expected signature.
|
||||
#
|
||||
# This change occurred in commit 62aeaeaa1b26 ("drm/aperture: Remove
|
||||
# primary argument") in v6.5 (2023-04-16).
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRM_DRV_H_PRESENT)
|
||||
#include <drm/drm_drv.h>
|
||||
#endif
|
||||
#if defined(NV_DRM_DRM_APERTURE_H_PRESENT)
|
||||
#include <drm/drm_aperture.h>
|
||||
#endif
|
||||
typeof(drm_aperture_remove_conflicting_framebuffers) conftest_drm_aperture_remove_conflicting_framebuffers;
|
||||
int conftest_drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
|
||||
const struct drm_driver *req_driver)
|
||||
{
|
||||
return 0;
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_APERTURE_REMOVE_CONFLICTING_FRAMEBUFFERS_HAS_NO_PRIMARY_ARG" "" "types"
|
||||
;;
|
||||
|
||||
platform_driver_struct_remove_returns_void)
|
||||
#
|
||||
# Determine if the 'platform_driver' structure 'remove' function
|
||||
# pointer returns void.
|
||||
#
|
||||
# Commit 0edb555a65d1 ("platform: Make platform_driver::remove()
|
||||
# return void") updated the platform_driver structure 'remove'
|
||||
# callback to return void instead of int in Linux v6.11-rc1.
|
||||
#
|
||||
echo "$CONFTEST_PREAMBLE
|
||||
#include <linux/platform_device.h>
|
||||
int conftest_platform_driver_struct_remove_returns_void(struct platform_device *pdev,
|
||||
struct platform_driver *driver) {
|
||||
return driver->remove(pdev);
|
||||
}" > conftest$$.c
|
||||
|
||||
$CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
|
||||
rm -f conftest$$.c
|
||||
|
||||
if [ -f conftest$$.o ]; then
|
||||
rm -f conftest$$.o
|
||||
|
||||
echo "#undef NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID" | append_conftest "types"
|
||||
else
|
||||
echo "#define NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID" | append_conftest "types"
|
||||
fi
|
||||
;;
|
||||
|
||||
drm_mode_create_dp_colorspace_property_has_supported_colorspaces_arg)
|
||||
# Determine if drm_mode_create_dp_colorspace_property() takes the
|
||||
# 'supported_colorspaces' argument.
|
||||
#
|
||||
# The 'u32 supported_colorspaces' argument was added to
|
||||
# drm_mode_create_dp_colorspace_property() by linux-next commit
|
||||
# c265f340eaa8 ("drm/connector: Allow drivers to pass list of
|
||||
# supported colorspaces").
|
||||
#
|
||||
# To test if drm_mode_create_dp_colorspace_property() has the
|
||||
# 'supported_colorspaces' argument, declare a function prototype
|
||||
# with typeof drm_mode_create_dp_colorspace_property and then
|
||||
# define the corresponding function implementation with the
|
||||
# expected signature. Successful compilation indicates that
|
||||
# drm_mode_create_dp_colorspace_property() has the
|
||||
# 'supported_colorspaces' argument.
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRM_CRTC_H_PRESENT)
|
||||
#include <drm/drm_crtc.h>
|
||||
#endif
|
||||
#if defined(NV_DRM_DRM_CONNECTOR_H_PRESENT)
|
||||
#include <drm/drm_connector.h>
|
||||
#endif
|
||||
|
||||
typeof(drm_mode_create_dp_colorspace_property) conftest_drm_mode_create_dp_colorspace_property_has_supported_colorspaces_arg;
|
||||
int conftest_drm_mode_create_dp_colorspace_property_has_supported_colorspaces_arg(struct drm_connector *connector,
|
||||
u32 supported_colorspaces)
|
||||
{
|
||||
return 0;
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DRM_MODE_CREATE_DP_COLORSPACE_PROPERTY_HAS_SUPPORTED_COLORSPACES_ARG" "" "types"
|
||||
;;
|
||||
|
||||
# When adding a new conftest entry, please use the correct format for
|
||||
# specifying the relevant upstream Linux kernel commit.
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017 - 2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -61,4 +61,15 @@
|
||||
#undef NV_DRM_FENCE_AVAILABLE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We can support color management if either drm_helper_crtc_enable_color_mgmt()
|
||||
* or drm_crtc_enable_color_mgmt() exist.
|
||||
*/
|
||||
#if defined(NV_DRM_HELPER_CRTC_ENABLE_COLOR_MGMT_PRESENT) || \
|
||||
defined(NV_DRM_CRTC_ENABLE_COLOR_MGMT_PRESENT)
|
||||
#define NV_DRM_COLOR_MGMT_AVAILABLE
|
||||
#else
|
||||
#undef NV_DRM_COLOR_MGMT_AVAILABLE
|
||||
#endif
|
||||
|
||||
#endif /* defined(__NVIDIA_DRM_CONFTEST_H__) */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015- 2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -45,6 +45,16 @@
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#if defined(NV_DRM_DISPLAY_DRM_HDCP_HELPER_H_PRESENT)
|
||||
#include <drm/display/drm_hdcp_helper.h>
|
||||
#elif defined(NV_DRM_DISPLAY_DRM_HDCP_H_PRESENT)
|
||||
#include <drm/display/drm_hdcp.h>
|
||||
#else
|
||||
#include <drm/drm_hdcp.h>
|
||||
#endif
|
||||
|
||||
#include <drm/drm_sysfs.h>
|
||||
|
||||
static void nv_drm_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
struct nv_drm_connector *nv_connector = to_nv_connector(connector);
|
||||
@@ -216,6 +226,56 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void nv_drm_connector_reset(struct drm_connector *connector)
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(connector->dev);
|
||||
struct nv_drm_connector_state * nv_connector_state =
|
||||
nv_drm_calloc(1, sizeof(*nv_connector_state));
|
||||
|
||||
if (!nv_connector_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
__drm_atomic_helper_connector_reset(connector, &nv_connector_state->base);
|
||||
}
|
||||
|
||||
static struct drm_connector_state* nv_drm_connector_atomic_duplicate_state(struct drm_connector *connector)
|
||||
{
|
||||
struct nv_drm_connector_state *nv_drm_old_connector_state =
|
||||
to_nv_drm_connector_state(connector->state);
|
||||
|
||||
struct nv_drm_connector_state *nv_drm_new_connector_state =
|
||||
nv_drm_calloc(1, sizeof(*nv_drm_new_connector_state));
|
||||
|
||||
if (!nv_drm_new_connector_state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__drm_atomic_helper_connector_duplicate_state(connector, &nv_drm_new_connector_state->base);
|
||||
|
||||
nv_drm_new_connector_state->output_colorrange = nv_drm_old_connector_state->output_colorrange;
|
||||
nv_drm_new_connector_state->op_colorrange_changed = false;
|
||||
nv_drm_new_connector_state->hdcp_topology_blob = nv_drm_old_connector_state->hdcp_topology_blob;
|
||||
if (nv_drm_new_connector_state->hdcp_topology_blob) {
|
||||
drm_property_blob_get(nv_drm_new_connector_state->hdcp_topology_blob);
|
||||
}
|
||||
|
||||
return &nv_drm_new_connector_state->base;
|
||||
}
|
||||
|
||||
static void nv_drm_connector_atomic_destroy_state(
|
||||
struct drm_connector *connector,
|
||||
struct drm_connector_state *state)
|
||||
{
|
||||
struct nv_drm_connector_state *nv_drm_connector_state =
|
||||
to_nv_drm_connector_state(state);
|
||||
|
||||
__drm_atomic_helper_connector_destroy_state(state);
|
||||
drm_property_blob_put(nv_drm_connector_state->hdcp_topology_blob);
|
||||
|
||||
nv_drm_free(nv_drm_connector_state);
|
||||
}
|
||||
|
||||
static void __nv_drm_connector_force(struct drm_connector *connector)
|
||||
{
|
||||
__nv_drm_connector_detect_internal(connector);
|
||||
@@ -227,17 +287,60 @@ nv_drm_connector_detect(struct drm_connector *connector, bool force)
|
||||
return __nv_drm_connector_detect_internal(connector);
|
||||
}
|
||||
|
||||
static int nv_drm_connector_atomic_get_property(
|
||||
struct drm_connector *connector,
|
||||
const struct drm_connector_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t *val)
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(connector->dev);
|
||||
const struct nv_drm_connector_state *nv_drm_connector_state =
|
||||
to_nv_drm_connector_state_const(state);
|
||||
|
||||
if (property == nv_dev->nv_output_colorrange_property) {
|
||||
*val = nv_drm_connector_state->output_colorrange;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_drm_connector_atomic_set_property(
|
||||
struct drm_connector *connector,
|
||||
struct drm_connector_state *state,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(connector->dev);
|
||||
struct nv_drm_connector_state *nv_drm_connector_state =
|
||||
to_nv_drm_connector_state(state);
|
||||
|
||||
if (property == nv_dev->nv_output_colorrange_property) {
|
||||
if (val != nv_drm_connector_state->output_colorrange) {
|
||||
nv_drm_connector_state->output_colorrange = val;
|
||||
nv_drm_connector_state->op_colorrange_changed = true;
|
||||
}
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_connector_funcs nv_connector_funcs = {
|
||||
#if defined NV_DRM_ATOMIC_HELPER_CONNECTOR_DPMS_PRESENT
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
#endif
|
||||
.destroy = nv_drm_connector_destroy,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.reset = nv_drm_connector_reset,
|
||||
.force = __nv_drm_connector_force,
|
||||
.detect = nv_drm_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = nv_drm_connector_atomic_duplicate_state,
|
||||
.atomic_destroy_state = nv_drm_connector_atomic_destroy_state,
|
||||
.atomic_get_property = nv_drm_connector_atomic_get_property,
|
||||
.atomic_set_property = nv_drm_connector_atomic_set_property,
|
||||
};
|
||||
|
||||
static int nv_drm_connector_get_modes(struct drm_connector *connector)
|
||||
@@ -349,10 +452,95 @@ nv_drm_connector_best_encoder(struct drm_connector *connector)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_MODE_CREATE_DP_COLORSPACE_PROPERTY_HAS_SUPPORTED_COLORSPACES_ARG)
|
||||
static const NvU32 __nv_drm_connector_supported_colorspaces =
|
||||
BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |
|
||||
BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
|
||||
#endif
|
||||
|
||||
static int
|
||||
nv_drm_connector_atomic_check(struct drm_connector *connector,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_connector_state *new_connector_state =
|
||||
drm_atomic_get_new_connector_state(state, connector);
|
||||
struct drm_connector_state *old_connector_state =
|
||||
drm_atomic_get_old_connector_state(state, connector);
|
||||
struct nv_drm_device *nv_dev = to_nv_device(connector->dev);
|
||||
|
||||
const struct nv_drm_connector_state *nv_drm_new_connector_state =
|
||||
to_nv_drm_connector_state_const(new_connector_state);
|
||||
|
||||
const struct nv_drm_connector_state *nv_drm_old_connector_state =
|
||||
to_nv_drm_connector_state_const(old_connector_state);
|
||||
|
||||
struct drm_crtc *crtc = new_connector_state->crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct nv_drm_crtc_state *nv_crtc_state;
|
||||
struct NvKmsKapiHeadRequestedConfig *req_config;
|
||||
|
||||
if (!crtc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
nv_crtc_state = to_nv_crtc_state(crtc_state);
|
||||
req_config = &nv_crtc_state->req_config;
|
||||
|
||||
if ((nv_drm_new_connector_state->op_colorrange_changed == true) ||
|
||||
(nv_drm_old_connector_state->output_colorrange != nv_drm_new_connector_state->output_colorrange)) {
|
||||
switch (nv_drm_new_connector_state->output_colorrange) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL:
|
||||
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED:
|
||||
req_config->modeSetConfig.outputColorRange =
|
||||
nv_drm_new_connector_state->output_colorrange;
|
||||
|
||||
req_config->flags.colorrangeChanged = true;
|
||||
break;
|
||||
default:
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Unsupported ouput color range");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
req_config->flags.colorimetryChanged =
|
||||
(old_connector_state->colorspace != new_connector_state->colorspace);
|
||||
// When adding a case here, also add to __nv_drm_connector_supported_colorspaces
|
||||
switch (new_connector_state->colorspace) {
|
||||
case DRM_MODE_COLORIMETRY_DEFAULT:
|
||||
req_config->modeSetConfig.colorimetry =
|
||||
NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
|
||||
break;
|
||||
case DRM_MODE_COLORIMETRY_XVYCC_601:
|
||||
case DRM_MODE_COLORIMETRY_SYCC_601:
|
||||
case DRM_MODE_COLORIMETRY_OPYCC_601:
|
||||
req_config->modeSetConfig.colorimetry =
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT601;
|
||||
break;
|
||||
case DRM_MODE_COLORIMETRY_BT709_YCC:
|
||||
case DRM_MODE_COLORIMETRY_XVYCC_709:
|
||||
req_config->modeSetConfig.colorimetry =
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT709;
|
||||
break;
|
||||
case DRM_MODE_COLORIMETRY_BT2020_RGB:
|
||||
case DRM_MODE_COLORIMETRY_BT2020_YCC:
|
||||
req_config->modeSetConfig.colorimetry =
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT2100;
|
||||
break;
|
||||
default:
|
||||
// XXX HDR TODO: Add support for more color spaces
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Unsupported color space");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs nv_connector_helper_funcs = {
|
||||
.get_modes = nv_drm_connector_get_modes,
|
||||
.mode_valid = nv_drm_connector_mode_valid,
|
||||
.best_encoder = nv_drm_connector_best_encoder,
|
||||
.atomic_check = nv_drm_connector_atomic_check,
|
||||
};
|
||||
|
||||
static struct drm_connector*
|
||||
@@ -363,16 +551,18 @@ nv_drm_connector_new(struct drm_device *dev,
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
struct nv_drm_connector *nv_connector = NULL;
|
||||
struct nv_drm_connector_state *nv_connector_state = NULL;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
if ((nv_connector = nv_drm_calloc(1, sizeof(*nv_connector))) == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if ((nv_connector->base.state =
|
||||
nv_drm_calloc(1, sizeof(*nv_connector->base.state))) == NULL) {
|
||||
if ((nv_connector_state = nv_drm_calloc(1, sizeof(*nv_connector_state))) == NULL) {
|
||||
goto failed_state_alloc;
|
||||
}
|
||||
|
||||
nv_connector->base.state = &nv_connector_state->base;
|
||||
nv_connector->base.state->connector = &nv_connector->base;
|
||||
|
||||
nv_connector->physicalIndex = physicalIndex;
|
||||
@@ -380,6 +570,7 @@ nv_drm_connector_new(struct drm_device *dev,
|
||||
nv_connector->internal = internal;
|
||||
nv_connector->modeset_permission_filep = NULL;
|
||||
nv_connector->modeset_permission_crtc = NULL;
|
||||
nv_connector->cp = NVKMS_CP_OFF;
|
||||
|
||||
strcpy(nv_connector->dpAddress, dpAddress);
|
||||
|
||||
@@ -405,6 +596,52 @@ nv_drm_connector_new(struct drm_device *dev,
|
||||
DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
}
|
||||
|
||||
/* attach content protection properties */
|
||||
if (nv_connector->type != NVKMS_CONNECTOR_TYPE_DSI) {
|
||||
ret = drm_connector_attach_content_protection_property(&nv_connector->base, true);
|
||||
if (ret != 0) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"Failed to attach content protction properties to connector created from physical index %u",
|
||||
nv_connector->physicalIndex);
|
||||
goto failed_connector_init;
|
||||
}
|
||||
}
|
||||
|
||||
/* attach nvidia defined connector properties */
|
||||
if (nv_connector->type != NVKMS_CONNECTOR_TYPE_DSI) {
|
||||
drm_object_attach_property(&nv_connector->base.base,
|
||||
nv_dev->nv_hdcp_topology_property,
|
||||
0);
|
||||
}
|
||||
drm_object_attach_property(&nv_connector->base.base,
|
||||
nv_dev->nv_output_colorrange_property,
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL);
|
||||
|
||||
if (nv_connector->type == NVKMS_CONNECTOR_TYPE_HDMI) {
|
||||
#if defined(NV_DRM_MODE_CREATE_DP_COLORSPACE_PROPERTY_HAS_SUPPORTED_COLORSPACES_ARG)
|
||||
if (drm_mode_create_hdmi_colorspace_property(
|
||||
&nv_connector->base,
|
||||
__nv_drm_connector_supported_colorspaces) == 0) {
|
||||
#else
|
||||
if (drm_mode_create_hdmi_colorspace_property(&nv_connector->base) == 0) {
|
||||
#endif
|
||||
drm_connector_attach_colorspace_property(&nv_connector->base);
|
||||
}
|
||||
drm_connector_attach_hdr_output_metadata_property(&nv_connector->base);
|
||||
} else if (nv_connector->type == NVKMS_CONNECTOR_TYPE_DP) {
|
||||
#if defined(NV_DRM_MODE_CREATE_DP_COLORSPACE_PROPERTY_HAS_SUPPORTED_COLORSPACES_ARG)
|
||||
if (drm_mode_create_dp_colorspace_property(
|
||||
&nv_connector->base,
|
||||
__nv_drm_connector_supported_colorspaces) == 0) {
|
||||
#else
|
||||
if (drm_mode_create_dp_colorspace_property(&nv_connector->base) == 0) {
|
||||
#endif
|
||||
drm_connector_attach_colorspace_property(&nv_connector->base);
|
||||
}
|
||||
drm_connector_attach_hdr_output_metadata_property(&nv_connector->base);
|
||||
}
|
||||
|
||||
/* Register connector with DRM subsystem */
|
||||
|
||||
ret = drm_connector_register(&nv_connector->base);
|
||||
@@ -504,4 +741,67 @@ bool nv_drm_connector_revoke_permissions(struct drm_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nv_drm_connector_update_content_protection(struct nv_drm_connector *nv_connector)
|
||||
{
|
||||
struct drm_connector *connector = &nv_connector->base;
|
||||
struct drm_connector_state *state = connector->state;
|
||||
unsigned int content_protection = state->content_protection;
|
||||
unsigned int hdcp_content_type = state->hdcp_content_type;
|
||||
bool update_cp = false;
|
||||
unsigned int cp_val;
|
||||
|
||||
if ((content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) &&
|
||||
(hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0)) {
|
||||
if ((nv_connector->cp == NVKMS_CP_HDCP1X_ON) ||
|
||||
(nv_connector->cp == NVKMS_CP_HDCP2X_TYPE0_ON) ||
|
||||
(nv_connector->cp == NVKMS_CP_HDCP2X_TYPE1_ON)) {
|
||||
cp_val = DRM_MODE_CONTENT_PROTECTION_ENABLED;
|
||||
update_cp = true;
|
||||
}
|
||||
} else if ((content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) &&
|
||||
(hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE1)) {
|
||||
if (nv_connector->cp == NVKMS_CP_HDCP2X_TYPE1_ON) {
|
||||
cp_val = DRM_MODE_CONTENT_PROTECTION_ENABLED;
|
||||
update_cp = true;
|
||||
}
|
||||
} else if (content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
|
||||
if (nv_connector->cp == NVKMS_CP_OFF) {
|
||||
cp_val = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
update_cp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (update_cp) {
|
||||
drm_hdcp_update_content_protection(connector, cp_val);
|
||||
}
|
||||
}
|
||||
|
||||
int nv_drm_connector_update_topology_property(struct nv_drm_connector *nv_connector,
|
||||
struct NvKmsHdcpTopology *topology)
|
||||
{
|
||||
struct drm_connector *connector = &nv_connector->base;
|
||||
struct drm_connector_state *state = connector->state;
|
||||
struct nv_drm_connector_state *nv_state = to_nv_drm_connector_state(state);
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
int ret;
|
||||
|
||||
ret = drm_property_replace_global_blob(dev,
|
||||
&nv_state->hdcp_topology_blob,
|
||||
sizeof(*topology),
|
||||
topology,
|
||||
&connector->base,
|
||||
nv_dev->nv_hdcp_topology_property);
|
||||
// Generate uevent on cp property when topology is updated
|
||||
#if defined(NV_DRM_SYSFS_CONNECTOR_PROPERTY_EVENT_PRESENT)
|
||||
drm_sysfs_connector_property_event(connector,
|
||||
dev->mode_config.content_protection_property);
|
||||
#else
|
||||
drm_sysfs_connector_status_event(connector,
|
||||
dev->mode_config.content_protection_property);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016 - 2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -49,6 +49,8 @@ struct nv_drm_connector {
|
||||
struct nv_drm_encoder *nv_detected_encoder;
|
||||
struct edid *edid;
|
||||
|
||||
enum NvKmsContentProtection cp;
|
||||
|
||||
atomic_t connection_status_dirty;
|
||||
|
||||
/**
|
||||
@@ -77,6 +79,25 @@ static inline struct nv_drm_connector *to_nv_connector(
|
||||
return container_of(connector, struct nv_drm_connector, base);
|
||||
}
|
||||
|
||||
struct nv_drm_connector_state {
|
||||
struct drm_connector_state base;
|
||||
enum NvKmsDpyAttributeColorRangeValue output_colorrange;
|
||||
NvBool op_colorrange_changed;
|
||||
struct drm_property_blob *hdcp_topology_blob;
|
||||
};
|
||||
|
||||
static inline struct nv_drm_connector_state *to_nv_drm_connector_state(
|
||||
struct drm_connector_state *state)
|
||||
{
|
||||
return container_of(state, struct nv_drm_connector_state, base);
|
||||
}
|
||||
|
||||
static inline const struct nv_drm_connector_state *to_nv_drm_connector_state_const(
|
||||
const struct drm_connector_state *state)
|
||||
{
|
||||
return container_of(state, const struct nv_drm_connector_state, base);
|
||||
}
|
||||
|
||||
static inline void nv_drm_connector_mark_connection_status_dirty(
|
||||
struct nv_drm_connector *nv_connector)
|
||||
{
|
||||
@@ -100,6 +121,10 @@ nv_drm_get_connector(struct drm_device *dev,
|
||||
|
||||
bool nv_drm_connector_revoke_permissions(struct drm_device *dev,
|
||||
struct nv_drm_connector *nv_connector);
|
||||
void nv_drm_connector_update_content_protection(struct nv_drm_connector *nv_connector);
|
||||
int nv_drm_connector_update_topology_property(struct nv_drm_connector *nv_connector,
|
||||
struct NvKmsHdcpTopology *topology);
|
||||
|
||||
|
||||
#endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@
|
||||
#include <linux/host1x-next.h>
|
||||
#endif
|
||||
|
||||
#include <drm/drm_vblank.h>
|
||||
#if defined(NV_DRM_DRM_COLOR_MGMT_H_PRESENT)
|
||||
#include <drm/drm_color_mgmt.h>
|
||||
#endif
|
||||
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
static int
|
||||
nv_drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
|
||||
@@ -87,11 +92,22 @@ static void nv_drm_plane_destroy(struct drm_plane *plane)
|
||||
nv_drm_free(nv_plane);
|
||||
}
|
||||
|
||||
static inline void
|
||||
plane_config_clear(struct NvKmsKapiLayerConfig *layerConfig)
|
||||
{
|
||||
if (layerConfig == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(layerConfig, 0, sizeof(*layerConfig));
|
||||
layerConfig->csc = NVKMS_IDENTITY_CSC_MATRIX;
|
||||
}
|
||||
|
||||
static inline void
|
||||
plane_req_config_disable(struct NvKmsKapiLayerRequestedConfig *req_config)
|
||||
{
|
||||
/* Clear layer config */
|
||||
memset(&req_config->config, 0, sizeof(req_config->config));
|
||||
plane_config_clear(&req_config->config);
|
||||
|
||||
/* Set flags to get cleared layer config applied */
|
||||
req_config->flags.surfaceChanged = NV_TRUE;
|
||||
@@ -108,6 +124,45 @@ cursor_req_config_disable(struct NvKmsKapiCursorRequestedConfig *req_config)
|
||||
req_config->flags.surfaceChanged = NV_TRUE;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_COLOR_MGMT_AVAILABLE)
|
||||
static void color_mgmt_config_ctm_to_csc(struct NvKmsCscMatrix *nvkms_csc,
|
||||
struct drm_color_ctm *drm_ctm)
|
||||
{
|
||||
int y;
|
||||
|
||||
/* CTM is a 3x3 matrix while ours is 3x4. Zero out the last column. */
|
||||
nvkms_csc->m[0][3] = nvkms_csc->m[1][3] = nvkms_csc->m[2][3] = 0;
|
||||
|
||||
for (y = 0; y < 3; y++) {
|
||||
int x;
|
||||
|
||||
for (x = 0; x < 3; x++) {
|
||||
/*
|
||||
* Values in the CTM are encoded in S31.32 sign-magnitude fixed-
|
||||
* point format, while NvKms CSC values are signed 2's-complement
|
||||
* S15.16 (Ssign-extend12-3.16?) fixed-point format.
|
||||
*/
|
||||
NvU64 ctmVal = drm_ctm->matrix[y*3 + x];
|
||||
NvU64 signBit = ctmVal & (1ULL << 63);
|
||||
NvU64 magnitude = ctmVal & ~signBit;
|
||||
|
||||
/*
|
||||
* Drop the low 16 bits of the fractional part and the high 17 bits
|
||||
* of the integral part. Drop 17 bits to avoid corner cases where
|
||||
* the highest resulting bit is a 1, causing the `cscVal = -cscVal`
|
||||
* line to result in a positive number.
|
||||
*/
|
||||
NvS32 cscVal = (magnitude >> 16) & ((1ULL << 31) - 1);
|
||||
if (signBit) {
|
||||
cscVal = -cscVal;
|
||||
}
|
||||
|
||||
nvkms_csc->m[y][x] = cscVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NV_DRM_COLOR_MGMT_AVAILABLE */
|
||||
|
||||
static void
|
||||
cursor_plane_req_config_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *plane_state,
|
||||
@@ -234,6 +289,8 @@ plane_req_config_update(struct drm_plane *plane,
|
||||
.dstY = plane_state->crtc_y,
|
||||
.dstWidth = plane_state->crtc_w,
|
||||
.dstHeight = plane_state->crtc_h,
|
||||
|
||||
.csc = old_config.csc
|
||||
},
|
||||
};
|
||||
|
||||
@@ -339,6 +396,9 @@ plane_req_config_update(struct drm_plane *plane,
|
||||
req_config->config.inputColorSpace =
|
||||
nv_drm_plane_state->input_colorspace;
|
||||
|
||||
req_config->config.inputColorRange =
|
||||
nv_drm_plane_state->input_colorrange;
|
||||
|
||||
req_config->config.syncptParams.preSyncptSpecified = false;
|
||||
req_config->config.syncptParams.postSyncptRequested = false;
|
||||
|
||||
@@ -564,6 +624,24 @@ static int nv_drm_plane_atomic_check(struct drm_plane *plane,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_COLOR_MGMT_AVAILABLE)
|
||||
if (crtc_state->color_mgmt_changed || ((plane->state->crtc != plane_state->crtc))) {
|
||||
/*
|
||||
* According to the comment in the Linux kernel's
|
||||
* drivers/gpu/drm/drm_color_mgmt.c, if this property is NULL,
|
||||
* the CTM needs to be changed to the identity matrix
|
||||
*/
|
||||
if (crtc_state->ctm) {
|
||||
color_mgmt_config_ctm_to_csc(&plane_requested_config->config.csc,
|
||||
(struct drm_color_ctm *)crtc_state->ctm->data);
|
||||
} else {
|
||||
plane_requested_config->config.csc = NVKMS_IDENTITY_CSC_MATRIX;
|
||||
}
|
||||
plane_requested_config->config.cscUseMain = NV_FALSE;
|
||||
plane_requested_config->flags.cscChanged = NV_TRUE;
|
||||
}
|
||||
#endif /* NV_DRM_COLOR_MGMT_AVAILABLE */
|
||||
|
||||
if (__is_async_flip_requested(plane, crtc_state)) {
|
||||
/*
|
||||
* Async flip requests that the flip happen 'as soon as
|
||||
@@ -609,6 +687,9 @@ static int nv_drm_plane_atomic_set_property(
|
||||
} else if (property == nv_dev->nv_input_colorspace_property) {
|
||||
nv_drm_plane_state->input_colorspace = val;
|
||||
return 0;
|
||||
} else if (property == nv_dev->nv_input_colorrange_property) {
|
||||
nv_drm_plane_state->input_colorrange = val;
|
||||
return 0;
|
||||
}
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
else if (property == nv_dev->nv_hdr_output_metadata_property) {
|
||||
@@ -638,6 +719,9 @@ static int nv_drm_plane_atomic_get_property(
|
||||
} else if (property == nv_dev->nv_input_colorspace_property) {
|
||||
*val = nv_drm_plane_state->input_colorspace;
|
||||
return 0;
|
||||
} else if (property == nv_dev->nv_input_colorrange_property) {
|
||||
*val = nv_drm_plane_state->input_colorrange;
|
||||
return 0;
|
||||
}
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
else if (property == nv_dev->nv_hdr_output_metadata_property) {
|
||||
@@ -652,6 +736,38 @@ static int nv_drm_plane_atomic_get_property(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nv_drm_plane_atomic_reset - plane state reset hook
|
||||
* @plane: DRM plane
|
||||
*
|
||||
* Allocate an empty DRM plane state.
|
||||
*/
|
||||
static void nv_drm_plane_atomic_reset(struct drm_plane *plane)
|
||||
{
|
||||
struct nv_drm_plane_state *nv_plane_state =
|
||||
nv_drm_calloc(1, sizeof(*nv_plane_state));
|
||||
|
||||
if (!nv_plane_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
drm_atomic_helper_plane_reset(plane);
|
||||
|
||||
/*
|
||||
* The drm atomic helper function allocates a state object that is the wrong
|
||||
* size. Copy its contents into the one we allocated above and replace the
|
||||
* pointer.
|
||||
*/
|
||||
if (plane->state) {
|
||||
nv_plane_state->base = *plane->state;
|
||||
kfree(plane->state);
|
||||
plane->state = &nv_plane_state->base;
|
||||
} else {
|
||||
kfree(nv_plane_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct drm_plane_state *
|
||||
nv_drm_plane_atomic_duplicate_state(struct drm_plane *plane)
|
||||
{
|
||||
@@ -668,6 +784,7 @@ nv_drm_plane_atomic_duplicate_state(struct drm_plane *plane)
|
||||
|
||||
nv_plane_state->fd_user_ptr = nv_old_plane_state->fd_user_ptr;
|
||||
nv_plane_state->input_colorspace = nv_old_plane_state->input_colorspace;
|
||||
nv_plane_state->input_colorrange = nv_old_plane_state->input_colorrange;
|
||||
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
nv_plane_state->hdr_output_metadata = nv_old_plane_state->hdr_output_metadata;
|
||||
@@ -711,7 +828,7 @@ static const struct drm_plane_funcs nv_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = nv_drm_plane_destroy,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.reset = nv_drm_plane_atomic_reset,
|
||||
.atomic_get_property = nv_drm_plane_atomic_get_property,
|
||||
.atomic_set_property = nv_drm_plane_atomic_set_property,
|
||||
.atomic_duplicate_state = nv_drm_plane_atomic_duplicate_state,
|
||||
@@ -768,6 +885,51 @@ static inline void nv_drm_crtc_duplicate_req_head_modeset_config(
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct nv_drm_crtc_state *nv_drm_crtc_state_alloc(void)
|
||||
{
|
||||
struct nv_drm_crtc_state *nv_state = nv_drm_calloc(1, sizeof(*nv_state));
|
||||
int i;
|
||||
|
||||
if (nv_state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nv_state->req_config.layerRequestedConfig); i++) {
|
||||
plane_config_clear(&nv_state->req_config.layerRequestedConfig[i].config);
|
||||
}
|
||||
return nv_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* nv_drm_atomic_crtc_reset - crtc state reset hook
|
||||
* @crtc: DRM crtc
|
||||
*
|
||||
* Allocate an empty DRM crtc state.
|
||||
*/
|
||||
static void nv_drm_atomic_crtc_reset(struct drm_crtc *crtc)
|
||||
{
|
||||
struct nv_drm_crtc_state *nv_state = nv_drm_crtc_state_alloc();
|
||||
|
||||
if (!nv_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
drm_atomic_helper_crtc_reset(crtc);
|
||||
|
||||
/*
|
||||
* The drm atomic helper function allocates a state object that is the wrong
|
||||
* size. Copy its contents into the one we allocated above and replace the
|
||||
* pointer.
|
||||
*/
|
||||
if (crtc->state) {
|
||||
nv_state->base = *crtc->state;
|
||||
kfree(crtc->state);
|
||||
crtc->state = &nv_state->base;
|
||||
} else {
|
||||
kfree(nv_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nv_drm_atomic_crtc_duplicate_state - crtc state duplicate hook
|
||||
* @crtc: DRM crtc
|
||||
@@ -779,7 +941,7 @@ static inline void nv_drm_crtc_duplicate_req_head_modeset_config(
|
||||
static struct drm_crtc_state*
|
||||
nv_drm_atomic_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct nv_drm_crtc_state *nv_state = nv_drm_calloc(1, sizeof(*nv_state));
|
||||
struct nv_drm_crtc_state *nv_state = nv_drm_crtc_state_alloc();
|
||||
|
||||
if (nv_state == NULL) {
|
||||
return NULL;
|
||||
@@ -791,15 +953,20 @@ nv_drm_atomic_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__drm_atomic_helper_crtc_duplicate_state(crtc, &nv_state->base);
|
||||
|
||||
INIT_LIST_HEAD(&nv_state->nv_flip->list_entry);
|
||||
INIT_LIST_HEAD(&nv_state->nv_flip->deferred_flip_list);
|
||||
|
||||
/*
|
||||
* nv_drm_crtc_duplicate_req_head_modeset_config potentially allocates
|
||||
* nv_state->req_config.modeSetConfig.lut.{in,out}put.pRamps, so they should
|
||||
* be freed in any following failure paths.
|
||||
*/
|
||||
|
||||
nv_drm_crtc_duplicate_req_head_modeset_config(
|
||||
&(to_nv_crtc_state(crtc->state)->req_config),
|
||||
&nv_state->req_config);
|
||||
|
||||
__drm_atomic_helper_crtc_duplicate_state(crtc, &nv_state->base);
|
||||
|
||||
return &nv_state->base;
|
||||
}
|
||||
|
||||
@@ -826,13 +993,50 @@ static void nv_drm_atomic_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
nv_drm_free(nv_state);
|
||||
}
|
||||
|
||||
static int nv_drm_crtc_enable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
struct nv_drm_device *nv_dev = to_nv_device(nv_crtc->base.dev);
|
||||
|
||||
while (!mutex_trylock(&nv_crtc->vblank_q_lock)) {
|
||||
cpu_relax();
|
||||
}
|
||||
if (nv_crtc->vblank_enabled) {
|
||||
goto done;
|
||||
}
|
||||
nv_crtc->vblank_enabled = true;
|
||||
nv_kthread_q_schedule_q_item(&nv_dev->nv_kthread_q, &nv_crtc->enable_vblank_q_item);
|
||||
done:
|
||||
mutex_unlock(&nv_crtc->vblank_q_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nv_drm_crtc_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
struct nv_drm_device *nv_dev = to_nv_device(nv_crtc->base.dev);
|
||||
|
||||
while (!mutex_trylock(&nv_crtc->vblank_q_lock)) {
|
||||
cpu_relax();
|
||||
}
|
||||
if (!nv_crtc->vblank_enabled) {
|
||||
goto done;
|
||||
}
|
||||
nv_crtc->vblank_enabled = false;
|
||||
nv_kthread_q_schedule_q_item(&nv_dev->nv_kthread_q, &nv_crtc->disable_vblank_q_item);
|
||||
done:
|
||||
mutex_unlock(&nv_crtc->vblank_q_lock);
|
||||
}
|
||||
|
||||
static struct drm_crtc_funcs nv_crtc_funcs = {
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
.reset = nv_drm_atomic_crtc_reset,
|
||||
.destroy = nv_drm_crtc_destroy,
|
||||
.atomic_duplicate_state = nv_drm_atomic_crtc_duplicate_state,
|
||||
.atomic_destroy_state = nv_drm_atomic_crtc_destroy_state,
|
||||
.enable_vblank = nv_drm_crtc_enable_vblank,
|
||||
.disable_vblank = nv_drm_crtc_disable_vblank,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -958,6 +1162,11 @@ static void nv_drm_plane_install_properties(
|
||||
NVKMS_INPUT_COLORSPACE_NONE);
|
||||
}
|
||||
|
||||
if (nv_dev->nv_input_colorrange_property) {
|
||||
drm_object_attach_property(
|
||||
&plane->base, nv_dev->nv_input_colorrange_property,
|
||||
NVKMS_INPUT_COLORRANGE_DEFAULT);
|
||||
}
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
if (supportsHDR && nv_dev->nv_hdr_output_metadata_property) {
|
||||
drm_object_attach_property(
|
||||
@@ -1104,6 +1313,7 @@ nv_drm_plane_create(struct drm_device *dev,
|
||||
plane = &nv_plane->base;
|
||||
|
||||
nv_plane->defaultCompositionMode = defaultCompositionMode;
|
||||
nv_plane->head = head;
|
||||
nv_plane->layer_idx = layer_idx;
|
||||
|
||||
if ((nv_plane_state =
|
||||
@@ -1173,6 +1383,44 @@ failed:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
void nv_drm_crtc_vblank_callback(NvU64 param1, NvU64 param2)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = (void*)(NvUPtr)param1;
|
||||
struct drm_crtc *crtc = &nv_crtc->base;
|
||||
|
||||
drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
|
||||
}
|
||||
|
||||
static void nv_drm_vblank_enable_fn(void *t)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = t;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(nv_crtc->base.dev);
|
||||
|
||||
mutex_lock(&nv_crtc->vblank_q_lock);
|
||||
if (nv_crtc->vblank_enabled &&
|
||||
(nv_crtc->vblankIntrCallback == NULL)) {
|
||||
nv_crtc->vblankIntrCallback =
|
||||
nvKms->RegisterVblankIntrCallback(nv_dev->pDevice, nv_crtc->head,
|
||||
nv_drm_crtc_vblank_callback, (NvU64)(NvUPtr)nv_crtc, 0);
|
||||
}
|
||||
mutex_unlock(&nv_crtc->vblank_q_lock);
|
||||
}
|
||||
|
||||
static void nv_drm_vblank_disable_fn(void *t)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = t;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(nv_crtc->base.dev);
|
||||
|
||||
mutex_lock(&nv_crtc->vblank_q_lock);
|
||||
if (!nv_crtc->vblank_enabled &&
|
||||
(nv_crtc->vblankIntrCallback != NULL)) {
|
||||
nvKms->UnregisterVblankIntrCallback(nv_dev->pDevice, nv_crtc->head,
|
||||
nv_crtc->vblankIntrCallback);
|
||||
nv_crtc->vblankIntrCallback = NULL;
|
||||
}
|
||||
mutex_unlock(&nv_crtc->vblank_q_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add drm crtc for given head and supported enum NvKmsSurfaceMemoryFormats.
|
||||
*/
|
||||
@@ -1189,7 +1437,7 @@ static struct drm_crtc *__nv_drm_crtc_create(struct nv_drm_device *nv_dev,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
nv_state = nv_drm_calloc(1, sizeof(*nv_state));
|
||||
nv_state = nv_drm_crtc_state_alloc();
|
||||
if (nv_state == NULL) {
|
||||
goto failed_state_alloc;
|
||||
}
|
||||
@@ -1199,9 +1447,12 @@ static struct drm_crtc *__nv_drm_crtc_create(struct nv_drm_device *nv_dev,
|
||||
|
||||
nv_crtc->head = head;
|
||||
INIT_LIST_HEAD(&nv_crtc->flip_list);
|
||||
spin_lock_init(&nv_crtc->flip_list_lock);
|
||||
mutex_init(&nv_crtc->vblank_q_lock);
|
||||
nv_crtc->modeset_permission_filep = NULL;
|
||||
|
||||
nv_kthread_q_item_init(&nv_crtc->disable_vblank_q_item, nv_drm_vblank_disable_fn, nv_crtc);
|
||||
nv_kthread_q_item_init(&nv_crtc->enable_vblank_q_item, nv_drm_vblank_enable_fn, nv_crtc);
|
||||
|
||||
ret = drm_crtc_init_with_planes(nv_dev->dev,
|
||||
&nv_crtc->base,
|
||||
primary_plane, cursor_plane,
|
||||
@@ -1222,6 +1473,14 @@ static struct drm_crtc *__nv_drm_crtc_create(struct nv_drm_device *nv_dev,
|
||||
|
||||
drm_crtc_helper_add(&nv_crtc->base, &nv_crtc_helper_funcs);
|
||||
|
||||
#if defined(NV_DRM_COLOR_MGMT_AVAILABLE)
|
||||
#if defined(NV_DRM_CRTC_ENABLE_COLOR_MGMT_PRESENT)
|
||||
drm_crtc_enable_color_mgmt(&nv_crtc->base, 0, true, 0);
|
||||
#else
|
||||
drm_helper_crtc_enable_color_mgmt(&nv_crtc->base, 0, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return &nv_crtc->base;
|
||||
|
||||
failed_init_crtc:
|
||||
|
||||
@@ -41,20 +41,16 @@
|
||||
struct nv_drm_crtc {
|
||||
NvU32 head;
|
||||
|
||||
bool vblank_enabled;
|
||||
/**
|
||||
* @flip_list:
|
||||
*
|
||||
* List of flips pending to get processed by __nv_drm_handle_flip_event().
|
||||
* Protected by @flip_list_lock.
|
||||
* Protected by @vblank_q_lock.
|
||||
*/
|
||||
struct list_head flip_list;
|
||||
|
||||
/**
|
||||
* @flip_list_lock:
|
||||
*
|
||||
* Spinlock to protect @flip_list.
|
||||
*/
|
||||
spinlock_t flip_list_lock;
|
||||
struct mutex vblank_q_lock;
|
||||
|
||||
/**
|
||||
* @modeset_permission_filep:
|
||||
@@ -63,6 +59,11 @@ struct nv_drm_crtc {
|
||||
*/
|
||||
struct drm_file *modeset_permission_filep;
|
||||
|
||||
struct NvKmsKapiVblankIntrCallback *vblankIntrCallback;
|
||||
|
||||
nv_kthread_q_item_t disable_vblank_q_item;
|
||||
nv_kthread_q_item_t enable_vblank_q_item;
|
||||
|
||||
struct drm_crtc base;
|
||||
};
|
||||
|
||||
@@ -85,33 +86,29 @@ struct nv_drm_flip {
|
||||
*/
|
||||
struct drm_pending_vblank_event *event;
|
||||
|
||||
/**
|
||||
* @pending_events
|
||||
*
|
||||
* Number of HW events pending to signal completion of the state
|
||||
* update.
|
||||
*/
|
||||
uint32_t pending_events;
|
||||
/**
|
||||
* @plane_mask
|
||||
*
|
||||
* Bitmask of drm_plane_mask(plane) of planes attached to the completion of
|
||||
* the state update.
|
||||
*/
|
||||
uint32_t plane_mask;
|
||||
|
||||
/**
|
||||
* @list_entry:
|
||||
*
|
||||
* Entry on the per-CRTC &nv_drm_crtc.flip_list. Protected by
|
||||
* &nv_drm_crtc.flip_list_lock.
|
||||
*/
|
||||
struct list_head list_entry;
|
||||
/**
|
||||
* @pending_events_plane_mask
|
||||
*
|
||||
* Bitmask of drm_plane_mask(plane) of planes for which HW events are
|
||||
* pending before signaling the completion of the state update.
|
||||
*/
|
||||
uint32_t pending_events_plane_mask;
|
||||
|
||||
/**
|
||||
* @deferred_flip_list
|
||||
*
|
||||
* List flip objects whose processing is deferred until processing of
|
||||
* this flip object. Protected by &nv_drm_crtc.flip_list_lock.
|
||||
* nv_drm_atomic_commit() gets last flip object from
|
||||
* nv_drm_crtc:flip_list and add deferred flip objects into
|
||||
* @deferred_flip_list, __nv_drm_handle_flip_event() processes
|
||||
* @deferred_flip_list.
|
||||
*/
|
||||
struct list_head deferred_flip_list;
|
||||
/**
|
||||
* @list_entry:
|
||||
*
|
||||
* Entry on the per-CRTC &nv_drm_crtc.flip_list. Protected by
|
||||
* &nv_drm_crtc.vblank_q_lock.
|
||||
*/
|
||||
struct list_head list_entry;
|
||||
};
|
||||
|
||||
struct nv_drm_crtc_state {
|
||||
@@ -164,6 +161,8 @@ struct nv_drm_plane {
|
||||
*/
|
||||
enum NvKmsCompositionBlendingMode defaultCompositionMode;
|
||||
|
||||
NvU32 head;
|
||||
|
||||
/**
|
||||
* @layer_idx
|
||||
*
|
||||
@@ -184,6 +183,7 @@ struct nv_drm_plane_state {
|
||||
struct drm_plane_state base;
|
||||
s32 __user *fd_user_ptr;
|
||||
enum NvKmsInputColorSpace input_colorspace;
|
||||
enum NvKmsInputColorRange input_colorrange;
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
struct drm_property_blob *hdr_output_metadata;
|
||||
#endif
|
||||
@@ -226,46 +226,29 @@ struct nv_drm_crtc *nv_drm_crtc_lookup(struct nv_drm_device *nv_dev, NvU32 head)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct nv_drm_plane *nv_drm_plane_lookup(struct nv_drm_device *nv_dev, NvU32 head, NvU32 layer)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
nv_drm_for_each_plane(plane, nv_dev->dev) {
|
||||
struct nv_drm_plane *nv_plane = to_nv_plane(plane);
|
||||
|
||||
if ((nv_plane->head == head) && (nv_plane->layer_idx == layer)) {
|
||||
return nv_plane;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nv_drm_crtc_enqueue_flip - Enqueue nv_drm_flip object to flip_list of crtc.
|
||||
*/
|
||||
static inline void nv_drm_crtc_enqueue_flip(struct nv_drm_crtc *nv_crtc,
|
||||
struct nv_drm_flip *nv_flip)
|
||||
{
|
||||
spin_lock(&nv_crtc->flip_list_lock);
|
||||
spin_lock(&nv_crtc->base.dev->event_lock);
|
||||
list_add(&nv_flip->list_entry, &nv_crtc->flip_list);
|
||||
spin_unlock(&nv_crtc->flip_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* nv_drm_crtc_dequeue_flip - Dequeue nv_drm_flip object to flip_list of crtc.
|
||||
*/
|
||||
static inline
|
||||
struct nv_drm_flip *nv_drm_crtc_dequeue_flip(struct nv_drm_crtc *nv_crtc)
|
||||
{
|
||||
struct nv_drm_flip *nv_flip = NULL;
|
||||
uint32_t pending_events = 0;
|
||||
|
||||
spin_lock(&nv_crtc->flip_list_lock);
|
||||
nv_flip = list_first_entry_or_null(&nv_crtc->flip_list,
|
||||
struct nv_drm_flip, list_entry);
|
||||
if (likely(nv_flip != NULL)) {
|
||||
/*
|
||||
* Decrement pending_event count and dequeue flip object if
|
||||
* pending_event count becomes 0.
|
||||
*/
|
||||
pending_events = --nv_flip->pending_events;
|
||||
if (!pending_events) {
|
||||
list_del(&nv_flip->list_entry);
|
||||
}
|
||||
}
|
||||
spin_unlock(&nv_crtc->flip_list_lock);
|
||||
|
||||
if (WARN_ON(nv_flip == NULL) || pending_events) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nv_flip;
|
||||
spin_unlock(&nv_crtc->base.dev->event_lock);
|
||||
}
|
||||
|
||||
void nv_drm_enumerate_crtcs_and_planes(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "nvidia-drm-gem-nvkms-memory.h"
|
||||
#include "nvidia-drm-gem-user-memory.h"
|
||||
#include "nvidia-drm-gem-dma-buf.h"
|
||||
#include "nvidia-drm-utils.h"
|
||||
#include "nv_dpy_id.h"
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
@@ -60,7 +62,18 @@
|
||||
#include <drm/drm_ioctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
#include <drm/drm_aperture.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#endif
|
||||
|
||||
#if defined(NV_DRM_DRM_FBDEV_GENERIC_H_PRESENT)
|
||||
#include <drm/drm_fbdev_generic.h>
|
||||
#endif
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
/*
|
||||
* Commit fcd70cd36b9b ("drm: Split out drm_probe_helper.h")
|
||||
@@ -84,6 +97,13 @@
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#endif
|
||||
|
||||
#include "nv-kthread-q.h"
|
||||
|
||||
static int nv_drm_revoke_modeset_permission(struct drm_device *dev,
|
||||
struct drm_file *filep,
|
||||
NvU32 dpyId);
|
||||
static int nv_drm_revoke_sub_ownership(struct drm_device *dev);
|
||||
|
||||
static struct nv_drm_device *dev_list = NULL;
|
||||
|
||||
static const char* nv_get_input_colorspace_name(
|
||||
@@ -96,6 +116,16 @@ static const char* nv_get_input_colorspace_name(
|
||||
return "IEC 61966-2-2 linear FP";
|
||||
case NVKMS_INPUT_COLORSPACE_BT2100_PQ:
|
||||
return "ITU-R BT.2100-PQ YCbCr";
|
||||
case NVKMS_INPUT_COLORSPACE_SRGB:
|
||||
return "IEC 61966-2-1 RGB";
|
||||
case NVKMS_INPUT_COLORSPACE_BT601:
|
||||
return "ITU-R BT.601-7";
|
||||
case NVKMS_INPUT_COLORSPACE_BT709:
|
||||
return "ITU-R BT.709-6";
|
||||
case NVKMS_INPUT_COLORSPACE_BT709_LINEAR:
|
||||
return "ITU-R BT.709-6 linear";
|
||||
case NVKMS_INPUT_COLORSPACE_BT2020:
|
||||
return "ITU-R BT.2020-2";
|
||||
default:
|
||||
/* We shoudn't hit this */
|
||||
WARN_ON("Unsupported input colorspace");
|
||||
@@ -103,8 +133,41 @@ static const char* nv_get_input_colorspace_name(
|
||||
}
|
||||
};
|
||||
|
||||
static const char* nv_get_input_colorrange_name(
|
||||
enum NvKmsInputColorRange colorRange)
|
||||
{
|
||||
switch (colorRange) {
|
||||
case NVKMS_INPUT_COLORRANGE_DEFAULT:
|
||||
return "Default";
|
||||
case NVKMS_INPUT_COLORRANGE_LIMITED:
|
||||
return "Input Color range Limited";
|
||||
case NVKMS_INPUT_COLORRANGE_FULL:
|
||||
return "Input Color range Full";
|
||||
default:
|
||||
/* We shoudn't hit this */
|
||||
WARN_ON("Unsupported input Color range");
|
||||
return "None";
|
||||
}
|
||||
};
|
||||
|
||||
static const char* nv_get_output_colorrange_name(
|
||||
enum NvKmsDpyAttributeColorRangeValue colorRange)
|
||||
{
|
||||
switch (colorRange) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL:
|
||||
return "Output Color range Full";
|
||||
case NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED:
|
||||
return "Output Color range Limited";
|
||||
default:
|
||||
/* We shoudn't hit this */
|
||||
WARN_ON("Unsupported output colorrange");
|
||||
return "None";
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
#if defined(NV_DRM_OUTPUT_POLL_CHANGED_PRESENT)
|
||||
static void nv_drm_output_poll_changed(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector = NULL;
|
||||
@@ -148,6 +211,7 @@ static void nv_drm_output_poll_changed(struct drm_device *dev)
|
||||
nv_drm_connector_list_iter_end(&conn_iter);
|
||||
#endif
|
||||
}
|
||||
#endif /* NV_DRM_OUTPUT_POLL_CHANGED_PRESENT */
|
||||
|
||||
static struct drm_framebuffer *nv_drm_framebuffer_create(
|
||||
struct drm_device *dev,
|
||||
@@ -185,7 +249,9 @@ static const struct drm_mode_config_funcs nv_mode_config_funcs = {
|
||||
.atomic_check = nv_drm_atomic_check,
|
||||
.atomic_commit = nv_drm_atomic_commit,
|
||||
|
||||
#if defined(NV_DRM_OUTPUT_POLL_CHANGED_PRESENT)
|
||||
.output_poll_changed = nv_drm_output_poll_changed,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void nv_drm_event_callback(const struct NvKmsKapiEvent *event)
|
||||
@@ -205,16 +271,30 @@ static void nv_drm_event_callback(const struct NvKmsKapiEvent *event)
|
||||
event->u.displayChanged.display);
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_CHANGED:
|
||||
nv_drm_handle_display_cp_change(
|
||||
nv_dev,
|
||||
event->u.displayCpChanged.display,
|
||||
event->u.displayCpChanged.cp);
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED:
|
||||
nv_drm_handle_display_cp_topology_change(
|
||||
nv_dev,
|
||||
event->u.displayCpTopologyChanged.display,
|
||||
event->u.displayCpTopologyChanged.topology);
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED:
|
||||
nv_drm_handle_dynamic_display_connected(
|
||||
nv_dev,
|
||||
event->u.dynamicDisplayConnected.display);
|
||||
break;
|
||||
case NVKMS_EVENT_TYPE_FLIP_OCCURRED:
|
||||
nv_drm_handle_flip_occurred(
|
||||
nv_drm_handle_flip_event(
|
||||
nv_dev,
|
||||
event->u.flipOccurred.head,
|
||||
event->u.flipOccurred.layer);
|
||||
event->u.flipOccurred.layer, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -225,6 +305,123 @@ done:
|
||||
mutex_unlock(&nv_dev->lock);
|
||||
}
|
||||
|
||||
struct nv_drm_mst_display_info {
|
||||
NvKmsKapiDisplay handle;
|
||||
NvBool isDpMST;
|
||||
char dpAddress[NVKMS_DP_ADDRESS_STRING_LENGTH];
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper function to get DpMST display info.
|
||||
* dpMSTDisplayInfos is allocated dynamically,
|
||||
* so it needs to be freed after finishing the query.
|
||||
*/
|
||||
static int nv_drm_get_mst_display_infos
|
||||
(
|
||||
struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay,
|
||||
struct nv_drm_mst_display_info **dpMSTDisplayInfos,
|
||||
NvU32 *nDynamicDisplays
|
||||
)
|
||||
{
|
||||
struct NvKmsKapiStaticDisplayInfo *displayInfo = NULL;
|
||||
struct NvKmsKapiStaticDisplayInfo *dynamicDisplayInfo = NULL;
|
||||
struct NvKmsKapiConnectorInfo *connectorInfo = NULL;
|
||||
struct nv_drm_mst_display_info *displayInfos = NULL;
|
||||
NvU32 i = 0;
|
||||
int ret = 0;
|
||||
NVDpyId dpyId;
|
||||
*nDynamicDisplays = 0;
|
||||
|
||||
/* Query NvKmsKapiStaticDisplayInfo and NvKmsKapiConnectorInfo */
|
||||
|
||||
if ((displayInfo = nv_drm_calloc(1, sizeof(*displayInfo))) == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((dynamicDisplayInfo = nv_drm_calloc(1, sizeof(*dynamicDisplayInfo))) == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!nvKms->getStaticDisplayInfo(nv_dev->pDevice, hDisplay, displayInfo)) {
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
connectorInfo = nvkms_get_connector_info(nv_dev->pDevice,
|
||||
displayInfo->connectorHandle);
|
||||
|
||||
if (IS_ERR(connectorInfo)) {
|
||||
ret = PTR_ERR(connectorInfo);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
*nDynamicDisplays = nvCountDpyIdsInDpyIdList(connectorInfo->dynamicDpyIdList);
|
||||
|
||||
if (*nDynamicDisplays == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((displayInfos = nv_drm_calloc(*nDynamicDisplays, sizeof(*displayInfos))) == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
FOR_ALL_DPY_IDS(dpyId, connectorInfo->dynamicDpyIdList) {
|
||||
if (!nvKms->getStaticDisplayInfo(nv_dev->pDevice,
|
||||
nvDpyIdToNvU32(dpyId),
|
||||
dynamicDisplayInfo)) {
|
||||
ret = -EINVAL;
|
||||
nv_drm_free(displayInfos);
|
||||
goto done;
|
||||
}
|
||||
|
||||
displayInfos[i].handle = dynamicDisplayInfo->handle;
|
||||
displayInfos[i].isDpMST = dynamicDisplayInfo->isDpMST;
|
||||
memcpy(displayInfos[i].dpAddress, dynamicDisplayInfo->dpAddress, sizeof(dynamicDisplayInfo->dpAddress));
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
*dpMSTDisplayInfos = displayInfos;
|
||||
|
||||
done:
|
||||
|
||||
nv_drm_free(displayInfo);
|
||||
|
||||
nv_drm_free(dynamicDisplayInfo);
|
||||
|
||||
nv_drm_free(connectorInfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nv_drm_disp_cmp (const void *l, const void *r)
|
||||
{
|
||||
struct nv_drm_mst_display_info *l_info = (struct nv_drm_mst_display_info *)l;
|
||||
struct nv_drm_mst_display_info *r_info = (struct nv_drm_mst_display_info *)r;
|
||||
|
||||
return strcmp(l_info->dpAddress, r_info->dpAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to sort the dpAddress in terms of string.
|
||||
* This function is to create DRM connectors ID order deterministically.
|
||||
* It's not numerically.
|
||||
*/
|
||||
static void nv_drm_sort_dynamic_displays_by_dp_addr
|
||||
(
|
||||
struct nv_drm_mst_display_info *infos,
|
||||
int nDynamicDisplays
|
||||
)
|
||||
{
|
||||
sort(infos, nDynamicDisplays, sizeof(*infos), nv_drm_disp_cmp, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helper function to initialize drm_device::mode_config from
|
||||
* NvKmsKapiDevice's resource information.
|
||||
@@ -306,9 +503,11 @@ static void nv_drm_enumerate_encoders_and_connectors
|
||||
nv_dev,
|
||||
"Failed to enumurate NvKmsKapiDisplay handles");
|
||||
} else {
|
||||
NvU32 i;
|
||||
NvU32 i, j;
|
||||
NvU32 nDynamicDisplays = 0;
|
||||
|
||||
for (i = 0; i < nDisplays; i++) {
|
||||
struct nv_drm_mst_display_info *displayInfos = NULL;
|
||||
struct drm_encoder *encoder =
|
||||
nv_drm_add_encoder(dev, hDisplays[i]);
|
||||
|
||||
@@ -318,6 +517,34 @@ static void nv_drm_enumerate_encoders_and_connectors
|
||||
"Failed to add connector for NvKmsKapiDisplay 0x%08x",
|
||||
hDisplays[i]);
|
||||
}
|
||||
|
||||
if (nv_drm_get_mst_display_infos(nv_dev, hDisplays[i],
|
||||
&displayInfos, &nDynamicDisplays)) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"Failed to get dynamic displays");
|
||||
} else if (nDynamicDisplays) {
|
||||
nv_drm_sort_dynamic_displays_by_dp_addr(displayInfos, nDynamicDisplays);
|
||||
|
||||
for (j = 0; j < nDynamicDisplays; j++) {
|
||||
if (displayInfos[j].isDpMST) {
|
||||
struct drm_encoder *mst_encoder =
|
||||
nv_drm_add_encoder(dev, displayInfos[j].handle);
|
||||
|
||||
NV_DRM_DEV_DEBUG_DRIVER(nv_dev, "found DP MST port display handle %u",
|
||||
displayInfos[j].handle);
|
||||
|
||||
if (IS_ERR(mst_encoder)) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"Failed to add connector for NvKmsKapiDisplay 0x%08x",
|
||||
displayInfos[j].handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nv_drm_free(displayInfos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,14 +572,11 @@ static void nv_drm_enumerate_encoders_and_connectors
|
||||
*/
|
||||
static int nv_drm_create_properties(struct nv_drm_device *nv_dev)
|
||||
{
|
||||
struct drm_prop_enum_list enum_list[3] = { };
|
||||
struct drm_prop_enum_list list_cs[8] = { };
|
||||
struct drm_prop_enum_list list_input_cr[3] = { };
|
||||
struct drm_prop_enum_list list_output_cr[2] = { };
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
enum_list[len].type = i;
|
||||
enum_list[len].name = nv_get_input_colorspace_name(i);
|
||||
len++;
|
||||
}
|
||||
|
||||
if (nv_dev->supportsSyncpts) {
|
||||
nv_dev->nv_out_fence_property =
|
||||
@@ -363,14 +587,47 @@ static int nv_drm_create_properties(struct nv_drm_device *nv_dev)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
list_cs[len].type = i;
|
||||
list_cs[len].name = nv_get_input_colorspace_name(i);
|
||||
len++;
|
||||
}
|
||||
|
||||
nv_dev->nv_input_colorspace_property =
|
||||
drm_property_create_enum(nv_dev->dev, 0, "NV_INPUT_COLORSPACE",
|
||||
enum_list, len);
|
||||
list_cs, len);
|
||||
if (nv_dev->nv_input_colorspace_property == NULL) {
|
||||
NV_DRM_LOG_ERR("Failed to create NV_INPUT_COLORSPACE property");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0, len = 0; i < 3; i++) {
|
||||
list_input_cr[len].type = i;
|
||||
list_input_cr[len].name = nv_get_input_colorrange_name(i);
|
||||
len++;
|
||||
}
|
||||
|
||||
nv_dev->nv_input_colorrange_property =
|
||||
drm_property_create_enum(nv_dev->dev, 0, "NV_INPUT_COLORRANGE",
|
||||
list_input_cr, len);
|
||||
if (nv_dev->nv_input_colorrange_property == NULL) {
|
||||
NV_DRM_LOG_ERR("Failed to create NV_INPUT_COLORRANGE property");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0, len = 0; i < 2; i++) {
|
||||
list_output_cr[len].type = i;
|
||||
list_output_cr[len].name = nv_get_output_colorrange_name(i);
|
||||
len++;
|
||||
}
|
||||
|
||||
nv_dev->nv_output_colorrange_property =
|
||||
drm_property_create_enum(nv_dev->dev, 0, "NV_OUTPUT_COLORRANGE",
|
||||
list_output_cr, len);
|
||||
if (nv_dev->nv_output_colorrange_property == NULL) {
|
||||
NV_DRM_LOG_ERR("Failed to create NV_OUTPUT_COLORRANGE property");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
nv_dev->nv_hdr_output_metadata_property =
|
||||
drm_property_create(nv_dev->dev, DRM_MODE_PROP_BLOB,
|
||||
@@ -380,9 +637,36 @@ static int nv_drm_create_properties(struct nv_drm_device *nv_dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* hdcp_topology is immutable by user space */
|
||||
nv_dev->nv_hdcp_topology_property =
|
||||
drm_property_create(nv_dev->dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE,
|
||||
"NV_HDCP_TOPOLOGY", 0);
|
||||
if (nv_dev->nv_hdcp_topology_property == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't just call drm_kms_helper_hotplug_event directly because
|
||||
* fbdev_generic may attempt to set a mode from inside the hotplug event
|
||||
* handler. Because kapi event handling runs on nvkms_kthread_q, this blocks
|
||||
* other event processing including the flip completion notifier expected by
|
||||
* nv_drm_atomic_commit.
|
||||
*
|
||||
* Defer hotplug event handling to a work item so that nvkms_kthread_q can
|
||||
* continue processing events while a DRM modeset is in progress.
|
||||
*/
|
||||
static void nv_drm_handle_hotplug_event(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct nv_drm_device *nv_dev =
|
||||
container_of(dwork, struct nv_drm_device, hotplug_event_work);
|
||||
|
||||
drm_kms_helper_hotplug_event(nv_dev->dev);
|
||||
}
|
||||
|
||||
static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
@@ -436,6 +720,22 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
/*
|
||||
* If fbdev is enabled, take modeset ownership now before other DRM clients
|
||||
* can take master (and thus NVKMS ownership).
|
||||
*/
|
||||
if (nv_drm_fbdev_module_param) {
|
||||
if (!nvKms->grabOwnership(pDevice)) {
|
||||
nvKms->freeDevice(pDevice);
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
nv_dev->hasFramebufferConsole = NV_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(&nv_dev->lock);
|
||||
|
||||
/* Set NvKmsKapiDevice */
|
||||
@@ -493,6 +793,8 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
nv_dev->pDevice,
|
||||
((1 << NVKMS_EVENT_TYPE_DPY_CHANGED) |
|
||||
(1 << NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED) |
|
||||
(1 << NVKMS_EVENT_TYPE_DPY_CP_CHANGED) |
|
||||
(1 << NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED) |
|
||||
(1 << NVKMS_EVENT_TYPE_FLIP_OCCURRED)))) {
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to register event mask");
|
||||
}
|
||||
@@ -505,9 +807,9 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
|
||||
nv_drm_enumerate_encoders_and_connectors(nv_dev);
|
||||
|
||||
#if !defined(NV_DRM_CRTC_STATE_HAS_NO_VBLANK)
|
||||
nv_kthread_q_init(&nv_dev->nv_kthread_q, "nvidia-drm-nv-thread-q");
|
||||
|
||||
drm_vblank_init(dev, dev->mode_config.num_crtc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Trigger hot-plug processing, to update connection status of
|
||||
@@ -518,6 +820,7 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
||||
|
||||
/* Enable event handling */
|
||||
|
||||
INIT_DELAYED_WORK(&nv_dev->hotplug_event_work, nv_drm_handle_hotplug_event);
|
||||
atomic_set(&nv_dev->enable_event_handling, true);
|
||||
|
||||
init_waitqueue_head(&nv_dev->flip_event_wq);
|
||||
@@ -545,8 +848,20 @@ static void __nv_drm_unload(struct drm_device *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Release modeset ownership if fbdev is enabled */
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
if (nv_dev->hasFramebufferConsole) {
|
||||
drm_atomic_helper_shutdown(dev);
|
||||
nvKms->releaseOwnership(nv_dev->pDevice);
|
||||
}
|
||||
#endif
|
||||
|
||||
cancel_delayed_work_sync(&nv_dev->hotplug_event_work);
|
||||
mutex_lock(&nv_dev->lock);
|
||||
|
||||
WARN_ON(nv_dev->subOwnershipGranted);
|
||||
|
||||
/* Disable event handling */
|
||||
|
||||
atomic_set(&nv_dev->enable_event_handling, false);
|
||||
@@ -555,6 +870,8 @@ static void __nv_drm_unload(struct drm_device *dev)
|
||||
|
||||
drm_kms_helper_poll_fini(dev);
|
||||
|
||||
nv_kthread_q_stop(&nv_dev->nv_kthread_q);
|
||||
|
||||
/* Clean up mode configuration */
|
||||
|
||||
drm_mode_config_cleanup(dev);
|
||||
@@ -596,7 +913,12 @@ static int __nv_drm_master_set(struct drm_device *dev,
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
|
||||
if (!nvKms->grabOwnership(nv_dev->pDevice)) {
|
||||
/*
|
||||
* If this device is driving a framebuffer, then nvidia-drm already has
|
||||
* modeset ownership. Otherwise, grab ownership now.
|
||||
*/
|
||||
if (!nv_dev->hasFramebufferConsole &&
|
||||
!nvKms->grabOwnership(nv_dev->pDevice)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -619,6 +941,62 @@ static void nv_drm_master_set(struct drm_device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
int nv_drm_reset_input_colorspace(struct drm_device *dev)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_plane_state *plane_state;
|
||||
struct drm_plane *plane;
|
||||
struct nv_drm_plane_state *nv_drm_plane_state;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
int ret = 0;
|
||||
bool do_reset = false;
|
||||
NvU32 flags = 0;
|
||||
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
#if defined(DRM_MODESET_ACQUIRE_INTERRUPTIBLE)
|
||||
flags |= DRM_MODESET_ACQUIRE_INTERRUPTIBLE;
|
||||
#endif
|
||||
drm_modeset_acquire_init(&ctx, flags);
|
||||
state->acquire_ctx = &ctx;
|
||||
|
||||
nv_drm_for_each_plane(plane, dev) {
|
||||
plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
if (IS_ERR(plane_state)) {
|
||||
ret = PTR_ERR(plane_state);
|
||||
goto out;
|
||||
}
|
||||
|
||||
nv_drm_plane_state = to_nv_drm_plane_state(plane_state);
|
||||
if (nv_drm_plane_state) {
|
||||
if (nv_drm_plane_state->input_colorspace != NVKMS_INPUT_COLORSPACE_NONE) {
|
||||
nv_drm_plane_state->input_colorspace = NVKMS_INPUT_COLORSPACE_NONE;
|
||||
do_reset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_reset) {
|
||||
ret = drm_atomic_commit(state);
|
||||
}
|
||||
|
||||
out:
|
||||
#if defined(NV_DRM_ATOMIC_STATE_REF_COUNTING_PRESENT)
|
||||
drm_atomic_state_put(state);
|
||||
#else
|
||||
// In case of success, drm_atomic_commit() takes care to cleanup and free state.
|
||||
if (ret != 0) {
|
||||
drm_atomic_state_free(state);
|
||||
}
|
||||
#endif
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_MASTER_DROP_HAS_FROM_RELEASE_ARG)
|
||||
static
|
||||
@@ -630,33 +1008,45 @@ void nv_drm_master_drop(struct drm_device *dev, struct drm_file *file_priv)
|
||||
#endif
|
||||
{
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
int err;
|
||||
|
||||
/*
|
||||
* After dropping nvkms modeset onwership, it is not guaranteed that
|
||||
* drm and nvkms modeset state will remain in sync. Therefore, disable
|
||||
* all outputs and crtcs before dropping nvkms modeset ownership.
|
||||
*
|
||||
* First disable all active outputs atomically and then disable each crtc one
|
||||
* by one, there is not helper function available to disable all crtcs
|
||||
* atomically.
|
||||
*/
|
||||
nv_drm_revoke_modeset_permission(dev, file_priv, 0);
|
||||
nv_drm_revoke_sub_ownership(dev);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
if (!nv_dev->hasFramebufferConsole) {
|
||||
int err;
|
||||
|
||||
if ((err = nv_drm_atomic_helper_disable_all(
|
||||
dev,
|
||||
dev->mode_config.acquire_ctx)) != 0) {
|
||||
/*
|
||||
* After dropping nvkms modeset onwership, it is not guaranteed that drm
|
||||
* and nvkms modeset state will remain in sync. Therefore, disable all
|
||||
* outputs and crtcs before dropping nvkms modeset ownership.
|
||||
*
|
||||
* First disable all active outputs atomically and then disable each
|
||||
* crtc one by one, there is not helper function available to disable
|
||||
* all crtcs atomically.
|
||||
*/
|
||||
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"nv_drm_atomic_helper_disable_all failed with error code %d !",
|
||||
err);
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
if ((err = nv_drm_atomic_helper_disable_all(
|
||||
dev,
|
||||
dev->mode_config.acquire_ctx)) != 0) {
|
||||
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"nv_drm_atomic_helper_disable_all failed with error code %d !",
|
||||
err);
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
nvKms->releaseOwnership(nv_dev->pDevice);
|
||||
} else {
|
||||
int err = nv_drm_reset_input_colorspace(dev);
|
||||
if (err != 0) {
|
||||
NV_DRM_DEV_LOG_WARN(nv_dev,
|
||||
"nv_drm_reset_input_colorspace failed with error code: %d !", err);
|
||||
}
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
nvKms->releaseOwnership(nv_dev->pDevice);
|
||||
}
|
||||
#endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
|
||||
|
||||
@@ -840,10 +1230,10 @@ static NvU32 nv_drm_get_head_bit_from_connector(struct drm_connector *connector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_drm_grant_permission_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filep)
|
||||
static int nv_drm_grant_modeset_permission(struct drm_device *dev,
|
||||
struct drm_nvidia_grant_permissions_params *params,
|
||||
struct drm_file *filep)
|
||||
{
|
||||
struct drm_nvidia_grant_permissions_params *params = data;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
struct nv_drm_connector *target_nv_connector = NULL;
|
||||
struct nv_drm_crtc *target_nv_crtc = NULL;
|
||||
@@ -965,6 +1355,67 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nv_drm_grant_sub_ownership(struct drm_device *dev,
|
||||
struct drm_nvidia_grant_permissions_params *params)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
struct drm_modeset_acquire_ctx *pctx;
|
||||
#if NV_DRM_MODESET_LOCK_ALL_END_ARGUMENT_COUNT == 3
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE,
|
||||
ret);
|
||||
pctx = &ctx;
|
||||
#else
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
pctx = dev->mode_config.acquire_ctx;
|
||||
#endif
|
||||
|
||||
if (nv_dev->subOwnershipGranted ||
|
||||
!nvKms->grantSubOwnership(params->fd, nv_dev->pDevice)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* When creating an ownership grant, shut down all heads and disable flip
|
||||
* notifications.
|
||||
*/
|
||||
ret = nv_drm_atomic_helper_disable_all(dev, pctx);
|
||||
if (ret != 0) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"nv_drm_atomic_helper_disable_all failed with error code %d!",
|
||||
ret);
|
||||
}
|
||||
|
||||
atomic_set(&nv_dev->enable_event_handling, false);
|
||||
nv_dev->subOwnershipGranted = NV_TRUE;
|
||||
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
#if NV_DRM_MODESET_LOCK_ALL_END_ARGUMENT_COUNT == 3
|
||||
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
|
||||
#else
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_drm_grant_permission_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filep)
|
||||
{
|
||||
struct drm_nvidia_grant_permissions_params *params = data;
|
||||
|
||||
if (params->type == NV_DRM_PERMISSIONS_TYPE_MODESET) {
|
||||
return nv_drm_grant_modeset_permission(dev, params, filep);
|
||||
} else if (params->type == NV_DRM_PERMISSIONS_TYPE_SUB_OWNER) {
|
||||
return nv_drm_grant_sub_ownership(dev, params);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static bool nv_drm_revoke_connector(struct nv_drm_device *nv_dev,
|
||||
struct nv_drm_connector *nv_connector)
|
||||
{
|
||||
@@ -982,8 +1433,8 @@ static bool nv_drm_revoke_connector(struct nv_drm_device *nv_dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nv_drm_revoke_permission(struct drm_device *dev,
|
||||
struct drm_file *filep, NvU32 dpyId)
|
||||
static int nv_drm_revoke_modeset_permission(struct drm_device *dev,
|
||||
struct drm_file *filep, NvU32 dpyId)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc;
|
||||
@@ -1036,14 +1487,55 @@ static int nv_drm_revoke_permission(struct drm_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nv_drm_revoke_sub_ownership(struct drm_device *dev)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
#if NV_DRM_MODESET_LOCK_ALL_END_ARGUMENT_COUNT == 3
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE,
|
||||
ret);
|
||||
#else
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
#endif
|
||||
|
||||
if (!nv_dev->subOwnershipGranted) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!nvKms->revokeSubOwnership(nv_dev->pDevice)) {
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to revoke sub-ownership from NVKMS");
|
||||
goto done;
|
||||
}
|
||||
|
||||
nv_dev->subOwnershipGranted = NV_FALSE;
|
||||
atomic_set(&nv_dev->enable_event_handling, true);
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
#if NV_DRM_MODESET_LOCK_ALL_END_ARGUMENT_COUNT == 3
|
||||
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
|
||||
#else
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nv_drm_revoke_permission_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filep)
|
||||
{
|
||||
struct drm_nvidia_revoke_permissions_params *params = data;
|
||||
if (!params->dpyId) {
|
||||
return -EINVAL;
|
||||
|
||||
if (params->type == NV_DRM_PERMISSIONS_TYPE_MODESET) {
|
||||
if (!params->dpyId) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return nv_drm_revoke_modeset_permission(dev, filep, params->dpyId);
|
||||
} else if (params->type == NV_DRM_PERMISSIONS_TYPE_SUB_OWNER) {
|
||||
return nv_drm_revoke_sub_ownership(dev);
|
||||
}
|
||||
return nv_drm_revoke_permission(dev, filep, params->dpyId);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void nv_drm_postclose(struct drm_device *dev, struct drm_file *filep)
|
||||
@@ -1058,7 +1550,7 @@ static void nv_drm_postclose(struct drm_device *dev, struct drm_file *filep)
|
||||
dev->mode_config.num_connector > 0 &&
|
||||
dev->mode_config.connector_list.next != NULL &&
|
||||
dev->mode_config.connector_list.prev != NULL) {
|
||||
nv_drm_revoke_permission(dev, filep, 0);
|
||||
nv_drm_revoke_modeset_permission(dev, filep, 0);
|
||||
}
|
||||
}
|
||||
#endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
|
||||
@@ -1288,6 +1780,10 @@ static const struct file_operations nv_drm_fops = {
|
||||
.read = drm_read,
|
||||
|
||||
.llseek = noop_llseek,
|
||||
|
||||
#if defined(FOP_UNSIGNED_OFFSET)
|
||||
.fop_flags = FOP_UNSIGNED_OFFSET,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct drm_ioctl_desc nv_drm_ioctls[] = {
|
||||
@@ -1495,6 +1991,7 @@ static void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
||||
struct nv_drm_device *nv_dev = NULL;
|
||||
struct drm_device *dev = NULL;
|
||||
struct device *device = gpu_info->os_device_ptr;
|
||||
bool bus_is_pci;
|
||||
|
||||
DRM_DEBUG(
|
||||
"Registering device for NVIDIA GPU ID 0x08%x",
|
||||
@@ -1528,8 +2025,15 @@ static void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
||||
dev->dev_private = nv_dev;
|
||||
nv_dev->dev = dev;
|
||||
|
||||
bus_is_pci =
|
||||
#if defined(NV_LINUX)
|
||||
device->bus == &pci_bus_type;
|
||||
#elif defined(NV_BSD)
|
||||
devclass_find("pci");
|
||||
#endif
|
||||
|
||||
#if defined(NV_DRM_DEVICE_HAS_PDEV)
|
||||
if (device->bus == &pci_bus_type) {
|
||||
if (bus_is_pci) {
|
||||
dev->pdev = to_pci_dev(device);
|
||||
}
|
||||
#endif
|
||||
@@ -1541,6 +2045,42 @@ static void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
||||
goto failed_drm_register;
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
if (nv_drm_fbdev_module_param &&
|
||||
drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
|
||||
if (bus_is_pci) {
|
||||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
|
||||
#if defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_HAS_DRIVER_ARG)
|
||||
drm_aperture_remove_conflicting_pci_framebuffers(pdev, &nv_drm_driver);
|
||||
#else
|
||||
drm_aperture_remove_conflicting_pci_framebuffers(pdev, nv_drm_driver.name);
|
||||
#endif
|
||||
} else {
|
||||
struct NvKmsKapiVtFbParams params;
|
||||
resource_size_t base, size = 0;
|
||||
|
||||
if (nvKms->getVtFbInfo(nv_dev->pDevice, ¶ms)) {
|
||||
|
||||
base = (resource_size_t) params.baseAddress;
|
||||
size = (resource_size_t) params.size;
|
||||
|
||||
#if defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_FRAMEBUFFERS_HAS_DRIVER_ARG)
|
||||
drm_aperture_remove_conflicting_framebuffers(base, size, false, &nv_drm_driver);
|
||||
#elif defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_FRAMEBUFFERS_HAS_NO_PRIMARY_ARG)
|
||||
drm_aperture_remove_conflicting_framebuffers(base, size, &nv_drm_driver);
|
||||
#else
|
||||
drm_aperture_remove_conflicting_framebuffers(base, size, false, nv_drm_driver.name);
|
||||
#endif
|
||||
} else {
|
||||
NV_DRM_DEV_LOG_WARN(nv_dev, "Failed to get framebuffer console info");
|
||||
}
|
||||
}
|
||||
drm_fbdev_generic_setup(dev, 32);
|
||||
}
|
||||
#endif /* defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) */
|
||||
|
||||
/* Add NVIDIA-DRM device into list */
|
||||
|
||||
nv_dev->next = dev_list;
|
||||
@@ -1610,9 +2150,10 @@ void nv_drm_remove_devices(void)
|
||||
{
|
||||
while (dev_list != NULL) {
|
||||
struct nv_drm_device *next = dev_list->next;
|
||||
struct drm_device *dev = dev_list->dev;
|
||||
|
||||
drm_dev_unregister(dev_list->dev);
|
||||
nv_drm_dev_free(dev_list->dev);
|
||||
drm_dev_unregister(dev);
|
||||
nv_drm_dev_free(dev);
|
||||
|
||||
nv_drm_free(dev_list);
|
||||
|
||||
@@ -1620,4 +2161,79 @@ void nv_drm_remove_devices(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle system suspend and resume.
|
||||
*
|
||||
* Normally, a DRM driver would use drm_mode_config_helper_suspend() to save the
|
||||
* current state on suspend and drm_mode_config_helper_resume() to restore it
|
||||
* after resume. This works for upstream drivers because user-mode tasks are
|
||||
* frozen before the suspend hook is called.
|
||||
*
|
||||
* In the case of nvidia-drm, the suspend hook is also called when 'suspend' is
|
||||
* written to /proc/driver/nvidia/suspend, before user-mode tasks are frozen.
|
||||
* However, we don't actually need to save and restore the display state because
|
||||
* the driver requires a VT switch to an unused VT before suspending and a
|
||||
* switch back to the application (or fbdev console) on resume. The DRM client
|
||||
* (or fbdev helper functions) will restore the appropriate mode on resume.
|
||||
*
|
||||
*/
|
||||
void nv_drm_suspend_resume(NvBool suspend)
|
||||
{
|
||||
static DEFINE_MUTEX(nv_drm_suspend_mutex);
|
||||
static NvU32 nv_drm_suspend_count = 0;
|
||||
struct nv_drm_device *nv_dev;
|
||||
|
||||
mutex_lock(&nv_drm_suspend_mutex);
|
||||
|
||||
/*
|
||||
* Count the number of times the driver is asked to suspend. Suspend all DRM
|
||||
* devices on the first suspend call and resume them on the last resume
|
||||
* call. This is necessary because the kernel may call nvkms_suspend()
|
||||
* simultaneously for each GPU, but NVKMS itself also suspends all GPUs on
|
||||
* the first call.
|
||||
*/
|
||||
if (suspend) {
|
||||
if (nv_drm_suspend_count++ > 0) {
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
BUG_ON(nv_drm_suspend_count == 0);
|
||||
|
||||
if (--nv_drm_suspend_count > 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
nv_dev = dev_list;
|
||||
|
||||
/*
|
||||
* NVKMS shuts down all heads on suspend. Update DRM state accordingly.
|
||||
*/
|
||||
for (nv_dev = dev_list; nv_dev; nv_dev = nv_dev->next) {
|
||||
struct drm_device *dev = nv_dev->dev;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (suspend) {
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
|
||||
#endif
|
||||
drm_mode_config_reset(dev);
|
||||
} else {
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
|
||||
#endif
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
}
|
||||
}
|
||||
#endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
|
||||
|
||||
done:
|
||||
mutex_unlock(&nv_drm_suspend_mutex);
|
||||
}
|
||||
|
||||
#endif /* NV_DRM_AVAILABLE */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define __NVIDIA_DRM_DRV_H__
|
||||
|
||||
#include "nvidia-drm-conftest.h"
|
||||
#include "nv-kthread-q.h"
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
@@ -31,6 +32,8 @@ int nv_drm_probe_devices(void);
|
||||
|
||||
void nv_drm_remove_devices(void);
|
||||
|
||||
void nv_drm_suspend_resume(NvBool suspend);
|
||||
|
||||
#endif /* defined(NV_DRM_AVAILABLE) */
|
||||
|
||||
#endif /* __NVIDIA_DRM_DRV_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -300,7 +300,48 @@ void nv_drm_handle_display_change(struct nv_drm_device *nv_dev,
|
||||
|
||||
nv_drm_connector_mark_connection_status_dirty(nv_encoder->nv_connector);
|
||||
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
schedule_delayed_work(&nv_dev->hotplug_event_work, 0);
|
||||
}
|
||||
|
||||
void nv_drm_handle_display_cp_change(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay,
|
||||
enum NvKmsContentProtection cp)
|
||||
{
|
||||
struct drm_device *dev = nv_dev->dev;
|
||||
struct nv_drm_encoder *nv_encoder = NULL;
|
||||
|
||||
nv_encoder = get_nv_encoder_from_nvkms_display(dev, hDisplay);
|
||||
if (nv_encoder == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
nv_encoder->nv_connector->cp = cp;
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
nv_drm_connector_update_content_protection(nv_encoder->nv_connector);
|
||||
}
|
||||
|
||||
void nv_drm_handle_display_cp_topology_change(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay,
|
||||
struct NvKmsHdcpTopology *topology)
|
||||
{
|
||||
struct drm_device *dev = nv_dev->dev;
|
||||
struct nv_drm_encoder *nv_encoder = NULL;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
nv_encoder = get_nv_encoder_from_nvkms_display(dev, hDisplay);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (nv_encoder == NULL) {
|
||||
NV_DRM_DEV_LOG_ERR(nv_dev, "Encoder not found for display %d", hDisplay);
|
||||
return;
|
||||
}
|
||||
nv_drm_connector_update_topology_property(nv_encoder->nv_connector, topology);
|
||||
}
|
||||
|
||||
void nv_drm_handle_dynamic_display_connected(struct nv_drm_device *nv_dev,
|
||||
@@ -319,7 +360,7 @@ void nv_drm_handle_dynamic_display_connected(struct nv_drm_device *nv_dev,
|
||||
nv_encoder = get_nv_encoder_from_nvkms_display(dev, hDisplay);
|
||||
|
||||
if (nv_encoder != NULL) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
NV_DRM_DEV_LOG_INFO(
|
||||
nv_dev,
|
||||
"Encoder with NvKmsKapiDisplay 0x%08x already exists.",
|
||||
hDisplay);
|
||||
@@ -347,6 +388,6 @@ void nv_drm_handle_dynamic_display_connected(struct nv_drm_device *nv_dev,
|
||||
drm_reinit_primary_mode_group(dev);
|
||||
#endif
|
||||
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
schedule_delayed_work(&nv_dev->hotplug_event_work, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -60,6 +60,14 @@ nv_drm_add_encoder(struct drm_device *dev, NvKmsKapiDisplay hDisplay);
|
||||
void nv_drm_handle_display_change(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay);
|
||||
|
||||
void nv_drm_handle_display_cp_change(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay,
|
||||
enum NvKmsContentProtection cp);
|
||||
|
||||
void nv_drm_handle_display_cp_topology_change(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay,
|
||||
struct NvKmsHdcpTopology *topology);
|
||||
|
||||
void nv_drm_handle_dynamic_display_connected(struct nv_drm_device *nv_dev,
|
||||
NvKmsKapiDisplay hDisplay);
|
||||
|
||||
|
||||
@@ -180,7 +180,35 @@ static void *__nv_drm_gem_nvkms_prime_vmap(
|
||||
}
|
||||
}
|
||||
|
||||
return nv_nvkms_memory->pWriteCombinedIORemapAddress;
|
||||
if (nv_nvkms_memory->physically_mapped) {
|
||||
return nv_nvkms_memory->pWriteCombinedIORemapAddress;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this buffer isn't physically mapped, it might be backed by struct
|
||||
* pages. Use vmap in that case. Do a noncached mapping for system memory
|
||||
* as display is non io-coherent device in case of Tegra.
|
||||
*/
|
||||
if (nv_nvkms_memory->pages_count > 0) {
|
||||
return nv_drm_vmap(nv_nvkms_memory->pages,
|
||||
nv_nvkms_memory->pages_count,
|
||||
false);
|
||||
}
|
||||
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
static void __nv_drm_gem_nvkms_prime_vunmap(
|
||||
struct nv_drm_gem_object *nv_gem,
|
||||
void *address)
|
||||
{
|
||||
struct nv_drm_gem_nvkms_memory *nv_nvkms_memory =
|
||||
to_nv_nvkms_memory(nv_gem);
|
||||
|
||||
if (!nv_nvkms_memory->physically_mapped &&
|
||||
nv_nvkms_memory->pages_count > 0) {
|
||||
nv_drm_vunmap(address);
|
||||
}
|
||||
}
|
||||
|
||||
static int __nv_drm_gem_map_nvkms_memory_offset(
|
||||
@@ -228,6 +256,7 @@ const struct nv_drm_gem_object_funcs nv_gem_nvkms_memory_ops = {
|
||||
.free = __nv_drm_gem_nvkms_memory_free,
|
||||
.prime_dup = __nv_drm_gem_nvkms_prime_dup,
|
||||
.prime_vmap = __nv_drm_gem_nvkms_prime_vmap,
|
||||
.prime_vunmap = __nv_drm_gem_nvkms_prime_vunmap,
|
||||
.mmap = __nv_drm_gem_nvkms_mmap,
|
||||
.handle_vma_fault = __nv_drm_gem_nvkms_handle_vma_fault,
|
||||
.create_mmap_offset = __nv_drm_gem_map_nvkms_memory_offset,
|
||||
|
||||
@@ -64,7 +64,8 @@ static void *__nv_drm_gem_user_memory_prime_vmap(
|
||||
struct nv_drm_gem_user_memory *nv_user_memory = to_nv_user_memory(nv_gem);
|
||||
|
||||
return nv_drm_vmap(nv_user_memory->pages,
|
||||
nv_user_memory->pages_count);
|
||||
nv_user_memory->pages_count,
|
||||
true);
|
||||
}
|
||||
|
||||
static void __nv_drm_gem_user_memory_prime_vunmap(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016 - 2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -306,6 +306,36 @@ int nv_drm_atomic_helper_disable_all(struct drm_device *dev,
|
||||
for_each_plane_in_state(__state, plane, plane_state, __i)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* for_each_new_plane_in_state() was added by kernel commit
|
||||
* 581e49fe6b411f407102a7f2377648849e0fa37f which was Signed-off-by:
|
||||
* Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
|
||||
* Daniel Vetter <daniel.vetter@ffwll.ch>
|
||||
*
|
||||
* This commit also added the old_state and new_state pointers to
|
||||
* __drm_planes_state. Because of this, the best that can be done on kernel
|
||||
* versions without this macro is for_each_plane_in_state.
|
||||
*/
|
||||
|
||||
/**
|
||||
* nv_drm_for_each_new_plane_in_state - iterate over all planes in an atomic update
|
||||
* @__state: &struct drm_atomic_state pointer
|
||||
* @plane: &struct drm_plane iteration cursor
|
||||
* @new_plane_state: &struct drm_plane_state iteration cursor for the new state
|
||||
* @__i: int iteration cursor, for macro-internal use
|
||||
*
|
||||
* This iterates over all planes in an atomic update, tracking only the new
|
||||
* state. This is useful in enable functions, where we need the new state the
|
||||
* hardware should be in when the atomic commit operation has completed.
|
||||
*/
|
||||
#if !defined(for_each_new_plane_in_state)
|
||||
#define nv_drm_for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \
|
||||
nv_drm_for_each_plane_in_state(__state, plane, new_plane_state, __i)
|
||||
#else
|
||||
#define nv_drm_for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \
|
||||
for_each_new_plane_in_state(__state, plane, new_plane_state, __i)
|
||||
#endif
|
||||
|
||||
static inline struct drm_connector *
|
||||
nv_drm_connector_lookup(struct drm_device *dev, struct drm_file *filep,
|
||||
uint32_t id)
|
||||
|
||||
@@ -289,13 +289,20 @@ struct drm_nvidia_get_connector_id_for_dpy_id_params {
|
||||
uint32_t connectorId; /* OUT */
|
||||
};
|
||||
|
||||
enum drm_nvidia_permissions_type {
|
||||
NV_DRM_PERMISSIONS_TYPE_MODESET = 2,
|
||||
NV_DRM_PERMISSIONS_TYPE_SUB_OWNER = 3
|
||||
};
|
||||
|
||||
struct drm_nvidia_grant_permissions_params {
|
||||
int32_t fd; /* IN */
|
||||
uint32_t dpyId; /* IN */
|
||||
uint32_t type; /* IN */
|
||||
};
|
||||
|
||||
struct drm_nvidia_revoke_permissions_params {
|
||||
uint32_t dpyId; /* IN */
|
||||
uint32_t type; /* IN */
|
||||
};
|
||||
|
||||
struct drm_nvidia_semsurf_fence_ctx_create_params {
|
||||
|
||||
@@ -51,6 +51,14 @@ MODULE_PARM_DESC(
|
||||
bool nv_drm_modeset_module_param = false;
|
||||
module_param_named(modeset, nv_drm_modeset_module_param, bool, 0400);
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
MODULE_PARM_DESC(
|
||||
fbdev,
|
||||
"Create a framebuffer device (1 = enable, 0 = disable (default)) (EXPERIMENTAL)");
|
||||
bool nv_drm_fbdev_module_param = false;
|
||||
module_param_named(fbdev, nv_drm_fbdev_module_param, bool, 0400);
|
||||
#endif
|
||||
|
||||
void *nv_drm_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
size_t total_size = nmemb * size;
|
||||
@@ -156,9 +164,15 @@ void nv_drm_unlock_user_pages(unsigned long pages_count, struct page **pages)
|
||||
nv_drm_free(pages);
|
||||
}
|
||||
|
||||
void *nv_drm_vmap(struct page **pages, unsigned long pages_count)
|
||||
void *nv_drm_vmap(struct page **pages, unsigned long pages_count, bool cached)
|
||||
{
|
||||
return vmap(pages, pages_count, VM_USERMAP, PAGE_KERNEL);
|
||||
pgprot_t prot = PAGE_KERNEL;
|
||||
|
||||
if (!cached) {
|
||||
prot = pgprot_noncached(PAGE_KERNEL);
|
||||
}
|
||||
|
||||
return vmap(pages, pages_count, VM_USERMAP, prot);
|
||||
}
|
||||
|
||||
void nv_drm_vunmap(void *address)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015 - 2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "nvidia-drm-priv.h"
|
||||
#include "nvidia-drm-modeset.h"
|
||||
#include "nvidia-drm-connector.h"
|
||||
#include "nvidia-drm-crtc.h"
|
||||
#include "nvidia-drm-os-interface.h"
|
||||
#include "nvidia-drm-helper.h"
|
||||
@@ -85,28 +86,32 @@ void nv_drm_atomic_state_free(struct drm_atomic_state *state)
|
||||
* function is called after drm_atomic_helper_swap_state(), therefore new state
|
||||
* is swapped into current state.
|
||||
*/
|
||||
static bool __will_generate_flip_event(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
static void __get_events_plane_mask(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state,
|
||||
unsigned int *plane_mask,
|
||||
unsigned int *pending_events_plane_mask)
|
||||
{
|
||||
struct drm_crtc_state *new_crtc_state = crtc->state;
|
||||
struct nv_drm_crtc_state *nv_new_crtc_state =
|
||||
to_nv_crtc_state(new_crtc_state);
|
||||
struct drm_plane_state *old_plane_state = NULL;
|
||||
struct drm_plane *plane = NULL;
|
||||
int i;
|
||||
|
||||
*plane_mask = 0x0;
|
||||
*pending_events_plane_mask = 0x0;
|
||||
|
||||
if (!old_crtc_state->active && !new_crtc_state->active) {
|
||||
/*
|
||||
* crtc is not active in old and new states therefore all planes are
|
||||
* disabled, hardware can not generate flip events.
|
||||
*/
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find out whether primary & overlay flip done events will be generated. */
|
||||
nv_drm_for_each_plane_in_state(old_crtc_state->state,
|
||||
plane, old_plane_state, i) {
|
||||
if (old_plane_state->crtc != crtc) {
|
||||
if ((old_plane_state->crtc != crtc) &&
|
||||
(plane->state->crtc != crtc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -114,16 +119,16 @@ static bool __will_generate_flip_event(struct drm_crtc *crtc,
|
||||
continue;
|
||||
}
|
||||
|
||||
*plane_mask |= NVBIT(plane->index);
|
||||
|
||||
/*
|
||||
* Hardware generates flip event for only those
|
||||
* planes which were active previously.
|
||||
*/
|
||||
if (old_crtc_state->active && old_plane_state->fb != NULL) {
|
||||
nv_new_crtc_state->nv_flip->pending_events++;
|
||||
*pending_events_plane_mask |= NVBIT(plane->index);
|
||||
}
|
||||
}
|
||||
|
||||
return nv_new_crtc_state->nv_flip->pending_events != 0;
|
||||
}
|
||||
|
||||
static int __nv_drm_put_back_post_fence_fd(
|
||||
@@ -237,6 +242,14 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If sub-owner permission was granted to another NVKMS client, disallow
|
||||
* modesets through the DRM interface.
|
||||
*/
|
||||
if (nv_dev->subOwnershipGranted) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(requested_config, 0, sizeof(*requested_config));
|
||||
|
||||
/* Loop over affected crtcs and construct NvKmsKapiRequestedModeSetConfig */
|
||||
@@ -260,23 +273,35 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
|
||||
struct nv_drm_crtc_state *nv_new_crtc_state =
|
||||
to_nv_crtc_state(new_crtc_state);
|
||||
|
||||
if (!old_crtc_state->active && new_crtc_state->active) {
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
nv_new_crtc_state->nv_flip->event = new_crtc_state->event;
|
||||
nv_new_crtc_state->nv_flip->pending_events = 0;
|
||||
new_crtc_state->event = NULL;
|
||||
|
||||
/*
|
||||
* If flip event will be generated by hardware
|
||||
* then defer flip object processing to flip event from hardware.
|
||||
*/
|
||||
if (__will_generate_flip_event(crtc, old_crtc_state)) {
|
||||
nv_drm_crtc_enqueue_flip(nv_crtc,
|
||||
nv_new_crtc_state->nv_flip);
|
||||
__get_events_plane_mask(crtc, old_crtc_state,
|
||||
&nv_new_crtc_state->nv_flip->plane_mask,
|
||||
&nv_new_crtc_state->nv_flip->pending_events_plane_mask);
|
||||
|
||||
nv_new_crtc_state->nv_flip = NULL;
|
||||
if (nv_new_crtc_state->nv_flip->event != NULL) {
|
||||
drm_crtc_vblank_get(crtc);
|
||||
}
|
||||
nv_drm_crtc_enqueue_flip(nv_crtc,
|
||||
nv_new_crtc_state->nv_flip);
|
||||
nv_new_crtc_state->nv_flip = NULL;
|
||||
|
||||
#if defined(NV_DRM_CRTC_STATE_HAS_VRR_ENABLED)
|
||||
requested_config->headRequestedConfig[nv_crtc->head].modeSetConfig.vrrEnabled = new_crtc_state->vrr_enabled;
|
||||
#endif
|
||||
|
||||
if (new_crtc_state->mode_changed) {
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)];
|
||||
|
||||
spin_lock_irq(&dev->vbl_lock);
|
||||
vblank->inmodeset = 0x2;
|
||||
spin_unlock_irq(&dev->vbl_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,6 +311,8 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
|
||||
* to be presented.
|
||||
*/
|
||||
nv_drm_write_combine_flush();
|
||||
|
||||
nv_kthread_q_flush(&nv_dev->nv_kthread_q);
|
||||
}
|
||||
|
||||
if (!nvKms->applyModeSetConfig(nv_dev->pDevice,
|
||||
@@ -295,6 +322,34 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct drm_crtc_state *new_crtc_state = crtc->state;
|
||||
struct drm_crtc_state *old_crtc_state = crtc_state;
|
||||
|
||||
if (new_crtc_state->mode_changed) {
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)];
|
||||
|
||||
spin_lock_irq(&dev->vbl_lock);
|
||||
vblank->inmodeset = 0x0;
|
||||
spin_unlock_irq(&dev->vbl_lock);
|
||||
}
|
||||
|
||||
if (old_crtc_state->active && !new_crtc_state->active) {
|
||||
drm_crtc_vblank_off(crtc);
|
||||
}
|
||||
|
||||
}
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *connector_state;
|
||||
int j;
|
||||
nv_drm_for_each_connector_in_state(state, connector, connector_state, j) {
|
||||
if (connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
nv_drm_connector_update_content_protection(to_nv_connector(connector));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (commit && nv_dev->supportsSyncpts) {
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
/*! loop over affected crtcs and get NvKmsKapiModeSetReplyConfig */
|
||||
@@ -314,6 +369,24 @@ int nv_drm_atomic_check(struct drm_device *dev,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#if defined(NV_DRM_COLOR_MGMT_AVAILABLE)
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int i;
|
||||
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
/*
|
||||
* if the color management changed on the crtc, we need to update the
|
||||
* crtc's plane's CSC matrices, so add the crtc's planes to the commit
|
||||
*/
|
||||
if (crtc_state->color_mgmt_changed) {
|
||||
if ((ret = drm_atomic_add_affected_planes(state, crtc)) != 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NV_DRM_COLOR_MGMT_AVAILABLE */
|
||||
|
||||
if ((ret = drm_atomic_helper_check(dev, state)) != 0) {
|
||||
goto done;
|
||||
}
|
||||
@@ -325,6 +398,43 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nv_drm_update_vblank_timestamp(struct nv_drm_crtc *nv_crtc)
|
||||
{
|
||||
/* If high-precision query is unsupported, DRM core resets vblank
|
||||
* timestamp to 0 to mark it invalid in drm_crtc_vblank_on. It's
|
||||
* possible that the initial event sending to userspace with 0
|
||||
* timestamp before 1st valid vblank timestamp updated by
|
||||
* drm_handle_vblank. Update timestamp for such case only.
|
||||
*/
|
||||
struct drm_crtc *crtc = &nv_crtc->base;
|
||||
if (!crtc->funcs->get_vblank_timestamp) {
|
||||
ktime_t t_vblank = 0;
|
||||
drm_crtc_vblank_count_and_time(crtc, &t_vblank);
|
||||
if (t_vblank == 0) {
|
||||
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
|
||||
|
||||
write_seqlock(&vblank->seqlock);
|
||||
vblank->time = ktime_get();
|
||||
write_sequnlock(&vblank->seqlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nv_drm_send_completion_event(struct nv_drm_crtc *nv_crtc,
|
||||
struct nv_drm_flip *nv_flip_pos)
|
||||
{
|
||||
WARN_ON(nv_flip_pos->pending_events_plane_mask);
|
||||
|
||||
if (nv_flip_pos->event != NULL) {
|
||||
nv_drm_update_vblank_timestamp(nv_crtc);
|
||||
drm_crtc_send_vblank_event(&nv_crtc->base, nv_flip_pos->event);
|
||||
drm_crtc_vblank_put(&nv_crtc->base);
|
||||
}
|
||||
|
||||
list_del(&nv_flip_pos->list_entry);
|
||||
nv_drm_free(nv_flip_pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* __nv_drm_handle_flip_event - handle flip occurred event
|
||||
* @nv_crtc: crtc on which flip has been occurred
|
||||
@@ -332,48 +442,71 @@ done:
|
||||
* This handler dequeues the first nv_drm_flip from the crtc's flip_list,
|
||||
* generates an event if requested at flip time, and frees the nv_drm_flip.
|
||||
*/
|
||||
static void __nv_drm_handle_flip_event(struct nv_drm_crtc *nv_crtc)
|
||||
void nv_drm_handle_flip_event(struct nv_drm_device *nv_dev, NvU32 head, NvU32 layer, bool process_pending)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = nv_drm_crtc_lookup(nv_dev, head);
|
||||
struct nv_drm_plane *nv_plane = nv_drm_plane_lookup(nv_dev, head, layer);
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
struct nv_drm_flip *nv_flip;
|
||||
struct nv_drm_flip *nv_flip_pos, *nv_flip_n;
|
||||
const uint32_t plane_mask = NVBIT(nv_plane->base.index);
|
||||
bool process_pending_crtc = true;
|
||||
|
||||
/*
|
||||
* Acquire event_lock before nv_flip object dequeue, otherwise immediate
|
||||
* flip event delivery from nv_drm_atomic_commit() races ahead and
|
||||
* messes up with event delivery order.
|
||||
*/
|
||||
spin_lock(&dev->event_lock);
|
||||
nv_flip = nv_drm_crtc_dequeue_flip(nv_crtc);
|
||||
if (likely(nv_flip != NULL)) {
|
||||
struct nv_drm_flip *nv_deferred_flip, *nv_next_deferred_flip;
|
||||
list_for_each_entry_safe(nv_flip_pos, nv_flip_n, &nv_crtc->flip_list, list_entry) {
|
||||
|
||||
if (nv_flip->event != NULL) {
|
||||
drm_crtc_send_vblank_event(&nv_crtc->base, nv_flip->event);
|
||||
if (!(nv_flip_pos->plane_mask & plane_mask)) {
|
||||
if (nv_flip_pos->plane_mask) {
|
||||
process_pending_crtc = false;
|
||||
}
|
||||
|
||||
if (process_pending_crtc && !nv_flip_pos->plane_mask) {
|
||||
nv_drm_send_completion_event(nv_crtc, nv_flip_pos);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process flips that were deferred until processing of this nv_flip
|
||||
* object.
|
||||
*/
|
||||
list_for_each_entry_safe(nv_deferred_flip,
|
||||
nv_next_deferred_flip,
|
||||
&nv_flip->deferred_flip_list, list_entry) {
|
||||
if (!process_pending && (nv_flip_pos->pending_events_plane_mask &
|
||||
plane_mask)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nv_deferred_flip->event != NULL) {
|
||||
drm_crtc_send_vblank_event(&nv_crtc->base,
|
||||
nv_deferred_flip->event);
|
||||
}
|
||||
list_del(&nv_deferred_flip->list_entry);
|
||||
if (nv_flip_pos->pending_events_plane_mask & plane_mask) {
|
||||
process_pending = false;
|
||||
}
|
||||
|
||||
nv_drm_free(nv_deferred_flip);
|
||||
nv_flip_pos->pending_events_plane_mask &= ~plane_mask;
|
||||
nv_flip_pos->plane_mask &= ~plane_mask;
|
||||
|
||||
if (!nv_flip_pos->plane_mask) {
|
||||
nv_drm_send_completion_event(nv_crtc, nv_flip_pos);
|
||||
} else {
|
||||
process_pending_crtc = false;
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev->event_lock);
|
||||
|
||||
wake_up_all(&nv_dev->flip_event_wq);
|
||||
wake_up(&nv_dev->flip_event_wq);
|
||||
|
||||
nv_drm_free(nv_flip);
|
||||
WARN_ON(process_pending);
|
||||
}
|
||||
|
||||
static void nv_drm_crtc_handle_completion_event(struct nv_drm_device *nv_dev, struct nv_drm_crtc *nv_crtc)
|
||||
{
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
struct nv_drm_flip *nv_flip_pos, *nv_flip_n;
|
||||
|
||||
spin_lock(&dev->event_lock);
|
||||
list_for_each_entry_safe(nv_flip_pos, nv_flip_n, &nv_crtc->flip_list, list_entry) {
|
||||
if (nv_flip_pos->plane_mask) {
|
||||
break;
|
||||
} else {
|
||||
nv_drm_send_completion_event(nv_crtc, nv_flip_pos);
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev->event_lock);
|
||||
|
||||
wake_up(&nv_dev->flip_event_wq);
|
||||
}
|
||||
|
||||
int nv_drm_atomic_commit(struct drm_device *dev,
|
||||
@@ -385,45 +518,61 @@ int nv_drm_atomic_commit(struct drm_device *dev,
|
||||
int i;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
struct drm_crtc_state *crtc_state = NULL;
|
||||
struct drm_plane *plane = NULL;
|
||||
struct drm_plane_state *plane_state = NULL;
|
||||
struct nv_drm_device *nv_dev = to_nv_device(dev);
|
||||
|
||||
/*
|
||||
* drm_mode_config_funcs::atomic_commit() mandates to return -EBUSY
|
||||
* for nonblocking commit if previous updates (commit tasks/flip event) are
|
||||
* pending. In case of blocking commits it mandates to wait for previous
|
||||
* updates to complete.
|
||||
* XXX: drm_mode_config_funcs::atomic_commit() mandates to return -EBUSY
|
||||
* for nonblocking commit if the commit would need to wait for previous
|
||||
* updates (commit tasks/flip event) to complete. In case of blocking
|
||||
* commits it mandates to wait for previous updates to complete. However,
|
||||
* the kernel DRM-KMS documentation does explicitly allow maintaining a
|
||||
* queue of outstanding commits.
|
||||
*
|
||||
* Our system already implements such a queue, but due to
|
||||
* bug 4054608, it is currently not used.
|
||||
*/
|
||||
if (nonblock) {
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
|
||||
/*
|
||||
* Here you aren't required to hold nv_drm_crtc::flip_list_lock
|
||||
* because:
|
||||
*
|
||||
* The core DRM driver acquires lock for all affected crtcs before
|
||||
* calling into ->commit() hook, therefore it is not possible for
|
||||
* other threads to call into ->commit() hook affecting same crtcs
|
||||
* and enqueue flip objects into flip_list -
|
||||
*
|
||||
* nv_drm_atomic_commit_internal()
|
||||
* |-> nv_drm_atomic_apply_modeset_config(commit=true)
|
||||
* |-> nv_drm_crtc_enqueue_flip()
|
||||
*
|
||||
* Only possibility is list_empty check races with code path
|
||||
* dequeuing flip object -
|
||||
*
|
||||
* __nv_drm_handle_flip_event()
|
||||
* |-> nv_drm_crtc_dequeue_flip()
|
||||
*
|
||||
* But this race condition can't lead list_empty() to return
|
||||
* incorrect result. nv_drm_crtc_dequeue_flip() in the middle of
|
||||
* updating the list could not trick us into thinking the list is
|
||||
* empty when it isn't.
|
||||
*/
|
||||
/*
|
||||
* Here you aren't required to hold nv_drm_crtc::flip_list_lock
|
||||
* because:
|
||||
*
|
||||
* The core DRM driver acquires lock for all affected crtcs before
|
||||
* calling into ->commit() hook, therefore it is not possible for
|
||||
* other threads to call into ->commit() hook affecting same crtcs
|
||||
* and enqueue flip objects into flip_list -
|
||||
*
|
||||
* nv_drm_atomic_commit_internal()
|
||||
* |-> nv_drm_atomic_apply_modeset_config(commit=true)
|
||||
* |-> nv_drm_crtc_enqueue_flip()
|
||||
*
|
||||
* Only possibility is list_empty check races with code path
|
||||
* dequeuing flip object -
|
||||
*
|
||||
* __nv_drm_handle_flip_event()
|
||||
* |-> nv_drm_crtc_dequeue_flip()
|
||||
*
|
||||
* But this race condition can't lead list_empty() to return
|
||||
* incorrect result. nv_drm_crtc_dequeue_flip() in the middle of
|
||||
* updating the list could not trick us into thinking the list is
|
||||
* empty when it isn't.
|
||||
*/
|
||||
if (nonblock) {
|
||||
if (!list_empty(&nv_crtc->flip_list)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
} else {
|
||||
if (wait_event_timeout(
|
||||
nv_dev->flip_event_wq,
|
||||
list_empty(&nv_crtc->flip_list),
|
||||
3 * HZ /* 3 second */) == 0) {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"Flip event timeout on head %u", nv_crtc->head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,52 +617,22 @@ int nv_drm_atomic_commit(struct drm_device *dev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
nv_drm_for_each_plane_in_state(state, plane, plane_state, i) {
|
||||
struct nv_drm_plane *nv_plane = to_nv_plane(plane);
|
||||
if (plane->type == DRM_PLANE_TYPE_CURSOR) {
|
||||
continue;
|
||||
}
|
||||
nv_drm_handle_flip_event(nv_dev, nv_plane->head,
|
||||
nv_plane->layer_idx, false);
|
||||
}
|
||||
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
struct nv_drm_crtc_state *nv_new_crtc_state =
|
||||
to_nv_crtc_state(crtc->state);
|
||||
nv_drm_crtc_handle_completion_event(nv_dev, nv_crtc);
|
||||
}
|
||||
|
||||
/*
|
||||
* If nv_drm_atomic_apply_modeset_config() hasn't consumed the flip
|
||||
* object, no event will be generated for this flip, and we need process
|
||||
* it:
|
||||
*/
|
||||
|
||||
if (nv_new_crtc_state->nv_flip != NULL) {
|
||||
/*
|
||||
* First, defer processing of all pending flips for this crtc until
|
||||
* last flip in the queue has been processed. This is to ensure a
|
||||
* correct order in event delivery.
|
||||
*/
|
||||
spin_lock(&nv_crtc->flip_list_lock);
|
||||
if (!list_empty(&nv_crtc->flip_list)) {
|
||||
struct nv_drm_flip *nv_last_flip =
|
||||
list_last_entry(&nv_crtc->flip_list,
|
||||
struct nv_drm_flip, list_entry);
|
||||
|
||||
list_add(&nv_new_crtc_state->nv_flip->list_entry,
|
||||
&nv_last_flip->deferred_flip_list);
|
||||
|
||||
nv_new_crtc_state->nv_flip = NULL;
|
||||
}
|
||||
spin_unlock(&nv_crtc->flip_list_lock);
|
||||
}
|
||||
|
||||
if (nv_new_crtc_state->nv_flip != NULL) {
|
||||
/*
|
||||
* Then, if no more pending flips for this crtc, deliver event for the
|
||||
* current flip.
|
||||
*/
|
||||
if (nv_new_crtc_state->nv_flip->event != NULL) {
|
||||
spin_lock(&dev->event_lock);
|
||||
drm_crtc_send_vblank_event(crtc,
|
||||
nv_new_crtc_state->nv_flip->event);
|
||||
spin_unlock(&dev->event_lock);
|
||||
}
|
||||
|
||||
nv_drm_free(nv_new_crtc_state->nv_flip);
|
||||
nv_new_crtc_state->nv_flip = NULL;
|
||||
}
|
||||
nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc);
|
||||
|
||||
if (!nonblock) {
|
||||
/*
|
||||
@@ -565,16 +684,4 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nv_drm_handle_flip_occurred(struct nv_drm_device *nv_dev,
|
||||
NvU32 head, NvU32 plane)
|
||||
{
|
||||
struct nv_drm_crtc *nv_crtc = nv_drm_crtc_lookup(nv_dev, head);
|
||||
|
||||
if (NV_DRM_WARN(nv_crtc == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
__nv_drm_handle_flip_event(nv_crtc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,9 +42,7 @@ int nv_drm_atomic_check(struct drm_device *dev,
|
||||
int nv_drm_atomic_commit(struct drm_device *dev,
|
||||
struct drm_atomic_state *state, bool nonblock);
|
||||
|
||||
|
||||
void nv_drm_handle_flip_occurred(struct nv_drm_device *nv_dev,
|
||||
NvU32 head, NvU32 plane);
|
||||
void nv_drm_handle_flip_event(struct nv_drm_device *nv_dev, NvU32 head, NvU32 layer, bool process_pending);
|
||||
|
||||
int nv_drm_shut_down_all_crtcs(struct drm_device *dev);
|
||||
|
||||
|
||||
@@ -58,10 +58,18 @@ typedef struct nv_timer nv_drm_timer;
|
||||
#error "Need to define kernel timer callback primitives for this OS"
|
||||
#endif /* else defined(NV_LINUX) */
|
||||
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_SETUP_PRESENT) && defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_PRESENT)
|
||||
#define NV_DRM_FBDEV_GENERIC_AVAILABLE
|
||||
#endif
|
||||
|
||||
struct page;
|
||||
|
||||
/* Set to true when the atomic modeset feature is enabled. */
|
||||
extern bool nv_drm_modeset_module_param;
|
||||
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
||||
/* Set to true when the nvidia-drm driver should install a framebuffer device */
|
||||
extern bool nv_drm_fbdev_module_param;
|
||||
#endif
|
||||
|
||||
void *nv_drm_calloc(size_t nmemb, size_t size);
|
||||
|
||||
@@ -76,7 +84,7 @@ int nv_drm_lock_user_pages(unsigned long address,
|
||||
|
||||
void nv_drm_unlock_user_pages(unsigned long pages_count, struct page **pages);
|
||||
|
||||
void *nv_drm_vmap(struct page **pages, unsigned long pages_count);
|
||||
void *nv_drm_vmap(struct page **pages, unsigned long pages_count, bool cached);
|
||||
|
||||
void nv_drm_vunmap(void *address);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2015-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -126,6 +126,7 @@ struct nv_drm_device {
|
||||
NvU64 modifiers[6 /* block linear */ + 1 /* linear */ + 1 /* terminator */];
|
||||
#endif
|
||||
|
||||
struct delayed_work hotplug_event_work;
|
||||
atomic_t enable_event_handling;
|
||||
|
||||
/**
|
||||
@@ -146,15 +147,22 @@ struct nv_drm_device {
|
||||
NvBool hasVideoMemory;
|
||||
|
||||
NvBool supportsSyncpts;
|
||||
NvBool subOwnershipGranted;
|
||||
NvBool hasFramebufferConsole;
|
||||
|
||||
struct drm_property *nv_out_fence_property;
|
||||
struct drm_property *nv_input_colorspace_property;
|
||||
|
||||
struct drm_property *nv_input_colorrange_property;
|
||||
struct drm_property *nv_output_colorrange_property;
|
||||
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
|
||||
struct drm_property *nv_hdr_output_metadata_property;
|
||||
#endif
|
||||
struct drm_property *nv_hdcp_topology_property;
|
||||
|
||||
struct nv_drm_device *next;
|
||||
|
||||
nv_kthread_q_t nv_kthread_q;
|
||||
};
|
||||
|
||||
static inline struct nv_drm_device *to_nv_device(
|
||||
|
||||
@@ -84,6 +84,12 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += list_is_first
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += timer_setup
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_fence_set_error
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += sync_file_get_fence
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_aperture_remove_conflicting_framebuffers
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_aperture_remove_conflicting_pci_framebuffers
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_fbdev_generic_setup
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_helper_crtc_enable_color_mgmt
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_crtc_enable_color_mgmt
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_sysfs_connector_property_event
|
||||
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_present
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_has_bus_type
|
||||
@@ -124,7 +130,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_atomic_check_has_atomic_state_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_gem_object_vmap_has_map_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_plane_atomic_check_has_atomic_state_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_device_has_pdev
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_state_has_no_vblank
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_config_has_allow_fb_modifiers
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_has_hdr_output_metadata
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_resv_add_fence
|
||||
@@ -140,3 +145,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_dumb_destroy
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += fence_ops_use_64bit_seqno
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_unlocked_ioctl_flag_present
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_aperture_remove_conflicting_framebuffers_has_driver_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_aperture_remove_conflicting_framebuffers_has_no_primary_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_aperture_remove_conflicting_pci_framebuffers_has_driver_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_create_dp_colorspace_property_has_supported_colorspaces_arg
|
||||
|
||||
@@ -45,6 +45,7 @@ int nv_drm_init(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nvKms->setSuspendResumeCallback(nv_drm_suspend_resume);
|
||||
return nv_drm_probe_devices();
|
||||
#else
|
||||
return 0;
|
||||
@@ -54,6 +55,7 @@ int nv_drm_init(void)
|
||||
void nv_drm_exit(void)
|
||||
{
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
nvKms->setSuspendResumeCallback(NULL);
|
||||
nv_drm_remove_devices();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -682,6 +682,8 @@ nvkms_event_queue_changed(nvkms_per_open_handle_t *pOpenKernel,
|
||||
|
||||
static void nvkms_suspend(NvU32 gpuId)
|
||||
{
|
||||
nvKmsKapiSuspendResume(NV_TRUE /* suspend */);
|
||||
|
||||
if (gpuId == 0) {
|
||||
nvkms_write_lock_pm_lock();
|
||||
}
|
||||
@@ -700,6 +702,8 @@ static void nvkms_resume(NvU32 gpuId)
|
||||
if (gpuId == 0) {
|
||||
nvkms_write_unlock_pm_lock();
|
||||
}
|
||||
|
||||
nvKmsKapiSuspendResume(NV_FALSE /* suspend */);
|
||||
}
|
||||
|
||||
|
||||
@@ -1452,6 +1456,26 @@ void nvkms_close_from_kapi(struct nvkms_per_open *popen)
|
||||
nvkms_close_pm_unlocked(popen);
|
||||
}
|
||||
|
||||
NvBool nvkms_ioctl_from_kapi_try_pmlock
|
||||
(
|
||||
struct nvkms_per_open *popen,
|
||||
NvU32 cmd, void *params_address, const size_t param_size
|
||||
)
|
||||
{
|
||||
NvBool ret;
|
||||
|
||||
if (nvkms_read_trylock_pm_lock()) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
ret = nvkms_ioctl_common(popen,
|
||||
cmd,
|
||||
(NvU64)(NvUPtr)params_address, param_size) == 0;
|
||||
nvkms_read_unlock_pm_lock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NvBool nvkms_ioctl_from_kapi
|
||||
(
|
||||
struct nvkms_per_open *popen,
|
||||
|
||||
@@ -329,6 +329,16 @@ NvBool nvkms_ioctl_from_kapi
|
||||
NvU32 cmd, void *params_address, const size_t params_size
|
||||
);
|
||||
|
||||
/*!
|
||||
* Like nvkms_ioctl_from_kapi, but return NV_FALSE instead of waiting if the
|
||||
* power management read lock cannot be acquired.
|
||||
*/
|
||||
NvBool nvkms_ioctl_from_kapi_try_pmlock
|
||||
(
|
||||
struct nvkms_per_open *popen,
|
||||
NvU32 cmd, void *params_address, const size_t params_size
|
||||
);
|
||||
|
||||
/*!
|
||||
* APIs for locking.
|
||||
*/
|
||||
|
||||
@@ -55,7 +55,7 @@ nvidia-modeset-y += $(NVIDIA_MODESET_BINARY_OBJECT_O)
|
||||
# Define nvidia-modeset.ko-specific CFLAGS.
|
||||
#
|
||||
|
||||
NVIDIA_MODESET_CFLAGS += -I$(src)/nvidia-modeset
|
||||
NVIDIA_MODESET_CFLAGS += -I$(src)/nvidia-modeset -I$(src)/common/inc
|
||||
NVIDIA_MODESET_CFLAGS += -UDEBUG -U_DEBUG -DNDEBUG -DNV_BUILD_MODULE_INSTANCES=0
|
||||
|
||||
$(call ASSIGN_PER_OBJ_CFLAGS, $(NVIDIA_MODESET_OBJECTS), $(NVIDIA_MODESET_CFLAGS))
|
||||
|
||||
@@ -66,6 +66,8 @@ enum NvKmsClientType {
|
||||
NVKMS_CLIENT_KERNEL_SPACE,
|
||||
};
|
||||
|
||||
struct NvKmsPerOpenDev;
|
||||
|
||||
NvBool nvKmsIoctl(
|
||||
void *pOpenVoid,
|
||||
NvU32 cmd,
|
||||
@@ -101,7 +103,11 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
struct NvKmsKapiFunctionsTable *funcsTable
|
||||
);
|
||||
|
||||
void nvKmsKapiSuspendResume(NvBool suspend);
|
||||
|
||||
NvBool nvKmsGetBacklight(NvU32 display_id, void *drv_priv, NvU32 *brightness);
|
||||
NvBool nvKmsSetBacklight(NvU32 display_id, void *drv_priv, NvU32 brightness);
|
||||
|
||||
NvBool nvKmsOpenDevHasSubOwnerPermissionOrBetter(const struct NvKmsPerOpenDev *pOpenDev);
|
||||
|
||||
#endif /* __NV_KMS_H__ */
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
#include "internal_crypt_lib.h"
|
||||
|
||||
#ifdef USE_LKCA
|
||||
#ifndef NV_CRYPTO_TFM_CTX_ALIGNED_PRESENT
|
||||
#include <crypto/internal/hash.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void *lkca_hash_new(const char* alg_name)
|
||||
{
|
||||
#ifndef USE_LKCA
|
||||
@@ -87,9 +93,24 @@ bool lkca_hmac_duplicate(struct shash_desc *dst, struct shash_desc const *src)
|
||||
|
||||
struct crypto_shash *src_tfm = src->tfm;
|
||||
struct crypto_shash *dst_tfm = dst->tfm;
|
||||
int ss = crypto_shash_statesize(dst_tfm);
|
||||
|
||||
#ifdef NV_CRYPTO_TFM_CTX_ALIGNED_PRESENT
|
||||
char *src_ipad = crypto_tfm_ctx_aligned(&src_tfm->base);
|
||||
char *dst_ipad = crypto_tfm_ctx_aligned(&dst_tfm->base);
|
||||
int ss = crypto_shash_statesize(dst_tfm);
|
||||
#else
|
||||
int ctx_size = crypto_shash_alg(dst_tfm)->base.cra_ctxsize;
|
||||
char *src_ipad = crypto_shash_ctx(src_tfm);
|
||||
char *dst_ipad = crypto_shash_ctx(dst_tfm);
|
||||
/*
|
||||
* Actual struct definition is hidden, so I assume data we need is at
|
||||
* the end. In 6.0 the struct has a pointer to crpyto_shash followed by:
|
||||
* 'u8 ipad[statesize];', then 'u8 opad[statesize];'
|
||||
*/
|
||||
src_ipad += ctx_size - 2 * ss;
|
||||
dst_ipad += ctx_size - 2 * ss;
|
||||
#endif
|
||||
|
||||
memcpy(dst_ipad, src_ipad, crypto_shash_blocksize(src->tfm));
|
||||
memcpy(dst_ipad + ss, src_ipad + ss, crypto_shash_blocksize(src->tfm));
|
||||
crypto_shash_clear_flags(dst->tfm, CRYPTO_TFM_NEED_KEY);
|
||||
|
||||
@@ -290,8 +290,10 @@ static int parse_dsi_properties(const struct device_node *np_dsi, DSI_PANEL_INFO
|
||||
{
|
||||
u32 temp;
|
||||
int ret = 0;
|
||||
#if defined(NV_OF_PROPERTY_FOR_EACH_U32_HAS_INTERNAL_ARGS)
|
||||
const __be32 *p;
|
||||
struct property *prop;
|
||||
#endif
|
||||
struct device_node *np_dsi_panel;
|
||||
|
||||
// Get Panel Node from active-panel phandle
|
||||
@@ -493,7 +495,11 @@ static int parse_dsi_properties(const struct device_node *np_dsi, DSI_PANEL_INFO
|
||||
"nvidia,dsi-lvds-bridge", &temp))
|
||||
dsi->dsi2lvds_bridge_enable = (bool)temp;
|
||||
|
||||
#if defined(NV_OF_PROPERTY_FOR_EACH_U32_HAS_INTERNAL_ARGS)
|
||||
of_property_for_each_u32(np_dsi_panel, "nvidia,dsi-dpd-pads", prop, p, temp)
|
||||
#else
|
||||
of_property_for_each_u32(np_dsi_panel, "nvidia,dsi-dpd-pads", temp)
|
||||
#endif
|
||||
dsi->dpd_dsi_pads |= (u32)temp;
|
||||
|
||||
if (!of_property_read_u32(np_dsi_panel,
|
||||
|
||||
@@ -852,6 +852,8 @@ static int nv_platform_device_display_probe(struct platform_device *plat_dev)
|
||||
nv->mipical_regs->cpu_address = res_addr;
|
||||
nv->mipical_regs->size = res_size;
|
||||
|
||||
pm_vt_switch_required(&plat_dev->dev, NV_TRUE);
|
||||
|
||||
// Enabling power management for the device.
|
||||
pm_runtime_enable(&plat_dev->dev);
|
||||
|
||||
@@ -1073,18 +1075,18 @@ err_free_stack:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nv_platform_device_display_remove(struct platform_device *plat_dev)
|
||||
static void nv_platform_device_display_remove(struct platform_device *plat_dev)
|
||||
{
|
||||
nv_linux_state_t *nvl = NULL;
|
||||
nv_state_t *nv;
|
||||
nvidia_stack_t *sp = NULL;
|
||||
int rc;
|
||||
|
||||
nv_printf(NV_DBG_SETUP, "NVRM: removing SOC Display device\n");
|
||||
|
||||
rc = nv_kmem_cache_alloc_stack(&sp);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (WARN_ON(nv_kmem_cache_alloc_stack(&sp) < 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK_NV_LINUX_DEVICES();
|
||||
nvl = platform_get_drvdata(plat_dev);
|
||||
@@ -1162,13 +1164,13 @@ static int nv_platform_device_display_remove(struct platform_device *plat_dev)
|
||||
|
||||
nv_kmem_cache_free_stack(sp);
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
done:
|
||||
UNLOCK_NV_LINUX_DEVICES();
|
||||
nv_kmem_cache_free_stack(sp);
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int nv_platform_device_probe(struct platform_device *plat_dev)
|
||||
@@ -1189,24 +1191,34 @@ static int nv_platform_device_probe(struct platform_device *plat_dev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nv_platform_device_remove(struct platform_device *plat_dev)
|
||||
static void nv_platform_device_remove(struct platform_device *plat_dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (plat_dev->dev.of_node)
|
||||
{
|
||||
{
|
||||
rc = nv_platform_device_display_remove(plat_dev);
|
||||
nv_platform_device_display_remove(plat_dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = nv_platform_device_display_remove(plat_dev);
|
||||
nv_platform_device_display_remove(plat_dev);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void nv_platform_device_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nv_platform_device_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int nv_platform_device_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nv_platform_device_remove(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct of_device_id nv_platform_device_table[] =
|
||||
{
|
||||
{ .compatible = "nvidia,tegra234-display",},
|
||||
@@ -1228,7 +1240,7 @@ struct platform_driver nv_platform_driver = {
|
||||
#endif
|
||||
},
|
||||
.probe = nv_platform_device_probe,
|
||||
.remove = nv_platform_device_remove,
|
||||
.remove = nv_platform_device_remove_wrapper,
|
||||
};
|
||||
|
||||
int nv_platform_count_devices(void)
|
||||
@@ -1385,57 +1397,3 @@ NvBool nv_get_hdcp_enabled(nv_state_t *nv)
|
||||
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
int nv_disable_simplefb_clocks(void)
|
||||
{
|
||||
int status = 0;
|
||||
static bool is_coldboot = true;
|
||||
|
||||
#if defined(CONFIG_FB) && defined(NV_NUM_REGISTERED_FB_PRESENT)
|
||||
if (num_registered_fb > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_registered_fb; i++)
|
||||
{
|
||||
if (!registered_fb[i])
|
||||
continue;
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
|
||||
struct clk *clock;
|
||||
struct device_node *np = NULL;
|
||||
unsigned int clk_count = 0;
|
||||
int j;
|
||||
|
||||
np = of_find_node_by_name(NULL, "framebuffer");
|
||||
if ((np != NULL) && of_device_is_available(np) && is_coldboot)
|
||||
{
|
||||
#if defined(NV_LINUX_OF_CLK_H_PRESENT) && defined(NV_OF_CLK_GET_PARENT_COUNT_PRESENT)
|
||||
clk_count = of_clk_get_parent_count(np);
|
||||
for (j = 0; j < clk_count; j++)
|
||||
{
|
||||
clock = of_clk_get(np, j);
|
||||
if (IS_ERR(clock))
|
||||
{
|
||||
nv_printf(NV_DBG_ERRORS, "clock %d not found %ld\n", j, PTR_ERR(clock));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__clk_is_enabled(clock))
|
||||
{
|
||||
clk_disable_unprepare(clock);
|
||||
}
|
||||
clk_put(clock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
is_coldboot = false;
|
||||
}
|
||||
of_node_put(np);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
NvU64 NV_API_CALL nv_get_kern_phys_address(NvU64 address)
|
||||
{
|
||||
/* direct-mapped kernel address */
|
||||
if (virt_addr_valid(address))
|
||||
if (virt_addr_valid((void *)address))
|
||||
return __pa(address);
|
||||
|
||||
nv_printf(NV_DBG_ERRORS,
|
||||
|
||||
@@ -1255,15 +1255,6 @@ static int nv_start_device(nv_state_t *nv, nvidia_stack_t *sp)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = nv_disable_simplefb_clocks();
|
||||
if (rc)
|
||||
{
|
||||
NV_DEV_PRINTF(NV_DBG_ERRORS, nv,
|
||||
"nv_disable_simplefb_clocks failed, status %d\n",
|
||||
rc);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
{
|
||||
const NvU8 *uuid = rm_get_gpu_uuid_raw(sp, nv);
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_enable_atomic_ops_to_root
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vga_tryget
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += cc_platform_has
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += seq_read_iter
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += unsafe_follow_pfn
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += follow_pfn
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_gem_object_get
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_gem_object_put_unlocked
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += add_memory_driver_managed
|
||||
@@ -196,7 +196,6 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += devm_clk_bulk_get_all
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_task_ioprio
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += mdev_set_iommu_device
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += offline_and_remove_memory
|
||||
NV_CONFTEST_FUNCTION_COMPILE_TESTS += of_clk_get_parent_count
|
||||
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_of_node_to_nid
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_sme_active
|
||||
@@ -227,6 +226,7 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_clear_in
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_alloc_mem_from_gscco
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_free_gscco_mem
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += crypto
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_follow_pte
|
||||
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += swiotlb_dma_ops
|
||||
@@ -249,6 +249,8 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += num_registered_fb
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += pci_driver_has_driver_managed_dma
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += memory_failure_has_trapno_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += of_property_for_each_u32_has_internal_args
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += platform_driver_struct_remove_returns_void
|
||||
|
||||
NV_CONFTEST_GENERIC_COMPILE_TESTS += dom0_kernel_present
|
||||
NV_CONFTEST_GENERIC_COMPILE_TESTS += nvidia_vgpu_kvm_build
|
||||
|
||||
@@ -1201,12 +1201,13 @@ void NV_API_CALL os_get_screen_info(
|
||||
NvU32 *pFbHeight,
|
||||
NvU32 *pFbDepth,
|
||||
NvU32 *pFbPitch,
|
||||
NvU64 *pFbSize,
|
||||
NvU64 consoleBar1Address,
|
||||
NvU64 consoleBar2Address
|
||||
)
|
||||
{
|
||||
*pPhysicalAddress = 0;
|
||||
*pFbWidth = *pFbHeight = *pFbDepth = *pFbPitch = 0;
|
||||
*pFbWidth = *pFbHeight = *pFbDepth = *pFbPitch = *pFbSize = 0;
|
||||
|
||||
#if defined(CONFIG_FB) && defined(NV_NUM_REGISTERED_FB_PRESENT)
|
||||
if (num_registered_fb > 0)
|
||||
@@ -1224,6 +1225,7 @@ void NV_API_CALL os_get_screen_info(
|
||||
*pFbHeight = registered_fb[i]->var.yres;
|
||||
*pFbDepth = registered_fb[i]->var.bits_per_pixel;
|
||||
*pFbPitch = registered_fb[i]->fix.line_length;
|
||||
*pFbSize = registered_fb[i]->fix.smem_len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,28 @@ static inline int nv_follow_pfn(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
unsigned long *pfn)
|
||||
{
|
||||
#if defined(NV_UNSAFE_FOLLOW_PFN_PRESENT)
|
||||
return unsafe_follow_pfn(vma, address, pfn);
|
||||
#else
|
||||
#if defined(NV_FOLLOW_PFN_PRESENT)
|
||||
return follow_pfn(vma, address, pfn);
|
||||
#else
|
||||
#if NV_IS_EXPORT_SYMBOL_PRESENT_follow_pte
|
||||
int status = 0;
|
||||
spinlock_t *ptl;
|
||||
pte_t *ptep;
|
||||
|
||||
if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
||||
return status;
|
||||
|
||||
status = follow_pte(vma, address, &ptep, &ptl);
|
||||
if (status)
|
||||
return status;
|
||||
*pfn = pte_pfn(ptep_get(ptep));
|
||||
|
||||
// The lock is acquired inside follow_pte()
|
||||
pte_unmap_unlock(ptep, ptl);
|
||||
return 0;
|
||||
#else // NV_IS_EXPORT_SYMBOL_PRESENT_follow_pte
|
||||
return -1;
|
||||
#endif // NV_IS_EXPORT_SYMBOL_PRESENT_follow_pte
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
rel-36_lws2_eng_2025-09-23
|
||||
rel-36_eng_2025-12-11
|
||||
|
||||
@@ -34,16 +34,6 @@
|
||||
|
||||
#define DPCD_MESSAGEBOX_SIZE 48
|
||||
|
||||
//
|
||||
// This definitions are being used for orin Hdcp opensourcing. Ideally this
|
||||
// should be replaced with build flags. Bug ID: 200733434
|
||||
//
|
||||
#define DP_OPTION_HDCP_SUPPORT_ENABLE 1 /* HDCP Enable */
|
||||
|
||||
#define DP_OPTION_HDCP_12_ENABLED 1 /* DP1.2 HDCP ENABLE */
|
||||
|
||||
#define DP_OPTION_QSE_ENABLED 1 /* Remove here when QSE p4r check-in */
|
||||
|
||||
//
|
||||
// If a message is outstanding for at least 4 seconds
|
||||
// assume no reply is coming through
|
||||
@@ -77,6 +67,9 @@
|
||||
#define HDCP_AUTHENTICATION_COOLDOWN_HPD 3000// 3 sec for first stream Add
|
||||
#define HDCP_CPIRQ_RXSTATUS_COOLDOWN 20 // 20ms between attempts
|
||||
|
||||
#define HDCP_QSEANDSETECF_RETRIES 6 // 6 retries as authentication retires
|
||||
#define HDCP_QSEANDSETECF_COOLDOWN 3000// 3 sec between attempts as authentication period
|
||||
|
||||
// Need to re-submit Stream Validation request to falcon microcontroller after 1 sec if current request fails
|
||||
#define HDCP_STREAM_VALIDATION_RESUBMIT_COOLDOWN 1000
|
||||
|
||||
@@ -86,6 +79,12 @@
|
||||
//
|
||||
#define HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN 8000
|
||||
|
||||
//
|
||||
// Wait till 1 sec to check if still have active QSE message then send QSE message or queue
|
||||
// to check next time. 1sec should be enough that sink reply QSE request.
|
||||
//
|
||||
#define HDCP_SEND_QSE_MESSAGE_COOLDOWN 1000
|
||||
|
||||
#define DPCD_OUI_NVIDIA 0x00044B
|
||||
|
||||
//
|
||||
|
||||
@@ -330,6 +330,7 @@ namespace DisplayPort
|
||||
virtual void destroy() = 0; // Destroy the group object
|
||||
|
||||
// Toggles the encryption status for the stream.
|
||||
virtual bool hdcpSetEncrypted(bool encrypted, NvU8 streamType = NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NvBool bForceClear = NV_FALSE, NvBool bAddStreamBack = NV_FALSE) = 0;
|
||||
// Returns whether encryption is currently enabled.
|
||||
virtual bool hdcpGetEncrypted() = 0;
|
||||
|
||||
@@ -657,6 +658,8 @@ namespace DisplayPort
|
||||
virtual void resetDp11ProtocolForced() = 0;
|
||||
virtual bool isDp11ProtocolForced() = 0;
|
||||
|
||||
// Operates at the Link Level. Causes reauthentication of the entire link.
|
||||
virtual void hdcpRenegotiate(NvU64 cN, NvU64 cKsv) = 0;
|
||||
virtual bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12) = 0;
|
||||
|
||||
virtual bool getOuiSink(unsigned &ouiId, char * modelName,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "dp_discovery.h"
|
||||
#include "dp_groupimpl.h"
|
||||
#include "dp_deviceimpl.h"
|
||||
#include "dp_qse.h"
|
||||
#include "./dptestutil/dp_testmessage.h"
|
||||
|
||||
// HDCP abort codes
|
||||
@@ -69,6 +70,8 @@ static inline unsigned getDataClockMultiplier(NvU64 linkRate, NvU64 laneCount)
|
||||
namespace DisplayPort
|
||||
{
|
||||
|
||||
class QSENonceGenerator;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DP_TRANSPORT_MODE_INIT = 0,
|
||||
@@ -126,6 +129,7 @@ namespace DisplayPort
|
||||
bool bPConConnected; // HDMI2.1-Protocol Converter (Support SRC control mode) connected.
|
||||
bool bSkipAssessLinkForPCon; // Skip assessLink() for PCON. DD will call assessFRLLink later.
|
||||
bool bHdcpAuthOnlyOnDemand; // True if only initiate Hdcp authentication on demand and MST won't auto-trigger authenticate at device attach.
|
||||
bool bHdcpStrmEncrEnblOnlyOnDemand; // True if only initiate Hdcp Stream Encryption Enable on demand and MST won't auto-trigger.
|
||||
bool bReassessMaxLink; // Retry assessLink() if the first assessed link config is lower than the panel max config.
|
||||
|
||||
bool constructorFailed;
|
||||
@@ -175,6 +179,7 @@ namespace DisplayPort
|
||||
List activeGroups;
|
||||
LinkedList<GroupImpl> intransitionGroups;
|
||||
LinkedList<GroupImpl> addStreamMSTIntransitionGroups;
|
||||
LinkedList<GroupImpl> hdcpEnableTransitionGroups;
|
||||
List inactiveGroups;
|
||||
|
||||
// Compound query
|
||||
@@ -233,6 +238,15 @@ namespace DisplayPort
|
||||
|
||||
Device * lastDeviceSetForVbios;
|
||||
|
||||
QSENonceGenerator * qseNonceGenerator;
|
||||
|
||||
// Tells whether requests made by library to Downstream Device (i.e QSE messages sent to Branch Device) and RM
|
||||
// (i.e KSV validation and Stream Validation requests sent by library to RM after getting QSE message reply from Downstream)
|
||||
// during querying stream status is valid or not.
|
||||
bool bValidQSERequest;
|
||||
ListElement * message; // Outstanding QSE message pointer for which Stream Validation submission failed.
|
||||
NvU8 * clientId; // ClientId of the group for which Stream Validation submission failed.
|
||||
|
||||
// Flag which gets set when ACPI init is done. DD calls notifyAcpiInitDone to tell client that ACPI init is completed
|
||||
// & client can now initiate DDC EDID read for a device which supports EDID through SBIOS
|
||||
bool bAcpiInitDone;
|
||||
@@ -295,6 +309,9 @@ namespace DisplayPort
|
||||
//
|
||||
bool bNoFallbackInPostLQA;
|
||||
|
||||
// Flag to tell whether to send QSE after stream encryption on
|
||||
bool bIsEncryptionQseValid;
|
||||
|
||||
bool bReportDeviceLostBeforeNew;
|
||||
bool bEnableAudioBeyond48K;
|
||||
bool bDisableSSC;
|
||||
@@ -425,6 +442,8 @@ namespace DisplayPort
|
||||
char tagHDCPReauthentication;
|
||||
char tagDelayedHdcpCapRead;
|
||||
char tagDelayedHDCPCPIrqHandling;
|
||||
char tagSendQseMessage;
|
||||
char tagHDCPStreamEncrEnable;
|
||||
|
||||
//
|
||||
// Enable disable TMDS mode
|
||||
@@ -545,6 +564,8 @@ namespace DisplayPort
|
||||
bool allocateTimeslice(GroupImpl * targetGroup);
|
||||
void freeTimeslice(GroupImpl * targetGroup);
|
||||
void flushTimeslotsToHardware();
|
||||
void hdcpRenegotiate(NvU64 cN, NvU64 cKsv);
|
||||
void hdcpActiveGroupsSetECF();
|
||||
bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12);
|
||||
bool getOuiSink(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision);
|
||||
bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "dp_edid.h"
|
||||
#include "dp_list.h"
|
||||
#include "dp_auxdefs.h"
|
||||
#include "dp_qse.h"
|
||||
#include "dp_vrr.h"
|
||||
|
||||
namespace DisplayPort
|
||||
|
||||
@@ -178,6 +178,7 @@ namespace DisplayPort
|
||||
unsigned maxNumHztSlices;
|
||||
unsigned lineBufferBitDepth;
|
||||
}_DSC;
|
||||
NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS paramsHdcpCtrl;
|
||||
|
||||
private:
|
||||
void initializeRegkeyDatabase();
|
||||
@@ -332,6 +333,13 @@ namespace DisplayPort
|
||||
virtual bool dscCrcTransaction(NvBool bEnable, gpuDscCrc *data, NvU16 *headIndex);
|
||||
|
||||
void triggerACT();
|
||||
void configureAndTriggerECF(NvU64 ecf, NvBool bForceClearEcf = NV_FALSE, NvBool bAddStreamBack = NV_FALSE); // This function program as well as trigger ECF on branch devices.
|
||||
virtual void disableAlternateScramblerReset();
|
||||
void configureHDCPDisableAuthentication();
|
||||
void configureHDCPAbortAuthentication(AbortAuthReason abortAuthReason);
|
||||
bool setStreamType(unsigned streamIndex, NvU8 streamType, bool * bNeedReNegotiate);
|
||||
void configureHDCPValidateLink(HDCPValidateData &hdcpValidateData, NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV);
|
||||
void forwardPendingKsvListReady(NvBool bKsvListReady);
|
||||
void configureHDCPRenegotiate(NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV, bool bForceReAuth = false,
|
||||
bool bRxIDMsgPending = false);
|
||||
void configureHDCPGetHDCPState(HDCPState &hdcpState);
|
||||
|
||||
@@ -37,11 +37,14 @@
|
||||
|
||||
namespace DisplayPort
|
||||
{
|
||||
class StreamEncryptionStatusDetection;
|
||||
|
||||
struct GroupImpl : public Group, ListElement, Timer::TimerCallback
|
||||
{
|
||||
ConnectorImpl * parent;
|
||||
LinkedList<Device> members;
|
||||
StreamEncryptionStatusDetection * streamEncryptionStatusDetection;
|
||||
NvU8 clientId[CLIENT_ID_SIZE];
|
||||
List elements;
|
||||
unsigned headIndex;
|
||||
unsigned streamIndex;
|
||||
@@ -50,6 +53,7 @@ namespace DisplayPort
|
||||
bool bIsHeadShutdownNeeded; // Set if head shutdown is requested during modeset
|
||||
bool hdcpEnabled;
|
||||
bool hdcpPreviousStatus;
|
||||
bool qseEncryptionStatusMismatch;
|
||||
bool bWaitForDeAllocACT;
|
||||
bool bDeferredPayloadAlloc;
|
||||
ModesetInfo lastModesetInfo;
|
||||
@@ -75,6 +79,7 @@ namespace DisplayPort
|
||||
bIsHeadShutdownNeeded(true),
|
||||
hdcpEnabled(false),
|
||||
hdcpPreviousStatus(false),
|
||||
qseEncryptionStatusMismatch(false),
|
||||
bWaitForDeAllocACT(false),
|
||||
dscModeRequest(DSC_MODE_NONE),
|
||||
dscModeActive(DSC_MODE_NONE),
|
||||
@@ -82,11 +87,22 @@ namespace DisplayPort
|
||||
singleHeadMultiStreamMode(DP_SINGLE_HEAD_MULTI_STREAM_MODE_NONE),
|
||||
headAttached(false)
|
||||
{
|
||||
if (isFirmwareGroup)
|
||||
streamEncryptionStatusDetection = 0;
|
||||
else
|
||||
{
|
||||
streamEncryptionStatusDetection = new StreamEncryptionStatusDetection(this, parent);
|
||||
}
|
||||
timeslot.count = 0;
|
||||
}
|
||||
|
||||
~GroupImpl()
|
||||
{
|
||||
if (streamEncryptionStatusDetection)
|
||||
{
|
||||
delete streamEncryptionStatusDetection;
|
||||
streamEncryptionStatusDetection = 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void insert(Device * dev);
|
||||
@@ -104,9 +120,14 @@ namespace DisplayPort
|
||||
char tagHDCPReauthentication;
|
||||
char tagStreamValidation;
|
||||
|
||||
char tagMSTQSEandSetECF;
|
||||
unsigned QSESetECFRetries; // Retry counter for MST QSE and set ECF.
|
||||
virtual void hdcpMSTQSEandSetECF();
|
||||
|
||||
unsigned authRetries; // Retry counter for the authentication.
|
||||
|
||||
virtual void expired(const void * tag);
|
||||
virtual bool hdcpSetEncrypted(bool encrypted, NvU8 streamType = NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NvBool bForceClear = NV_FALSE, NvBool bAddStreamBack = NV_FALSE);
|
||||
virtual bool hdcpGetEncrypted();
|
||||
virtual void destroy();
|
||||
void cancelHdcpCallbacks();
|
||||
|
||||
@@ -202,6 +202,9 @@ namespace DisplayPort
|
||||
|
||||
struct HDCPValidateData
|
||||
{
|
||||
NvU8 vP[NV0073_CTRL_HDCP_VPRIME_SIZE];
|
||||
NvU64 aN;
|
||||
NvU64 mP;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -186,6 +186,18 @@ namespace DisplayPort
|
||||
// HDCP Renegotiate and trigger ACT.
|
||||
//
|
||||
virtual void configureHDCPRenegotiate(NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV, bool bForceReAuth = false, bool bRxIDMsgPending = false) = 0;
|
||||
// HDCP set ECF
|
||||
virtual void configureAndTriggerECF(NvU64 ecf, NvBool bForceClearEcf = NV_FALSE, NvBool bAddStreamBack = NV_FALSE) = 0;
|
||||
//
|
||||
// Enable of disable alternate scrambler SR (ASSR)
|
||||
//
|
||||
// (used for embedded displayport)
|
||||
virtual void disableAlternateScramblerReset() = 0;
|
||||
virtual void configureHDCPDisableAuthentication() = 0;
|
||||
virtual void configureHDCPAbortAuthentication(AbortAuthReason abortAuthReason) = 0;
|
||||
virtual bool setStreamType(unsigned streamIndex, NvU8 streamType, bool * bNeedReNegotiate) = 0;
|
||||
virtual void configureHDCPValidateLink(HDCPValidateData &hdcpValidateData, NvU64 cN = HDCP_DUMMY_CN, NvU64 cKsv = HDCP_DUMMY_CKSV) = 0;
|
||||
virtual void forwardPendingKsvListReady(NvBool bKsvListReady) = 0;
|
||||
virtual void triggerACT() = 0;
|
||||
virtual void configureHDCPGetHDCPState(HDCPState &hdcpState) = 0;
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace DisplayPort
|
||||
{
|
||||
StreamUnconnected = 0,
|
||||
NonAuthLegacyDevice = 1, // TV or CRT
|
||||
Non12CPOrNonQSE = 2, // DVI/HDMI or DP 1.1 sink/repeater
|
||||
DP_MST = 4
|
||||
}OutputSinkType;
|
||||
|
||||
@@ -557,6 +558,105 @@ namespace DisplayPort
|
||||
SinkEventNotifyMessage(MessageReceiverEventSink * sink, unsigned requestId);
|
||||
};
|
||||
|
||||
//
|
||||
// QUERY_STREAM_ENCRYPTION_STATUS 0x38
|
||||
//
|
||||
class QueryStreamEncryptionMessage : public MessageManager::Message
|
||||
{
|
||||
virtual ParseResponseStatus parseResponseAck(EncodedMessage * message,
|
||||
BitStreamReader * reader);
|
||||
|
||||
private:
|
||||
struct QSES_REPLY
|
||||
{
|
||||
StreamState streamState;
|
||||
bool repeaterFuncPresent;
|
||||
bool encryption;
|
||||
bool authentication;
|
||||
OutputSinkType sinkType;
|
||||
OutputCPType cpType;
|
||||
bool signedLPrime;
|
||||
NvU8 streamId;
|
||||
} reply;
|
||||
|
||||
bool bIsHdcp22Qse;
|
||||
|
||||
public:
|
||||
QueryStreamEncryptionMessage() :
|
||||
Message(NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS,
|
||||
NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
|
||||
{
|
||||
dpMemZero(&reply, sizeof(reply));
|
||||
bIsHdcp22Qse = false;
|
||||
}
|
||||
|
||||
void set(const Address & target,
|
||||
unsigned streamId,
|
||||
NvU8* clientId,
|
||||
StreamEvent streamEvent,
|
||||
bool streamEventMask,
|
||||
StreamBehavior streamBehavior,
|
||||
bool streamBehaviorMask);
|
||||
NvU8 getStreamId()
|
||||
{
|
||||
return reply.streamId;
|
||||
}
|
||||
|
||||
void getReply(void *p)
|
||||
{
|
||||
*(struct QSES_REPLY *)p = reply;
|
||||
}
|
||||
|
||||
NvU16 getStreamStatus()
|
||||
{
|
||||
NvU16 streamStatus = 0;
|
||||
|
||||
streamStatus = (NvU16)reply.streamState;
|
||||
|
||||
if (reply.repeaterFuncPresent)
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_REPEATER);
|
||||
if (reply.encryption)
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_ENCRYPTION);
|
||||
if (reply.authentication)
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_AUTHENTICATION);
|
||||
|
||||
if (reply.sinkType != StreamUnconnected)
|
||||
{
|
||||
if (reply.sinkType & DP_MST)
|
||||
{
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_OUTPUT_SINK_MULTI);
|
||||
}
|
||||
|
||||
if (reply.sinkType & Non12CPOrNonQSE)
|
||||
{
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_OUTPUT_SINK_NON_DP1_2_CP);
|
||||
}
|
||||
|
||||
if (reply.sinkType & NonAuthLegacyDevice)
|
||||
{
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_OUTPUT_SINK_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
if (reply.cpType == HDCP1x)
|
||||
{
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP1X);
|
||||
}
|
||||
else if (reply.cpType == HDCP2x)
|
||||
{
|
||||
streamStatus |= 1 << (1 ? NV_DP_HDCP_STREAM_OUTPUT_CP_TYPE_HDCP2X);
|
||||
}
|
||||
|
||||
return streamStatus;
|
||||
|
||||
}
|
||||
|
||||
void setHdcp22Qse(bool bHdcp22Qse)
|
||||
{
|
||||
bIsHdcp22Qse = bHdcp22Qse;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //INCLUDED_DP_MESSAGECODINGS_H
|
||||
|
||||
@@ -153,6 +153,58 @@ namespace DisplayPort
|
||||
mergerDownReply.mailboxInterrupt();
|
||||
}
|
||||
|
||||
void clearNotYetSentQSEDownRequest()
|
||||
{
|
||||
for (ListElement * i = notYetSentDownRequest.begin(); i!=notYetSentDownRequest.end(); )
|
||||
{
|
||||
Message * m = (Message *)i;
|
||||
i = i->next; // Do this first since we may unlink the current node
|
||||
|
||||
if (m->requestIdentifier ==
|
||||
NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS)
|
||||
{
|
||||
notYetSentDownRequest.remove(m);
|
||||
m->parent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isAnyAwaitingQSEReplyDownRequest()
|
||||
{
|
||||
bool bQSEAwaiting = false;
|
||||
|
||||
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
|
||||
{
|
||||
Message * m = (Message *)i;
|
||||
i = i->next; // Do this first since we may unlink the current node
|
||||
|
||||
if (m->requestIdentifier ==
|
||||
NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS)
|
||||
{
|
||||
// We break because there could be only one outstanding QSE message at any time.
|
||||
bQSEAwaiting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bQSEAwaiting;
|
||||
}
|
||||
|
||||
void clearAwaitingQSEReplyDownRequest()
|
||||
{
|
||||
for (ListElement * i = awaitingReplyDownRequest.begin(); i!=awaitingReplyDownRequest.end(); )
|
||||
{
|
||||
Message * m = (Message *)i;
|
||||
i = i->next; // Do this first since we may unlink the current node
|
||||
|
||||
if (m->requestIdentifier ==
|
||||
NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS)
|
||||
{
|
||||
awaitingReplyDownRequest.remove(m);
|
||||
m->parent = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
MessageManager(DPCDHAL * hal, Timer * timer)
|
||||
: timer(timer), hal(hal),
|
||||
splitterDownRequest(hal, timer),
|
||||
|
||||
109
src/common/displayport/inc/dp_qse.h
Normal file
109
src/common/displayport/inc/dp_qse.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
/******************************* DisplayPort *******************************\
|
||||
* *
|
||||
* Module: dp_qse.h *
|
||||
* Class definition for HDCP Query Stream Encryption and relative reading.*
|
||||
* *
|
||||
\***************************************************************************/
|
||||
#ifndef INCLUDED_DP_QSE_H
|
||||
#define INCLUDED_DP_QSE_H
|
||||
|
||||
#include "dp_messagecodings.h"
|
||||
#include "dp_auxdefs.h"
|
||||
|
||||
namespace DisplayPort
|
||||
{
|
||||
#define CLIENT_ID_SIZE 7
|
||||
|
||||
|
||||
struct CLIENTID
|
||||
{
|
||||
NvU8 data[CLIENT_ID_SIZE];
|
||||
|
||||
CLIENTID()
|
||||
{
|
||||
dpMemZero(&data, sizeof(data));
|
||||
}
|
||||
};
|
||||
|
||||
enum QSE_REASON
|
||||
{
|
||||
qseReason_Generic,
|
||||
qseReason_Ssc
|
||||
};
|
||||
|
||||
class QSENonceGenerator: public Object
|
||||
{
|
||||
NvU32 previousRandomLSB;
|
||||
NvU32 previousRandomMSB;
|
||||
//
|
||||
// Linear congruential random number generator
|
||||
// Seed values chosen from numerical methods
|
||||
//
|
||||
NvU64 random();
|
||||
|
||||
public:
|
||||
QSENonceGenerator():previousRandomLSB(0),previousRandomMSB(0)
|
||||
{}
|
||||
|
||||
void clientIdBuilder(NvU64 aN);
|
||||
// For every clientId generation we need to call makeClientId
|
||||
void makeClientId(CLIENTID & clientId);
|
||||
};
|
||||
|
||||
struct GroupImpl;
|
||||
struct ConnectorImpl;
|
||||
|
||||
class StreamEncryptionStatusDetection : public Object, public MessageManager::Message::MessageEventSink, Timer::TimerCallback
|
||||
{
|
||||
GroupImpl * parent;
|
||||
ConnectorImpl * connector;
|
||||
QueryStreamEncryptionMessage qseMessage;
|
||||
unsigned retriesSendQSEMessage;
|
||||
QSE_REASON reason;
|
||||
bool bIsHdcp22Qse;
|
||||
bool bIsRepeater;
|
||||
|
||||
public:
|
||||
StreamEncryptionStatusDetection(GroupImpl * parent, ConnectorImpl * connector):
|
||||
parent(parent), connector(connector), retriesSendQSEMessage(0), bIsHdcp22Qse(false), bIsRepeater(false)
|
||||
{}
|
||||
|
||||
~StreamEncryptionStatusDetection();
|
||||
|
||||
void sendQSEMessage(GroupImpl * group, QSE_REASON reasonId = qseReason_Generic);
|
||||
void handleQSEDownReply();
|
||||
void messageFailed(MessageManager::Message * from, NakData * nakData);
|
||||
void messageCompleted(MessageManager::Message * from);
|
||||
void expired(const void * tag);
|
||||
bool handleQSEReplyValidation();
|
||||
void resetQseMessageState();
|
||||
void setHdcp22Qse(bool bHdcp22Qse);
|
||||
};
|
||||
|
||||
struct DeviceImpl;
|
||||
}
|
||||
|
||||
#endif // INCLUDED_DP_QSE_H
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "dp_auxdefs.h"
|
||||
|
||||
// Regkey Names
|
||||
#define NV_DP_REGKEY_DISABLE_QSES "DISABLE_QSES"
|
||||
#define NV_DP_REGKEY_ENABLE_AUDIO_BEYOND_48K "ENABLE_AUDIO_BEYOND48K"
|
||||
#define NV_DP_REGKEY_OVERRIDE_DPCD_REV "OVERRIDE_DPCD_REV"
|
||||
#define NV_DP_REGKEY_DISABLE_SSC "DISABLE_SSC"
|
||||
@@ -85,6 +86,7 @@ struct DP_REGKEY_DATABASE
|
||||
{
|
||||
bool bInitialized; // set to true after the first EvoMainLink instance is constructed
|
||||
// Below are regkey values
|
||||
bool bQsesDisabled;
|
||||
bool bAudioBeyond48kEnabled;
|
||||
NvU32 dpcdRevOveride;
|
||||
bool bSscDisabled;
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
|
||||
#include "dp_auxdefs.h"
|
||||
|
||||
#define DP_TESTMESSAGE_QSES 0x38
|
||||
#include "dp_qse.h"
|
||||
|
||||
#include "dp_connector.h"
|
||||
|
||||
#define DP_LPRIME_SIZE 20
|
||||
@@ -48,8 +51,59 @@ namespace DisplayPort
|
||||
// Request type enum.
|
||||
typedef enum
|
||||
{
|
||||
DP_TESTMESSAGE_REQUEST_TYPE_QSES, // TestMessage from DPTestUtil.
|
||||
} DP_TESTMESSAGE_REQUEST_TYPE;
|
||||
|
||||
//
|
||||
// NVAPI QSES reply message struct.
|
||||
// Do NOT inherit any class, need keep consist with definition with Nvapi part,
|
||||
// which is C STRUCT
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
StreamState streamState;
|
||||
bool repeaterFuncPresent;
|
||||
bool encryption;
|
||||
bool authentication;
|
||||
OutputSinkType sinkType;
|
||||
OutputCPType cpType;
|
||||
bool signedLPrime;
|
||||
NvU8 streamId;
|
||||
NvU8 LPrime[DP_LPRIME_SIZE];
|
||||
} DP_TESTMESSAGE_REQUEST_QSES_OUTPUT;
|
||||
|
||||
//
|
||||
// Version of QSES_OUTPUT that consistent with struct in dp_messageencodings.h
|
||||
// ( without QSES Lprime).
|
||||
//
|
||||
// Considering nvapi backward compatibility, don't modify DP_TESTMESSAGE_REQUEST_QSES_OUTPUT
|
||||
// definition but has internal version to sync up with dplib implementation.
|
||||
//
|
||||
// DPLib message implementation is using this version for now. TestMessage
|
||||
// need this structure to safely copy info from QSES message structure.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
StreamState streamState;
|
||||
bool repeaterFuncPresent;
|
||||
bool encryption;
|
||||
bool authentication;
|
||||
OutputSinkType sinkType;
|
||||
OutputCPType cpType;
|
||||
bool signedLPrime;
|
||||
NvU8 streamId;
|
||||
} DP_TESTMESSAGE_REQUEST_QSES_OUTPUT_V2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// indicated what status to get, for DP, user need fill this
|
||||
DP_TESTMESSAGE_REQUEST_TYPE requestType;
|
||||
// stream id for QSES to get, user need file this
|
||||
NvU32 streamID;
|
||||
// replay buffer
|
||||
DP_TESTMESSAGE_REQUEST_QSES_OUTPUT reply;
|
||||
} DP_TESTMESSAGE_REQUEST_QSES_INPUT;
|
||||
|
||||
class TestMessage;
|
||||
struct ConnectorImpl;
|
||||
|
||||
@@ -83,6 +137,10 @@ namespace DisplayPort
|
||||
{
|
||||
switch (requestType)
|
||||
{
|
||||
case DP_TESTMESSAGE_REQUEST_TYPE_QSES:
|
||||
{
|
||||
return structSize == sizeof(DP_TESTMESSAGE_REQUEST_QSES_INPUT) ? true : false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -92,8 +150,10 @@ namespace DisplayPort
|
||||
|
||||
// Data Structure for Generic Message.
|
||||
NvU32 replyBytes;
|
||||
void sendTestMsgQSES(void *pBuffer);
|
||||
|
||||
public:
|
||||
DP_TESTMESSAGE_REQUEST_QSES_OUTPUT_V2 qsesReply;
|
||||
|
||||
DP_TESTMESSAGE_REQUEST_STATUS testMessageStatus;
|
||||
|
||||
@@ -103,6 +163,14 @@ namespace DisplayPort
|
||||
pConnector = 0;
|
||||
pMsgManager = 0;
|
||||
replyBytes = 0;
|
||||
qsesReply.streamState = DoesNotExist;
|
||||
qsesReply.repeaterFuncPresent = 0;
|
||||
qsesReply.encryption = 0;
|
||||
qsesReply.authentication = 0;
|
||||
qsesReply.sinkType = StreamUnconnected;
|
||||
qsesReply.cpType = HDCP1x;
|
||||
qsesReply.signedLPrime = 0;
|
||||
qsesReply.streamId = '\0';
|
||||
}
|
||||
DP_TESTMESSAGE_STATUS sendDPTestMessage(void *pBuffer,
|
||||
NvU32 requestSize,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -41,6 +41,8 @@
|
||||
#include "dp_deviceimpl.h"
|
||||
#include "dp_connectorimpl.h"
|
||||
|
||||
#include "dp_qse.h"
|
||||
|
||||
#include "dp_auxbus.h"
|
||||
#include "dpringbuffertypes.h"
|
||||
|
||||
@@ -94,6 +96,7 @@ ConnectorImpl::ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Co
|
||||
bFromResumeToNAB(false),
|
||||
bAttachOnResume(false),
|
||||
bHdcpAuthOnlyOnDemand(false),
|
||||
bHdcpStrmEncrEnblOnlyOnDemand(false),
|
||||
constructorFailed(false),
|
||||
policyModesetOrderMitigation(false),
|
||||
policyForceLTAtNAB(false),
|
||||
@@ -111,6 +114,10 @@ ConnectorImpl::ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Co
|
||||
bAudioOverRightPanel(false),
|
||||
connectorActive(false),
|
||||
firmwareGroup(0),
|
||||
qseNonceGenerator(0),
|
||||
bValidQSERequest(false),
|
||||
message(0),
|
||||
clientId(0),
|
||||
bAcpiInitDone(false),
|
||||
bIsUefiSystem(false),
|
||||
bSkipLt(false),
|
||||
@@ -118,6 +125,7 @@ ConnectorImpl::ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Co
|
||||
bDelayAfterD3(false),
|
||||
bKeepOptLinkAlive(false),
|
||||
bNoFallbackInPostLQA(false),
|
||||
bIsEncryptionQseValid(true),
|
||||
LT2FecLatencyMs(0),
|
||||
bFECEnable(false),
|
||||
bDscCapBasedOnParent(false),
|
||||
@@ -230,6 +238,62 @@ void ConnectorImpl::readRemoteHdcpCaps()
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkUseMultistream())
|
||||
{
|
||||
for (Device * i = enumDevices(0); i; i=enumDevices(i))
|
||||
{
|
||||
DeviceImpl * dev = (DeviceImpl *)i;
|
||||
if (dev->isHDCPCap == False)
|
||||
{
|
||||
NvU8 portType;
|
||||
NvU8 peerType;
|
||||
bool bIsPortPresent;
|
||||
peerType = dev->peerDevice;
|
||||
bIsPortPresent = dev->hal->getDownstreamPort(&portType);
|
||||
|
||||
// Skip the Remote DPCD read if the DS is Dongle.
|
||||
if (bIsPortPresent && (peerType == Dongle))
|
||||
{
|
||||
// BKSV of the dongle might not be ready in some cases.
|
||||
// Setting it with Branch device value.
|
||||
hal->getBKSV(&dev->BKSV[0]);
|
||||
dev->nvBCaps[0] = dev->BCAPS[0] = 0x1;
|
||||
dev->isHDCPCap = True;
|
||||
dev->shadow.hdcpCapDone = false;
|
||||
fireEvents();
|
||||
continue;
|
||||
}
|
||||
//Issue a new Remote HDCP capability check
|
||||
DP_ASSERT(dev->isDeviceHDCPDetectionAlive == false);
|
||||
if((dev->deviceHDCPDetection = new DeviceHDCPDetection(dev, messageManager, timer)))
|
||||
{
|
||||
dev->isDeviceHDCPDetectionAlive = true;
|
||||
dev->deviceHDCPDetection->start();
|
||||
dev->shadow.hdcpCapDone = false;
|
||||
|
||||
if (hdcpCapsRetries < 1)
|
||||
{
|
||||
timer->queueCallback(this, &tagDelayedHdcpCapRead, 3000);
|
||||
hdcpCapsRetries++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For the risk control, make the device as not HDCPCap.
|
||||
DP_ASSERT(0 && "new failed");
|
||||
dev->isDeviceHDCPDetectionAlive = false;
|
||||
dev->isHDCPCap = False;
|
||||
|
||||
if (!dev->isMultistream())
|
||||
dev->shadow.hdcpCapDone = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_LOG(("DPCONN> This DP1.2 device is HDCP capable"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectorImpl::discoveryDetectComplete()
|
||||
@@ -606,6 +670,20 @@ create:
|
||||
{
|
||||
if (isHDCPAuthOn)
|
||||
{
|
||||
// Abort the Authentication
|
||||
DP_LOG(("DP> Topology limited. Abort Authentication."));
|
||||
isHDCPAuthOn = false;
|
||||
isHopLimitExceeded = true;
|
||||
for (ListElement * i = activeGroups.begin(); i != activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
group-> hdcpSetEncrypted(false);
|
||||
}
|
||||
}
|
||||
main->configureHDCPAbortAuthentication(KSVTOP);
|
||||
main->configureHDCPDisableAuthentication();
|
||||
isHDCPAuthOn = false;
|
||||
}
|
||||
isHopLimitExceeded = true;
|
||||
@@ -893,6 +971,7 @@ ConnectorImpl::~ConnectorImpl()
|
||||
delete discoveryManager;
|
||||
pendingEdidReads.clear();
|
||||
delete messageManager;
|
||||
delete qseNonceGenerator;
|
||||
delete hal;
|
||||
}
|
||||
|
||||
@@ -2062,6 +2141,24 @@ void ConnectorImpl::releaseLinkHandsOff()
|
||||
assessLink();
|
||||
}
|
||||
|
||||
void ConnectorImpl::hdcpActiveGroupsSetECF()
|
||||
{
|
||||
NvU64 ecf = 0x0;
|
||||
// Set the ECF for the groups which are already active.
|
||||
for (ListElement *i = this->activeGroups.begin(); i != this->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
NvU64 countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
NvU64 mask = countOnes << group->timeslot.begin;
|
||||
ecf |= mask;
|
||||
}
|
||||
}
|
||||
// Restore the ECF and trigger ACT
|
||||
main->configureAndTriggerECF(ecf);
|
||||
}
|
||||
|
||||
//
|
||||
// Timer callback for event management
|
||||
// Uses: fireEvents()
|
||||
@@ -2069,6 +2166,130 @@ void ConnectorImpl::expired(const void * tag)
|
||||
{
|
||||
if (tag == &tagFireEvents)
|
||||
fireEventsInternal();
|
||||
else if (tag == &tagDelayedHdcpCapRead)
|
||||
{
|
||||
DP_LOG(("DPCONN> Delayed HDCP Cap read called."));
|
||||
readRemoteHdcpCaps();
|
||||
}
|
||||
else if (tag == &tagHDCPStreamEncrEnable)
|
||||
{
|
||||
if (!(bHdcpStrmEncrEnblOnlyOnDemand))
|
||||
{
|
||||
while (!(hdcpEnableTransitionGroups.isEmpty()))
|
||||
{
|
||||
GroupImpl* curStrmEncrEnblGroup = hdcpEnableTransitionGroups.pop();
|
||||
if (!(curStrmEncrEnblGroup->hdcpEnabled))
|
||||
{
|
||||
curStrmEncrEnblGroup->hdcpSetEncrypted(true, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tag == &tagHDCPReauthentication)
|
||||
{
|
||||
if (authRetries < HDCP_AUTHENTICATION_RETRIES)
|
||||
{
|
||||
HDCPState hdcpState = {0};
|
||||
// Get hdcp state which will be !HDCP_State_Authenticated for the first entry and
|
||||
// subsequently it will reflect the result of last fired configureHDCPRenegotiate
|
||||
main->configureHDCPGetHDCPState(hdcpState);
|
||||
|
||||
unsigned authDelay = (hdcpState.HDCP_State_22_Capable ?
|
||||
HDCP22_AUTHENTICATION_COOLDOWN * 2 : HDCP_AUTHENTICATION_COOLDOWN);
|
||||
|
||||
// Don't fire any reauthentication if we're not done with the modeset
|
||||
if (!intransitionGroups.isEmpty())
|
||||
{
|
||||
isHDCPAuthOn = false;
|
||||
timer->queueCallback(this, &tagHDCPReauthentication,
|
||||
authDelay);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the ECF & Reauthentication here for the branch device.
|
||||
NvU64 ecf = 0x0;
|
||||
main->configureAndTriggerECF(ecf);
|
||||
isHDCPAuthOn = false;
|
||||
|
||||
authRetries++;
|
||||
isHDCPAuthTriggered = true;
|
||||
|
||||
// Skip configureHDCPRenegotiate if HDCP is already enabled from previous
|
||||
// previous call to configureHDCPRenegotiate
|
||||
if (!hdcpState.HDCP_State_Authenticated)
|
||||
{
|
||||
main->configureHDCPRenegotiate();
|
||||
// Get fresh hdcp state after Renegotiate as HDCP1X can be enabled
|
||||
// synchronously by configureHDCPRenegotiate (HDCP2X takes time)
|
||||
main->configureHDCPGetHDCPState(hdcpState);
|
||||
}
|
||||
|
||||
if (hdcpState.HDCP_State_Authenticated)
|
||||
{
|
||||
isHDCPAuthOn = true;
|
||||
authRetries = 0;
|
||||
// Set the ECF for the groups which are already active.
|
||||
hdcpActiveGroupsSetECF();
|
||||
// Enable HDCP for Group
|
||||
if (!(bHdcpStrmEncrEnblOnlyOnDemand))
|
||||
{
|
||||
timer->queueCallback(this, &tagHDCPStreamEncrEnable, 100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->queueCallback(this, &tagHDCPReauthentication,
|
||||
authDelay);
|
||||
}
|
||||
isHDCPReAuthPending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isHDCPAuthOn = false;
|
||||
}
|
||||
}
|
||||
else if (tag == &tagSendQseMessage)
|
||||
{
|
||||
if (this->messageManager->isAnyAwaitingQSEReplyDownRequest())
|
||||
{
|
||||
timer->queueCallback(this, &tagSendQseMessage, HDCP_SEND_QSE_MESSAGE_COOLDOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ListElement * i = activeGroups.begin(); i != activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *) i;
|
||||
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
group->streamEncryptionStatusDetection->sendQSEMessage(group, qseReason_Ssc);
|
||||
timer->queueCallback(group, &(group->tagStreamValidation), HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tag == &tagDelayedHDCPCPIrqHandling)
|
||||
{
|
||||
DP_LOG(("DPCONN> Delayed HDCP CPIRQ handling due to previous RxStatus read failed."));
|
||||
|
||||
if (handleCPIRQ())
|
||||
{
|
||||
hal->clearInterruptContentProtection();
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpCpIrqRxStatusRetries++;
|
||||
if (hdcpCpIrqRxStatusRetries < HDCP_CPIRQ_RXSTAUS_RETRIES)
|
||||
{
|
||||
timer->queueCallback(this, &tagHDCPReauthentication, HDCP_CPIRQ_RXSTATUS_COOLDOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_LOG(("DPCONN> Delayed HDCP CPIRQ RxStatus probe exceeds max retry and aborted."));
|
||||
hal->clearInterruptContentProtection();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
DP_ASSERT(0);
|
||||
}
|
||||
@@ -2898,6 +3119,12 @@ bool ConnectorImpl::notifyAttachBegin(Group * target, // Gr
|
||||
}
|
||||
|
||||
// TODO: Need to check if we can completely remove DP_OPTION_HDCP_12_ENABLED and remove it
|
||||
// Clean up: Clearing ECF
|
||||
if (linkUseMultistream())
|
||||
{
|
||||
targetImpl->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_FALSE);
|
||||
targetImpl->hdcpEnabled = false;
|
||||
}
|
||||
|
||||
beforeAddStream(targetImpl);
|
||||
|
||||
@@ -3037,8 +3264,46 @@ void ConnectorImpl::notifyAttachEnd(bool modesetCancelled)
|
||||
{
|
||||
currentModesetDeviceGroup->hdcpEnabled = isHDCPAuthOn = false;
|
||||
}
|
||||
else if (!bHdcpAuthOnlyOnDemand)
|
||||
{
|
||||
currentModesetDeviceGroup->cancelHdcpCallbacks();
|
||||
|
||||
if (hdcpState.HDCP_State_Authenticated)
|
||||
{
|
||||
isHDCPAuthOn = true;
|
||||
currentModesetDeviceGroup->hdcpSetEncrypted(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentModesetDeviceGroup->hdcpEnabled = isHDCPAuthOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Set stream type and bEnforceType0Hdcp1xDS upfront before enabling hdcp with hub
|
||||
bool bNeedReNegotiate = false;
|
||||
main->setStreamType(currentModesetDeviceGroup->streamIndex,
|
||||
NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_1, &bNeedReNegotiate);
|
||||
}
|
||||
|
||||
//
|
||||
// RM has the requirement of Head being ARMed to do authentication.
|
||||
// Postpone the authentication until the NAE to do the authentication for DP1.2 as solution.
|
||||
//
|
||||
if (isDP12AuthCap && !isHopLimitExceeded && !isHDCPReAuthPending &&
|
||||
!bHdcpAuthOnlyOnDemand)
|
||||
{
|
||||
isHDCPReAuthPending = true;
|
||||
timer->queueCallback(this, &tagHDCPReauthentication, HDCP_AUTHENTICATION_COOLDOWN_HPD);
|
||||
}
|
||||
|
||||
if (!bHdcpStrmEncrEnblOnlyOnDemand)
|
||||
{
|
||||
hdcpEnableTransitionGroups.insertFront(currentModesetDeviceGroup);
|
||||
}
|
||||
hdcpCapsRetries = 0;
|
||||
timer->queueCallback(this, &tagDelayedHdcpCapRead, 2000);
|
||||
|
||||
fireEvents();
|
||||
}
|
||||
|
||||
@@ -3066,6 +3331,20 @@ void ConnectorImpl::notifyDetachBegin(Group * target)
|
||||
DP_ASSERT(0 && "Could not set the PHY_TEST_PATTERN");
|
||||
}
|
||||
|
||||
//
|
||||
// At this point Pixels are dropped we can clear ECF,
|
||||
// Force Clear ECF is set to TRUE which will delete time slots and send ACT
|
||||
//
|
||||
if (linkUseMultistream())
|
||||
{
|
||||
if (!(bHdcpStrmEncrEnblOnlyOnDemand) && hdcpEnableTransitionGroups.contains(group))
|
||||
{
|
||||
hdcpEnableTransitionGroups.remove(group);
|
||||
}
|
||||
group->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_FALSE);
|
||||
group->hdcpEnabled = false;
|
||||
}
|
||||
|
||||
beforeDeleteStream(group);
|
||||
|
||||
//
|
||||
@@ -3145,6 +3424,17 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive)
|
||||
{
|
||||
currentModesetDeviceGroup->hdcpEnabled = false;
|
||||
}
|
||||
//
|
||||
// ToDo: Need to confirm the HW and UpStream SW behavior on DP1.2.
|
||||
// For HW, we need to know whether ECF will be cleared by modeset or not.
|
||||
// For UpStream Sw, we need to know whether the upstream will come to call off then encryption.
|
||||
// TODO: Need to remove this as we are already disabling encryption in Notify Detach Begin
|
||||
//
|
||||
else if ((this->linkUseMultistream()) && (currentModesetDeviceGroup->hdcpEnabled))
|
||||
{
|
||||
currentModesetDeviceGroup->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_FALSE);
|
||||
currentModesetDeviceGroup->hdcpEnabled = false;
|
||||
}
|
||||
|
||||
// Update Vbios scratch register
|
||||
for (Device * d = currentModesetDeviceGroup->enumDevices(0); d;
|
||||
@@ -3190,6 +3480,20 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive)
|
||||
//
|
||||
else
|
||||
{
|
||||
//
|
||||
// - if EDP; disable ASSR after switching off the stream from head
|
||||
// to prevent corruption (bug 926360)
|
||||
// - disable ASSR before power down link (bug 1641174)
|
||||
//
|
||||
if (main->isEDP())
|
||||
{
|
||||
bool bPanelPowerOn;
|
||||
// if eDP's power has been shutdown here, don't disable ASSR, else it will be turned on by LT.
|
||||
if (main->getEdpPowerData(&bPanelPowerOn, NULL) && bPanelPowerOn)
|
||||
{
|
||||
main->disableAlternateScramblerReset();
|
||||
}
|
||||
}
|
||||
//
|
||||
// Power down the links as we have switched away from the monitor.
|
||||
// For shared SOR case, we need this to keep SW stats in DP instances in sync.
|
||||
@@ -3208,6 +3512,27 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive)
|
||||
if (this->policyModesetOrderMitigation && this->modesetOrderMitigation)
|
||||
this->modesetOrderMitigation = false;
|
||||
}
|
||||
else // !activeGroups.isEmpty()
|
||||
{
|
||||
if ((this->linkUseMultistream()) && (hdcpState.HDCP_State_Authenticated))
|
||||
{
|
||||
if (hdcpState.HDCP_State_22_Capable)
|
||||
{
|
||||
main->configureAndTriggerECF(0x0);
|
||||
authRetries = 0;
|
||||
isHDCPAuthOn = false;
|
||||
// numOfStream changed, AKE_Init needed to change dpTypeMask
|
||||
main->configureHDCPRenegotiate();
|
||||
// ReAuth, so schedule callback to check state later.
|
||||
timer->queueCallback(this, &tagHDCPReauthentication, HDCP_AUTHENTICATION_COOLDOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpActiveGroupsSetECF();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fireEvents();
|
||||
}
|
||||
|
||||
@@ -3858,6 +4183,7 @@ bool ConnectorImpl::handleCPIRQ()
|
||||
{
|
||||
NvBool bReAuthReq = NV_FALSE;
|
||||
NvBool bRxIDMsgPending = NV_FALSE;
|
||||
NvBool bHdcp1xReadyPending = NV_FALSE;
|
||||
DP_LOG(("DP> CP_IRQ HDCP ver:%s RxStatus:0x%2x HDCP Authenticated:%s Encryption:%s",
|
||||
hdcpState.HDCP_State_22_Capable ? "2.2" : "1.x",
|
||||
bStatus,
|
||||
@@ -3908,6 +4234,10 @@ bool ConnectorImpl::handleCPIRQ()
|
||||
{
|
||||
bReAuthReq = NV_TRUE;
|
||||
}
|
||||
if (FLD_TEST_DRF(_DPCD, _HDCP_BSTATUS, _READY, _TRUE, bStatus))
|
||||
{
|
||||
bHdcp1xReadyPending = NV_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (bReAuthReq || bRxIDMsgPending)
|
||||
@@ -3940,8 +4270,41 @@ bool ConnectorImpl::handleCPIRQ()
|
||||
sstPrim->main->configureHDCPGetHDCPState(hdcpState);
|
||||
isHDCPAuthOn = hdcpState.HDCP_State_Authenticated;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Clear the ECF and issue another authentication and set ECF accordingly.
|
||||
// The flash monitor is expected here.
|
||||
//
|
||||
if (bReAuthReq)
|
||||
{
|
||||
main->configureAndTriggerECF(0x0);
|
||||
}
|
||||
|
||||
main->configureHDCPRenegotiate(HDCP_DUMMY_CN, HDCP_DUMMY_CKSV,
|
||||
!!bReAuthReq, !!bRxIDMsgPending);
|
||||
// If reAuth, schedule callback to check state later.
|
||||
if (bReAuthReq)
|
||||
{
|
||||
isHDCPAuthOn = false;
|
||||
timer->queueCallback(this, &tagHDCPReauthentication, HDCP_AUTHENTICATION_COOLDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bHdcp1xReadyPending)
|
||||
{
|
||||
DP_LOG(("DP> CP_IRQ: HDCP1X READY notification."));
|
||||
|
||||
//
|
||||
// Bug 200305105: Since RM HDCP1.x repeater authentication has polling
|
||||
// loop to check RxStatus READY event, here CPIRQ handling to read RxStatus
|
||||
// cause RM next polling read won't get the one-shot READY event anymore and
|
||||
// repeater authentication fail. The fix is to forward the READY event that
|
||||
// RM detect to continue authentication stage.
|
||||
//
|
||||
main->forwardPendingKsvListReady(bHdcp1xReadyPending);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -3953,6 +4316,106 @@ bool ConnectorImpl::handleCPIRQ()
|
||||
|
||||
void ConnectorImpl::handleSSC()
|
||||
{
|
||||
//
|
||||
// Bit 2 : STREAM_STATUS_CHANGED
|
||||
// When set to a indicates the source must re-check the Stream
|
||||
// Status with the QUERY_STREAM_ENCRYPTION_STATUS
|
||||
// message.
|
||||
//
|
||||
// i. Should trigger QueryStreamStatus on all HDCP enabled streams.
|
||||
// 1. L will change when the KSV list changes (aka new device)
|
||||
// 2. L will change when the encryption state changes
|
||||
// a. The library should attempt to recover from this bad state as soon as possible.
|
||||
// If the player catches it on its 1/2Hz callback, it will disrupt CP over the entire topology
|
||||
// 3. The output of QueryStreamStatus must be passed down to RM for validation.
|
||||
// The status is effectively and indirectly signed by M0, the secret value
|
||||
// for the immediate link between GPU and first branch.
|
||||
// 4. The stream status validation function in RM will update the encryption state that
|
||||
// our hardware signs and returns to the player.
|
||||
// Thus the DisplayDriver should pass any upstream status calls directly to RM.
|
||||
//
|
||||
// ii. Should watch out that the ready bit is cleared after Binfo read.
|
||||
//
|
||||
DP_LOG(("DP> SSC of DP_IRQ"));
|
||||
|
||||
//
|
||||
// Enable SSC process by default except when regkey 'DISABLE_SSC' set to 1 in DD's path.
|
||||
//
|
||||
if (!bDisableSSC)
|
||||
{
|
||||
this->messageManager->clearNotYetSentQSEDownRequest();
|
||||
|
||||
timer->cancelCallback(this, &tagSendQseMessage);
|
||||
|
||||
if (!isLinkActive())
|
||||
{
|
||||
DP_LOG(("DP> SSC of DP_IRQ: Ignored with link down"));
|
||||
return;
|
||||
}
|
||||
|
||||
BInfo bInfo;
|
||||
if (hal->getBinfo(bInfo))
|
||||
{
|
||||
if (bInfo.maxCascadeExceeded || bInfo.maxDevsExceeded)
|
||||
{
|
||||
// Abort the Authentication
|
||||
DP_LOG(("DP> StreamStatusChanged: Topology limited. Abort Authentication."));
|
||||
|
||||
isHDCPAuthOn = false;
|
||||
isHopLimitExceeded = true;
|
||||
|
||||
for (ListElement * i = activeGroups.begin(); i != activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
group->hdcpSetEncrypted(false);
|
||||
}
|
||||
}
|
||||
|
||||
main->configureHDCPAbortAuthentication(KSVTOP);
|
||||
main->configureHDCPDisableAuthentication();
|
||||
return;
|
||||
}
|
||||
HDCPValidateData hdcpValidateData = {0};
|
||||
NvU64 aN;
|
||||
|
||||
main->configureHDCPValidateLink(hdcpValidateData);
|
||||
aN = hdcpValidateData.aN;
|
||||
|
||||
this->qseNonceGenerator->clientIdBuilder(aN);
|
||||
|
||||
if (this->messageManager->isAnyAwaitingQSEReplyDownRequest())
|
||||
{
|
||||
// Mark waiting reply's QSE request as invalid.
|
||||
this->bValidQSERequest = false;
|
||||
|
||||
// Queue callback to check if pending QSE exist and send QSE message.
|
||||
timer->queueCallback(this, &tagSendQseMessage, HDCP_SEND_QSE_MESSAGE_COOLDOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->bValidQSERequest = true;
|
||||
|
||||
for (ListElement * i = activeGroups.begin(); i != activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *) i;
|
||||
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
group->streamEncryptionStatusDetection->sendQSEMessage(group, qseReason_Ssc);
|
||||
timer->queueCallback(group, &(group->tagStreamValidation), HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
DP_ASSERT(0 && "Unable to get Binfo");
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_LOG(("DP> StreamStatusChanged: SSC Disabled now."));
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectorImpl::handleHdmiLinkStatusChanged()
|
||||
@@ -5918,6 +6381,8 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
delete messageManager;
|
||||
messageManager = 0;
|
||||
discoveryManager = 0;
|
||||
delete qseNonceGenerator;
|
||||
qseNonceGenerator = 0;
|
||||
|
||||
cancelHdcpCallbacks();
|
||||
if (hal->getSupportsMultistream() && main->hasMultistream())
|
||||
@@ -5947,6 +6412,7 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
}
|
||||
|
||||
discoveryManager = new DiscoveryManager(messageManager, this, timer, hal);
|
||||
qseNonceGenerator = new QSENonceGenerator();
|
||||
|
||||
// Check and clear if any pending message here
|
||||
if (hal->clearPendingMsg())
|
||||
@@ -5984,6 +6450,23 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
assessLink(); // Link assessment may re-add a stream
|
||||
// and must be done AFTER the messaging system
|
||||
// is restored.
|
||||
//
|
||||
// SOR should be able to authentication and enable link encrpytion without being connected to any
|
||||
// head. From the RM code, it has the requirement of Head being ARMed to do authentication.
|
||||
// Postpone the authentication until the NAE to do the authentication for DP1.2 as solution.
|
||||
//
|
||||
DP_ASSERT((isHDCPAuthOn == false) && (isDP12AuthCap == false));
|
||||
|
||||
HDCPState hdcpState = {0};
|
||||
main->configureHDCPGetHDCPState(hdcpState);
|
||||
if (hdcpState.HDCP_State_1X_Capable || hdcpState.HDCP_State_22_Capable)
|
||||
{
|
||||
isDP12AuthCap = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isDP12AuthCap = false;
|
||||
}
|
||||
discoveryManager->notifyLongPulse(true);
|
||||
}
|
||||
else // SST case
|
||||
@@ -6189,6 +6672,15 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected)
|
||||
bNoFallbackInPostLQA = false;
|
||||
bDscCapBasedOnParent = false;
|
||||
|
||||
isHDCPAuthOn = isDP12AuthCap = false;
|
||||
delete qseNonceGenerator;
|
||||
qseNonceGenerator =0;
|
||||
|
||||
cancelHdcpCallbacks();
|
||||
|
||||
// Disable the authentication on the main link
|
||||
main->configureHDCPDisableAuthentication();
|
||||
|
||||
}
|
||||
completed:
|
||||
previousPlugged = statusConnected;
|
||||
@@ -6617,10 +7109,25 @@ void ConnectorImpl::notifyAcpiInitDone()
|
||||
return;
|
||||
}
|
||||
|
||||
void ConnectorImpl::hdcpRenegotiate(NvU64 cN, NvU64 cKsv)
|
||||
{
|
||||
this->main->configureHDCPRenegotiate(cN, cKsv);
|
||||
HDCPState hdcpState = {0};
|
||||
this->main->configureHDCPGetHDCPState(hdcpState);
|
||||
this->isHDCPAuthOn = hdcpState.HDCP_State_Authenticated;
|
||||
}
|
||||
|
||||
bool ConnectorImpl::getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12)
|
||||
{
|
||||
hdcpAbortCodesDP12 = 0;
|
||||
|
||||
if (isHopLimitExceeded)
|
||||
{
|
||||
hdcpAbortCodesDP12 = hdcpAbortCodesDP12 | HDCP_FLAGS_ABORT_HOP_LIMIT_EXCEEDED ;
|
||||
}
|
||||
|
||||
// Video has also expressed the need of bRevoked but we don't think it's needed. Next RFR will have conclusion.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6658,6 +7165,10 @@ void ConnectorImpl::cancelHdcpCallbacks()
|
||||
|
||||
timer->cancelCallback(this, &tagHDCPReauthentication); // Cancel any queue the auth callback.
|
||||
timer->cancelCallback(this, &tagDelayedHdcpCapRead); // Cancel any HDCP cap callbacks.
|
||||
timer->cancelCallback(this, &tagHDCPStreamEncrEnable); // Cancel any queued the stream encr enable callback.
|
||||
|
||||
this->bValidQSERequest = false;
|
||||
timer->cancelCallback(this, &tagSendQseMessage); // Cancel any queue the qse callback.
|
||||
|
||||
|
||||
for (ListElement * i = activeGroups.begin(); i != activeGroups.end(); i = i->next)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -1302,6 +1302,24 @@ TriState DeviceImpl::hdcpAvailable()
|
||||
{
|
||||
return this->hdcpAvailableHop();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceImpl *targetDevice = this;
|
||||
while (targetDevice)
|
||||
{
|
||||
if (!targetDevice->hdcpAvailableHop())
|
||||
{
|
||||
return False;
|
||||
}
|
||||
else if (targetDevice->hdcpAvailableHop() == Indeterminate)
|
||||
{
|
||||
return Indeterminate;
|
||||
}
|
||||
targetDevice = targetDevice->parent;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
@@ -2618,51 +2636,47 @@ DeviceHDCPDetection::start()
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->isHDCPCap = False;
|
||||
waivePendingHDCPCapDoneNotification();
|
||||
return;
|
||||
goto NativeDPCDHDCPCAPRead;
|
||||
}
|
||||
|
||||
NativeDPCDHDCPCAPRead:
|
||||
|
||||
BCaps bCaps = {0};
|
||||
unsigned char hdcp22BCAPS[HDCP22_BCAPS_SIZE];
|
||||
|
||||
parent->hal->getBCaps(bCaps, parent->BCAPS);
|
||||
*(parent->nvBCaps) = *(parent->BCAPS);
|
||||
|
||||
// Check if hdcp2.x only device and probe hdcp22Bcaps.
|
||||
parent->hal->getHdcp22BCaps(bCaps, hdcp22BCAPS);
|
||||
if (bCaps.HDCPCapable)
|
||||
{
|
||||
NvU8 tempBKSV[HDCP_KSV_SIZE] = {0};
|
||||
if (parent->hal->getBKSV(tempBKSV))
|
||||
{
|
||||
if (hdcpValidateKsv(tempBKSV, HDCP_KSV_SIZE))
|
||||
{
|
||||
for (unsigned i=0; i<HDCP_KSV_SIZE; i++)
|
||||
parent->BKSV[i] = tempBKSV[i];
|
||||
}
|
||||
}
|
||||
parent->nvBCaps[0] = FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET,
|
||||
_HDCP_CAPABLE, bCaps.HDCPCapable,
|
||||
parent->nvBCaps[0]) |
|
||||
FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET, _HDCP_REPEATER,
|
||||
bCaps.repeater, parent->nvBCaps[0]);
|
||||
|
||||
//
|
||||
// No need to validate 1.x bksv here and hdcp22 authentication would
|
||||
// validate certificate with bksv in uproc.
|
||||
//
|
||||
parent->isHDCPCap = True;
|
||||
waivePendingHDCPCapDoneNotification();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char hdcp22BCAPS[HDCP22_BCAPS_SIZE];
|
||||
|
||||
// Check if hdcp2.x only device and probe hdcp22Bcaps.
|
||||
parent->hal->getHdcp22BCaps(bCaps, hdcp22BCAPS);
|
||||
if (bCaps.HDCPCapable)
|
||||
{
|
||||
parent->nvBCaps[0] = FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET,
|
||||
_HDCP_CAPABLE, bCaps.HDCPCapable,
|
||||
parent->nvBCaps[0]) |
|
||||
FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET, _HDCP_REPEATER,
|
||||
bCaps.repeater, parent->nvBCaps[0]);
|
||||
|
||||
//
|
||||
// No need to validate 1.x bksv here and hdcp22 authentication would
|
||||
// validate certificate with bksv in uproc.
|
||||
//
|
||||
else
|
||||
{
|
||||
parent->hal->getBCaps(bCaps, parent->BCAPS);
|
||||
*(parent->nvBCaps) = *(parent->BCAPS);
|
||||
if (bCaps.HDCPCapable)
|
||||
{
|
||||
NvU8 tempBKSV[HDCP_KSV_SIZE] = {0};
|
||||
if (parent->hal->getBKSV(tempBKSV))
|
||||
{
|
||||
if (hdcpValidateKsv(tempBKSV, HDCP_KSV_SIZE))
|
||||
{
|
||||
for (unsigned i=0; i<HDCP_KSV_SIZE; i++)
|
||||
parent->BKSV[i] = tempBKSV[i];
|
||||
}
|
||||
}
|
||||
parent->isHDCPCap = True;
|
||||
waivePendingHDCPCapDoneNotification();
|
||||
return;
|
||||
@@ -2674,8 +2688,16 @@ NativeDPCDHDCPCAPRead:
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->isHDCPCap = False;
|
||||
waivePendingHDCPCapDoneNotification();
|
||||
parent->isHDCPCap = Indeterminate;
|
||||
Address parentAddress = parent->address.parent();
|
||||
//For DP1.4 atomic messaging, HDCP detection can be delayed, so lowering the priority.
|
||||
remote22BCapsReadMessage.setMessagePriority(NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT);
|
||||
remote22BCapsReadMessage.set(parentAddress, parent->address.tail(), NV_DPCD_HDCP22_BCAPS_OFFSET, HDCP22_BCAPS_SIZE);
|
||||
bCapsReadCompleted = false;
|
||||
bBCapsReadMessagePending = true;
|
||||
messageManager->post(&remote22BCapsReadMessage, this);
|
||||
if (parent->connector)
|
||||
parent->connector->incPendingRemoteHdcpDetection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2705,7 +2727,67 @@ DeviceHDCPDetection::handleRemoteDpcdReadDownReply
|
||||
Address::StringBuffer sb;
|
||||
DP_USED(sb);
|
||||
|
||||
if (from == &remoteBKSVReadMessage)
|
||||
if (from == &remote22BCapsReadMessage)
|
||||
{
|
||||
bCapsReadCompleted = true;
|
||||
bBCapsReadMessagePending = false;
|
||||
DP_LOG(("DP-QM> REMOTE_DPCD_READ(22BCaps) {%p} at '%s' completed",
|
||||
(MessageManager::Message *)&remote22BCapsReadMessage,
|
||||
parent->address.toString(sb)));
|
||||
|
||||
if (remote22BCapsReadMessage.replyNumOfBytesReadDPCD() != HDCP22_BCAPS_SIZE)
|
||||
{
|
||||
DP_ASSERT(0 && "Incomplete 22BCaps in remote DPCD read message");
|
||||
parent->isHDCPCap = False;
|
||||
|
||||
// Destruct only when no message is pending
|
||||
if (!(bBKSVReadMessagePending || bBCapsReadMessagePending))
|
||||
{
|
||||
parent->isDeviceHDCPDetectionAlive = false;
|
||||
delete this;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DP_ASSERT(remote22BCapsReadMessage.replyPortNumber() == parent->address.tail());
|
||||
if (!!(*remote22BCapsReadMessage.replyGetData() & 0x2))
|
||||
{
|
||||
unsigned char hdcp22BCAPS;
|
||||
bksvReadCompleted = true;
|
||||
bBKSVReadMessagePending = false;
|
||||
|
||||
hdcp22BCAPS = *remote22BCapsReadMessage.replyGetData();
|
||||
|
||||
parent->nvBCaps[0] = FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET,
|
||||
_HDCP_CAPABLE, (hdcp22BCAPS & 0x2) ? 1 : 0,
|
||||
parent->nvBCaps[0]) |
|
||||
FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET, _HDCP_REPEATER,
|
||||
(hdcp22BCAPS & 0x1) ? 1 : 0, parent->nvBCaps[0]);
|
||||
|
||||
// hdcp22 will validate certificate's bksv directly.
|
||||
isBCapsHDCP = isValidBKSV = true;
|
||||
|
||||
DP_LOG(("DP-QM> Device at '%s' is with valid 22BCAPS : %x",
|
||||
parent->address.toString(sb), *remote22BCapsReadMessage.replyGetData()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Address parentAddress = parent->address.parent();
|
||||
//For DP1.4 atomic messaging, HDCP detection can be delayed, so lowering the priority.
|
||||
remoteBKSVReadMessage.setMessagePriority(NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT);
|
||||
remoteBKSVReadMessage.set(parentAddress, parent->address.tail(), NV_DPCD_HDCP_BKSV_OFFSET, HDCP_KSV_SIZE);
|
||||
bksvReadCompleted = false;
|
||||
bBKSVReadMessagePending = true;
|
||||
messageManager->post(&remoteBKSVReadMessage, this);
|
||||
//For DP1.4 atomic messaging, HDCP detection can be delayed, so lowering the priority.
|
||||
remoteBCapsReadMessage.setMessagePriority(NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT);
|
||||
remoteBCapsReadMessage.set(parentAddress, parent->address.tail(), NV_DPCD_HDCP_BCAPS_OFFSET, HDCP_BCAPS_SIZE);
|
||||
bCapsReadCompleted = false;
|
||||
bBCapsReadMessagePending = true;
|
||||
messageManager->post(&remoteBCapsReadMessage, this);
|
||||
}
|
||||
}
|
||||
else if (from == &remoteBKSVReadMessage)
|
||||
{
|
||||
bksvReadCompleted = true;
|
||||
bBKSVReadMessagePending = false;
|
||||
@@ -2792,59 +2874,6 @@ DeviceHDCPDetection::handleRemoteDpcdReadDownReply
|
||||
*(parent->nvBCaps) = *(parent->BCAPS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_LOG(("DP-QM> Device at '%s' is without valid BKSV and BCAPS, thus try 22BCAPS"));
|
||||
|
||||
Address parentAddress = parent->address.parent();
|
||||
remote22BCapsReadMessage.setMessagePriority(NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT);
|
||||
remote22BCapsReadMessage.set(parentAddress, parent->address.tail(), NV_DPCD_HDCP22_BCAPS_OFFSET, HDCP22_BCAPS_SIZE);
|
||||
bCapsReadCompleted = false;
|
||||
bBCapsReadMessagePending = true;
|
||||
messageManager->post(&remote22BCapsReadMessage, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (from == &remote22BCapsReadMessage)
|
||||
{
|
||||
bCapsReadCompleted = true;
|
||||
bBCapsReadMessagePending = false;
|
||||
DP_LOG(("DP-QM> REMOTE_DPCD_READ(22BCaps) {%p} at '%s' completed",
|
||||
(MessageManager::Message *)&remote22BCapsReadMessage,
|
||||
parent->address.toString(sb)));
|
||||
|
||||
if (remote22BCapsReadMessage.replyNumOfBytesReadDPCD() != HDCP22_BCAPS_SIZE)
|
||||
{
|
||||
DP_ASSERT(0 && "Incomplete 22BCaps in remote DPCD read message");
|
||||
parent->isHDCPCap = False;
|
||||
|
||||
// Destruct only when no message is pending
|
||||
if (!(bBKSVReadMessagePending || bBCapsReadMessagePending))
|
||||
{
|
||||
parent->isDeviceHDCPDetectionAlive = false;
|
||||
delete this;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DP_ASSERT(remote22BCapsReadMessage.replyPortNumber() == parent->address.tail());
|
||||
if (!!(*remote22BCapsReadMessage.replyGetData() & 0x2))
|
||||
{
|
||||
unsigned char hdcp22BCAPS;
|
||||
|
||||
hdcp22BCAPS = *remote22BCapsReadMessage.replyGetData();
|
||||
|
||||
parent->nvBCaps[0] = FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET,
|
||||
_HDCP_CAPABLE, (hdcp22BCAPS & 0x2) ? 1 : 0,
|
||||
parent->nvBCaps[0]) |
|
||||
FLD_SET_DRF_NUM(_DPCD, _HDCP_BCAPS_OFFSET, _HDCP_REPEATER,
|
||||
(hdcp22BCAPS & 0x1) ? 1 : 0, parent->nvBCaps[0]);
|
||||
|
||||
// hdcp22 will validate certificate's bksv directly.
|
||||
isBCapsHDCP = isValidBKSV = true;
|
||||
|
||||
DP_LOG(("DP-QM> Device at '%s' is with valid 22BCAPS : %x",
|
||||
parent->address.toString(sb), *remote22BCapsReadMessage.replyGetData()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "dp_internal.h"
|
||||
#include "dp_evoadapter.h"
|
||||
#include "dp_auxdefs.h"
|
||||
#include "dp_qse.h"
|
||||
#include "dp_tracing.h"
|
||||
#include "dp_vrr.h"
|
||||
#include <nvmisc.h>
|
||||
@@ -74,6 +75,7 @@ const struct
|
||||
DP_REG_VAL_TYPE valueType;
|
||||
} DP_REGKEY_TABLE [] =
|
||||
{
|
||||
{NV_DP_REGKEY_DISABLE_QSES, &dpRegkeyDatabase.bQsesDisabled, DP_REG_VAL_BOOL},
|
||||
{NV_DP_REGKEY_ENABLE_AUDIO_BEYOND_48K, &dpRegkeyDatabase.bAudioBeyond48kEnabled, DP_REG_VAL_BOOL},
|
||||
{NV_DP_REGKEY_OVERRIDE_DPCD_REV, &dpRegkeyDatabase.dpcdRevOveride, DP_REG_VAL_U32},
|
||||
{NV_DP_REGKEY_DISABLE_SSC, &dpRegkeyDatabase.bSscDisabled, DP_REG_VAL_BOOL},
|
||||
@@ -117,6 +119,7 @@ EvoMainLink::EvoMainLink(EvoInterface * provider, Timer * timer) :
|
||||
_isLTPhyRepeaterSupported = true;
|
||||
_rmPhyRepeaterCount = 0;
|
||||
dpMemZero(&_DSC, sizeof(_DSC));
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
|
||||
//
|
||||
// Tell RM to hands off on the DisplayPort hardware
|
||||
@@ -325,14 +328,260 @@ void EvoMainLink::triggerACT()
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_DP_SEND_ACT, ¶ms, sizeof params);
|
||||
}
|
||||
|
||||
void EvoMainLink::configureHDCPRenegotiate(NvU64 cN, NvU64 cKSV, bool bForceReAuth, bool bRxIDMsgPending){}
|
||||
void EvoMainLink::configureAndTriggerECF(NvU64 ecf, NvBool bForceClearEcf, NvBool bAddStreamBack)
|
||||
{
|
||||
NV0073_CTRL_CMD_DP_SET_ECF_PARAMS params = {0};
|
||||
params.subDeviceInstance = this->subdeviceIndex;
|
||||
params.sorIndex = provider->getSorIndex();
|
||||
params.ecf = ecf;
|
||||
//
|
||||
// ForceClearECF will delete DP MST Time slots along with ECF from GA10X and Later
|
||||
// if ADD Stream Back is set then it will add back same time slots after clearing ECF
|
||||
// bForceClear = TRUE should be set to have significance for bAddStreamBack
|
||||
// bForceClear will be only set in case of Detach Stream/Flush mode
|
||||
// bAddStream will also be set only in case of QSES error scenario
|
||||
// In all other cases these are set to FALSE
|
||||
//
|
||||
params.bForceClearEcf = bForceClearEcf;
|
||||
params.bAddStreamBack = bAddStreamBack;
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_ECF, ¶ms, sizeof params);
|
||||
triggerACT();
|
||||
// Wait for 1 link frame time for ECF to take effect i.e
|
||||
// Wait Time = 1024 MTPs * 64 clocks/MTP * (1/162MHz) = 404.5 us.
|
||||
// As the minimum time available for timer->sleep() is 1 ms hence taking that time
|
||||
timer->sleep(1);
|
||||
|
||||
}
|
||||
|
||||
//TODO: we need to re-arch this code to remove from dp library
|
||||
void EvoMainLink::configureHDCPRenegotiate(NvU64 cN, NvU64 cKSV, bool bForceReAuth, bool bRxIDMsgPending)
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
paramsHdcpCtrl.cN = cN;
|
||||
paramsHdcpCtrl.cKsv = cKSV;
|
||||
if (bForceReAuth)
|
||||
{
|
||||
paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_FORCE_REAUTH, _YES);
|
||||
}
|
||||
else
|
||||
{
|
||||
paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_FORCE_REAUTH, _NO);
|
||||
}
|
||||
|
||||
if (bRxIDMsgPending)
|
||||
{
|
||||
paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_RXIDMSG_PENDING, _YES);
|
||||
}
|
||||
else
|
||||
{
|
||||
paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_RXIDMSG_PENDING, _NO);
|
||||
}
|
||||
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD, _RENEGOTIATE);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL, ¶msHdcpCtrl, sizeof paramsHdcpCtrl);
|
||||
}
|
||||
|
||||
void EvoMainLink::configureHDCPDisableAuthentication()
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD, _DISABLE_AUTHENTICATION);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL, ¶msHdcpCtrl, sizeof paramsHdcpCtrl);
|
||||
}
|
||||
|
||||
void EvoMainLink::configureHDCPAbortAuthentication(AbortAuthReason abortAuthReason)
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
paramsHdcpCtrl.cN = HDCP_DUMMY_CN;
|
||||
paramsHdcpCtrl.cKsv = HDCP_DUMMY_CKSV;
|
||||
switch (abortAuthReason)
|
||||
{
|
||||
case UNTRUST: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _UNTRUST); break; //Abort due to Kp mismatch
|
||||
case UNRELBL: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _UNRELBL); break; //Abort due to repeated link failure
|
||||
case KSV_LEN: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _KSV_LEN); break; //Abort due to KSV length
|
||||
case KSV_SIG: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _KSV_SIG); break; //Abort due to KSV signature
|
||||
case SRM_SIG: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _SRM_SIG); break; //Abort due to SRM signature
|
||||
case SRM_REV: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _SRM_REV); break; //Abort due to SRM revocation
|
||||
case NORDY: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _NORDY); break; //Abort due to repeater not ready
|
||||
case KSVTOP: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _KSVTOP); break; //Abort due to KSV topology error
|
||||
case BADBKSV: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _BADBKSV); break; //Abort due to invalid Bksv
|
||||
default: paramsHdcpCtrl.flags |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _FLAGS_ABORT, _NONE); break; // Default value;
|
||||
}
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD, _ABORT_AUTHENTICATION);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL, ¶msHdcpCtrl, sizeof paramsHdcpCtrl);
|
||||
}
|
||||
|
||||
void EvoMainLink::configureHDCPValidateLink(HDCPValidateData &hdcpValidateData, NvU64 cN, NvU64 cKsv)
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
paramsHdcpCtrl.linkCount = 1;
|
||||
paramsHdcpCtrl.cN = cN;
|
||||
paramsHdcpCtrl.cKsv = cKsv;
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD, _VALIDATE_LINK);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL, ¶msHdcpCtrl, sizeof paramsHdcpCtrl);
|
||||
|
||||
for (unsigned i = 0; i < NV0073_CTRL_HDCP_VPRIME_SIZE; i++)
|
||||
{
|
||||
hdcpValidateData.vP[i] = paramsHdcpCtrl.vP[i];
|
||||
}
|
||||
|
||||
hdcpValidateData.aN = paramsHdcpCtrl.aN[0]; // Only primary link An for DP use.
|
||||
hdcpValidateData.mP = paramsHdcpCtrl.mP;
|
||||
}
|
||||
|
||||
void EvoMainLink::configureHDCPGetHDCPState(HDCPState &hdcpState)
|
||||
{
|
||||
// HDCP Not Supported
|
||||
hdcpState.HDCP_State_Repeater_Capable = false;
|
||||
hdcpState.HDCP_State_22_Capable = false;
|
||||
hdcpState.HDCP_State_Encryption = false;
|
||||
hdcpState.HDCP_State_Authenticated = false;
|
||||
NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS params = {0};
|
||||
params.subDeviceInstance = this->subdeviceIndex;
|
||||
params.displayId = this->displayId;
|
||||
|
||||
// Set CACHED to False, it will cause a hdcpStatusRead which gating the eng.
|
||||
// params.flags = FLD_SET_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _ENCRYPTING_CACHED, _TRUE, 0);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_STATE, ¶ms, sizeof params);
|
||||
|
||||
hdcpState.HDCP_State_1X_Capable = FLD_TEST_DRF(0073_CTRL_SPECIFIC,
|
||||
_HDCP_STATE, _RECEIVER_CAPABLE, _YES, params.flags) ? true : false;
|
||||
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _REPEATER_CAPABLE,
|
||||
_YES, params.flags) ||
|
||||
FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _HDCP22_REPEATER_CAPABLE,
|
||||
_YES, params.flags))
|
||||
{
|
||||
hdcpState.HDCP_State_Repeater_Capable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpState.HDCP_State_Repeater_Capable = false;
|
||||
}
|
||||
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _HDCP22_RECEIVER_CAPABLE,
|
||||
_YES, params.flags) ||
|
||||
FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _HDCP22_REPEATER_CAPABLE,
|
||||
_YES, params.flags))
|
||||
{
|
||||
hdcpState.HDCP_State_22_Capable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpState.HDCP_State_22_Capable = false;
|
||||
}
|
||||
|
||||
if (hdcpState.HDCP_State_22_Capable)
|
||||
{
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _HDCP22_ENCRYPTING,_YES, params.flags))
|
||||
{
|
||||
hdcpState.HDCP_State_Encryption = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpState.HDCP_State_Encryption = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE,_ENCRYPTING, _YES, params.flags))
|
||||
{
|
||||
hdcpState.HDCP_State_Encryption = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpState.HDCP_State_Encryption = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_STATE, _AUTHENTICATED,
|
||||
_YES, params.flags))
|
||||
{
|
||||
hdcpState.HDCP_State_Authenticated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdcpState.HDCP_State_Authenticated = false;
|
||||
}
|
||||
}
|
||||
|
||||
void EvoMainLink::disableAlternateScramblerReset()
|
||||
{
|
||||
NV0073_CTRL_DP_ASSR_CTRL_PARAMS assrParams;
|
||||
dpMemZero(&assrParams, sizeof(assrParams));
|
||||
assrParams.subDeviceInstance = subdeviceIndex;
|
||||
assrParams.displayId = displayId;
|
||||
|
||||
assrParams.cmd = DRF_DEF(0073_CTRL, _DP, _ASSR_CMD, _DISABLE);
|
||||
|
||||
NvU32 code = provider->rmControl0073(NV0073_CTRL_CMD_DP_ASSR_CTRL, &assrParams, sizeof(assrParams));
|
||||
|
||||
if (code != NVOS_STATUS_SUCCESS || assrParams.err)
|
||||
{
|
||||
DP_ASSERT(0 && "Unable to change scrambler reset");
|
||||
}
|
||||
}
|
||||
|
||||
bool EvoMainLink::setStreamType(unsigned streamIndex, NvU8 streamType, bool * bNeedReNegotiate)
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
paramsHdcpCtrl.streamIndex = streamIndex;
|
||||
paramsHdcpCtrl.streamType = streamType;
|
||||
|
||||
//
|
||||
// According to spec, Type1 content cannot be transmitted to repeater HDCP1.X downstream device.
|
||||
// Thus RM provides option for client that force to type0 instead repeater blank the output with type1.
|
||||
// TODO: check Playready/HWDRM behavior with this,
|
||||
// 1. Will it stop engaging HWDRM with this fix ?
|
||||
// 2. VPR blanking gets applied and blanks repeater display as well
|
||||
//
|
||||
paramsHdcpCtrl.bEnforceType0Hdcp1xDS = NV_TRUE;
|
||||
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD,
|
||||
_SET_TYPE);
|
||||
|
||||
*bNeedReNegotiate = false;
|
||||
|
||||
if (!provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL,
|
||||
¶msHdcpCtrl, sizeof paramsHdcpCtrl))
|
||||
{
|
||||
if (FLD_TEST_DRF(0073_CTRL_SPECIFIC, _HDCP_CTRL_FLAGS, _TYPE_CHANGED,
|
||||
_YES, paramsHdcpCtrl.flags))
|
||||
{
|
||||
*bNeedReNegotiate = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_LOG(("DP_EVO> set stream type cmd failed!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void EvoMainLink::forwardPendingKsvListReady(NvBool bKsvListReady)
|
||||
{
|
||||
dpMemZero(¶msHdcpCtrl, sizeof(paramsHdcpCtrl));
|
||||
paramsHdcpCtrl.subDeviceInstance = this->subdeviceIndex;
|
||||
paramsHdcpCtrl.displayId = this->displayId;
|
||||
paramsHdcpCtrl.bPendingKsvListReady = bKsvListReady;
|
||||
paramsHdcpCtrl.cmd |= DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD,
|
||||
_FORWARD_KSVLIST_READY);
|
||||
|
||||
provider->rmControl0073(NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL, ¶msHdcpCtrl,
|
||||
sizeof paramsHdcpCtrl);
|
||||
}
|
||||
|
||||
void EvoMainLink::configureSingleStream(NvU32 head,
|
||||
|
||||
@@ -154,8 +154,42 @@ void GroupImpl::insert(Device * dev)
|
||||
|
||||
members.insertFront(di);
|
||||
|
||||
// Is HDCP on for this group?
|
||||
// YES? Disable HDCP (ECF)
|
||||
this->hdcpPreviousStatus = this->hdcpEnabled;
|
||||
if (this->hdcpEnabled)
|
||||
{
|
||||
NvU64 ecf = 0x0;
|
||||
NvU64 countOnes = 0x0;
|
||||
NvU64 mask = 0x0;
|
||||
// Get the MASK for the all active groups which is ECF enabled.
|
||||
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
mask = countOnes << group->timeslot.begin;
|
||||
ecf |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
countOnes = (((NvU64)1) << this->timeslot.count) - 1;
|
||||
mask = countOnes << this->timeslot.begin;
|
||||
ecf &= ~mask;
|
||||
|
||||
parent->main->configureAndTriggerECF(ecf);
|
||||
this->hdcpEnabled = false;
|
||||
}
|
||||
|
||||
update(dev, true);
|
||||
|
||||
// After Add Stream, we turn the encryption back if it was on.
|
||||
if (this->hdcpPreviousStatus)
|
||||
{
|
||||
hdcpSetEncrypted(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GroupImpl::remove(Device * dev)
|
||||
@@ -184,6 +218,11 @@ void GroupImpl::destroy()
|
||||
// Cancel any queue the auth callback.
|
||||
cancelHdcpCallbacks();
|
||||
|
||||
if (streamEncryptionStatusDetection)
|
||||
{
|
||||
delete streamEncryptionStatusDetection;
|
||||
streamEncryptionStatusDetection = 0;
|
||||
}
|
||||
parent = this->parent;
|
||||
|
||||
if (parent)
|
||||
@@ -240,6 +279,8 @@ void GroupImpl::cancelHdcpCallbacks()
|
||||
parent->timer->cancelCallback(this, &tagHDCPReauthentication);
|
||||
parent->timer->cancelCallback(this, &tagStreamValidation);
|
||||
|
||||
QSESetECFRetries = 0;
|
||||
parent->timer->cancelCallback(this, &tagMSTQSEandSetECF);
|
||||
}
|
||||
|
||||
Device * GroupImpl::enumDevices(Device * previousDevice)
|
||||
@@ -287,12 +328,196 @@ void GroupImpl::expired(const void * tag)
|
||||
DP_ASSERT(0 && "DP> Didn't get final notification." );
|
||||
}
|
||||
}
|
||||
else if (tag == &tagMSTQSEandSetECF)
|
||||
{
|
||||
if (QSESetECFRetries < HDCP_QSEANDSETECF_RETRIES)
|
||||
{
|
||||
HDCPState hdcpState = {0};
|
||||
parent->main->configureHDCPGetHDCPState(hdcpState);
|
||||
this->hdcpEnabled = parent->isHDCPAuthOn = hdcpState.HDCP_State_Authenticated;
|
||||
|
||||
// Wait till authenticated then enable QSE and set ECF.
|
||||
if (parent->isHDCPAuthOn)
|
||||
{
|
||||
QSESetECFRetries = 0;
|
||||
parent->timer->cancelCallback(this, &tagMSTQSEandSetECF);
|
||||
hdcpMSTQSEandSetECF();
|
||||
}
|
||||
else
|
||||
{
|
||||
QSESetECFRetries++;
|
||||
parent->timer->queueCallback(this, &tagMSTQSEandSetECF,
|
||||
HDCP_QSEANDSETECF_COOLDOWN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DP_ASSERT(0 && "MST HDCP not authenticated within timeout and fail to set ECF." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bForceClear stands for bForceClearECF.
|
||||
bool GroupImpl::hdcpSetEncrypted(bool encrypted, NvU8 streamType, NvBool bForceClear, NvBool bAddStreamBack)
|
||||
{
|
||||
if (encrypted == true)
|
||||
{
|
||||
bool bNeedReNegotiate = false;
|
||||
HDCPState hdcpState = {0};
|
||||
|
||||
DP_LOG(("DP-GRP: enable encryption with type=%d.", streamType));
|
||||
|
||||
// enumerate the displays in the group and see if they are hdcp capable.
|
||||
Device * d = 0;
|
||||
bool isHdcpCapable = false;
|
||||
for (d = ((Group*)this)->enumDevices(0); d != 0; d = ((Group*)this)->enumDevices(d))
|
||||
{
|
||||
NvU8 Bcaps = (NvU8)(((DeviceImpl*)d)->nvBCaps[0]);
|
||||
|
||||
if ((FLD_TEST_DRF(_DPCD, _HDCP_BCAPS_OFFSET, _HDCP_CAPABLE, _YES, Bcaps)) &&
|
||||
(((DeviceImpl*)d)->isHDCPCap == True))
|
||||
{
|
||||
isHdcpCapable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isHdcpCapable == false)
|
||||
{
|
||||
DP_LOG(("DP-GRP: group does not contain a hdcp capable device."));
|
||||
return false;
|
||||
}
|
||||
|
||||
parent->main->configureHDCPGetHDCPState(hdcpState);
|
||||
|
||||
// Clear dplib authentication state if RM reports not authenticated.
|
||||
if (!hdcpState.HDCP_State_Authenticated)
|
||||
{
|
||||
parent->isHDCPAuthOn = this->hdcpEnabled = false;
|
||||
}
|
||||
|
||||
// Update stream content type and trigger negotiation if need.
|
||||
if ((hdcpState.HDCP_State_22_Capable) &&
|
||||
(false == parent->main->setStreamType(streamIndex, streamType, &bNeedReNegotiate)))
|
||||
{
|
||||
DP_LOG(("DP-GRP: group set stream type failed."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!parent->isHDCPAuthOn || bNeedReNegotiate)
|
||||
{
|
||||
cancelHdcpCallbacks();
|
||||
|
||||
parent->main->configureHDCPRenegotiate();
|
||||
parent->main->configureHDCPGetHDCPState(hdcpState);
|
||||
if (hdcpState.HDCP_State_Encryption)
|
||||
{
|
||||
parent->isHDCPAuthOn = this->hdcpEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->isHDCPAuthOn = this->hdcpEnabled = false;
|
||||
parent->timer->queueCallback(this, &tagHDCPReauthentication, HDCP_AUTHENTICATION_COOLDOWN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// SST is done when it's authenticated.
|
||||
if (!(parent->linkUseMultistream()))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent->linkUseMultistream())
|
||||
{
|
||||
// Check if authenticated else wait it's authenticated then assigning ECF.
|
||||
if(!parent->isHDCPAuthOn)
|
||||
{
|
||||
parent->timer->queueCallback(this, &tagMSTQSEandSetECF, HDCP_AUTHENTICATION_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->timer->cancelCallback(this, &tagMSTQSEandSetECF);
|
||||
hdcpMSTQSEandSetECF();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent->isHDCPAuthOn)
|
||||
{
|
||||
if (!(parent->linkUseMultistream()))
|
||||
{
|
||||
parent->main->configureHDCPDisableAuthentication();
|
||||
parent->isHDCPAuthOn = this->hdcpEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
NvU64 ecf = 0x0;
|
||||
NvU64 countOnes = 0x0;
|
||||
NvU64 mask = 0x0;
|
||||
|
||||
// Get the MASK for the all active groups which is ECF enabled.
|
||||
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
mask = countOnes << group->timeslot.begin;
|
||||
ecf |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
//Just clear the ECF not turn off the auth.
|
||||
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
DP_ASSERT(group->hdcpEnabled);
|
||||
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
mask = countOnes << group->timeslot.begin;
|
||||
ecf &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
parent->main->configureAndTriggerECF(ecf, bForceClear, bAddStreamBack);
|
||||
|
||||
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
group->hdcpEnabled = false;
|
||||
{ // Inform ConnectorEventSink that we have disabled HDCP on this Device
|
||||
Device * d = 0;
|
||||
for (d = ((Group*)this)->enumDevices(0); d != 0; d = ((Group*)this)->enumDevices(d))
|
||||
{
|
||||
if (((DeviceImpl*)d)->isHDCPCap == True)
|
||||
{
|
||||
parent->sink->notifyHDCPCapDone(d, False);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//DP_OPTION_HDCP_SUPPORT_ENABLE
|
||||
|
||||
bool GroupImpl::hdcpGetEncrypted()
|
||||
{
|
||||
//
|
||||
// Returns whether encryption is currently enabled
|
||||
// After the setECFencyption we just set the flag for this group and make the default as false.
|
||||
//
|
||||
if (parent->isHDCPAuthOn)
|
||||
{
|
||||
@@ -304,6 +529,130 @@ bool GroupImpl::hdcpGetEncrypted()
|
||||
}
|
||||
}
|
||||
|
||||
void GroupImpl::hdcpMSTQSEandSetECF()
|
||||
{
|
||||
//
|
||||
// We become passive and wait for the Stream_Status_Change coming.
|
||||
// Otherwise, we might not have the change to get the update KSVlist to
|
||||
// validate it. Before, Naresh's Stream_Status_Change p4r in.
|
||||
// We just simple turn it on. (which can be the option for non-QSE
|
||||
// (AKA intel/AMD plan) branch.)
|
||||
//
|
||||
|
||||
//
|
||||
// Enable sending QSES message only when regkey 'DISABLE_QSES' set to 0
|
||||
// in DD's path.
|
||||
// This is added to provide driver for ST and not to be productized.
|
||||
//
|
||||
if ((parent->bIsEncryptionQseValid) &&
|
||||
(!parent->main->getRegkeyValue(NV_DP_REGKEY_DISABLE_QSES)))
|
||||
{
|
||||
for (ListElement * i = parent->activeGroups.begin();
|
||||
i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
HDCPValidateData hdcpValidateData = {0};
|
||||
parent->main->configureHDCPValidateLink(hdcpValidateData);
|
||||
parent->qseNonceGenerator->clientIdBuilder(hdcpValidateData.aN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Turn on the ECF set ECF on according to the group's active stream.
|
||||
// Set flag for the goup for later getting status using.
|
||||
//
|
||||
NvU64 ecf = 0x0;
|
||||
NvU64 countOnes = 0x0;
|
||||
NvU64 mask = 0x0;
|
||||
|
||||
// Get the MASK for the all active groups which is ECF enabled.
|
||||
for (ListElement * i = parent->activeGroups.begin();
|
||||
i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
mask = countOnes << group->timeslot.begin;
|
||||
ecf |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
for (ListElement * i = parent->activeGroups.begin();
|
||||
i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
|
||||
mask = countOnes << group->timeslot.begin;
|
||||
ecf |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the ECF with new added group.
|
||||
parent->main->configureAndTriggerECF(ecf);
|
||||
|
||||
//
|
||||
// Enable sending QSES message only when regkey 'DISABLE_QSES' set to 0 in
|
||||
// DD's path.
|
||||
// This is added to provide driver for ST and not to be productized.
|
||||
//
|
||||
if ((parent->bIsEncryptionQseValid) &&
|
||||
(!parent->main->getRegkeyValue(NV_DP_REGKEY_DISABLE_QSES)))
|
||||
{
|
||||
for (ListElement * i = parent->activeGroups.begin();
|
||||
i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
if (NULL == group->streamEncryptionStatusDetection)
|
||||
{
|
||||
group->streamEncryptionStatusDetection =
|
||||
new StreamEncryptionStatusDetection(group, parent);
|
||||
}
|
||||
if (group->streamEncryptionStatusDetection)
|
||||
{
|
||||
parent->bValidQSERequest = true;
|
||||
group->streamEncryptionStatusDetection->sendQSEMessage(group);
|
||||
parent->timer->queueCallback(group,
|
||||
&(group->tagStreamValidation),
|
||||
HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ListElement * i = parent->activeGroups.begin();
|
||||
i != parent->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
|
||||
if (this->headIndex == group->headIndex)
|
||||
{
|
||||
DP_ASSERT(group->hdcpEnabled == false);
|
||||
group->hdcpEnabled = true;
|
||||
{ // Inform ConnectorEventSink that we have enabled HDCP on this Device
|
||||
Device * d = 0;
|
||||
for (d = ((Group*)this)->enumDevices(0); d != 0; d = ((Group*)this)->enumDevices(d))
|
||||
{
|
||||
if (((DeviceImpl*)d)->isHDCPCap == True)
|
||||
{
|
||||
parent->sink->notifyHDCPCapDone(d, True);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GroupImpl::updateVbiosScratchRegister(Device * lastDev)
|
||||
{
|
||||
if (!parent->bDisableVbiosScratchRegisterUpdate &&
|
||||
|
||||
@@ -668,6 +668,63 @@ bool SinkEventNotifyMessage::processByType(EncodedMessage * message, BitStreamRe
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QUERY_STREAM_ENCRYPTION_STATUS 0x38
|
||||
// Follow the SCR DP1.2 Query Stream Encryption Status Definition v0.4
|
||||
//
|
||||
void QueryStreamEncryptionMessage::set
|
||||
(
|
||||
const Address & target,
|
||||
unsigned streamId,
|
||||
NvU8* clientId,
|
||||
StreamEvent streamEvent,
|
||||
bool streamEventMask,
|
||||
StreamBehavior streamBehavior,
|
||||
bool streamBehaviorMask
|
||||
)
|
||||
{
|
||||
clear();
|
||||
|
||||
BitStreamWriter writer(&encodedMessage.buffer, 0);
|
||||
|
||||
// Write request identifier
|
||||
writer.write(0/*zero*/, 1);
|
||||
writer.write(requestIdentifier, 7);
|
||||
|
||||
// Write message request body
|
||||
writer.write(streamId, 8);
|
||||
for (unsigned i=0; i<7; i++)
|
||||
{
|
||||
writer.write(clientId[i], 8);
|
||||
}
|
||||
|
||||
writer.write(streamEvent, 2);
|
||||
writer.write(streamEventMask?1:0, 1);
|
||||
writer.write(streamBehavior, 2);
|
||||
writer.write(streamBehaviorMask?1:0, 1);
|
||||
writer.write(0 /*zeroes*/, 2);
|
||||
|
||||
encodedMessage.isPathMessage = false;
|
||||
encodedMessage.isBroadcast = false;
|
||||
encodedMessage.address = target;
|
||||
}
|
||||
|
||||
ParseResponseStatus QueryStreamEncryptionMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
|
||||
{
|
||||
reply.streamState = (StreamState)reader->readOrDefault(2 /*Stream_State*/, 0x0);
|
||||
reply.repeaterFuncPresent = !!reader->readOrDefault(1 /*Stream_Repeater_Function*/, 0x0);
|
||||
reply.encryption = !!reader->readOrDefault(1 /*Stream_Encryption */, 0x0);
|
||||
reply.authentication = !!reader->readOrDefault(1 /*Stream_Authentication */, 0x0);
|
||||
reader->readOrDefault(3 /*zero*/, 0);
|
||||
reply.sinkType = (OutputSinkType)reader->readOrDefault(3 /*Stream_Output_Sink_Type*/, 0x0);
|
||||
reply.cpType = (OutputCPType)reader->readOrDefault(2 /*Stream_Output_CP_Type*/, 0x0);
|
||||
reader->readOrDefault(2 /*zeroes*/, 0);
|
||||
reply.signedLPrime = !!reader->readOrDefault(1 /*Signed*/, 0x0);
|
||||
reply.streamId = (NvU8)reader->readOrDefault(8/*Stream_ID*/, 0x0);
|
||||
|
||||
return ParseResponseSuccess;
|
||||
}
|
||||
|
||||
I2cWriteTransaction::I2cWriteTransaction
|
||||
(
|
||||
unsigned WriteI2cDeviceId,
|
||||
|
||||
292
src/common/displayport/src/dp_qse.cpp
Normal file
292
src/common/displayport/src/dp_qse.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
/******************************* DisplayPort *******************************\
|
||||
* *
|
||||
* Module: dp_qse.cpp *
|
||||
* The DP HDCP Query Stream Encryption. *
|
||||
* *
|
||||
\***************************************************************************/
|
||||
|
||||
#include "dp_auxdefs.h"
|
||||
|
||||
#include "dp_qse.h"
|
||||
#include "dp_internal.h"
|
||||
#include "dp_deviceimpl.h"
|
||||
#include "dp_connectorimpl.h"
|
||||
#include <nvmisc.h>
|
||||
|
||||
using namespace DisplayPort;
|
||||
|
||||
NvU64
|
||||
QSENonceGenerator::random()
|
||||
{
|
||||
NvU64 randomNumber;
|
||||
|
||||
previousRandomLSB = static_cast<NvU32>(((NvU64)1664525 * previousRandomLSB + 1013904223));
|
||||
previousRandomMSB = static_cast<NvU32>(((NvU64)1664525 * previousRandomMSB + 1013904223));
|
||||
|
||||
randomNumber = ((NvU64)previousRandomMSB << 32) | previousRandomLSB ;
|
||||
|
||||
return randomNumber;
|
||||
}
|
||||
|
||||
void
|
||||
QSENonceGenerator::clientIdBuilder
|
||||
(
|
||||
NvU64 aN
|
||||
)
|
||||
{
|
||||
previousRandomMSB = (NvU32)(aN >> 32) ;
|
||||
previousRandomLSB = (NvU32)(aN & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void
|
||||
QSENonceGenerator::makeClientId
|
||||
(
|
||||
CLIENTID &clientId
|
||||
)
|
||||
{
|
||||
// Generate 56 bit nonce
|
||||
NvU64 rnd = random();
|
||||
|
||||
clientId.data[0] = static_cast<NvU8>( rnd & 0xFF);
|
||||
clientId.data[1] = static_cast<NvU8>((rnd >> 8) & 0xFF);
|
||||
clientId.data[2] = static_cast<NvU8>((rnd >> 16) & 0xFF);
|
||||
clientId.data[3] = static_cast<NvU8>((rnd >> 24) & 0xFF);
|
||||
clientId.data[4] = static_cast<NvU8>((rnd >> 32) & 0xFF);
|
||||
clientId.data[5] = static_cast<NvU8>((rnd >> 40) & 0xFF);
|
||||
clientId.data[6] = static_cast<NvU8>((rnd >> 48) & 0xFF);
|
||||
}
|
||||
|
||||
StreamEncryptionStatusDetection::~StreamEncryptionStatusDetection()
|
||||
{
|
||||
connector->timer->cancelCallbacks(this);
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::messageFailed
|
||||
(
|
||||
MessageManager::Message *from,
|
||||
NakData *nakData
|
||||
)
|
||||
{
|
||||
if (from == &qseMessage)
|
||||
{
|
||||
connector->messageManager->clearAwaitingQSEReplyDownRequest();
|
||||
|
||||
if ((retriesSendQSEMessage < DPCD_QUERY_STREAM_MESSAGE_RETRIES) &&
|
||||
(nakData->reason == NakDefer || nakData->reason == NakTimeout))
|
||||
{
|
||||
connector->timer->cancelCallback(parent, &(parent->tagStreamValidation));
|
||||
retriesSendQSEMessage++;
|
||||
sendQSEMessage(parent);
|
||||
connector->timer->queueCallback(parent, &(parent->tagStreamValidation), HDCP_STREAM_VALIDATION_REQUEST_COOLDOWN);
|
||||
return;
|
||||
}
|
||||
//
|
||||
// If message failed is called after all retries have expired then
|
||||
// we should disable the HDCP.
|
||||
//
|
||||
else
|
||||
{
|
||||
DP_LOG(("DP-QSE> Downstream failed to handle %s QSES message",
|
||||
reason == qseReason_Ssc ? "SSC" : "generic"));
|
||||
//
|
||||
// Non-QSE supported branch would get HDCP off if we honor QSES's result even w/o SSC from it.
|
||||
// So to improve compatibility, we honor QSES's result to have HDCP off only if it's fired for SSC.
|
||||
//
|
||||
if (reason == qseReason_Ssc)
|
||||
{
|
||||
for (ListElement * i = connector->activeGroups.begin(); i != connector->activeGroups.end(); i = i->next)
|
||||
{
|
||||
GroupImpl * group = (GroupImpl *)i;
|
||||
if (group->hdcpEnabled)
|
||||
{
|
||||
//
|
||||
// In case of MST, time slots will be deleted and add back for clearing ECF
|
||||
// This will lead to blank screen momentarily
|
||||
// Similarly for all other QSES errors
|
||||
//
|
||||
group->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
}
|
||||
}
|
||||
connector->main->configureHDCPAbortAuthentication(KSV_SIG);
|
||||
connector->main->configureHDCPDisableAuthentication();
|
||||
// Clear HDCP cap for groups and connector and devices.
|
||||
connector->isHDCPAuthOn = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
connector->bIsEncryptionQseValid = false;
|
||||
}
|
||||
|
||||
retriesSendQSEMessage = 0;
|
||||
parent->streamValidationDone = true;
|
||||
|
||||
//Reset the MessageManager pointer state
|
||||
resetQseMessageState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::expired(
|
||||
const void * tag
|
||||
)
|
||||
{
|
||||
// Not required as of now.
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::handleQSEDownReply()
|
||||
{
|
||||
if ((connector->bValidQSERequest) && (handleQSEReplyValidation()))
|
||||
{
|
||||
parent->streamValidationDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
connector->bValidQSERequest = true;
|
||||
parent->streamValidationDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::messageCompleted
|
||||
(
|
||||
MessageManager::Message *from
|
||||
)
|
||||
{
|
||||
if (from == &qseMessage)
|
||||
{
|
||||
handleQSEDownReply();
|
||||
|
||||
//Reset the MessageManager pointer state
|
||||
resetQseMessageState();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::sendQSEMessage
|
||||
(
|
||||
GroupImpl *group,
|
||||
QSE_REASON reasonId
|
||||
)
|
||||
{
|
||||
Address address(0);
|
||||
CLIENTID clientId;
|
||||
HDCPState hdcpState = {0};
|
||||
|
||||
// Get hdcp version to see if hdcp22 QSE or not.
|
||||
connector->main->configureHDCPGetHDCPState(hdcpState);
|
||||
setHdcp22Qse(hdcpState.HDCP_State_22_Capable);
|
||||
|
||||
// Check whether repeater or not.
|
||||
bIsRepeater = hdcpState.HDCP_State_Repeater_Capable;
|
||||
|
||||
//Generate the Pseudo Random number
|
||||
connector->qseNonceGenerator->makeClientId(clientId);
|
||||
for (unsigned i = 0 ; i < CLIENT_ID_SIZE; i++)
|
||||
{
|
||||
group->clientId[i] = clientId.data[i];
|
||||
}
|
||||
this->reason = reasonId;
|
||||
group->streamValidationDone = false;
|
||||
qseMessage.set( address,
|
||||
group->streamIndex,
|
||||
clientId.data,
|
||||
CP_IRQ_ON,
|
||||
STREAM_EVENT_MASK_ON,
|
||||
Force_Reauth,
|
||||
STREAM_BEHAVIOUR_MASK_ON);
|
||||
connector->messageManager->post(&qseMessage, this);
|
||||
}
|
||||
|
||||
bool
|
||||
StreamEncryptionStatusDetection::handleQSEReplyValidation()
|
||||
{
|
||||
if (parent->streamIndex != qseMessage.getStreamId())
|
||||
{
|
||||
DP_LOG(("DP-QSE> Query the active Stream ID %d, but reply Stream ID %d mismatch.", parent->streamIndex, qseMessage.getStreamId()));
|
||||
parent->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
return false;
|
||||
}
|
||||
|
||||
NvU16 streamStatus = 0;
|
||||
streamStatus = qseMessage.getStreamStatus();
|
||||
DP_LOG(("DP-QSE> Query the active Stream ID %d. The reply streamStatus: %d", parent->streamIndex, streamStatus));
|
||||
|
||||
NvU16 streamState = DRF_VAL(_DP, _HDCP, _STREAM_STATE, streamStatus);
|
||||
if ((streamState == NV_DP_HDCP_STREAM_STATE_NO_EXIST) ||
|
||||
(streamState == NV_DP_HDCP_STREAM_STATE_ERROR))
|
||||
{
|
||||
DP_LOG(("DP-QSE> Query the active Stream ID %d, but reply as Stream does not exist or Error/Reserved", parent->streamIndex));
|
||||
parent->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
return false;
|
||||
}
|
||||
else if (streamState == NV_DP_HDCP_STREAM_STATE_NOT_ACTIVE)
|
||||
{
|
||||
DP_LOG(("DP-QSE> Query the active Stream ID %d, but reply as Stream does not exist or Error/Reserved", parent->streamIndex));
|
||||
parent->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
return false;
|
||||
}
|
||||
|
||||
NvU16 streamAuth = DRF_VAL(_DP, _HDCP, _STREAM_AUTHENTICATION, streamStatus);
|
||||
if (streamAuth == NV_DP_HDCP_STREAM_AUTHENTICATION_OFF)
|
||||
{
|
||||
DP_LOG(("DP-QSE> Query the Stream ID %d, reply as not authentication all the way down", parent->streamIndex));
|
||||
|
||||
parent->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Watch here for not over reacting encryption policy here.
|
||||
NvU16 streamEncrypt = DRF_VAL(_DP, _HDCP, _STREAM_ENCRYPTION, streamStatus);
|
||||
if (streamEncrypt == NV_DP_HDCP_STREAM_ENCRYPTION_OFF)
|
||||
{
|
||||
if (parent->hdcpEnabled)
|
||||
{
|
||||
DP_LOG(("DP-QSE> Query the Stream ID %d, reply as not encryption all the way down", parent->streamIndex));
|
||||
parent->qseEncryptionStatusMismatch = parent->hdcpEnabled;
|
||||
parent->hdcpSetEncrypted(false, NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0, NV_TRUE, NV_TRUE);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::resetQseMessageState()
|
||||
{
|
||||
qseMessage.clear();
|
||||
}
|
||||
|
||||
void
|
||||
StreamEncryptionStatusDetection::setHdcp22Qse(bool bHdcp22Qse)
|
||||
{
|
||||
bIsHdcp22Qse = bHdcp22Qse;
|
||||
qseMessage.setHdcp22Qse(bHdcp22Qse);
|
||||
}
|
||||
@@ -39,6 +39,11 @@ void DPTestMessageCompletion::messageFailed(MessageManager::Message * from, NakD
|
||||
{
|
||||
parent->testMessageStatus = DP_TESTMESSAGE_REQUEST_STATUS_DONE;
|
||||
|
||||
if (from->getMsgType() == NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS)
|
||||
{
|
||||
delete (QueryStreamEncryptionMessage *)from;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
DP_ASSERT(0 && "unknown msg type when msg failed");
|
||||
@@ -50,6 +55,12 @@ void DPTestMessageCompletion::messageCompleted(MessageManager::Message * from)
|
||||
{
|
||||
parent->testMessageStatus = DP_TESTMESSAGE_REQUEST_STATUS_DONE;
|
||||
|
||||
if (from->getMsgType() == NV_DP_SBMSG_REQUEST_ID_QUERY_STREAM_ENCRYPTION_STATUS)
|
||||
{
|
||||
((QueryStreamEncryptionMessage *)from)->getReply(&parent->qsesReply);
|
||||
delete (QueryStreamEncryptionMessage *)from;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
DP_ASSERT(0 && "unknown msg type when msg complete");
|
||||
@@ -62,6 +73,31 @@ MessageManager * TestMessage::getMessageManager()
|
||||
return pMsgManager;
|
||||
}
|
||||
|
||||
//pBuffer should point to a DP_TESTMESSAGE_REQUEST_QSES_INPUT structure
|
||||
void TestMessage::sendTestMsgQSES(void *pBuffer)
|
||||
{
|
||||
//Generate the Pseudo Random number
|
||||
QSENonceGenerator qseNonceGenerator;
|
||||
|
||||
//for qses, send to the root branch
|
||||
Address address(0);
|
||||
CLIENTID clientId;
|
||||
QueryStreamEncryptionMessage *pQseMessage = new QueryStreamEncryptionMessage();
|
||||
|
||||
DP_TESTMESSAGE_REQUEST_QSES_INPUT *pQSES =
|
||||
(DP_TESTMESSAGE_REQUEST_QSES_INPUT *)pBuffer;
|
||||
|
||||
pQseMessage->set(address,
|
||||
pQSES->streamID,
|
||||
clientId.data,
|
||||
CP_IRQ_ON,
|
||||
STREAM_EVENT_MASK_ON,
|
||||
Force_Reauth,
|
||||
STREAM_BEHAVIOUR_MASK_ON);
|
||||
|
||||
pMsgManager->post(pQseMessage, &diagCompl);
|
||||
}
|
||||
|
||||
//
|
||||
// The function request that the request struct size should be check first to ensure the right structure is used and
|
||||
// no BSOD will happen.
|
||||
@@ -88,7 +124,45 @@ DP_TESTMESSAGE_STATUS TestMessage::sendDPTestMessage
|
||||
if (!isValidStruct(type, requestSize))
|
||||
return DP_TESTMESSAGE_STATUS_ERROR_INVALID_PARAM;
|
||||
|
||||
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_ERROR;
|
||||
return DP_TESTMESSAGE_STATUS_ERROR;
|
||||
switch (type)
|
||||
{
|
||||
case DP_TESTMESSAGE_REQUEST_TYPE_QSES:
|
||||
// new request, try send message
|
||||
if (*pDpStatus == DP_TESTMESSAGE_REQUEST_STATUS_NEWREQUEST)
|
||||
{
|
||||
//there is still processing request, new one not allow now
|
||||
if (testMessageStatus == DP_TESTMESSAGE_REQUEST_STATUS_PENDING)
|
||||
{
|
||||
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_ERROR;
|
||||
return DP_TESTMESSAGE_STATUS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
sendTestMsgQSES(pBuffer);
|
||||
//need change the DP lib status accordingly
|
||||
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_PENDING;
|
||||
testMessageStatus = DP_TESTMESSAGE_REQUEST_STATUS_PENDING;
|
||||
}
|
||||
}
|
||||
//old request, check if request finished
|
||||
else if(*pDpStatus == DP_TESTMESSAGE_REQUEST_STATUS_PENDING)
|
||||
{
|
||||
//already finished, fill in the data
|
||||
if (testMessageStatus == DP_TESTMESSAGE_REQUEST_STATUS_DONE)
|
||||
{
|
||||
DP_TESTMESSAGE_REQUEST_QSES_INPUT *p =
|
||||
(DP_TESTMESSAGE_REQUEST_QSES_INPUT *)pBuffer;
|
||||
p->reply = *(DP_TESTMESSAGE_REQUEST_QSES_OUTPUT *)&qsesReply;
|
||||
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_DONE;
|
||||
}
|
||||
//otherwise, just return and ask the user try again
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*pDpStatus = DP_TESTMESSAGE_REQUEST_STATUS_ERROR;
|
||||
return DP_TESTMESSAGE_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return DP_TESTMESSAGE_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
|
||||
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
|
||||
|
||||
#define NV_VERSION_STRING "540.3.2"
|
||||
#define NV_VERSION_STRING "540.5.0"
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -34,7 +34,11 @@ extern "C" {
|
||||
#define NVC370_NOTIFIERS_BEGIN NV5070_NOTIFIERS_MAXCOUNT
|
||||
#define NVC370_NOTIFIERS_RG_SEM_NOTIFICATION NVC370_NOTIFIERS_BEGIN + (0)
|
||||
#define NVC370_NOTIFIERS_WIN_SEM_NOTIFICATION NVC370_NOTIFIERS_RG_SEM_NOTIFICATION + (1)
|
||||
#define NVC370_NOTIFIERS_MAXCOUNT NVC370_NOTIFIERS_WIN_SEM_NOTIFICATION + (1)
|
||||
#define NVC370_NOTIFIERS_RG_VBLANK_NOTIFICATION NVC370_NOTIFIERS_WIN_SEM_NOTIFICATION + (1)
|
||||
#define NVC370_NOTIFIERS_MAXCOUNT NVC370_NOTIFIERS_RG_VBLANK_NOTIFICATION + (1)
|
||||
|
||||
// Store head in bits [15:8]. Bits [16:31] are used as NV01_EVENT_ flags and stripped out in _insertEventNotification
|
||||
#define NVC370_NOTIFIERS_RG_VBLANK_NOTIFYINDEX(head) ((NVC370_NOTIFIERS_RG_VBLANK_NOTIFICATION) | (NVBIT(head + 8)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; /* extern "C" */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -845,6 +845,175 @@ typedef struct NV0073_CTRL_SYSTEM_ACPI_SUBSYSTEM_ACTIVATED_PARAMS {
|
||||
|
||||
#define NV0073_CTRL_CMD_SYSTEM_ACPI_SUBSYSTEM_ACTIVATED (0x73015cU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_ACPI_SUBSYSTEM_ACTIVATED_PARAMS_MESSAGE_ID" */
|
||||
|
||||
/*
|
||||
* To support RMCTRLs for BOARDOBJGRP_E255, we were required to increase the
|
||||
* XAPI limit to 16K. It was observed that XP does NOT allow the static array
|
||||
* size greater then 10K and this was causing the DVS failure. So we are using
|
||||
* the OLD XAPI value i.e. 4K for NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX while
|
||||
* internally we are using the new updated XAPI value i.e. 16K.
|
||||
*/
|
||||
#define XAPI_ENVELOPE_MAX_PAYLOAD_SIZE_OLD 4096U
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_SYSTEM_SRM_CHUNK
|
||||
*
|
||||
* Several control commands require an SRM, which may be larger than the
|
||||
* available buffer. Therefore, this structure is used to transfer the needed
|
||||
* data.
|
||||
*
|
||||
* startByte
|
||||
* Index of the byte in the SRM buffer at which the current chunk of data
|
||||
* starts. If this value is 0, it indicates the start of a new SRM. A
|
||||
* value other than 0 indicates additional data for an SRM.
|
||||
* numBytes
|
||||
* Size in bytes of the current chunk of data.
|
||||
* totalBytes
|
||||
* Size in bytes of the entire SRM.
|
||||
* srmBuffer
|
||||
* Buffer containing the current chunk of SRM data.
|
||||
*/
|
||||
/* Set max SRM size to the XAPI max, minus some space for other fields */
|
||||
#define NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX (0xe00U) /* finn: Evaluated from "(XAPI_ENVELOPE_MAX_PAYLOAD_SIZE_OLD - 512)" */
|
||||
|
||||
typedef struct NV0073_CTRL_SYSTEM_SRM_CHUNK {
|
||||
NvU32 startByte;
|
||||
NvU32 numBytes;
|
||||
NvU32 totalBytes;
|
||||
|
||||
/* C form: NvU8 srmBuffer[NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX]; */
|
||||
NvU8 srmBuffer[NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX];
|
||||
} NV0073_CTRL_SYSTEM_SRM_CHUNK;
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_CMD_SYSTEM_VALIDATE_SRM
|
||||
*
|
||||
* Instructs the RM to validate the SRM for use by HDCP revocation. The SRM
|
||||
* may be larger than the buffer provided by the API. In that case, the SRM is
|
||||
* sent in chunks no larger than NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX bytes.
|
||||
*
|
||||
* Upon completion of the validation, which is an asynchronous operation, the
|
||||
* client will receive a <PLACE_HOLDER_EVENT> event. Alternatively, the client
|
||||
* may poll for completion of SRM validation via
|
||||
* NV0073_CTRL_CMD_SYSTEM_GET_SRM_STATUS.
|
||||
*
|
||||
* subDeviceInstance
|
||||
* This parameter specifies the subdevice instance within the
|
||||
* NV04_DISPLAY_COMMON parent device to which the operation should be
|
||||
* directed. This parameter must specify a value between zero and the
|
||||
* total number of subdevices within the parent device. This parameter
|
||||
* should be set to zero for default behavior.
|
||||
* srm
|
||||
* A chunk of the SRM.
|
||||
*
|
||||
* Possible status values returned are:
|
||||
* NV_OK
|
||||
* NV_ERR_NOT_SUPPORTED
|
||||
* NV_ERR_NOT_READY
|
||||
* NV_ERR_INVALID_ARGUMENT
|
||||
* NV_WARN_MORE_PROCESSING_REQUIRED
|
||||
* NV_ERR_INSUFFICIENT_RESOURCES
|
||||
*/
|
||||
#define NV0073_CTRL_CMD_SYSTEM_VALIDATE_SRM (0x73015eU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS_MESSAGE_ID" */
|
||||
|
||||
#define NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS_MESSAGE_ID (0x5EU)
|
||||
|
||||
typedef struct NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS {
|
||||
NvU32 subDeviceInstance;
|
||||
NV0073_CTRL_SYSTEM_SRM_CHUNK srm;
|
||||
} NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS;
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_CMD_SYSTEM_GET_SRM_STATUS
|
||||
*
|
||||
* Retrieves the status of the request to validate the SRM. If a request to
|
||||
* validate an SRM is still pending, NV_ERR_NOT_READY will be
|
||||
* returned and the status will not be updated.
|
||||
*
|
||||
* subDeviceInstance
|
||||
* This parameter specifies the subdevice instance within the
|
||||
* NV04_DISPLAY_COMMON parent device to which the operation should be
|
||||
* directed. This parameter must specify a value between zero and the
|
||||
* total number of subdevices within the parent device. This parameter
|
||||
* should be set to zero for default behavior.
|
||||
* status
|
||||
* Result of the last SRM validation request.
|
||||
*
|
||||
* Possible status values returned are:
|
||||
* NV_OK
|
||||
* NV_ERR_NOT_SUPPORTED
|
||||
* NV_ERR_NOT_READY
|
||||
*/
|
||||
#define NV0073_CTRL_CMD_SYSTEM_GET_SRM_STATUS (0x73015fU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS_MESSAGE_ID" */
|
||||
|
||||
typedef enum NV0073_CTRL_SYSTEM_SRM_STATUS {
|
||||
NV0073_CTRL_SYSTEM_SRM_STATUS_OK = 0, // Validation succeeded
|
||||
NV0073_CTRL_SYSTEM_SRM_STATUS_FAIL = 1, // Validation request failed
|
||||
NV0073_CTRL_SYSTEM_SRM_STATUS_BAD_FORMAT = 2, // Bad SRM format
|
||||
NV0073_CTRL_SYSTEM_SRM_STATUS_INVALID = 3, // Bad SRM signature
|
||||
} NV0073_CTRL_SYSTEM_SRM_STATUS;
|
||||
|
||||
#define NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS_MESSAGE_ID (0x5FU)
|
||||
|
||||
typedef struct NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS {
|
||||
NvU32 subDeviceInstance;
|
||||
NvU32 status;
|
||||
} NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_CMD_SYSTEM_HDCP_REVOCATION_CHECK
|
||||
*
|
||||
* Performs the HDCP revocation process. Given the supplied SRM, all attached
|
||||
* devices will be checked to see if they are on the revocation list or not.
|
||||
*
|
||||
* srm
|
||||
* The SRM to do the revocation check against. For SRMs larger than
|
||||
* NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX, the caller will need to break up the
|
||||
* SRM into chunks and make multiple calls.
|
||||
*
|
||||
* Possible status values returned are:
|
||||
* NV_OK
|
||||
* NV_ERR_NOT_SUPPORTED
|
||||
* NV_ERR_NOT_READY
|
||||
* NV_ERR_INVALID_ARGUMENT
|
||||
* NV_WARN_MORE_PROCESSING_REQUIRED
|
||||
* NV_ERR_INSUFFICIENT_RESOURCES
|
||||
*/
|
||||
#define NV0073_CTRL_CMD_SYSTEM_HDCP_REVOCATION_CHECK (0x730161U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS_MESSAGE_ID" */
|
||||
|
||||
#define NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS_MESSAGE_ID (0x61U)
|
||||
|
||||
typedef struct NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS {
|
||||
NV0073_CTRL_SYSTEM_SRM_CHUNK srm;
|
||||
} NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS;
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_CMD_UPDATE_SRM
|
||||
*
|
||||
* Updates the SRM used by RM for HDCP revocation checks. The SRM must have
|
||||
* been previously validated as authentic.
|
||||
*
|
||||
* srm
|
||||
* The SRM data. For SRMs larger than NV0073_CTRL_SYSTEM_SRM_BUFFER_MAX,
|
||||
* the caller will need to break up the SRM into chunks and make multiple
|
||||
* calls.
|
||||
*
|
||||
* Possible status values returned are:
|
||||
* NV_OK
|
||||
* NV_ERR_NOT_SUPPORTED
|
||||
* NV_ERR_NOT_READY
|
||||
* NV_ERR_INVALID_ARGUMENT
|
||||
* NV_WARN_MORE_PROCESSING_REQUIRED
|
||||
* NV_ERR_INSUFFICIENT_RESOURCES
|
||||
*/
|
||||
#define NV0073_CTRL_CMD_SYSTEM_UPDATE_SRM (0x730162U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS_MESSAGE_ID" */
|
||||
|
||||
#define NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS_MESSAGE_ID (0x62U)
|
||||
|
||||
typedef struct NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS {
|
||||
NV0073_CTRL_SYSTEM_SRM_CHUNK srm;
|
||||
} NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS;
|
||||
|
||||
/*
|
||||
* NV0073_CTRL_SYSTEM_CONNECTOR_INFO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -88,6 +88,8 @@ typedef struct NV0080_CTRL_OS_UNIX_VT_GET_FB_INFO_PARAMS {
|
||||
NvU16 height; /* out */
|
||||
NvU16 depth; /* out */
|
||||
NvU16 pitch; /* out */
|
||||
NV_DECLARE_ALIGNED(NvU64 baseAddress, 8); /* out */
|
||||
NV_DECLARE_ALIGNED(NvU64 size, 8); /* out */
|
||||
} NV0080_CTRL_OS_UNIX_VT_GET_FB_INFO_PARAMS;
|
||||
|
||||
/* _ctrl0080unix_h_ */
|
||||
|
||||
@@ -55,6 +55,11 @@ INLINE NvU32 F32viewAsNvU32(float32_t f)
|
||||
return f.v;
|
||||
}
|
||||
|
||||
INLINE NvU16 F16viewAsNvU16(float16_t f)
|
||||
{
|
||||
return f.v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the value of a float32_t to an NvU16.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -28,5 +28,18 @@
|
||||
|
||||
void nvHandleHotplugEventDeferredWork(void *dataPtr, NvU32 dataU32);
|
||||
void nvHandleDPIRQEventDeferredWork(void *dataPtr, NvU32 dataU32);
|
||||
void nvHandleCpEventDeferredWork(void *dataPtr, NvU32 dataU32);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
hdcpStatusChangeNotif_DontCare = 0,
|
||||
hdcpStatusChangeNotif_EncEnabled,
|
||||
hdcpStatusChangeNotif_RepComplete,
|
||||
hdcpStatusChangeNotif_KsvOk,
|
||||
hdcpStatusChangeNotif_HdcpDisabled,
|
||||
hdcpStatusChangeNotif_HdcpInactive,
|
||||
hdcpStatusChangeNotif_LinkFailed,
|
||||
hdcpStatusChangeNotif_HdcpRestart
|
||||
} HDCPSTATUSCHANGENOTIF, *PHDCPSTATUSCHANGENOTIF;
|
||||
|
||||
#endif /* __NVKMS_EVENT_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -237,7 +237,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
const NVHwModeTimingsEvo *pHwTimings,
|
||||
NvU8 hdmiFrlBpc,
|
||||
enum NvKmsOutputTf tf,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
|
||||
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue *pCurrentColorSpace,
|
||||
@@ -247,6 +247,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
|
||||
NVDispEvoPtr pDispEvo,
|
||||
const NvU32 head,
|
||||
const enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
|
||||
const enum NvKmsDpyAttributeColorRangeValue colorRange,
|
||||
NVEvoUpdateState *pUpdateState);
|
||||
@@ -359,6 +360,12 @@ void nvEvoPostModesetUnregisterFlipOccurredEvent(NVDispEvoRec *pDispEvo,
|
||||
const NVEvoModesetUpdateState
|
||||
*pModesetUpdate);
|
||||
|
||||
NvU32 nvEvoRegisterVBlankEvent(NVDispEvoRec *pDispEvo,
|
||||
const NvU32 head,
|
||||
NVVBlankIntrCallbackRec *cbRec);
|
||||
|
||||
void nvEvoUnregisterVBlankEvent(NVDispEvoRec *pDispEvo, NvU32 handle);
|
||||
|
||||
void nvEvoLockStateSetMergeMode(NVDispEvoPtr pDispEvo);
|
||||
|
||||
void nvEvoEnableMergeModePreModeset(NVDispEvoRec *pDispEvo,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2020 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -29,6 +29,8 @@
|
||||
typedef struct {
|
||||
struct {
|
||||
enum NvKmsOutputTf tf;
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace;
|
||||
enum NvKmsDpyAttributeColorBpcValue colorBpc;
|
||||
enum NvKmsDpyAttributeColorRangeValue colorRange;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2017 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -42,6 +42,7 @@ typedef struct {
|
||||
NVDispHeadInfoFrameStateEvoRec infoFrame;
|
||||
NvU8 allowFlipLockGroup;
|
||||
enum NvKmsOutputTf tf;
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
NvBool colorSpaceSpecified : 1;
|
||||
NvBool colorRangeSpecified : 1;
|
||||
NvBool hs10bpcHint : 1;
|
||||
|
||||
@@ -75,6 +75,16 @@ void nvApiHeadGetScanLine(const NVDispEvoRec *pDispEvo,
|
||||
NvU16 *pScanLine,
|
||||
NvBool *pInBlankingPeriod);
|
||||
|
||||
NVVBlankIntrCallbackRec*
|
||||
nvApiHeadRegisterVBlankIntrCallback(NVDispEvoPtr pDispEvo,
|
||||
const NvU32 apiHead,
|
||||
NVVBlankIntrCallbackProc pCallback,
|
||||
NvU64 param1,
|
||||
NvU64 param2);
|
||||
|
||||
void nvApiHeadUnregisterVBlankIntrCallback(NVDispEvoPtr pDispEvo,
|
||||
NVVBlankIntrCallbackRec *pCallback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -37,6 +37,7 @@ void nvFreePerOpenDev(struct NvKmsPerOpen *pOpen,
|
||||
struct NvKmsPerOpenDev *pOpenDev);
|
||||
|
||||
void nvSendDpyEventEvo(const NVDpyEvoRec *pDpyEvo, const NvU32 eventType);
|
||||
void nvSendDpyClearEventEvo(const NVDpyEvoRec *pDpyEvo, const NvU32 eventType);
|
||||
|
||||
void nvSendDpyAttributeChangedEventEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
const enum NvKmsDpyAttribute attribute,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -36,6 +36,12 @@ NvBool nvWriteDPCDReg(NVConnectorEvoPtr pConnectorEvo,
|
||||
NvU32 dpcdAddr,
|
||||
NvU8 dpcdData);
|
||||
|
||||
void nvGetContentProtectionState(NVConnectorEvoPtr pConnectorEvo,
|
||||
enum NvKmsContentProtection *cp);
|
||||
|
||||
void nvGetContentProtectionTopology(NVConnectorEvoPtr pConnectorEvo,
|
||||
struct NvKmsHdcpTopology *topology);
|
||||
|
||||
NvBool nvRmRegisterCallback(const NVDevEvoRec *pDevEvo,
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX *cb,
|
||||
struct nvkms_ref_ptr *ref_ptr,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -693,6 +693,10 @@ typedef struct {
|
||||
NvBool disableMidFrameAndDWCFWatermark;
|
||||
enum NvKmsOutputTf tf;
|
||||
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
|
||||
NvBool skipLayerPendingFlips[NVKMS_MAX_LAYERS_PER_HEAD];
|
||||
|
||||
struct {
|
||||
@@ -701,6 +705,8 @@ typedef struct {
|
||||
NvBool cursorPosition : 1;
|
||||
NvBool tf : 1;
|
||||
NvBool hdrStaticMetadata : 1;
|
||||
NvBool colorimetry : 1;
|
||||
NvBool outputColorRange : 1;
|
||||
|
||||
NvBool layerPosition[NVKMS_MAX_LAYERS_PER_HEAD];
|
||||
NvBool layerSyncObjects[NVKMS_MAX_LAYERS_PER_HEAD];
|
||||
@@ -924,10 +930,14 @@ typedef struct _NVEvoSubDeviceRec {
|
||||
|
||||
} NVEvoSubDeviceRec;
|
||||
|
||||
enum NvKmsLUTState {
|
||||
NvKmsLUTStateUninitialized = 0,
|
||||
NvKmsLUTStateIdentity = 1,
|
||||
NvKmsLUTStatePQ = 2,
|
||||
enum NVKMS_GAMMA_LUT {
|
||||
NVKMS_GAMMA_LUT_IDENTITY = 0,
|
||||
NVKMS_GAMMA_LUT_SRGB = 1,
|
||||
NVKMS_GAMMA_LUT_PQ = 2,
|
||||
NVKMS_GAMMA_LUT_BT709 = 3,
|
||||
|
||||
// Must be last, used to track number of colorspaces.
|
||||
NVKMS_GAMMA_LUT_LAST = 4,
|
||||
};
|
||||
|
||||
/* Device-specific EVO state (subdevice- and channel-independent) */
|
||||
@@ -978,6 +988,13 @@ typedef struct _NVEvoDevRec {
|
||||
*/
|
||||
NvBool modesetOwnerChanged;
|
||||
|
||||
/*!
|
||||
* modesetSubOwner points to the pOpenDev of the client that called
|
||||
* NVKMS_IOCTL_ACQUIRE_PERMISSIONS with a file descriptor that grants
|
||||
* NV_KMS_PERMISSIONS_TYPE_SUB_OWNER.
|
||||
*/
|
||||
const struct NvKmsPerOpenDev *modesetSubOwner;
|
||||
|
||||
/*!
|
||||
* NVEvoDevRec::numSubDevices is the number of GPUs in the SLI
|
||||
* device. This is the number of NVEvoSubDevPtrs in
|
||||
@@ -1193,9 +1210,8 @@ typedef struct _NVEvoDevRec {
|
||||
nvkms_timer_handle_t *updateTimer;
|
||||
} disp[NVKMS_MAX_SUBDEVICES];
|
||||
} apiHead[NVKMS_MAX_HEADS_PER_DISP];
|
||||
NVLutSurfaceEvoPtr defaultLut;
|
||||
enum NvKmsLUTState defaultBaseLUTState[NVKMS_MAX_SUBDEVICES];
|
||||
enum NvKmsLUTState defaultOutputLUTState[NVKMS_MAX_SUBDEVICES];
|
||||
// Identity, sRGB, and PQ LUTs.
|
||||
NVLutSurfaceEvoPtr gammaLUTs[NVKMS_GAMMA_LUT_LAST];
|
||||
} lut;
|
||||
|
||||
/*! stores pre-syncpts */
|
||||
@@ -1542,6 +1558,8 @@ typedef struct _NVConnectorEvoRec {
|
||||
|
||||
NvEldCase audioDevEldCase[NV_MAX_AUDIO_DEVICE_ENTRIES];
|
||||
|
||||
struct NvKmsHdcpTopology cpTopology;
|
||||
|
||||
NvBool isHdmiEnabled;
|
||||
} NVConnectorEvoRec;
|
||||
|
||||
@@ -1738,6 +1756,10 @@ typedef struct _NVDispHeadStateEvoRec {
|
||||
|
||||
enum NvKmsOutputTf tf;
|
||||
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
|
||||
struct {
|
||||
enum NvKmsHDROutputState outputState;
|
||||
struct NvKmsHDRStaticMetadata staticMetadata;
|
||||
@@ -1786,6 +1808,11 @@ typedef struct _NVDispApiHeadStateEvoRec {
|
||||
NVAttributesSetEvoRec attributes;
|
||||
|
||||
enum NvKmsOutputTf tf;
|
||||
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
|
||||
nvkms_timer_handle_t *hdrToSdrTransitionTimer;
|
||||
|
||||
/*
|
||||
@@ -1830,8 +1857,10 @@ typedef struct _NVDispEvoRec {
|
||||
NVDevEvoPtr pDevEvo;
|
||||
NvU32 hotplugEventHandle;
|
||||
NvU32 DPIRQEventHandle;
|
||||
NvU32 cpEventHandle;
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX rmHotplugCallback;
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX rmDPIRQCallback;
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX rmCpCallback;
|
||||
|
||||
NVDispHeadStateEvoRec headState[NVKMS_MAX_HEADS_PER_DISP];
|
||||
NVDispApiHeadStateEvoRec apiHeadState[NVKMS_MAX_HEADS_PER_DISP];
|
||||
@@ -1923,6 +1952,8 @@ typedef struct _NVDispEvoRec {
|
||||
NvU32 vrrSetTimeoutEventUsageCount;
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX vrrSetTimeoutCallback;
|
||||
NvU32 vrrSetTimeoutEventHandle;
|
||||
|
||||
NVListRec vblankIntrCallbackList[NVKMS_MAX_HEADS_PER_DISP];
|
||||
} NVDispEvoRec;
|
||||
|
||||
static inline NvU32 GetNextHwHead(NvU32 hwHeadsMask, const NvU32 prevHwHead)
|
||||
@@ -1987,6 +2018,19 @@ typedef struct _NVVBlankCallbackRec {
|
||||
NvU32 apiHead;
|
||||
} NVVBlankCallbackRec;
|
||||
|
||||
typedef void (*NVVBlankIntrCallbackProc)(NvU64 param1, NvU64 param2);
|
||||
|
||||
typedef struct _NVVBlankIntrCallbackRec {
|
||||
NVListRec vblankIntrCallbackListEntry;
|
||||
NVVBlankIntrCallbackProc pCallback;
|
||||
NvU32 apiHead;
|
||||
NvU32 rmVBlankCallbackHandle;
|
||||
NvU64 param1;
|
||||
NvU64 param2;
|
||||
struct nvkms_ref_ptr *ref_ptr;
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX vblankNotifierEventCallback;
|
||||
} NVVBlankIntrCallbackRec;
|
||||
|
||||
typedef void (*NVRgLine1CallbackProc)(NVDispEvoRec *pDispEvo,
|
||||
const NvU32 head,
|
||||
NVRgLine1CallbackPtr pCallbackData);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -55,6 +55,7 @@ typedef NvU32 NvKmsFrameLockHandle;
|
||||
typedef NvU32 NvKmsDeferredRequestFifoHandle;
|
||||
typedef NvU32 NvKmsSwapGroupHandle;
|
||||
typedef NvU32 NvKmsVblankSyncObjectHandle;
|
||||
typedef NvU32 NvKmsVblankIntrCallbackHandle;
|
||||
|
||||
struct NvKmsSize {
|
||||
NvU16 width;
|
||||
@@ -179,6 +180,8 @@ enum NvKmsEventType {
|
||||
NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED,
|
||||
NVKMS_EVENT_TYPE_FRAMELOCK_ATTRIBUTE_CHANGED,
|
||||
NVKMS_EVENT_TYPE_FLIP_OCCURRED,
|
||||
NVKMS_EVENT_TYPE_DPY_CP_CHANGED,
|
||||
NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -545,6 +548,36 @@ enum NvKmsInputColorRange {
|
||||
NVKMS_INPUT_COLORRANGE_FULL = 2,
|
||||
};
|
||||
|
||||
enum NvKmsOutputColorimetry {
|
||||
NVKMS_OUTPUT_COLORIMETRY_DEFAULT = 0,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_SRGB = 1,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT601 = 2,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT709 = 3,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT2020 = 4,
|
||||
|
||||
NVKMS_OUTPUT_COLORIMETRY_BT2100 = 5,
|
||||
};
|
||||
|
||||
/*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE attribute. */
|
||||
enum NvKmsDpyAttributeRequestedColorSpaceValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr422 = 1,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr444 = 2,
|
||||
};
|
||||
|
||||
/*!
|
||||
* * Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE and
|
||||
* * NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE attributes.
|
||||
* */
|
||||
enum NvKmsDpyAttributeColorRangeValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED = 1,
|
||||
};
|
||||
|
||||
enum NvKmsInputColorSpace {
|
||||
/* Unknown colorspace; no de-gamma will be applied */
|
||||
NVKMS_INPUT_COLORSPACE_NONE = 0,
|
||||
@@ -554,6 +587,21 @@ enum NvKmsInputColorSpace {
|
||||
|
||||
/* PQ, Rec.2020 unity */
|
||||
NVKMS_INPUT_COLORSPACE_BT2100_PQ = 2,
|
||||
|
||||
/* sRGB colorspace with sRGB gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_SRGB = 3,
|
||||
|
||||
/* Rec601 colorspace with Rec601 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT601 = 4,
|
||||
|
||||
/* Rec709 colorspace with Rec709 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT709 = 5,
|
||||
|
||||
/* Rec709 colorspace with linear (identity) gamma */
|
||||
NVKMS_INPUT_COLORSPACE_BT709_LINEAR = 6,
|
||||
|
||||
/* Rec2020 colorspace with Rec2020 gamma transfer function */
|
||||
NVKMS_INPUT_COLORSPACE_BT2020 = 7,
|
||||
};
|
||||
|
||||
enum NvKmsOutputTf {
|
||||
@@ -644,4 +692,33 @@ struct NvKmsSuperframeInfo {
|
||||
} view[NVKMS_MAX_SUPERFRAME_VIEWS];
|
||||
};
|
||||
|
||||
typedef void (*NVVBlankIntrCallbackProc)(NvU64 param1, NvU64 param2);
|
||||
|
||||
enum NvKmsContentProtection {
|
||||
NVKMS_CP_OFF = 0,
|
||||
NVKMS_CP_HDCP1X_ON = 1,
|
||||
NVKMS_CP_HDCP2X_TYPE0_ON = 2,
|
||||
NVKMS_CP_HDCP2X_TYPE1_ON = 3,
|
||||
};
|
||||
|
||||
#define HDCP_TOPOLOGY_MAX_LINK_COUNT (2)
|
||||
#define HDCP_TOPOLOGY_MAX_DEV_COUNT (255)
|
||||
#define HDCP_TOPOLOGY_KSV_SIZE (5)
|
||||
|
||||
struct NvKmsHdcpTopology {
|
||||
NvBool isHdcpCapable;
|
||||
NvBool isHdcpAuthOn;
|
||||
NvBool isHdcpRp;
|
||||
NvBool isHdcp2X;
|
||||
NvBool maxCascadeExceeded;
|
||||
NvBool maxDeviceExceeded;
|
||||
NvBool isHdcp1DevDownstream;
|
||||
NvBool isHdcp2LegacyDevDownstream;
|
||||
NvU8 cascadeDepth;
|
||||
NvU8 linkCount;
|
||||
NvU8 bksv[HDCP_TOPOLOGY_MAX_LINK_COUNT * HDCP_TOPOLOGY_KSV_SIZE];
|
||||
NvU8 numOfBksv;
|
||||
NvU8 bksvList[HDCP_TOPOLOGY_MAX_DEV_COUNT * HDCP_TOPOLOGY_KSV_SIZE];
|
||||
};
|
||||
|
||||
#endif /* NVKMS_API_TYPES_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -267,6 +267,9 @@ enum NvKmsIoctlCommand {
|
||||
NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT,
|
||||
NVKMS_IOCTL_DISABLE_VBLANK_SYNC_OBJECT,
|
||||
NVKMS_IOCTL_NOTIFY_VBLANK,
|
||||
NVKMS_IOCTL_QUERY_VT_FB_DATA,
|
||||
NVKMS_IOCTL_REGISTER_VBLANK_INTR_CALLBACK,
|
||||
NVKMS_IOCTL_UNREGISTER_VBLANK_INTR_CALLBACK,
|
||||
};
|
||||
|
||||
|
||||
@@ -747,6 +750,22 @@ struct NvKmsFlipCommonParams {
|
||||
NvBool specified;
|
||||
} tf;
|
||||
|
||||
/*
|
||||
* Specifies required output color space value.
|
||||
*/
|
||||
struct {
|
||||
NvBool specified;
|
||||
enum NvKmsOutputColorimetry val;
|
||||
} colorimetry;
|
||||
|
||||
/*
|
||||
* Specifies required output color range value.
|
||||
*/
|
||||
struct {
|
||||
NvBool specified;
|
||||
enum NvKmsDpyAttributeColorRangeValue val;
|
||||
} outputcolorrange;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
NvKmsSurfaceHandle handle[NVKMS_MAX_EYES];
|
||||
@@ -916,7 +935,12 @@ struct NvKmsFlipCommonParams {
|
||||
NvBool specified;
|
||||
} colorRange;
|
||||
|
||||
/* This field has no effect right now. */
|
||||
/*
|
||||
* Specifies the input colorspace and gamma encoding.
|
||||
* If this is specified as any non-NONE colorspace, the driver will
|
||||
* load a predefined ILUT for that colorspace, and that will take
|
||||
* precedence over any custom LUTs the client supplies.
|
||||
*/
|
||||
struct {
|
||||
enum NvKmsInputColorSpace val;
|
||||
NvBool specified;
|
||||
@@ -1465,6 +1489,19 @@ struct NvKmsQueryDpyDynamicDataParams {
|
||||
struct NvKmsQueryDpyDynamicDataReply reply; /*! out */
|
||||
};
|
||||
|
||||
struct NvKmsQueryVtFbDataRequest {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
};
|
||||
|
||||
struct NvKmsQueryVtFbDataReply {
|
||||
NvU64 baseAddress;
|
||||
NvU64 size;
|
||||
};
|
||||
|
||||
struct NvKmsQueryVtFbDataParams {
|
||||
struct NvKmsQueryVtFbDataRequest request; /*! in */
|
||||
struct NvKmsQueryVtFbDataReply reply; /*! out */
|
||||
};
|
||||
|
||||
/*!
|
||||
* NVKMS_IOCTL_VALIDATE_MODE_INDEX: Validate a particular mode from a
|
||||
@@ -1741,22 +1778,6 @@ enum NvKmsAllowAdaptiveSync {
|
||||
NVKMS_ALLOW_ADAPTIVE_SYNC_ALL,
|
||||
};
|
||||
|
||||
/*! Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE attribute. */
|
||||
enum NvKmsDpyAttributeRequestedColorSpaceValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr422 = 1,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr444 = 2,
|
||||
};
|
||||
|
||||
/*!
|
||||
* Values for the NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE and
|
||||
* NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE attributes.
|
||||
*/
|
||||
enum NvKmsDpyAttributeColorRangeValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED = 1,
|
||||
};
|
||||
|
||||
struct NvKmsSetModeOneHeadRequest {
|
||||
/*!
|
||||
* The list of dpys to drive with this head; or, empty to disable
|
||||
@@ -1791,7 +1812,12 @@ struct NvKmsSetModeOneHeadRequest {
|
||||
struct NvKmsSize viewPortSizeIn;
|
||||
|
||||
/*!
|
||||
* Describe the LUT to be used with the modeset.
|
||||
* Clients can supply custom ILUT and OLUT ramps through this variable. If
|
||||
* a client wishes to use a custom ILUT/OLUT, they must specify
|
||||
* NVKMS_INPUT_COLORSPACE_NONE (see NvKmsInputColorSpace in
|
||||
* FlipCommonParams) and NVKMS_OUTPUT_COLORSPACE_NONE (see
|
||||
* NvKmsOutputColorSpace below), otherwise the predefined LUTs for the
|
||||
* specified input/output colorspaces will be used instead.
|
||||
*/
|
||||
struct NvKmsSetLutCommonParams lut;
|
||||
|
||||
@@ -3035,6 +3061,32 @@ struct NvKmsEventFlipOccurred {
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* NVKMS_EVENT_TYPE_DPY_CP_CHANGED
|
||||
*
|
||||
* When a dpy content protection status changes, this event will be generated.
|
||||
*/
|
||||
|
||||
struct NvKmsEventDpyCpChanged {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
NvKmsDispHandle dispHandle;
|
||||
NVDpyId dpyId;
|
||||
enum NvKmsContentProtection cp;
|
||||
};
|
||||
|
||||
/*!
|
||||
* NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED
|
||||
*
|
||||
* When a dpy content protection topology changes, this event will be generated.
|
||||
*/
|
||||
|
||||
struct NvKmsEventDpyCpTopologyChanged {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
NvKmsDispHandle dispHandle;
|
||||
NVDpyId dpyId;
|
||||
struct NvKmsHdcpTopology *topology;
|
||||
};
|
||||
|
||||
struct NvKmsEvent {
|
||||
enum NvKmsEventType eventType;
|
||||
union {
|
||||
@@ -3044,6 +3096,8 @@ struct NvKmsEvent {
|
||||
struct NvKmsEventDpyAttributeChanged dpyAttributeChanged;
|
||||
struct NvKmsEventFrameLockAttributeChanged frameLockAttributeChanged;
|
||||
struct NvKmsEventFlipOccurred flipOccurred;
|
||||
struct NvKmsEventDpyCpChanged dpyCpChanged;
|
||||
struct NvKmsEventDpyCpTopologyChanged dpyCpTopologyChanged;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3189,6 +3243,11 @@ struct NvKmsSetLayerPositionParams {
|
||||
*
|
||||
* Releasing modeset ownership enables console hotplug handling. See the
|
||||
* explanation in the comment for enableConsoleHotplugHandling above.
|
||||
*
|
||||
* If modeset ownership is held by nvidia-drm, then NVKMS_IOCTL_GRAB_OWNERSHIP
|
||||
* will fail. Clients should open the corresponding DRM device node, acquire
|
||||
* 'master' on it, and then use DRM_NVIDIA_GRANT_PERMISSIONS with permission
|
||||
* type NV_DRM_PERMISSIONS_TYPE_SUB_OWNER to acquire sub-owner permission.
|
||||
*/
|
||||
|
||||
struct NvKmsGrabOwnershipRequest {
|
||||
@@ -3227,8 +3286,9 @@ struct NvKmsReleaseOwnershipParams {
|
||||
* successfully called NVKMS_IOCTL_GRAB_OWNERSHIP) is allowed to flip
|
||||
* or set modes.
|
||||
*
|
||||
* However, the modeset owner can grant various permissions to other
|
||||
* clients through the following steps:
|
||||
* However, the modeset owner or another NVKMS client with
|
||||
* NV_KMS_PERMISSIONS_TYPE_SUB_OWNER permission can grant various
|
||||
* permissions to other clients through the following steps:
|
||||
*
|
||||
* - The modeset owner should open /dev/nvidia-modeset, and call
|
||||
* NVKMS_IOCTL_GRANT_PERMISSIONS to define a set of permissions
|
||||
@@ -3277,6 +3337,7 @@ struct NvKmsReleaseOwnershipParams {
|
||||
enum NvKmsPermissionsType {
|
||||
NV_KMS_PERMISSIONS_TYPE_FLIPPING = 1,
|
||||
NV_KMS_PERMISSIONS_TYPE_MODESET = 2,
|
||||
NV_KMS_PERMISSIONS_TYPE_SUB_OWNER = 3,
|
||||
};
|
||||
|
||||
struct NvKmsFlipPermissions {
|
||||
@@ -4024,4 +4085,40 @@ struct NvKmsNotifyVblankParams {
|
||||
struct NvKmsNotifyVblankReply reply; /*! out */
|
||||
};
|
||||
|
||||
struct NvKmsRegisterVblankIntrCallbackRequest {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
NvKmsDispHandle dispHandle;
|
||||
NvU32 head;
|
||||
|
||||
NVVBlankIntrCallbackProc pCallback;
|
||||
NvU64 param1;
|
||||
NvU64 param2;
|
||||
};
|
||||
|
||||
struct NvKmsRegisterVblankIntrCallbackReply {
|
||||
NvKmsVblankIntrCallbackHandle callbackHandle;
|
||||
};
|
||||
|
||||
struct NvKmsRegisterVblankIntrCallbackParams {
|
||||
struct NvKmsRegisterVblankIntrCallbackRequest request; /*! in */
|
||||
struct NvKmsRegisterVblankIntrCallbackReply reply; /*! out */
|
||||
};
|
||||
|
||||
struct NvKmsUnregisterVblankIntrCallbackRequest {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
NvKmsDispHandle dispHandle;
|
||||
NvU32 head;
|
||||
|
||||
NvKmsVblankIntrCallbackHandle callbackHandle;
|
||||
};
|
||||
|
||||
struct NvKmsUnregisterVblankIntrCallbackReply {
|
||||
NvU32 padding;
|
||||
};
|
||||
|
||||
struct NvKmsUnregisterVblankIntrCallbackParams {
|
||||
struct NvKmsUnregisterVblankIntrCallbackRequest request; /*! in */
|
||||
struct NvKmsUnregisterVblankIntrCallbackReply reply; /*! out */
|
||||
};
|
||||
|
||||
#endif /* NVKMS_API_H */
|
||||
|
||||
@@ -120,6 +120,10 @@ struct NvKmsKapiSurface {
|
||||
NvKmsSurfaceHandle hKmsHandle;
|
||||
};
|
||||
|
||||
struct NvKmsKapiVblankIntrCallback {
|
||||
NvKmsVblankIntrCallbackHandle hKmsHandle;
|
||||
};
|
||||
|
||||
static inline void *nvKmsKapiCalloc(size_t nmem, size_t size)
|
||||
{
|
||||
return nvInternalAlloc(nmem * size, NV_TRUE);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nvtypes.h"
|
||||
|
||||
#include "nv-gpu-info.h"
|
||||
#include "nv_dpy_id.h"
|
||||
#include "nvkms-api-types.h"
|
||||
#include "nvkms-format.h"
|
||||
|
||||
@@ -190,6 +191,7 @@ struct NvKmsKapiConnectorInfo {
|
||||
NvU32 numIncompatibleConnectors;
|
||||
NvKmsKapiConnector incompatibleConnectorHandles[NVKMS_KAPI_MAX_CONNECTORS];
|
||||
|
||||
NVDpyIdList dynamicDpyIdList;
|
||||
};
|
||||
|
||||
struct NvKmsKapiStaticDisplayInfo {
|
||||
@@ -208,6 +210,8 @@ struct NvKmsKapiStaticDisplayInfo {
|
||||
NvKmsKapiDisplay possibleCloneHandles[NVKMS_KAPI_MAX_CLONE_DISPLAYS];
|
||||
|
||||
NvU32 headMask;
|
||||
|
||||
NvBool isDpMST;
|
||||
};
|
||||
|
||||
struct NvKmsKapiSyncpt {
|
||||
@@ -248,6 +252,9 @@ struct NvKmsKapiLayerConfig {
|
||||
NvU16 dstWidth, dstHeight;
|
||||
|
||||
enum NvKmsInputColorSpace inputColorSpace;
|
||||
enum NvKmsInputColorRange inputColorRange;
|
||||
struct NvKmsCscMatrix csc;
|
||||
NvBool cscUseMain;
|
||||
};
|
||||
|
||||
struct NvKmsKapiLayerRequestedConfig {
|
||||
@@ -258,6 +265,7 @@ struct NvKmsKapiLayerRequestedConfig {
|
||||
NvBool srcWHChanged : 1;
|
||||
NvBool dstXYChanged : 1;
|
||||
NvBool dstWHChanged : 1;
|
||||
NvBool cscChanged : 1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
@@ -301,6 +309,10 @@ struct NvKmsKapiHeadModeSetConfig {
|
||||
struct NvKmsKapiDisplayMode mode;
|
||||
|
||||
NvBool vrrEnabled;
|
||||
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
|
||||
enum NvKmsDpyAttributeColorRangeValue outputColorRange;
|
||||
};
|
||||
|
||||
struct NvKmsKapiHeadRequestedConfig {
|
||||
@@ -309,6 +321,8 @@ struct NvKmsKapiHeadRequestedConfig {
|
||||
NvBool activeChanged : 1;
|
||||
NvBool displaysChanged : 1;
|
||||
NvBool modeChanged : 1;
|
||||
NvBool colorrangeChanged: 1;
|
||||
NvBool colorimetryChanged : 1;
|
||||
} flags;
|
||||
|
||||
struct NvKmsKapiCursorRequestedConfig cursorRequestedConfig;
|
||||
@@ -341,6 +355,16 @@ struct NvKmsKapiEventDisplayChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDisplayCpChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
enum NvKmsContentProtection cp;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDisplayCpTopologyChanged {
|
||||
NvKmsKapiDisplay display;
|
||||
struct NvKmsHdcpTopology *topology;
|
||||
};
|
||||
|
||||
struct NvKmsKapiEventDynamicDisplayConnected {
|
||||
NvKmsKapiDisplay display;
|
||||
};
|
||||
@@ -372,6 +396,8 @@ struct NvKmsKapiEvent {
|
||||
struct NvKmsKapiEventDisplayChanged displayChanged;
|
||||
struct NvKmsKapiEventDynamicDisplayConnected dynamicDisplayConnected;
|
||||
struct NvKmsKapiEventFlipOccurred flipOccurred;
|
||||
struct NvKmsKapiEventDisplayCpChanged displayCpChanged;
|
||||
struct NvKmsKapiEventDisplayCpTopologyChanged displayCpTopologyChanged;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -411,6 +437,14 @@ struct NvKmsKapiDynamicDisplayParams {
|
||||
NvBool forceDisconnected;
|
||||
};
|
||||
|
||||
struct NvKmsKapiVtFbParams {
|
||||
/* [OUT] VT framebuffer memory base address */
|
||||
NvU64 baseAddress;
|
||||
|
||||
/* [OUT] VT framebuffer memory size */
|
||||
NvU64 size;
|
||||
};
|
||||
|
||||
struct NvKmsKapiCreateSurfaceParams {
|
||||
|
||||
/* [IN] Parameter of each plane */
|
||||
@@ -455,6 +489,8 @@ typedef enum NvKmsKapiRegisterWaiterResultRec {
|
||||
NVKMS_KAPI_REG_WAITER_ALREADY_SIGNALLED,
|
||||
} NvKmsKapiRegisterWaiterResult;
|
||||
|
||||
typedef void NvKmsKapiSuspendResumeCallbackFunc(NvBool suspend);
|
||||
|
||||
struct NvKmsKapiFunctionsTable {
|
||||
|
||||
/*!
|
||||
@@ -540,8 +576,8 @@ struct NvKmsKapiFunctionsTable {
|
||||
);
|
||||
|
||||
/*!
|
||||
* Revoke permissions previously granted. Only one (dispIndex, head,
|
||||
* display) is currently supported.
|
||||
* Revoke modeset permissions previously granted. Only one (dispIndex,
|
||||
* head, display) is currently supported.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
@@ -558,6 +594,34 @@ struct NvKmsKapiFunctionsTable {
|
||||
NvKmsKapiDisplay display
|
||||
);
|
||||
|
||||
/*!
|
||||
* Grant modeset sub-owner permissions to fd. This is used by clients to
|
||||
* convert drm 'master' permissions into nvkms sub-owner permission.
|
||||
*
|
||||
* \param [in] fd fd from opening /dev/nvidia-modeset.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*grantSubOwnership)
|
||||
(
|
||||
NvS32 fd,
|
||||
struct NvKmsKapiDevice *device
|
||||
);
|
||||
|
||||
/*!
|
||||
* Revoke sub-owner permissions previously granted.
|
||||
*
|
||||
* \param [in] device A device returned by allocateDevice().
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*revokeSubOwnership)
|
||||
(
|
||||
struct NvKmsKapiDevice *device
|
||||
);
|
||||
|
||||
/*!
|
||||
* Registers for notification, via
|
||||
* NvKmsKapiAllocateDeviceParams::eventCallback, of the events specified
|
||||
@@ -679,6 +743,20 @@ struct NvKmsKapiFunctionsTable {
|
||||
struct NvKmsKapiDynamicDisplayParams *params
|
||||
);
|
||||
|
||||
/*!
|
||||
* Get VT framebuffer information.
|
||||
*
|
||||
* \param [out] params Parameters containing the base address and size
|
||||
* of VT framebuffer memory
|
||||
*
|
||||
* \return NV_TRUE on success, NV_FALSE on failure.
|
||||
*/
|
||||
NvBool (*getVtFbInfo)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiVtFbParams *params
|
||||
);
|
||||
|
||||
/*!
|
||||
* Allocate some unformatted video memory of the specified size.
|
||||
*
|
||||
@@ -1336,6 +1414,27 @@ struct NvKmsKapiFunctionsTable {
|
||||
NvU64 index,
|
||||
NvU64 new_value
|
||||
);
|
||||
|
||||
/*!
|
||||
* Set the callback function for suspending and resuming the display system.
|
||||
*/
|
||||
void
|
||||
(*setSuspendResumeCallback)
|
||||
(
|
||||
NvKmsKapiSuspendResumeCallbackFunc *function
|
||||
);
|
||||
|
||||
struct NvKmsKapiVblankIntrCallback*
|
||||
(*RegisterVblankIntrCallback)(struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
NVVBlankIntrCallbackProc pCallback,
|
||||
NvU64 param1,
|
||||
NvU64 param2);
|
||||
|
||||
void (*UnregisterVblankIntrCallback)(
|
||||
struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
struct NvKmsKapiVblankIntrCallback *pCallback);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -62,6 +62,8 @@ ct_assert(NVKMS_KAPI_LAYER_MAX == NVKMS_MAX_LAYERS_PER_HEAD);
|
||||
#define NVKMS_KAPI_SUPPORTED_EVENTS_MASK \
|
||||
((1 << NVKMS_EVENT_TYPE_DPY_CHANGED) | \
|
||||
(1 << NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED) | \
|
||||
(1 << NVKMS_EVENT_TYPE_DPY_CP_CHANGED) | \
|
||||
(1 << NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED) | \
|
||||
(1 << NVKMS_EVENT_TYPE_FLIP_OCCURRED))
|
||||
|
||||
static NvU32 EnumerateGpus(nv_gpu_info_t *gpuInfo)
|
||||
@@ -915,6 +917,51 @@ static NvBool RevokePermissions
|
||||
sizeof(paramsRevoke));
|
||||
}
|
||||
|
||||
static NvBool GrantSubOwnership
|
||||
(
|
||||
NvS32 fd,
|
||||
struct NvKmsKapiDevice *device
|
||||
)
|
||||
{
|
||||
struct NvKmsGrantPermissionsParams paramsGrant = { };
|
||||
struct NvKmsPermissions *perm = ¶msGrant.request.permissions;
|
||||
|
||||
if (device->hKmsDevice == 0x0) {
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
perm->type = NV_KMS_PERMISSIONS_TYPE_SUB_OWNER;
|
||||
|
||||
paramsGrant.request.fd = fd;
|
||||
paramsGrant.request.deviceHandle = device->hKmsDevice;
|
||||
|
||||
return nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_GRANT_PERMISSIONS, ¶msGrant,
|
||||
sizeof(paramsGrant));
|
||||
}
|
||||
|
||||
static NvBool RevokeSubOwnership
|
||||
(
|
||||
struct NvKmsKapiDevice *device
|
||||
)
|
||||
{
|
||||
struct NvKmsRevokePermissionsParams paramsRevoke = { };
|
||||
|
||||
if (device->hKmsDevice == 0x0) {
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
paramsRevoke.request.permissionsTypeBitmask =
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_FLIPPING) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_MODESET) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER);
|
||||
paramsRevoke.request.deviceHandle = device->hKmsDevice;
|
||||
|
||||
return nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_REVOKE_PERMISSIONS, ¶msRevoke,
|
||||
sizeof(paramsRevoke));
|
||||
}
|
||||
|
||||
static NvBool DeclareEventInterest
|
||||
(
|
||||
const struct NvKmsKapiDevice *device,
|
||||
@@ -1125,7 +1172,10 @@ static NvBool GetConnectorInfo
|
||||
)
|
||||
{
|
||||
struct NvKmsQueryConnectorStaticDataParams paramsConnector = { };
|
||||
struct NvKmsQueryConnectorDynamicDataParams paramsDynamicConnector = { };
|
||||
NvBool status = NV_FALSE;
|
||||
NvU64 startTime = 0;
|
||||
NvBool timeout;
|
||||
|
||||
if (device == NULL || info == NULL) {
|
||||
goto done;
|
||||
@@ -1156,6 +1206,44 @@ static NvBool GetConnectorInfo
|
||||
|
||||
info->type = paramsConnector.reply.type;
|
||||
|
||||
|
||||
startTime = nvkms_get_usec();
|
||||
do {
|
||||
nvkms_memset(¶msDynamicConnector, 0, sizeof(paramsDynamicConnector));
|
||||
paramsDynamicConnector.request.deviceHandle = device->hKmsDevice;
|
||||
paramsDynamicConnector.request.dispHandle = device->hKmsDisp;
|
||||
paramsDynamicConnector.request.connectorHandle = connector;
|
||||
|
||||
if (!nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_QUERY_CONNECTOR_DYNAMIC_DATA,
|
||||
¶msDynamicConnector,
|
||||
sizeof(paramsDynamicConnector))) {
|
||||
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"Failed to query dynamic data of connector 0x%08x",
|
||||
connector);
|
||||
status = NV_FALSE;
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
timeout = nvkms_get_usec() - startTime >
|
||||
NVKMS_DP_DETECT_COMPLETE_TIMEOUT_USEC;
|
||||
|
||||
if (!paramsDynamicConnector.reply.detectComplete && !timeout) {
|
||||
nvkms_usleep(NVKMS_DP_DETECT_COMPLETE_POLL_INTERVAL_USEC);
|
||||
}
|
||||
} while (!paramsDynamicConnector.reply.detectComplete && !timeout);
|
||||
|
||||
if (!paramsDynamicConnector.reply.detectComplete) {
|
||||
nvKmsKapiLogDeviceDebug(device, "Timed out waiting for DisplayPort"
|
||||
" device detection to complete.");
|
||||
status = NV_FALSE;
|
||||
}
|
||||
|
||||
info->dynamicDpyIdList = paramsDynamicConnector.reply.dynamicDpyIdList;
|
||||
|
||||
done:
|
||||
|
||||
return status;
|
||||
@@ -1208,6 +1296,7 @@ static NvBool GetStaticDisplayInfo
|
||||
|
||||
info->internal = paramsDpyStatic.reply.mobileInternal;
|
||||
info->headMask = paramsDpyStatic.reply.headMask;
|
||||
info->isDpMST = paramsDpyStatic.reply.isDpMST;
|
||||
done:
|
||||
|
||||
return status;
|
||||
@@ -1289,6 +1378,40 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static NvBool GetVtFbInfo
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiVtFbParams *pParam
|
||||
)
|
||||
{
|
||||
struct NvKmsQueryVtFbDataParams params = { };
|
||||
NvBool status = NV_FALSE;
|
||||
|
||||
if (device == NULL || pParam == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
params.request.deviceHandle = device->hKmsDevice;
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_QUERY_VT_FB_DATA,
|
||||
¶ms, sizeof(params));
|
||||
|
||||
if (!status)
|
||||
{
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"Failed to query VT framebuffer information");
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
pParam->baseAddress = params.reply.baseAddress;
|
||||
pParam->size = params.reply.size;
|
||||
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void FreeMemory
|
||||
(
|
||||
struct NvKmsKapiDevice *device, struct NvKmsKapiMemory *memory
|
||||
@@ -2534,6 +2657,14 @@ static NvBool NvKmsKapiOverlayLayerConfigToKms(
|
||||
layerConfig->minPresentInterval;
|
||||
}
|
||||
|
||||
if (layerRequestedConfig->flags.cscChanged || bFromKmsSetMode) {
|
||||
params->layer[layer].csc.specified = NV_TRUE;
|
||||
params->layer[layer].csc.useMain = layerConfig->cscUseMain;
|
||||
if (!layerConfig->cscUseMain) {
|
||||
params->layer[layer].csc.matrix = layerConfig->csc;
|
||||
}
|
||||
}
|
||||
|
||||
params->layer[layer].sizeIn.val.width = layerConfig->srcWidth;
|
||||
params->layer[layer].sizeIn.val.height = layerConfig->srcHeight;
|
||||
params->layer[layer].sizeIn.specified = TRUE;
|
||||
@@ -2552,6 +2683,9 @@ static NvBool NvKmsKapiOverlayLayerConfigToKms(
|
||||
params->layer[layer].colorSpace.val = layerConfig->inputColorSpace;
|
||||
params->layer[layer].colorSpace.specified = TRUE;
|
||||
|
||||
params->layer[layer].colorRange.val = layerConfig->inputColorRange;
|
||||
params->layer[layer].colorRange.specified = TRUE;
|
||||
|
||||
AssignHDRMetadataConfig(layerConfig, layer, params);
|
||||
|
||||
if (commit) {
|
||||
@@ -2649,9 +2783,22 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (layerRequestedConfig->flags.cscChanged || bFromKmsSetMode) {
|
||||
nvAssert(!layerConfig->cscUseMain);
|
||||
|
||||
params->layer[NVKMS_MAIN_LAYER].csc.specified = NV_TRUE;
|
||||
params->layer[NVKMS_MAIN_LAYER].csc.useMain = FALSE;
|
||||
params->layer[NVKMS_MAIN_LAYER].csc.matrix = layerConfig->csc;
|
||||
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
params->layer[NVKMS_MAIN_LAYER].colorSpace.val = layerConfig->inputColorSpace;
|
||||
params->layer[NVKMS_MAIN_LAYER].colorSpace.specified = TRUE;
|
||||
|
||||
params->layer[NVKMS_MAIN_LAYER].colorRange.val = layerConfig->inputColorRange;
|
||||
params->layer[NVKMS_MAIN_LAYER].colorRange.specified = TRUE;
|
||||
|
||||
AssignHDRMetadataConfig(layerConfig, NVKMS_MAIN_LAYER, params);
|
||||
|
||||
if (commit && changed) {
|
||||
@@ -2816,6 +2963,9 @@ static NvBool NvKmsKapiRequestedModeSetConfigToKms(
|
||||
|
||||
NvKmsKapiDisplayModeToKapi(&headModeSetConfig->mode, ¶msHead->mode);
|
||||
|
||||
paramsHead->colorRange = headModeSetConfig->outputColorRange;
|
||||
paramsHead->colorRangeSpecified = NV_TRUE;
|
||||
|
||||
NvKmsKapiCursorConfigToKms(&headRequestedConfig->cursorRequestedConfig,
|
||||
¶msHead->flip,
|
||||
NV_TRUE /* bFromKmsSetMode */);
|
||||
@@ -2844,6 +2994,9 @@ static NvBool NvKmsKapiRequestedModeSetConfigToKms(
|
||||
paramsHead->flip.tf.val = tf;
|
||||
paramsHead->flip.tf.specified = NV_TRUE;
|
||||
|
||||
paramsHead->flip.colorimetry.specified = NV_TRUE;
|
||||
paramsHead->flip.colorimetry.val = headModeSetConfig->colorimetry;
|
||||
|
||||
paramsHead->viewPortSizeIn.width =
|
||||
headModeSetConfig->mode.timings.hVisible;
|
||||
paramsHead->viewPortSizeIn.height =
|
||||
@@ -2883,10 +3036,9 @@ static NvBool KmsSetMode(
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_SET_MODE,
|
||||
params, sizeof(*params));
|
||||
|
||||
status = nvkms_ioctl_from_kapi_try_pmlock(device->pKmsOpen,
|
||||
NVKMS_IOCTL_SET_MODE,
|
||||
params, sizeof(*params));
|
||||
if (!status) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
@@ -3033,6 +3185,18 @@ static NvBool KmsFlip(
|
||||
flipParams->tf.val = tf;
|
||||
flipParams->tf.specified = NV_TRUE;
|
||||
|
||||
flipParams->colorimetry.specified =
|
||||
headRequestedConfig->flags.colorimetryChanged;
|
||||
if (flipParams->colorimetry.specified) {
|
||||
flipParams->colorimetry.val = headModeSetConfig->colorimetry;
|
||||
}
|
||||
|
||||
flipParams->outputcolorrange.specified =
|
||||
headRequestedConfig->flags.colorrangeChanged;
|
||||
if (flipParams->outputcolorrange.specified) {
|
||||
flipParams->outputcolorrange.val = headModeSetConfig->outputColorRange;
|
||||
}
|
||||
|
||||
if (headModeSetConfig->vrrEnabled) {
|
||||
params->request.allowVrr = NV_TRUE;
|
||||
}
|
||||
@@ -3042,9 +3206,9 @@ static NvBool KmsFlip(
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_FLIP,
|
||||
params, sizeof(*params));
|
||||
status = nvkms_ioctl_from_kapi_try_pmlock(device->pKmsOpen,
|
||||
NVKMS_IOCTL_FLIP,
|
||||
params, sizeof(*params));
|
||||
|
||||
if (!status) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
@@ -3196,6 +3360,20 @@ void nvKmsKapiHandleEventQueueChange
|
||||
nvDpyIdToNvU32(kmsEventParams.
|
||||
reply.event.u.dpyChanged.dpyId);
|
||||
break;
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_CHANGED:
|
||||
kapiEvent.u.displayCpChanged.display =
|
||||
nvDpyIdToNvU32(kmsEventParams.
|
||||
reply.event.u.dpyCpChanged.dpyId);
|
||||
kapiEvent.u.displayCpChanged.cp =
|
||||
kmsEventParams.reply.event.u.dpyCpChanged.cp;
|
||||
break;
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED:
|
||||
kapiEvent.u.displayCpTopologyChanged.display =
|
||||
nvDpyIdToNvU32(kmsEventParams.
|
||||
reply.event.u.dpyCpTopologyChanged.dpyId);
|
||||
kapiEvent.u.displayCpTopologyChanged.topology =
|
||||
kmsEventParams.reply.event.u.dpyCpTopologyChanged.topology;
|
||||
break;
|
||||
case NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED:
|
||||
kapiEvent.u.dynamicDisplayConnected.display =
|
||||
nvDpyIdToNvU32(kmsEventParams.
|
||||
@@ -3271,6 +3449,118 @@ static NvBool GetCRC32
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
static NvKmsKapiSuspendResumeCallbackFunc *pSuspendResumeFunc;
|
||||
|
||||
void nvKmsKapiSuspendResume
|
||||
(
|
||||
NvBool suspend
|
||||
)
|
||||
{
|
||||
if (pSuspendResumeFunc) {
|
||||
pSuspendResumeFunc(suspend);
|
||||
}
|
||||
}
|
||||
|
||||
static void nvKmsKapiSetSuspendResumeCallback
|
||||
(
|
||||
NvKmsKapiSuspendResumeCallbackFunc *function
|
||||
)
|
||||
{
|
||||
if (pSuspendResumeFunc && function) {
|
||||
nvKmsKapiLogDebug("Kapi suspend/resume callback function already registered");
|
||||
}
|
||||
|
||||
pSuspendResumeFunc = function;
|
||||
}
|
||||
|
||||
static struct NvKmsKapiVblankIntrCallback*
|
||||
RegisterVblankIntrCallback(struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
NVVBlankIntrCallbackProc pCallbackProc,
|
||||
NvU64 param1,
|
||||
NvU64 param2)
|
||||
{
|
||||
struct NvKmsRegisterVblankIntrCallbackParams params = { };
|
||||
NvBool status;
|
||||
|
||||
struct NvKmsKapiVblankIntrCallback *pCallback =
|
||||
nvKmsKapiCalloc(1, sizeof(*pCallback));
|
||||
|
||||
if (pCallback == NULL) {
|
||||
nvKmsKapiLogDebug(
|
||||
"Failed to allocate memory for NVKMS vblank callback object on "
|
||||
"NvKmsKapiDevice 0x%p",
|
||||
device);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (device->hKmsDevice == 0x0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create NVKMS surface */
|
||||
|
||||
params.request.deviceHandle = device->hKmsDevice;
|
||||
params.request.dispHandle = device->hKmsDisp;
|
||||
params.request.head = head;
|
||||
params.request.pCallback = pCallbackProc;
|
||||
params.request.param1 = param1;
|
||||
params.request.param2 = param2;
|
||||
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_REGISTER_VBLANK_INTR_CALLBACK,
|
||||
¶ms, sizeof(params));
|
||||
if (!status) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"Failed to register NVKMS vblank callback");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
pCallback->hKmsHandle = params.reply.callbackHandle;
|
||||
|
||||
done:
|
||||
return pCallback;
|
||||
|
||||
failed:
|
||||
nvKmsKapiFree(pCallback);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void UnregisterVblankIntrCallback(
|
||||
struct NvKmsKapiDevice *device,
|
||||
const NvU32 head,
|
||||
struct NvKmsKapiVblankIntrCallback *pCallback)
|
||||
{
|
||||
struct NvKmsUnregisterVblankIntrCallbackParams params = { };
|
||||
NvBool status;
|
||||
|
||||
if (device->hKmsDevice == 0x0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
params.request.deviceHandle = device->hKmsDevice;
|
||||
params.request.dispHandle = device->hKmsDisp;
|
||||
params.request.head = head;
|
||||
params.request.callbackHandle = pCallback->hKmsHandle;
|
||||
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_UNREGISTER_VBLANK_INTR_CALLBACK,
|
||||
¶ms, sizeof(params));
|
||||
|
||||
if (!status) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"Failed to unregister NVKMS vblank callback registered for "
|
||||
"NvKmsKapiVblankIntrCallback 0x%p",
|
||||
pCallback);
|
||||
}
|
||||
|
||||
done:
|
||||
nvKmsKapiFree(pCallback);
|
||||
}
|
||||
|
||||
NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
(
|
||||
struct NvKmsKapiFunctionsTable *funcsTable
|
||||
@@ -3298,6 +3588,8 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
|
||||
funcsTable->grantPermissions = GrantPermissions;
|
||||
funcsTable->revokePermissions = RevokePermissions;
|
||||
funcsTable->grantSubOwnership = GrantSubOwnership;
|
||||
funcsTable->revokeSubOwnership = RevokeSubOwnership;
|
||||
|
||||
funcsTable->declareEventInterest = DeclareEventInterest;
|
||||
|
||||
@@ -3308,6 +3600,8 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
funcsTable->getStaticDisplayInfo = GetStaticDisplayInfo;
|
||||
funcsTable->getDynamicDisplayInfo = GetDynamicDisplayInfo;
|
||||
|
||||
funcsTable->getVtFbInfo = GetVtFbInfo;
|
||||
|
||||
funcsTable->allocateVideoMemory = AllocateVideoMemory;
|
||||
funcsTable->allocateSystemMemory = AllocateSystemMemory;
|
||||
funcsTable->importMemory = ImportMemory;
|
||||
@@ -3347,6 +3641,9 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
nvKmsKapiUnregisterSemaphoreSurfaceCallback;
|
||||
funcsTable->setSemaphoreSurfaceValue =
|
||||
nvKmsKapiSetSemaphoreSurfaceValue;
|
||||
funcsTable->setSuspendResumeCallback = nvKmsKapiSetSuspendResumeCallback;
|
||||
funcsTable->RegisterVblankIntrCallback = RegisterVblankIntrCallback;
|
||||
funcsTable->UnregisterVblankIntrCallback = UnregisterVblankIntrCallback;
|
||||
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
@@ -329,6 +329,16 @@ NvBool nvkms_ioctl_from_kapi
|
||||
NvU32 cmd, void *params_address, const size_t params_size
|
||||
);
|
||||
|
||||
/*!
|
||||
* Like nvkms_ioctl_from_kapi, but return NV_FALSE instead of waiting if the
|
||||
* power management read lock cannot be acquired.
|
||||
*/
|
||||
NvBool nvkms_ioctl_from_kapi_try_pmlock
|
||||
(
|
||||
struct nvkms_per_open *popen,
|
||||
NvU32 cmd, void *params_address, const size_t params_size
|
||||
);
|
||||
|
||||
/*!
|
||||
* APIs for locking.
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,8 @@ enum NvKmsClientType {
|
||||
NVKMS_CLIENT_KERNEL_SPACE,
|
||||
};
|
||||
|
||||
struct NvKmsPerOpenDev;
|
||||
|
||||
NvBool nvKmsIoctl(
|
||||
void *pOpenVoid,
|
||||
NvU32 cmd,
|
||||
@@ -101,7 +103,11 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
struct NvKmsKapiFunctionsTable *funcsTable
|
||||
);
|
||||
|
||||
void nvKmsKapiSuspendResume(NvBool suspend);
|
||||
|
||||
NvBool nvKmsGetBacklight(NvU32 display_id, void *drv_priv, NvU32 *brightness);
|
||||
NvBool nvKmsSetBacklight(NvU32 display_id, void *drv_priv, NvU32 brightness);
|
||||
|
||||
NvBool nvKmsOpenDevHasSubOwnerPermissionOrBetter(const struct NvKmsPerOpenDev *pOpenDev);
|
||||
|
||||
#endif /* __NV_KMS_H__ */
|
||||
|
||||
@@ -552,6 +552,19 @@ void ConnectorEventSink::notifyCableOkStateChange(DisplayPort::Device *dev,
|
||||
void ConnectorEventSink::notifyHDCPCapDone(DisplayPort::Device *dev,
|
||||
bool hdcpCap)
|
||||
{
|
||||
NVDpyEvoPtr pDpyEvo = NULL;
|
||||
pDpyEvo = FindDpyByDevice(pConnectorEvo, dev);
|
||||
if (pDpyEvo)
|
||||
{
|
||||
if (hdcpCap)
|
||||
{
|
||||
nvSendDpyEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_CHANGED);
|
||||
}
|
||||
else
|
||||
{
|
||||
nvSendDpyClearEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_CHANGED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectorEventSink::notifyMCCSEvent(DisplayPort::Device *dev)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -609,7 +609,6 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
|
||||
NVDispApiHeadStateEvoRec *pApiHeadState;
|
||||
NvU8 hdmiFrlBpc;
|
||||
enum NvKmsOutputTf tf;
|
||||
NvU32 head;
|
||||
#if defined(DEBUG)
|
||||
NvU32 hwHead;
|
||||
@@ -625,12 +624,10 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
|
||||
head = nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
|
||||
hdmiFrlBpc = pDispEvo->headState[head].hdmiFrlBpc;
|
||||
tf = pDispEvo->headState[head].tf;
|
||||
#if defined(DEBUG)
|
||||
FOR_EACH_EVO_HW_HEAD_IN_MASK(pApiHeadState->hwHeadsMask, hwHead) {
|
||||
nvAssert(pDispEvo->headState[head].timings.yuv420Mode ==
|
||||
pDispEvo->headState[hwHead].timings.yuv420Mode);
|
||||
nvAssert(tf == pDispEvo->headState[hwHead].tf);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -641,7 +638,7 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
if (!nvChooseCurrentColorSpaceAndRangeEvo(pDpyEvo,
|
||||
&pDispEvo->headState[head].timings,
|
||||
hdmiFrlBpc,
|
||||
tf,
|
||||
pApiHeadState->colorimetry,
|
||||
pDpyEvo->requestedColorSpace,
|
||||
pDpyEvo->requestedColorRange,
|
||||
&colorSpace,
|
||||
@@ -670,6 +667,7 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
|
||||
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(pDispEvo,
|
||||
head,
|
||||
pApiHeadState->colorimetry,
|
||||
pApiHeadState->attributes.colorSpace,
|
||||
pApiHeadState->attributes.colorRange,
|
||||
&updateState);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2016 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2016 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -165,6 +165,10 @@ static void FlipBaseToNull(NVDevEvoPtr pDevEvo)
|
||||
i++;
|
||||
nvAssert(i <= numFlipApiHeads);
|
||||
|
||||
pRequestApiHead->colorimetry.specified = TRUE;
|
||||
pRequestApiHead->colorimetry.val = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
|
||||
|
||||
|
||||
for (layer = 0; layer < pDevEvo->apiHead[apiHead].numLayers; layer++) {
|
||||
pRequestApiHead->layer[layer].surface.specified = TRUE;
|
||||
// No need to specify sizeIn/sizeOut as we are flipping NULL surface.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2008-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2008-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -205,3 +205,32 @@ nvHandleDPIRQEventDeferredWork(void *dataPtr, NvU32 dataU32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvHandleCpEventDeferredWork(void *dataPtr, NvU32 dataU32)
|
||||
{
|
||||
NVDispEvoPtr pDispEvo = dataPtr;
|
||||
NVDpyIdList dpyIdList = nvEmptyDpyIdList();
|
||||
NVDpyEvoPtr pDpyEvo;
|
||||
NvU32 displayId = dataU32 & 0x00FFFFFFU;
|
||||
NvU32 hdcpStatusChangeNotif = ((dataU32 & 0xFF000000) >> 24);
|
||||
|
||||
dpyIdList = nvAddDpyIdToDpyIdList(nvNvU32ToDpyId(displayId), dpyIdList);
|
||||
FOR_ALL_EVO_DPYS(pDpyEvo, dpyIdList, pDispEvo) {
|
||||
if (hdcpStatusChangeNotif == hdcpStatusChangeNotif_EncEnabled) {
|
||||
nvSendDpyEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_CHANGED);
|
||||
}
|
||||
else if (hdcpStatusChangeNotif == hdcpStatusChangeNotif_KsvOk ||
|
||||
hdcpStatusChangeNotif == hdcpStatusChangeNotif_RepComplete) {
|
||||
nvSendDpyEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED);
|
||||
}
|
||||
else if (hdcpStatusChangeNotif == hdcpStatusChangeNotif_HdcpDisabled ||
|
||||
hdcpStatusChangeNotif == hdcpStatusChangeNotif_HdcpInactive ||
|
||||
hdcpStatusChangeNotif == hdcpStatusChangeNotif_LinkFailed ||
|
||||
hdcpStatusChangeNotif == hdcpStatusChangeNotif_HdcpRestart) {
|
||||
nvSendDpyClearEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_CHANGED);
|
||||
nvSendDpyClearEventEvo(pDpyEvo, NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <ctrl/ctrl5070/ctrl5070system.h> // NV5070_CTRL_CMD_SYSTEM_GET_CAPS_V2
|
||||
#include <ctrl/ctrl5070/ctrl5070or.h> // NV5070_CTRL_CMD_SET_SOR_FLUSH_MODE
|
||||
#include <ctrl/ctrl0073/ctrl0073dp.h> // NV0073_CTRL_DP_CTRL
|
||||
#include <class/clc370_notification.h> // NVC370_NOTIFIERS_RG_VBLANK_NOTIFICATION
|
||||
|
||||
#include "nvkms.h"
|
||||
#include "nvkms-private.h"
|
||||
@@ -2130,7 +2131,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
const NVHwModeTimingsEvo *pHwTimings,
|
||||
NvU8 hdmiFrlBpc,
|
||||
enum NvKmsOutputTf tf,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
|
||||
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue *pCurrentColorSpace,
|
||||
@@ -2146,11 +2147,11 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
const NVColorFormatInfoRec colorFormatsInfo =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
|
||||
// XXX HDR TODO: Handle other transfer functions
|
||||
// XXX HDR TODO: Handle other colorimetries
|
||||
// XXX HDR TODO: Handle YUV
|
||||
if (tf == NVKMS_OUTPUT_TF_PQ) {
|
||||
if (colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
|
||||
/*
|
||||
* If the head is currently in PQ output mode, we override the
|
||||
* If the head is currently has BT2100 colorimetry, we override the
|
||||
* requested color space with RGB. We cannot support yuv420Mode in
|
||||
* that configuration, so fail in that case.
|
||||
*/
|
||||
@@ -2210,8 +2211,8 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
if ((newColorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444) ||
|
||||
(newColorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422) ||
|
||||
(newColorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420) ||
|
||||
(tf == NVKMS_OUTPUT_TF_PQ)) {
|
||||
newColorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
|
||||
(colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100)) {
|
||||
newColorRange = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED;
|
||||
} else if ((newColorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) &&
|
||||
(newColorBpc == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6)) {
|
||||
/* At depth 18 only RGB and full range are allowed */
|
||||
@@ -2234,9 +2235,9 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
}
|
||||
|
||||
// 10 BPC required for HDR
|
||||
// XXX HDR TODO: Handle other transfer functions
|
||||
// XXX HDR TODO: Handle other colorimetries
|
||||
// XXX HDR TODO: Handle YUV
|
||||
if ((tf == NVKMS_OUTPUT_TF_PQ) &&
|
||||
if ((colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) &&
|
||||
(newColorBpc < NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10)) {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2251,6 +2252,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
|
||||
NVDispEvoPtr pDispEvo,
|
||||
const NvU32 head,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace,
|
||||
const enum NvKmsDpyAttributeColorRangeValue colorRange,
|
||||
NVEvoUpdateState *pUpdateState)
|
||||
@@ -2261,7 +2263,7 @@ void nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
|
||||
|
||||
nvAssert(pConnectorEvo != NULL);
|
||||
|
||||
if (pHeadState->tf == NVKMS_OUTPUT_TF_PQ) {
|
||||
if (colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
|
||||
nvAssert(pHeadState->timings.yuv420Mode == NV_YUV420_MODE_NONE);
|
||||
nvAssert(colorSpace == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB);
|
||||
nvAssert(colorRange == NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_LIMITED);
|
||||
@@ -4389,6 +4391,77 @@ void nvEvoPostModesetUnregisterFlipOccurredEvent(NVDispEvoRec *pDispEvo,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
VBlankNotifierEventDeferredWork(void *dataPtr, NvU32 dataU32)
|
||||
{
|
||||
NVVBlankIntrCallbackRec *pVBlankIntrCallback = dataPtr;
|
||||
pVBlankIntrCallback->pCallback(pVBlankIntrCallback->param1,
|
||||
pVBlankIntrCallback->param2);
|
||||
}
|
||||
|
||||
static void VBlankNotifierEvent(void *arg, void *pEventDataVoid,
|
||||
NvU32 hEvent, NvU32 Data, NV_STATUS Status)
|
||||
{
|
||||
(void) nvkms_alloc_timer_with_ref_ptr(
|
||||
VBlankNotifierEventDeferredWork, /* callback */
|
||||
arg, /* argument (this is a ref_ptr to NVVBlankIntrCallbackRec) */
|
||||
Data, /* dataU32 */
|
||||
0); /* timeout: schedule the work immediately */
|
||||
}
|
||||
|
||||
NvU32 nvEvoRegisterVBlankEvent(NVDispEvoRec *pDispEvo,
|
||||
const NvU32 head,
|
||||
NVVBlankIntrCallbackRec *cbRec)
|
||||
{
|
||||
NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
|
||||
NVEvoChannelPtr pChannel = pDevEvo->core;
|
||||
NvU32 handle = 0;
|
||||
|
||||
///* XXX NVKMS TODO: need disp-scope in event */
|
||||
if (pDispEvo->displayOwner != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nvAssert(cbRec->rmVBlankCallbackHandle == 0);
|
||||
|
||||
handle = nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
|
||||
|
||||
if (!nvRmRegisterCallback(pDevEvo,
|
||||
&cbRec->vblankNotifierEventCallback,
|
||||
cbRec->ref_ptr,
|
||||
pChannel->pb.channel_handle,
|
||||
handle,
|
||||
VBlankNotifierEvent,
|
||||
NVC370_NOTIFIERS_RG_VBLANK_NOTIFYINDEX(head))) {
|
||||
nvFreeUnixRmHandle(&pDevEvo->handleAllocator, handle);
|
||||
handle = 0;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void nvEvoUnregisterVBlankEvent(NVDispEvoRec *pDispEvo, NvU32 handle)
|
||||
{
|
||||
NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
|
||||
NVEvoChannelPtr pChannel = pDevEvo->core;
|
||||
|
||||
///* XXX NVKMS TODO: need disp-scope in event */
|
||||
if (pDispEvo->displayOwner != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
nvRmApiFree(nvEvoGlobal.clientHandle,
|
||||
pChannel->pb.channel_handle,
|
||||
handle);
|
||||
nvFreeUnixRmHandle(&pDevEvo->handleAllocator,
|
||||
handle);
|
||||
}
|
||||
|
||||
|
||||
static NvBool InitApiHeadState(NVDevEvoRec *pDevEvo)
|
||||
{
|
||||
NVDispEvoRec *pDispEvo;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -126,6 +126,17 @@ static NvBool UpdateProposedFlipStateOneApiHead(
|
||||
const NVDispApiHeadStateEvoRec *pApiHeadState =
|
||||
&pDispEvo->apiHeadState[apiHead];
|
||||
|
||||
|
||||
if (pParams->colorimetry.specified) {
|
||||
pProposedApiHead->dirty.hdr = TRUE;
|
||||
pProposedApiHead->hdr.colorimetry = pParams->colorimetry.val;
|
||||
}
|
||||
|
||||
if (pParams->outputcolorrange.specified) {
|
||||
pProposedApiHead->dirty.hdr = TRUE;
|
||||
pProposedApiHead->hdr.outputColorRange = pParams->outputcolorrange.val;
|
||||
}
|
||||
|
||||
if (pParams->tf.specified) {
|
||||
const NVDpyEvoRec *pDpyEvo =
|
||||
nvGetOneArbitraryDpyEvo(pApiHeadState->activeDpys, pDispEvo);
|
||||
@@ -156,7 +167,7 @@ static NvBool UpdateProposedFlipStateOneApiHead(
|
||||
if (!nvChooseCurrentColorSpaceAndRangeEvo(pDpyEvo,
|
||||
&pApiHeadState->timings,
|
||||
pDispEvo->headState[primaryHead].hdmiFrlBpc,
|
||||
pParams->tf.val,
|
||||
pProposedApiHead->hdr.colorimetry,
|
||||
pDpyEvo->requestedColorSpace,
|
||||
pDpyEvo->requestedColorRange,
|
||||
&pProposedApiHead->hdr.colorSpace,
|
||||
@@ -353,6 +364,8 @@ static void InitNvKmsFlipWorkArea(const NVDevEvoRec *pDevEvo,
|
||||
&pDispEvo->apiHeadState[apiHead];
|
||||
|
||||
pProposedApiHead->hdr.tf = pApiHeadState->tf;
|
||||
pProposedApiHead->hdr.colorimetry = pApiHeadState->colorimetry;
|
||||
pProposedApiHead->hdr.outputColorRange = pApiHeadState->outputColorRange;
|
||||
pProposedApiHead->hdr.colorSpace =
|
||||
pApiHeadState->attributes.colorSpace;
|
||||
pProposedApiHead->hdr.colorBpc =
|
||||
@@ -398,8 +411,9 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo,
|
||||
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(
|
||||
pDispEvo,
|
||||
head,
|
||||
pProposedApiHead->hdr.colorimetry,
|
||||
pProposedApiHead->hdr.colorSpace,
|
||||
pProposedApiHead->hdr.colorRange,
|
||||
pProposedApiHead->hdr.outputColorRange,
|
||||
pUpdateState);
|
||||
}
|
||||
}
|
||||
@@ -420,6 +434,10 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo,
|
||||
|
||||
pApiHeadState->tf = pProposedApiHead->hdr.tf;
|
||||
|
||||
pApiHeadState->colorimetry = pProposedApiHead->hdr.colorimetry;
|
||||
|
||||
pApiHeadState->outputColorRange = pProposedApiHead->hdr.outputColorRange;
|
||||
|
||||
nvUpdateInfoFrames(pDpyEvo);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2007 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2007 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -68,7 +68,7 @@ static inline const NVT_EDID_CEA861_INFO *GetExt861(const NVParsedEdidEvoRec *pP
|
||||
*/
|
||||
static void CalculateVideoInfoFrameColorFormat(
|
||||
const NVAttributesSetEvoRec *pAttributesSet,
|
||||
enum NvKmsOutputTf tf,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const NvU32 hdTimings,
|
||||
NVT_VIDEO_INFOFRAME_CTRL *pCtrl,
|
||||
NVT_EDID_INFO *pEdidInfo)
|
||||
@@ -76,10 +76,10 @@ static void CalculateVideoInfoFrameColorFormat(
|
||||
NvBool sinkSupportsRGBQuantizationOverride = FALSE;
|
||||
|
||||
/*
|
||||
* If NVKMS_OUTPUT_TF_PQ is enabled, we expect the colorSpace is RGB. This
|
||||
* If NVKMS_OUTPUT_COLORIMETRY_BT2100 is enabled, we expect the colorSpace is RGB. This
|
||||
* is enforced when the colorSpace is selected.
|
||||
*/
|
||||
nvAssert((tf != NVKMS_OUTPUT_TF_PQ) ||
|
||||
nvAssert((colorimetry != NVKMS_OUTPUT_COLORIMETRY_BT2100) ||
|
||||
(pAttributesSet->colorSpace ==
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB));
|
||||
|
||||
@@ -105,7 +105,7 @@ static void CalculateVideoInfoFrameColorFormat(
|
||||
// sets video infoframe colorimetry.
|
||||
switch (pAttributesSet->colorSpace) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
|
||||
if (tf == NVKMS_OUTPUT_TF_PQ) {
|
||||
if (colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
|
||||
pCtrl->colorimetry = NVT_COLORIMETRY_BT2020RGB;
|
||||
} else {
|
||||
pCtrl->colorimetry = NVT_COLORIMETRY_RGB;
|
||||
@@ -525,7 +525,7 @@ static void SendVideoInfoFrame(const NVDispEvoRec *pDispEvo,
|
||||
|
||||
|
||||
CalculateVideoInfoFrameColorFormat(pAttributesSet,
|
||||
pDispEvo->headState[head].tf,
|
||||
pDispEvo->headState[head].colorimetry,
|
||||
hdTimings,
|
||||
&videoCtrl,
|
||||
pEdidInfo);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -175,6 +175,8 @@ void nvInitFlipEvoHwState(
|
||||
{
|
||||
NVDispEvoRec *pDispEvo = pDevEvo->gpus[sd].pDispEvo;
|
||||
const NVEvoSubDevHeadStateRec *pSdHeadState;
|
||||
const NVDispHeadStateEvoRec *pHeadState;
|
||||
|
||||
NvU32 i;
|
||||
|
||||
nvClearFlipEvoHwState(pFlipState);
|
||||
@@ -184,6 +186,7 @@ void nvInitFlipEvoHwState(
|
||||
}
|
||||
|
||||
pSdHeadState = &pDevEvo->gpus[sd].headState[head];
|
||||
pHeadState = &pDispEvo->headState[head];
|
||||
|
||||
pFlipState->viewPortPointIn = pSdHeadState->viewPortPointIn;
|
||||
pFlipState->cursor = pSdHeadState->cursor;
|
||||
@@ -208,6 +211,8 @@ void nvInitFlipEvoHwState(
|
||||
|
||||
pFlipState->disableMidFrameAndDWCFWatermark =
|
||||
pSdHeadState->targetDisableMidFrameAndDWCFWatermark;
|
||||
|
||||
pFlipState->colorimetry = pHeadState->colorimetry;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,7 +228,8 @@ NvBool nvIsLayerDirty(const struct NvKmsFlipCommonParams *pParams,
|
||||
pParams->layer[layer].compositionParams.specified ||
|
||||
pParams->layer[layer].csc.specified ||
|
||||
pParams->layer[layer].hdr.specified ||
|
||||
pParams->layer[layer].colorSpace.specified;
|
||||
pParams->layer[layer].colorSpace.specified ||
|
||||
pParams->layer[layer].colorRange.specified;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -974,6 +980,16 @@ NvBool nvUpdateFlipEvoHwState(
|
||||
pFlipState->tf = pParams->tf.val;
|
||||
}
|
||||
|
||||
if (pParams->colorimetry.specified) {
|
||||
pFlipState->dirty.colorimetry = TRUE;
|
||||
pFlipState->colorimetry = pParams->colorimetry.val;
|
||||
}
|
||||
|
||||
if (pParams->outputcolorrange.specified) {
|
||||
pFlipState->dirty.outputColorRange = TRUE;
|
||||
pFlipState->outputColorRange = pParams->outputcolorrange.val;
|
||||
}
|
||||
|
||||
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
|
||||
if (layer == NVKMS_MAIN_LAYER) {
|
||||
if (!UpdateMainLayerFlipEvoHwState(pOpenDev, pDevEvo, sd, head,
|
||||
@@ -1565,6 +1581,16 @@ static void UpdateHDR(NVDevEvoPtr pDevEvo,
|
||||
dirty = TRUE;
|
||||
}
|
||||
|
||||
if (pFlipState->dirty.colorimetry) {
|
||||
pHeadState->colorimetry = pFlipState->colorimetry;
|
||||
dirty = TRUE;
|
||||
}
|
||||
|
||||
if (pFlipState->dirty.outputColorRange) {
|
||||
pHeadState->outputColorRange = pFlipState->outputColorRange;
|
||||
dirty = TRUE;
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
// Update OCSC / OLUT
|
||||
nvEvoSetLUTContextDma(pDispEvo, head, updateState);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "nvkms-dma.h"
|
||||
#include "nvkms-utils.h"
|
||||
#include "nvos.h"
|
||||
#include "nvkms-softfloat.h"
|
||||
|
||||
#include <class/cl0040.h> /* NV01_MEMORY_LOCAL_USER */
|
||||
|
||||
@@ -367,7 +368,7 @@ void nvUnrefTmoLutSurfacesEvo(NVDevEvoPtr pDevEvo,
|
||||
NvBool nvAllocLutSurfacesEvo(NVDevEvoPtr pDevEvo)
|
||||
{
|
||||
NVDispEvoPtr pDispEvo;
|
||||
NvU32 apiHead, dispIndex, i, sd;
|
||||
NvU32 apiHead, dispIndex, i;
|
||||
|
||||
for (apiHead = 0; apiHead < pDevEvo->numApiHeads; apiHead++) {
|
||||
for (i = 0; i < ARRAY_LEN(pDevEvo->lut.apiHead[apiHead].LUT); i++) {
|
||||
@@ -387,22 +388,18 @@ NvBool nvAllocLutSurfacesEvo(NVDevEvoPtr pDevEvo)
|
||||
}
|
||||
}
|
||||
|
||||
if (pDevEvo->hal->caps.needDefaultLutSurface) {
|
||||
pDevEvo->lut.defaultLut = AllocLutSurfaceEvo(pDevEvo);
|
||||
if (pDevEvo->lut.defaultLut == NULL) {
|
||||
// Allocate memory for the predefined LUTs.
|
||||
for (i = 0; i < NVKMS_GAMMA_LUT_LAST; i++) {
|
||||
pDevEvo->lut.gammaLUTs[i] = AllocLutSurfaceEvo(pDevEvo);
|
||||
if (pDevEvo->lut.gammaLUTs[i] == NULL) {
|
||||
nvFreeLutSurfacesEvo(pDevEvo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (sd = 0; sd < NVKMS_MAX_SUBDEVICES; sd++) {
|
||||
pDevEvo->lut.defaultBaseLUTState[sd] =
|
||||
pDevEvo->lut.defaultOutputLUTState[sd] =
|
||||
NvKmsLUTStateUninitialized;
|
||||
}
|
||||
|
||||
pDevEvo->hal->InitDefaultLut(pDevEvo);
|
||||
}
|
||||
|
||||
// Initialize the predefined LUTs.
|
||||
pDevEvo->hal->InitDefaultLut(pDevEvo);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -432,9 +429,12 @@ void nvFreeLutSurfacesEvo(NVDevEvoPtr pDevEvo)
|
||||
}
|
||||
}
|
||||
|
||||
if (pDevEvo->lut.defaultLut != NULL) {
|
||||
FreeLutSurfaceEvo(pDevEvo->lut.defaultLut);
|
||||
pDevEvo->lut.defaultLut = NULL;
|
||||
// Free any previously-allocated predefined gamma LUTs.
|
||||
for (i = 0; i < NVKMS_GAMMA_LUT_LAST; i++) {
|
||||
if (pDevEvo->lut.gammaLUTs[i] != NULL) {
|
||||
FreeLutSurfaceEvo(pDevEvo->lut.gammaLUTs[i]);
|
||||
pDevEvo->lut.gammaLUTs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (apiHead = 0; apiHead < pDevEvo->numApiHeads; apiHead++) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -312,7 +312,7 @@ GetColorSpaceAndColorRange(
|
||||
if (!nvChooseCurrentColorSpaceAndRangeEvo(pOneArbitraryDpyEvo,
|
||||
&pProposedApiHead->timings,
|
||||
pProposedPrimaryHead->hdmiFrlBpc,
|
||||
pProposedApiHead->tf,
|
||||
pProposedApiHead->colorimetry,
|
||||
requestedColorSpace,
|
||||
requestedColorRange,
|
||||
&pProposedApiHead->attributes.colorSpace,
|
||||
@@ -443,14 +443,14 @@ static void AdjustHwModeTimingsForVrr(const NVDispEvoRec *pDispEvo,
|
||||
|
||||
/*
|
||||
* Return whether headSurface is allowed. But, only honor the requestor's
|
||||
* setting if they are the modeset owner. Otherwise, inherit the cached value
|
||||
* in pDevEvo.
|
||||
* setting if they have modeset owner permission. Otherwise, inherit the cached
|
||||
* value in pDevEvo.
|
||||
*/
|
||||
NvBool nvGetAllowHeadSurfaceInNvKms(const NVDevEvoRec *pDevEvo,
|
||||
const struct NvKmsPerOpenDev *pOpenDev,
|
||||
const struct NvKmsSetModeRequest *pRequest)
|
||||
{
|
||||
if (pOpenDev == pDevEvo->modesetOwner || pOpenDev == pDevEvo->pNvKmsOpenDev) {
|
||||
if (nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
return pRequest->allowHeadSurfaceInNvKms;
|
||||
}
|
||||
|
||||
@@ -490,6 +490,7 @@ InitNVProposedModeSetStateOneApiHead(
|
||||
pProposedApiHead->infoFrame =
|
||||
pDispEvo->apiHeadState[apiHead].infoFrame;
|
||||
pProposedApiHead->tf = pDispEvo->apiHeadState[apiHead].tf;
|
||||
pProposedApiHead->colorimetry = pDispEvo->apiHeadState[apiHead].colorimetry;
|
||||
pProposedApiHead->viewPortPointIn =
|
||||
pDispEvo->apiHeadState[apiHead].viewPortPointIn;
|
||||
|
||||
@@ -544,6 +545,7 @@ InitProposedModeSetHwState(const NVDevEvoRec *pDevEvo,
|
||||
for (NvU32 head = 0; head < pDevEvo->numHeads; head++) {
|
||||
NvU32 layer;
|
||||
NVFlipEvoHwState *pFlip = &pProposed->sd[sd].head[head].flip;
|
||||
pFlip->dirty.colorimetry = TRUE;
|
||||
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
|
||||
pFlip->dirty.layer[layer] = TRUE;
|
||||
}
|
||||
@@ -617,6 +619,7 @@ AssignProposedModeSetNVFlipEvoHwState(
|
||||
if (commit) {
|
||||
NvU32 layer;
|
||||
|
||||
pFlip->dirty.colorimetry = TRUE;
|
||||
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
|
||||
pFlip->dirty.layer[layer] = TRUE;
|
||||
}
|
||||
@@ -1172,6 +1175,17 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo,
|
||||
pProposedApiHead->lut.input.specified = FALSE;
|
||||
}
|
||||
|
||||
if (pRequestHead->flip.colorimetry.specified) {
|
||||
pProposedApiHead->colorimetry = pRequestHead->flip.colorimetry.val;
|
||||
|
||||
// A specified output color space takes precedence over a
|
||||
// specified custom OLUT. Setting the lut.output as follows
|
||||
// will cause nvEvoSetLut() to set the relevant parameter to
|
||||
// output disabled.
|
||||
pProposedApiHead->lut.output.specified = TRUE;
|
||||
pProposedApiHead->lut.output.enabled = FALSE;
|
||||
}
|
||||
|
||||
if (pRequestHead->flip.viewPortIn.specified) {
|
||||
pProposedApiHead->viewPortPointIn =
|
||||
pRequestHead->flip.viewPortIn.point;
|
||||
@@ -2331,6 +2345,14 @@ ApplyProposedModeSetStateOneApiHeadShutDown(
|
||||
*/
|
||||
DisableActiveCoreRGSyncObjects(pDispEvo, apiHead,
|
||||
&pWorkArea->modesetUpdateState.updateState);
|
||||
{
|
||||
NVVBlankIntrCallbackRec *pCallback;
|
||||
nvListForEachEntry(pCallback, &pDispEvo->vblankIntrCallbackList[apiHead],
|
||||
vblankIntrCallbackListEntry) {
|
||||
nvEvoUnregisterVBlankEvent(pDispEvo, pCallback->rmVBlankCallbackHandle);
|
||||
pCallback->rmVBlankCallbackHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pApiHeadState->rmVBlankCallbackHandle != 0) {
|
||||
nvRmRemoveVBlankCallback(pDispEvo,
|
||||
@@ -2401,6 +2423,9 @@ ApplyProposedModeSetStateOneDispFlip(
|
||||
}
|
||||
}
|
||||
|
||||
pDispEvo->apiHeadState[apiHead].colorimetry =
|
||||
pProposedApiHead->colorimetry;
|
||||
|
||||
pDispEvo->apiHeadState[apiHead].viewPortPointIn =
|
||||
pProposedApiHead->viewPortPointIn;
|
||||
}
|
||||
@@ -2458,6 +2483,7 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate(
|
||||
nvEvoColorSpaceBpcToPixelDepth(pProposedApiHead->attributes.colorSpace,
|
||||
pProposedApiHead->attributes.colorBpc);
|
||||
pHeadState->audio = pProposedHead->audio;
|
||||
pHeadState->colorimetry = pProposedApiHead->colorimetry;
|
||||
|
||||
/* Update current LUT to hardware */
|
||||
nvEvoSetLUTContextDma(pDispEvo, head, updateState);
|
||||
@@ -2474,6 +2500,7 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate(
|
||||
/* Update hardware's current colorSpace and colorRange */
|
||||
nvUpdateCurrentHardwareColorSpaceAndRangeEvo(pDispEvo,
|
||||
head,
|
||||
pProposedApiHead->colorimetry,
|
||||
pProposedApiHead->attributes.colorSpace,
|
||||
pProposedApiHead->attributes.colorRange,
|
||||
updateState);
|
||||
@@ -2639,8 +2666,18 @@ ApplyProposedModeSetStateOneApiHeadPreUpdate(
|
||||
VBlankCallback, (void *)(NvUPtr)apiHead);
|
||||
}
|
||||
|
||||
{
|
||||
NVVBlankIntrCallbackRec *pCallback;
|
||||
nvListForEachEntry(pCallback, &pDispEvo->vblankIntrCallbackList[apiHead],
|
||||
vblankIntrCallbackListEntry) {
|
||||
pCallback->rmVBlankCallbackHandle =
|
||||
nvEvoRegisterVBlankEvent(pDispEvo, proposedPrimaryHead, pCallback);
|
||||
}
|
||||
}
|
||||
|
||||
pApiHeadState->attributes = pProposedApiHead->attributes;
|
||||
pApiHeadState->tf = pProposedApiHead->tf;
|
||||
pApiHeadState->colorimetry = pProposedApiHead->colorimetry;
|
||||
pApiHeadState->hs10bpcHint = pProposedApiHead->hs10bpcHint;
|
||||
|
||||
if (nvPopCount32(pProposedApiHead->hwHeadsMask) > 1) {
|
||||
@@ -3772,6 +3809,58 @@ void nvApiHeadUnregisterVBlankCallback(NVDispEvoPtr pDispEvo,
|
||||
}
|
||||
}
|
||||
|
||||
NVVBlankIntrCallbackRec*
|
||||
nvApiHeadRegisterVBlankIntrCallback(NVDispEvoPtr pDispEvo,
|
||||
const NvU32 apiHead,
|
||||
NVVBlankIntrCallbackProc pCallback,
|
||||
NvU64 param1,
|
||||
NvU64 param2)
|
||||
{
|
||||
const NvU32 head = nvGetPrimaryHwHead(pDispEvo, apiHead);
|
||||
NVVBlankIntrCallbackRec *pVBlankIntrCallback = NULL;
|
||||
|
||||
pVBlankIntrCallback = nvCalloc(1, sizeof(*pVBlankIntrCallback));
|
||||
if (pVBlankIntrCallback == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVBlankIntrCallback->pCallback = pCallback;
|
||||
pVBlankIntrCallback->apiHead = apiHead;
|
||||
pVBlankIntrCallback->param1 = param1;
|
||||
pVBlankIntrCallback->param2 = param2;
|
||||
pVBlankIntrCallback->ref_ptr = nvkms_alloc_ref_ptr(pVBlankIntrCallback);
|
||||
|
||||
nvListAppend(&pVBlankIntrCallback->vblankIntrCallbackListEntry,
|
||||
&pDispEvo->vblankIntrCallbackList[apiHead]);
|
||||
|
||||
if (pDispEvo->pDevEvo->coreInitMethodsPending) {
|
||||
return pVBlankIntrCallback;
|
||||
}
|
||||
if (head != NV_INVALID_HEAD) {
|
||||
pVBlankIntrCallback->rmVBlankCallbackHandle =
|
||||
nvEvoRegisterVBlankEvent(pDispEvo, head, pVBlankIntrCallback);
|
||||
}
|
||||
|
||||
return pVBlankIntrCallback;
|
||||
}
|
||||
|
||||
void nvApiHeadUnregisterVBlankIntrCallback(NVDispEvoPtr pDispEvo,
|
||||
NVVBlankIntrCallbackRec *pCallback)
|
||||
{
|
||||
nvAssert((nvGetPrimaryHwHead(pDispEvo, pCallback->apiHead) != NV_INVALID_HEAD)||
|
||||
(pCallback->rmVBlankCallbackHandle == 0));
|
||||
|
||||
// If there are no more callbacks, disable the RM-level callback
|
||||
if (pCallback->rmVBlankCallbackHandle != 0) {
|
||||
nvEvoUnregisterVBlankEvent(pDispEvo, pCallback->rmVBlankCallbackHandle);
|
||||
pCallback->rmVBlankCallbackHandle = 0;
|
||||
}
|
||||
|
||||
nvListDel(&pCallback->vblankIntrCallbackListEntry);
|
||||
nvkms_free_ref_ptr(pCallback->ref_ptr);
|
||||
nvFree(pCallback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Perform a modeset that disables some or all api heads.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -315,6 +315,11 @@ static inline NVDispEvoPtr AllocDisplay(NVDevEvoPtr pDevEvo)
|
||||
pDispEvo->framelock.clients = nvEmptyDpyIdList();
|
||||
pDispEvo->framelock.currentServerHead = NV_INVALID_HEAD;
|
||||
|
||||
for (NvU32 apiHead = 0;
|
||||
apiHead < ARRAY_LEN(pDispEvo->vblankIntrCallbackList); apiHead++) {
|
||||
|
||||
nvListInit(&pDispEvo->vblankIntrCallbackList[apiHead]);
|
||||
}
|
||||
pDispEvo->ref_ptr = nvkms_alloc_ref_ptr(pDispEvo);
|
||||
if (!pDispEvo->ref_ptr) {
|
||||
goto fail;
|
||||
@@ -1347,6 +1352,99 @@ NvBool nvWriteDPCDReg(NVConnectorEvoPtr pConnectorEvo,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void nvGetContentProtectionState(NVConnectorEvoPtr pConnectorEvo, enum NvKmsContentProtection *cp)
|
||||
{
|
||||
NVDevEvoPtr pDevEvo = pConnectorEvo->pDispEvo->pDevEvo;
|
||||
NvU32 subDeviceIndex = pConnectorEvo->pDispEvo->displayOwner;
|
||||
NvU32 displayId = nvDpyIdToNvU32(pConnectorEvo->displayId);
|
||||
NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS params = {0};
|
||||
NvU32 ret = NVOS_STATUS_SUCCESS;
|
||||
NvBool hdcpAuthOn, hdcp1xCapable, hdcp2xCapable, hdcp2xType1;
|
||||
|
||||
params.subDeviceInstance = subDeviceIndex;
|
||||
params.displayId = displayId;
|
||||
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
|
||||
pDevEvo->displayCommonHandle,
|
||||
NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_STATE,
|
||||
¶ms, sizeof params);
|
||||
if (ret != NVOS_STATUS_SUCCESS)
|
||||
{
|
||||
nvEvoLogDev(pDevEvo, EVO_LOG_ERROR, "CTRL CMD GET_HDCP_STATE failed");
|
||||
*cp = NVKMS_CP_OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
hdcpAuthOn = FLD_TEST_DRF(0073_CTRL_SPECIFIC,
|
||||
_HDCP_STATE, _AUTHENTICATED, _YES, params.flags) ? TRUE : FALSE;
|
||||
hdcp1xCapable = FLD_TEST_DRF(0073_CTRL_SPECIFIC,
|
||||
_HDCP_STATE, _RECEIVER_CAPABLE, _YES, params.flags) ? TRUE : FALSE;
|
||||
hdcp2xCapable = FLD_TEST_DRF(0073_CTRL_SPECIFIC,
|
||||
_HDCP_STATE, _HDCP22_RECEIVER_CAPABLE, _YES, params.flags) ? TRUE : FALSE;
|
||||
hdcp2xType1 = FLD_TEST_DRF(0073_CTRL_SPECIFIC,
|
||||
_HDCP_STATE, _HDCP22_TYPE1, _YES, params.flags) ? TRUE : FALSE;
|
||||
|
||||
if (hdcpAuthOn && hdcp2xCapable && hdcp2xType1) {
|
||||
*cp = NVKMS_CP_HDCP2X_TYPE1_ON;
|
||||
} else if (hdcpAuthOn && hdcp2xCapable) {
|
||||
*cp = NVKMS_CP_HDCP2X_TYPE0_ON;
|
||||
} else if (hdcpAuthOn && hdcp1xCapable) {
|
||||
*cp = NVKMS_CP_HDCP1X_ON;
|
||||
} else {
|
||||
*cp = NVKMS_CP_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void nvGetContentProtectionTopology(NVConnectorEvoPtr pConnectorEvo,
|
||||
struct NvKmsHdcpTopology *topology)
|
||||
{
|
||||
NVDevEvoPtr pDevEvo = pConnectorEvo->pDispEvo->pDevEvo;
|
||||
NvU32 subDeviceIndex = pConnectorEvo->pDispEvo->displayOwner;
|
||||
NvU32 displayId = nvDpyIdToNvU32(pConnectorEvo->displayId);
|
||||
NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS *params = nvCalloc(1, sizeof(NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS));
|
||||
NvU32 ret = NVOS_STATUS_SUCCESS;
|
||||
|
||||
if (params == NULL) {
|
||||
nvEvoLogDev(pDevEvo, EVO_LOG_ERROR,
|
||||
"Failed to allocate memory for NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS");
|
||||
goto exit1;
|
||||
}
|
||||
nvkms_memset(topology, 0, sizeof(*topology));
|
||||
params->subDeviceInstance = subDeviceIndex;
|
||||
params->displayId = displayId;
|
||||
params->cmd = DRF_DEF(0073_CTRL_SPECIFIC, _HDCP_CTRL, _CMD, _READ_TOPOLOGY);
|
||||
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
|
||||
pDevEvo->displayCommonHandle,
|
||||
NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL,
|
||||
params, sizeof(*params));
|
||||
if (ret != NVOS_STATUS_SUCCESS)
|
||||
{
|
||||
nvEvoLogDev(pDevEvo, EVO_LOG_ERROR, "CTRL CMD READ_TOPOLOGY failed");
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
topology->isHdcpCapable = params->isHdcpCapable;
|
||||
topology->isHdcpAuthOn = params->isHdcpAuthOn;
|
||||
topology->isHdcpRp = params->isHdcpRp;
|
||||
topology->isHdcp2X = params->isHdcp2X;
|
||||
topology->maxCascadeExceeded = params->bMaxCascadeExceeded;
|
||||
topology->maxDeviceExceeded = params->bMaxDeviceExceeded;
|
||||
topology->isHdcp1DevDownstream = params->bHdcp1DevDownstream;
|
||||
topology->isHdcp2LegacyDevDownstream = params->bHdcp2LegacyDevDownstream;
|
||||
topology->cascadeDepth = params->cascadeDepth;
|
||||
topology->linkCount = params->linkCount;
|
||||
nvkms_memcpy(topology->bksv,
|
||||
params->bKsv,
|
||||
params->linkCount * HDCP_TOPOLOGY_KSV_SIZE);
|
||||
topology->numOfBksv = params->numBksvs;
|
||||
nvkms_memcpy(topology->bksvList,
|
||||
params->bKsvList,
|
||||
params->numBksvs * HDCP_TOPOLOGY_KSV_SIZE);
|
||||
exit2:
|
||||
nvFree(params);
|
||||
exit1:
|
||||
return;
|
||||
}
|
||||
|
||||
static NvBool ReadDPSerializerCaps(NVConnectorEvoPtr pConnectorEvo)
|
||||
{
|
||||
NVDpyIdList oneDpyIdList =
|
||||
@@ -1484,7 +1582,7 @@ static void ReceiveHotplugEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
|
||||
nvHandleHotplugEventDeferredWork, /* callback */
|
||||
arg, /* argument (this is a ref_ptr to a pDispEvo) */
|
||||
0, /* dataU32 */
|
||||
0);
|
||||
100000 /*sleep 100 ms */);
|
||||
}
|
||||
|
||||
static void ReceiveDPIRQEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
|
||||
@@ -1500,6 +1598,19 @@ static void ReceiveDPIRQEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
|
||||
0);
|
||||
}
|
||||
|
||||
static void ReceiveCpEvent(void *arg, void *pEventDataVoid, NvU32 hEvent,
|
||||
NvU32 Data, NV_STATUS Status)
|
||||
{
|
||||
Nv2080HdcpStatusChangeNotification *pEventData = (Nv2080HdcpStatusChangeNotification*)(pEventDataVoid);
|
||||
NvU32 eventData = ((pEventData->hdcpStatusChangeNotif & 0xFFU) << 24) |
|
||||
(pEventData->displayId & 0x00FFFFFFU);
|
||||
(void) nvkms_alloc_timer_with_ref_ptr(
|
||||
nvHandleCpEventDeferredWork, /* callback */
|
||||
arg, /* argument (this is a ref_ptr to a pDispEvo) */
|
||||
eventData, /* dataU32 */
|
||||
0);
|
||||
}
|
||||
|
||||
NvBool nvRmRegisterCallback(const NVDevEvoRec *pDevEvo,
|
||||
NVOS10_EVENT_KERNEL_CALLBACK_EX *cb,
|
||||
struct nvkms_ref_ptr *ref_ptr,
|
||||
@@ -1710,6 +1821,40 @@ enum NvKmsAllocDeviceStatus nvRmAllocDisplays(NVDevEvoPtr pDevEvo)
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a handler for the Content Protection event, which is signaled
|
||||
// when there is a change in HDCP status
|
||||
FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) {
|
||||
NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS setEventParams = { };
|
||||
NvU32 subDevice, ret;
|
||||
|
||||
subDevice = pDevEvo->pSubDevices[pDispEvo->displayOwner]->handle;
|
||||
|
||||
pDispEvo->cpEventHandle =
|
||||
nvGenerateUnixRmHandle(&pDevEvo->handleAllocator);
|
||||
|
||||
if (!RegisterDispCallback(&pDispEvo->rmCpCallback, pDispEvo,
|
||||
pDispEvo->cpEventHandle, ReceiveCpEvent,
|
||||
NV2080_NOTIFIERS_HDCP_STATUS_CHANGE)) {
|
||||
nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
|
||||
"Failed to register Content Protection event");
|
||||
}
|
||||
|
||||
// Enable HDCP Status Change notifications from this subdevice.
|
||||
setEventParams.event = NV2080_NOTIFIERS_HDCP_STATUS_CHANGE;
|
||||
setEventParams.action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT;
|
||||
if ((ret = nvRmApiControl(nvEvoGlobal.clientHandle,
|
||||
subDevice,
|
||||
NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION,
|
||||
&setEventParams,
|
||||
sizeof(setEventParams)))
|
||||
!= NVOS_STATUS_SUCCESS) {
|
||||
nvEvoLogDev(pDevEvo, EVO_LOG_WARN,
|
||||
"Failed to register Content Protection event "
|
||||
"handler: 0x%x\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FOR_ALL_EVO_DISPLAYS(pDispEvo, sd, pDevEvo) {
|
||||
ProbeBootDisplays(pDispEvo);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -143,6 +143,7 @@ struct NvKmsPerOpenDisp {
|
||||
struct NvKmsPerOpenConnector connector[NVKMS_MAX_CONNECTORS_PER_DISP];
|
||||
NVEvoApiHandlesRec vblankSyncObjectHandles[NVKMS_MAX_HEADS_PER_DISP];
|
||||
NVEvoApiHandlesRec vblankCallbackHandles[NVKMS_MAX_HEADS_PER_DISP];
|
||||
NVEvoApiHandlesRec vblankIntrCallbackHandles[NVKMS_MAX_HEADS_PER_DISP];
|
||||
};
|
||||
|
||||
struct NvKmsPerOpenDev {
|
||||
@@ -685,6 +686,8 @@ static void ClearPerOpenDisp(
|
||||
nvEvoDestroyApiHandles(&pOpenDisp->connectorHandles);
|
||||
|
||||
for (NvU32 i = 0; i < NVKMS_MAX_HEADS_PER_DISP; i++) {
|
||||
NVVBlankIntrCallbackRec *pCallback;
|
||||
|
||||
nvEvoDestroyApiHandles(&pOpenDisp->vblankSyncObjectHandles[i]);
|
||||
|
||||
FOR_ALL_POINTERS_IN_EVO_API_HANDLES(&pOpenDisp->vblankCallbackHandles[i],
|
||||
@@ -692,6 +695,13 @@ static void ClearPerOpenDisp(
|
||||
nvRemoveUnicastEvent(pCallbackData->pUserData);
|
||||
}
|
||||
nvEvoDestroyApiHandles(&pOpenDisp->vblankCallbackHandles[i]);
|
||||
|
||||
FOR_ALL_POINTERS_IN_EVO_API_HANDLES(&pOpenDisp->vblankIntrCallbackHandles[i],
|
||||
pCallback, callback) {
|
||||
nvApiHeadUnregisterVBlankIntrCallback(pOpenDisp->pDispEvo,
|
||||
pCallback);
|
||||
}
|
||||
nvEvoDestroyApiHandles(&pOpenDisp->vblankIntrCallbackHandles[i]);
|
||||
}
|
||||
|
||||
nvEvoDestroyApiHandle(&pOpenDev->dispHandles, pOpenDisp->nvKmsApiHandle);
|
||||
@@ -766,8 +776,14 @@ static NvBool InitPerOpenDisp(
|
||||
NVKMS_MAX_VBLANK_SYNC_OBJECTS_PER_HEAD)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!nvEvoInitApiHandles(&pOpenDisp->vblankIntrCallbackHandles[i],
|
||||
NVKMS_MAX_VBLANK_SYNC_OBJECTS_PER_HEAD)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!AllocPerOpenFrameLock(pOpen, pOpenDisp)) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -784,7 +800,8 @@ fail:
|
||||
*/
|
||||
static NvBool ValidateNvKmsPermissions(
|
||||
const NVDevEvoRec *pDevEvo,
|
||||
const struct NvKmsPermissions *pPermissions)
|
||||
const struct NvKmsPermissions *pPermissions,
|
||||
enum NvKmsClientType clientType)
|
||||
{
|
||||
if (pPermissions->type == NV_KMS_PERMISSIONS_TYPE_FLIPPING) {
|
||||
NvU32 d, h;
|
||||
@@ -845,6 +862,13 @@ static NvBool ValidateNvKmsPermissions(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (pPermissions->type == NV_KMS_PERMISSIONS_TYPE_SUB_OWNER) {
|
||||
|
||||
/* Only kapi uses this permission type, so disallow it from userspace */
|
||||
if (clientType != NVKMS_CLIENT_KERNEL_SPACE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -888,6 +912,16 @@ static void AssignFullNvKmsModesetPermissions(
|
||||
}
|
||||
}
|
||||
|
||||
static void AssignFullNvKmsPermissions(
|
||||
struct NvKmsPerOpenDev *pOpenDev
|
||||
)
|
||||
{
|
||||
NVDevEvoPtr pDevEvo = pOpenDev->pDevEvo;
|
||||
|
||||
AssignFullNvKmsFlipPermissions(pDevEvo, &pOpenDev->flipPermissions);
|
||||
AssignFullNvKmsModesetPermissions(pDevEvo, &pOpenDev->modesetPermissions);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the modeset owner to pOpenDev
|
||||
*
|
||||
@@ -917,9 +951,7 @@ static NvBool GrabModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
|
||||
pDevEvo->modesetOwner = pOpenDev;
|
||||
pDevEvo->modesetOwnerChanged = TRUE;
|
||||
|
||||
AssignFullNvKmsFlipPermissions(pDevEvo, &pOpenDev->flipPermissions);
|
||||
AssignFullNvKmsModesetPermissions(pDevEvo, &pOpenDev->modesetPermissions);
|
||||
|
||||
AssignFullNvKmsPermissions(pOpenDev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -991,7 +1023,7 @@ static NvBool RemoveModesetPermissions(struct NvKmsModesetPermissions *pModeset,
|
||||
*/
|
||||
static void RevokePermissionsInternal(
|
||||
const NvU32 typeBitmask,
|
||||
const NVDevEvoRec *pDevEvo,
|
||||
NVDevEvoRec *pDevEvo,
|
||||
const struct NvKmsPerOpenDev *pOpenDevExclude)
|
||||
{
|
||||
struct NvKmsPerOpen *pOpen;
|
||||
@@ -1019,6 +1051,19 @@ static void RevokePermissionsInternal(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pOpenDev == pDevEvo->modesetSubOwner &&
|
||||
(typeBitmask & NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER))) {
|
||||
pDevEvo->modesetSubOwner = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clients with sub-owner permission (or better) don't get flipping
|
||||
* or modeset permission revoked.
|
||||
*/
|
||||
if (nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeBitmask & NVBIT(NV_KMS_PERMISSIONS_TYPE_FLIPPING)) {
|
||||
nvkms_memset(&pOpenDev->flipPermissions, 0,
|
||||
sizeof(pOpenDev->flipPermissions));
|
||||
@@ -1075,7 +1120,8 @@ static NvBool ReleaseModesetOwnership(struct NvKmsPerOpenDev *pOpenDev)
|
||||
|
||||
RestoreConsole(pDevEvo);
|
||||
RevokePermissionsInternal(NVBIT(NV_KMS_PERMISSIONS_TYPE_FLIPPING) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_MODESET),
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_MODESET) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER),
|
||||
pDevEvo, NULL /* pOpenDevExclude */);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1173,10 +1219,7 @@ struct NvKmsPerOpenDev *nvAllocPerOpenDev(struct NvKmsPerOpen *pOpen,
|
||||
|
||||
pOpenDev->isPrivileged = isPrivileged;
|
||||
if (pOpenDev->isPrivileged) {
|
||||
AssignFullNvKmsFlipPermissions(pDevEvo,
|
||||
&pOpenDev->flipPermissions);
|
||||
AssignFullNvKmsModesetPermissions(pOpenDev->pDevEvo,
|
||||
&pOpenDev->modesetPermissions);
|
||||
AssignFullNvKmsPermissions(pOpenDev);
|
||||
}
|
||||
|
||||
if (!nvEvoInitApiHandles(&pOpenDev->deferredRequestFifoHandles, 4)) {
|
||||
@@ -1513,6 +1556,11 @@ static void FreeDeviceReference(struct NvKmsPerOpen *pOpen,
|
||||
ReleaseModesetOwnership(pOpenDev);
|
||||
|
||||
nvAssert(pOpenDev->pDevEvo->modesetOwner != pOpenDev);
|
||||
|
||||
// If this pOpenDev is the modeset sub-owner, implicitly release it.
|
||||
if (pOpenDev->pDevEvo->modesetSubOwner == pOpenDev) {
|
||||
pOpenDev->pDevEvo->modesetSubOwner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nvFreePerOpenDev(pOpen, pOpenDev);
|
||||
@@ -1753,6 +1801,36 @@ static NvBool QueryDpyDynamicData(struct NvKmsPerOpen *pOpen,
|
||||
return nvDpyGetDynamicData(pDpyEvo, pParams);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get the base address and size of the VT framebuffer memory
|
||||
*/
|
||||
static NvBool QueryVtFbData(struct NvKmsPerOpen *pOpen,
|
||||
void *pParamsVoid)
|
||||
{
|
||||
struct NvKmsQueryVtFbDataParams *pParams = pParamsVoid;
|
||||
struct NvKmsPerOpenDev *pOpenDev;
|
||||
NV0080_CTRL_OS_UNIX_VT_GET_FB_INFO_PARAMS *vtFbInfo;
|
||||
|
||||
if (pOpen->clientType != NVKMS_CLIENT_KERNEL_SPACE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pOpenDev = GetPerOpenDev(pOpen, pParams->request.deviceHandle);
|
||||
|
||||
if (pOpenDev == NULL ||
|
||||
!nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vtFbInfo = &pOpenDev->pDevEvo->vtFbInfo;
|
||||
|
||||
nvkms_memset(&pParams->reply, 0, sizeof(pParams->reply));
|
||||
pParams->reply.baseAddress = vtFbInfo->baseAddress;
|
||||
pParams->reply.size = vtFbInfo->size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Store a copy of the user's infoString pointer, so we can copy out to it when
|
||||
* we're done. */
|
||||
struct InfoStringExtraUserStateCommon
|
||||
@@ -2380,9 +2458,9 @@ static NvBool IdleBaseChannel(struct NvKmsPerOpen *pOpen,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Only the modesetOwner can idle base. */
|
||||
/* Only a modeset owner can idle base. */
|
||||
|
||||
if (pOpenDev->pDevEvo->modesetOwner != pOpenDev) {
|
||||
if (!nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2571,7 +2649,7 @@ static NvBool RegisterSurface(struct NvKmsPerOpen *pOpen,
|
||||
|
||||
nvEvoRegisterSurface(pOpenDev->pDevEvo, pOpenDev, pParams,
|
||||
NvHsMapPermissionsReadOnly);
|
||||
return TRUE;
|
||||
return pParams->reply.surfaceHandle != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3080,14 +3158,15 @@ static NvBool GrantPermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Only the modesetOwner can grant permissions. */
|
||||
/* Only a modeset owner can grant permissions. */
|
||||
|
||||
if (pOpenDev->pDevEvo->modesetOwner != pOpenDev) {
|
||||
if (!nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ValidateNvKmsPermissions(pOpenDev->pDevEvo,
|
||||
&pParams->request.permissions)) {
|
||||
&pParams->request.permissions,
|
||||
pOpen->clientType)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -3165,6 +3244,16 @@ static NvBool AcquirePermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
|
||||
|
||||
pParams->reply.permissions.modeset = pOpenDev->modesetPermissions;
|
||||
|
||||
} else if (type == NV_KMS_PERMISSIONS_TYPE_SUB_OWNER) {
|
||||
|
||||
if (pOpenDev->pDevEvo->modesetSubOwner != NULL) {
|
||||
/* There can be only one sub-owner */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pOpenDev->pDevEvo->modesetSubOwner = pOpenDev;
|
||||
AssignFullNvKmsPermissions(pOpenDev);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* GrantPermissions() should ensure that
|
||||
@@ -3267,23 +3356,45 @@ static NvBool RevokePermissions(struct NvKmsPerOpen *pOpen, void *pParamsVoid)
|
||||
GetPerOpenDev(pOpen, pParams->request.deviceHandle);
|
||||
const NvU32 validBitmask =
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_FLIPPING) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_MODESET);
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_MODESET) |
|
||||
NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER);
|
||||
|
||||
if (pOpenDev == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Only the modeset owner can revoke permissions. */
|
||||
if (pOpenDev->pDevEvo->modesetOwner != pOpenDev) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Reject invalid bitmasks. */
|
||||
|
||||
if ((pParams->request.permissionsTypeBitmask & ~validBitmask) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((pParams->request.permissionsTypeBitmask & NVBIT(NV_KMS_PERMISSIONS_TYPE_SUB_OWNER)) != 0) {
|
||||
if (pOpenDev->pDevEvo->modesetOwner != pOpenDev) {
|
||||
/* Only the modeset owner can revoke sub-owner permissions. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When revoking ownership permissions, shut down all heads.
|
||||
*
|
||||
* This is necessary to keep the state of nvidia-drm in sync with NVKMS.
|
||||
* Otherwise, an NVKMS client can leave heads enabled when handing off
|
||||
* control of the device back to nvidia-drm, and nvidia-drm's flip queue
|
||||
* handling will get out of sync because it thinks all heads are
|
||||
* disabled and does not expect flip events on those heads.
|
||||
*/
|
||||
nvShutDownApiHeads(pOpenDev->pDevEvo, NULL /* pTestFunc */);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only a client with sub-owner permissions (or better) can revoke other
|
||||
* kinds of permissions.
|
||||
*/
|
||||
if (!nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pParams->request.permissionsTypeBitmask > 0) {
|
||||
// Old behavior, revoke all permissions of a type.
|
||||
|
||||
@@ -3410,8 +3521,8 @@ static NvBool QueryDpyCRC32(struct NvKmsPerOpen *pOpen,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pOpenDev->pDevEvo->modesetOwner != pOpenDev) {
|
||||
// Only the current owner can query CRC32 values.
|
||||
if (!nvKmsOpenDevHasSubOwnerPermissionOrBetter(pOpenDev)) {
|
||||
// Only a current owner can query CRC32 values.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -3452,15 +3563,13 @@ static NvBool SwitchMux(
|
||||
struct NvKmsSwitchMuxParams *pParams = pParamsVoid;
|
||||
const struct NvKmsSwitchMuxRequest *r = &pParams->request;
|
||||
NVDpyEvoPtr pDpyEvo;
|
||||
NVDevEvoPtr pDevEvo;
|
||||
|
||||
pDpyEvo = GetPerOpenDpy(pOpen, r->deviceHandle, r->dispHandle, r->dpyId);
|
||||
if (pDpyEvo == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pDevEvo = pDpyEvo->pDispEvo->pDevEvo;
|
||||
if (pDevEvo->modesetOwner != GetPerOpenDev(pOpen, r->deviceHandle)) {
|
||||
if (!nvKmsOpenDevHasSubOwnerPermissionOrBetter(GetPerOpenDev(pOpen, r->deviceHandle))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -3891,6 +4000,68 @@ static NvBool NotifyVblank(
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
static NvBool RegisterVblankIntrCallback(struct NvKmsPerOpen *pOpen,
|
||||
void *pParamsVoid)
|
||||
{
|
||||
NvKmsVblankIntrCallbackHandle callbackHandle;
|
||||
struct NvKmsRegisterVblankIntrCallbackParams *pParams = pParamsVoid;
|
||||
struct NvKmsPerOpenDisp* pOpenDisp =
|
||||
GetPerOpenDisp(pOpen, pParams->request.deviceHandle,
|
||||
pParams->request.dispHandle);
|
||||
|
||||
NVVBlankIntrCallbackRec *pCallback =
|
||||
nvApiHeadRegisterVBlankIntrCallback(pOpenDisp->pDispEvo,
|
||||
pParams->request.head,
|
||||
pParams->request.pCallback,
|
||||
pParams->request.param1,
|
||||
pParams->request.param2);
|
||||
|
||||
if (pCallback == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
callbackHandle = nvEvoCreateApiHandle(
|
||||
&pOpenDisp->vblankIntrCallbackHandles[pParams->request.head],
|
||||
pCallback);
|
||||
if (callbackHandle == 0) {
|
||||
nvApiHeadUnregisterVBlankIntrCallback(pOpenDisp->pDispEvo,
|
||||
pCallback);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pParams->reply.callbackHandle = callbackHandle;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool UnregisterVblankIntrCallback(struct NvKmsPerOpen *pOpen,
|
||||
void *pParamsVoid)
|
||||
{
|
||||
struct NvKmsUnregisterVblankIntrCallbackParams *pParams = pParamsVoid;
|
||||
struct NvKmsPerOpenDisp* pOpenDisp =
|
||||
GetPerOpenDisp(pOpen, pParams->request.deviceHandle,
|
||||
pParams->request.dispHandle);
|
||||
const NvU32 apiHead = pParams->request.head;
|
||||
NVVBlankIntrCallbackRec *pCallback;
|
||||
|
||||
if (apiHead >= ARRAY_LEN(pOpenDisp->vblankIntrCallbackHandles)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pCallback = nvEvoGetPointerFromApiHandle(
|
||||
&pOpenDisp->vblankIntrCallbackHandles[apiHead],
|
||||
pParams->request.callbackHandle);
|
||||
if (pCallback == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nvApiHeadUnregisterVBlankIntrCallback(pOpenDisp->pDispEvo,
|
||||
pCallback);
|
||||
nvEvoDestroyApiHandle(&pOpenDisp->vblankIntrCallbackHandles[apiHead],
|
||||
pParams->request.callbackHandle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Perform the ioctl operation requested by the client.
|
||||
*
|
||||
@@ -3956,6 +4127,7 @@ NvBool nvKmsIoctl(
|
||||
ENTRY(NVKMS_IOCTL_QUERY_CONNECTOR_DYNAMIC_DATA, QueryConnectorDynamicData),
|
||||
ENTRY(NVKMS_IOCTL_QUERY_DPY_STATIC_DATA, QueryDpyStaticData),
|
||||
ENTRY(NVKMS_IOCTL_QUERY_DPY_DYNAMIC_DATA, QueryDpyDynamicData),
|
||||
ENTRY(NVKMS_IOCTL_QUERY_VT_FB_DATA, QueryVtFbData),
|
||||
ENTRY_CUSTOM_USER(NVKMS_IOCTL_VALIDATE_MODE_INDEX, ValidateModeIndex),
|
||||
ENTRY_CUSTOM_USER(NVKMS_IOCTL_VALIDATE_MODE, ValidateMode),
|
||||
ENTRY_CUSTOM_USER(NVKMS_IOCTL_SET_MODE, SetMode),
|
||||
@@ -4004,6 +4176,8 @@ NvBool nvKmsIoctl(
|
||||
ENTRY(NVKMS_IOCTL_ENABLE_VBLANK_SYNC_OBJECT, EnableVblankSyncObject),
|
||||
ENTRY(NVKMS_IOCTL_DISABLE_VBLANK_SYNC_OBJECT, DisableVblankSyncObject),
|
||||
ENTRY(NVKMS_IOCTL_NOTIFY_VBLANK, NotifyVblank),
|
||||
ENTRY(NVKMS_IOCTL_REGISTER_VBLANK_INTR_CALLBACK, RegisterVblankIntrCallback),
|
||||
ENTRY(NVKMS_IOCTL_UNREGISTER_VBLANK_INTR_CALLBACK, UnregisterVblankIntrCallback),
|
||||
};
|
||||
|
||||
struct NvKmsPerOpen *pOpen = pOpenVoid;
|
||||
@@ -4232,6 +4406,7 @@ static const char *ProcFsPermissionsTypeString(
|
||||
switch (permissionsType) {
|
||||
case NV_KMS_PERMISSIONS_TYPE_FLIPPING: return "flipping";
|
||||
case NV_KMS_PERMISSIONS_TYPE_MODESET: return "modeset";
|
||||
case NV_KMS_PERMISSIONS_TYPE_SUB_OWNER:return "sub-owner";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
@@ -4944,11 +5119,16 @@ static void ConsoleRestoreTimerFired(void *dataPtr, NvU32 dataU32)
|
||||
* NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED.
|
||||
* \param[in] NvS64 The NvKmsDpyAttribute value; only used for
|
||||
* NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED.
|
||||
* \param[in] NvBool Only valid for NVKMS_EVENT_TYPE_DPY_CP_CHANGED
|
||||
* and NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED.
|
||||
* When set to NV_TRUE cp is considerd disabled
|
||||
* and topology will be cleared.
|
||||
*/
|
||||
static void SendDpyEventEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
const NvU32 eventType,
|
||||
const enum NvKmsDpyAttribute attribute,
|
||||
const NvS64 value)
|
||||
const NvS64 value,
|
||||
const NvBool clear)
|
||||
{
|
||||
struct NvKmsPerOpen *pOpen;
|
||||
const NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
|
||||
@@ -4978,6 +5158,29 @@ static void SendDpyEventEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
event.u.dpyChanged.dpyId = pDpyEvo->id;
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_CHANGED:
|
||||
event.u.dpyCpChanged.deviceHandle = deviceHandle;
|
||||
event.u.dpyCpChanged.dispHandle = dispHandle;
|
||||
event.u.dpyCpChanged.dpyId = pDpyEvo->id;
|
||||
if (clear) {
|
||||
event.u.dpyCpChanged.cp = NVKMS_CP_OFF;
|
||||
} else {
|
||||
nvGetContentProtectionState(pDpyEvo->pConnectorEvo, &(event.u.dpyCpChanged.cp));
|
||||
}
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DPY_CP_TOPOLOGY_CHANGED:
|
||||
event.u.dpyCpTopologyChanged.deviceHandle = deviceHandle;
|
||||
event.u.dpyCpTopologyChanged.dispHandle = dispHandle;
|
||||
event.u.dpyCpTopologyChanged.dpyId = pDpyEvo->id;
|
||||
event.u.dpyCpTopologyChanged.topology = &(pDpyEvo->pConnectorEvo->cpTopology);
|
||||
if (clear) {
|
||||
nvkms_memset(&(pDpyEvo->pConnectorEvo->cpTopology), 0, sizeof(struct NvKmsHdcpTopology ));
|
||||
} else {
|
||||
nvGetContentProtectionTopology(pDpyEvo->pConnectorEvo, &(pDpyEvo->pConnectorEvo->cpTopology));
|
||||
}
|
||||
break;
|
||||
|
||||
case NVKMS_EVENT_TYPE_DYNAMIC_DPY_CONNECTED:
|
||||
event.u.dynamicDpyConnected.deviceHandle = deviceHandle;
|
||||
event.u.dynamicDpyConnected.dispHandle = dispHandle;
|
||||
@@ -5022,7 +5225,17 @@ void nvSendDpyEventEvo(const NVDpyEvoRec *pDpyEvo, const NvU32 eventType)
|
||||
nvAssert(eventType != NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED);
|
||||
SendDpyEventEvo(pDpyEvo, eventType,
|
||||
0 /* attribute (unused) */,
|
||||
0 /* value (unused) */ );
|
||||
0 /* value (unused) */,
|
||||
NV_FALSE);
|
||||
}
|
||||
|
||||
void nvSendDpyClearEventEvo(const NVDpyEvoRec *pDpyEvo, const NvU32 eventType)
|
||||
{
|
||||
nvAssert(eventType != NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED);
|
||||
SendDpyEventEvo(pDpyEvo, eventType,
|
||||
0 /* attribute (unused) */,
|
||||
0 /* value (unused) */,
|
||||
NV_TRUE);
|
||||
}
|
||||
|
||||
void nvSendDpyAttributeChangedEventEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
@@ -5031,7 +5244,7 @@ void nvSendDpyAttributeChangedEventEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
{
|
||||
SendDpyEventEvo(pDpyEvo,
|
||||
NVKMS_EVENT_TYPE_DPY_ATTRIBUTE_CHANGED,
|
||||
attribute, value);
|
||||
attribute, value, NV_FALSE);
|
||||
}
|
||||
|
||||
void nvSendFrameLockAttributeChangedEventEvo(
|
||||
@@ -5532,3 +5745,10 @@ NvBool nvKmsSetBacklight(NvU32 display_id, void *drv_priv, NvU32 brightness)
|
||||
|
||||
return status == NV_OK;
|
||||
}
|
||||
|
||||
NvBool nvKmsOpenDevHasSubOwnerPermissionOrBetter(const struct NvKmsPerOpenDev *pOpenDev)
|
||||
{
|
||||
return pOpenDev->isPrivileged ||
|
||||
pOpenDev->pDevEvo->modesetOwner == pOpenDev ||
|
||||
pOpenDev->pDevEvo->modesetSubOwner == pOpenDev;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ SRCS_CXX += ../common/displayport/src/dp_timer.cpp
|
||||
SRCS_CXX += ../common/displayport/src/dp_vrr.cpp
|
||||
SRCS_CXX += ../common/displayport/src/dp_wardatabase.cpp
|
||||
SRCS_CXX += ../common/displayport/src/dp_watermark.cpp
|
||||
SRCS_CXX += ../common/displayport/src/dp_qse.cpp
|
||||
SRCS_CXX += ../common/displayport/src/dptestutil/dp_testmessage.cpp
|
||||
SRCS += ../common/modeset/hdmipacket/nvhdmipkt.c
|
||||
SRCS += ../common/modeset/hdmipacket/nvhdmipkt_0073.c
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -162,7 +162,7 @@ NvBool NV_API_CALL os_is_vgx_hyper (void);
|
||||
NV_STATUS NV_API_CALL os_inject_vgx_msi (NvU16, NvU64, NvU32);
|
||||
NvBool NV_API_CALL os_is_grid_supported (void);
|
||||
NvU32 NV_API_CALL os_get_grid_csp_support (void);
|
||||
void NV_API_CALL os_get_screen_info (NvU64 *, NvU32 *, NvU32 *, NvU32 *, NvU32 *, NvU64, NvU64);
|
||||
void NV_API_CALL os_get_screen_info (NvU64 *, NvU32 *, NvU32 *, NvU32 *, NvU32 *, NvU64 *, NvU64, NvU64);
|
||||
void NV_API_CALL os_bug_check (NvU32, const char *);
|
||||
NV_STATUS NV_API_CALL os_lock_user_pages (void *, NvU64, void **, NvU32);
|
||||
NV_STATUS NV_API_CALL os_lookup_user_io_memory (void *, NvU64, NvU64 **, void**);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -4351,12 +4351,10 @@ NvBool rm_get_uefi_console_status(
|
||||
// UEFI console check the fbBaseAddress: if it was set up by the EFI GOP
|
||||
// driver, it will point into BAR1 (FB); if it was set up by the VBIOS,
|
||||
// it will point to BAR2 + 16MB.
|
||||
os_get_screen_info(&fbBaseAddress, &fbWidth, &fbHeight, &fbDepth, &fbPitch,
|
||||
os_get_screen_info(&fbBaseAddress, &fbWidth, &fbHeight, &fbDepth, &fbPitch, &fbSize,
|
||||
nv->bars[NV_GPU_BAR_INDEX_FB].cpu_address,
|
||||
nv->bars[NV_GPU_BAR_INDEX_IMEM].cpu_address + 0x1000000);
|
||||
|
||||
fbSize = (NvU64)fbHeight * (NvU64)fbPitch;
|
||||
|
||||
bConsoleDevice = (fbSize != 0);
|
||||
|
||||
return bConsoleDevice;
|
||||
@@ -4377,12 +4375,10 @@ NvU64 rm_get_uefi_console_size(
|
||||
// UEFI console check the fbBaseAddress: if it was set up by the EFI GOP
|
||||
// driver, it will point into BAR1 (FB); if it was set up by the VBIOS,
|
||||
// it will point to BAR2 + 16MB.
|
||||
os_get_screen_info(pFbBaseAddress, &fbWidth, &fbHeight, &fbDepth, &fbPitch,
|
||||
os_get_screen_info(pFbBaseAddress, &fbWidth, &fbHeight, &fbDepth, &fbPitch, &fbSize,
|
||||
nv->bars[NV_GPU_BAR_INDEX_FB].cpu_address,
|
||||
nv->bars[NV_GPU_BAR_INDEX_IMEM].cpu_address + 0x1000000);
|
||||
|
||||
fbSize = (NvU64)fbHeight * (NvU64)fbPitch;
|
||||
|
||||
return fbSize;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user