diff --git a/commitFile.txt b/commitFile.txt index c9456e5..43f20c6 100644 --- a/commitFile.txt +++ b/commitFile.txt @@ -10,7 +10,7 @@ ec5f1eb408e0b650158e0310fb1ddd8e9b323a6f - CONTRIBUTING.md af3ee56442f16029cb9b13537477c384226b22fc - CODE_OF_CONDUCT.md 41123f5c3015f9a14cf35b7c75c5b720f5fbed07 - kernel-open/Kbuild 4f4410c3c8db46e5a98d7a35f7d909a49de6cb43 - kernel-open/Makefile -aca7afeeee3cd44b43a8cc8aebacdffd0da96ff9 - kernel-open/conftest.sh +4f39cccb3a96d6a8be929f524e48e673aaa0093f - 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 @@ -53,10 +53,10 @@ 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 -ba72879894c335c61a67f7bae9f6ea94c3b74e1f - kernel-open/common/inc/nvkms-kapi.h +23e71bf8f57bc6777ee6ee419dfdd44d7a2a3c6e - 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 -314f2400c5f4342ebec578c24689329ab79e497d - kernel-open/common/inc/nvkms-api-types.h +1e9c09285aabbfd1010e786f08494cba36658a0d - 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 c75bfc368c6ce3fc2c1a0c5062834e90d822b365 - kernel-open/common/inc/nv-memdbg.h @@ -148,12 +148,12 @@ 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 +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 f454b9ae53a2c308d6909d197c2b9a6543f7d8c3 - kernel-open/nvidia-drm/nvidia-drm-gem-nvkms-memory.c -4d390f6b4c50510ffa5aca47977ec12e47b3947c - kernel-open/nvidia-drm/nvidia-drm-modeset.c +69f2ad23a2df1e20a38c60d251673db8bffcbd9e - 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 @@ -162,8 +162,8 @@ c52acdbc07f16aa78570d9e6a7f62e493264fde1 - kernel-open/nvidia-drm/nvidia-drm-hel 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 -14b62226771ac7d69ea048b567bcf22ab6a59cb7 - 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 +624b30dc76058cc3a0797a86ffa5da46803e3ace - 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 @@ -171,7 +171,7 @@ eca70b3b8146903ec678a60eebb0462e6ccf4569 - kernel-open/nvidia-drm/nvidia-drm-enc b1bc97e6e0564f1526dedaf8bb68d081fc509cc7 - 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 -b8128c6806ef60d0f0c59bd93ee84fc0fdf47f62 - kernel-open/nvidia-drm/nvidia-drm-drv.c +77339943a9d60e01708aae95c258476831f0b8fb - kernel-open/nvidia-drm/nvidia-drm-drv.c 203295380efca7e422746805437b05ce22505424 - kernel-open/nvidia-drm/nvidia-drm-gem.c c1a318e90decef16aa29768ea5c8946becc5a4a0 - kernel-open/nvidia-drm/nvidia-drm-encoder.c 8bedc7374d7a43250e49fb09139c511b489d45e3 - kernel-open/nvidia-drm/nv-pci-table.h @@ -179,16 +179,16 @@ c1a318e90decef16aa29768ea5c8946becc5a4a0 - kernel-open/nvidia-drm/nvidia-drm-enc 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 +b59e4cccbc405babf7cf230455b5b089e81b03bc - kernel-open/nvidia-drm/nvidia-drm-connector.c 97b6c56b1407de976898e0a8b5a8f38a5211f8bb - kernel-open/nvidia-drm/nvidia-drm-format.h -b4cdad1b38e8fdac0f2c3ef8ebeb73a83973eed1 - kernel-open/nvidia-drm/nvidia-drm-priv.h +6859a86572262b38ae7a905f21921e9ceb74523d - 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 -7e87b94b550dbfba205959932a22cf943a4adb26 - kernel-open/nvidia-drm/nvidia-drm.Kbuild +1b7c0e4bc236101b930a9a95a622c0031c56978d - kernel-open/nvidia-drm/nvidia-drm-modeset.h +7ba9a7661d0227a2f8a8b96614e40302dfcd8c37 - 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 -2f49d56a57e1dcb1ded646bf606172890a0f2dc7 - kernel-open/nvidia-drm/nvidia-drm-crtc.c +53f37dd6d99d4bc8227db5d532e2f1309723468b - 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 @@ -252,7 +252,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 @@ -381,8 +381,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 +51cbe71bafc97e853c2b75147d7e9cb5cf72cefa - 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 @@ -504,7 +504,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 +513,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 +c953ceae3005d389fb0873d8c3cc3783c7b2d885 - 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 +f3d79cc73199a2250ac8219f0a696512f4e67d63 - 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 +6a27fd2443690afb573116c13d3f976348dee298 - 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 +b487eed6e639a1aa485b06255beef61e112f24b3 - 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 @@ -835,7 +837,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 +850,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 @@ -1149,7 +1151,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 +1180,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 +0739ffa368efb761544295c03bc0ad633b5a3349 - 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 @@ -1192,7 +1194,7 @@ a79cfb74026085b0aa612c0ae6789083e196bbc2 - src/nvidia-modeset/include/nvkms-evo- 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 +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 @@ -1201,14 +1203,14 @@ ae03509966df56d98fa72b7528ab43ec2b258381 - src/nvidia-modeset/include/nvkms-util 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 +6fa4708e4f6dfe63f149a1c70fa84bf9df01026a - src/nvidia-modeset/include/nvkms-evo.h 4a94381bd8c24b09193577d3f05d6d61f178e1cf - src/nvidia-modeset/include/nvkms-ctxdma.h 11bae7c491bbb0ba4cad94b645d47c384191fa5c - src/nvidia-modeset/include/nvkms-flip.h -041f03c5a566d8549843405cd3e6e0a3520d014d - src/nvidia-modeset/include/nvkms-modeset-types.h +00d2f2fa1f7c96757f67b9ca3ff1c2699a493bd0 - src/nvidia-modeset/include/nvkms-modeset-types.h 260b6ef87c755e55a803adad4ce49f2d57315f9a - src/nvidia-modeset/include/nvkms-event.h 35fa1444c57f7adbbddddc612237f3ad38cdd78f - src/nvidia-modeset/include/nvkms-rmapi.h 118d0ea84ff81de16fbdc2c7daf249ee5c82ed6e - src/nvidia-modeset/include/nvkms-modepool.h -472c68eb149714b9fe9a5c3b052f60144e9ba297 - src/nvidia-modeset/include/nvkms-types.h +62be8578b3eec01438014f11a1b1b210b09d6ce6 - 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,33 +1220,33 @@ 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 -8a6f30959567fa85df3ded73a5c54c67a23b5fd3 - src/nvidia-modeset/kapi/src/nvkms-kapi.c +d77e520819f0fa8a775542f493af03f9f2aafc47 - src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h +277738dc6ab009b77546355299cadabc5144fc5c - 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 -ba72879894c335c61a67f7bae9f6ea94c3b74e1f - src/nvidia-modeset/kapi/interface/nvkms-kapi.h -89bd2f4757d3b901071e523a981903834cca2d7f - src/nvidia-modeset/src/nvkms-modeset.c -b7232f4b4b8f0d4c395c241c451fc17b6ab84d7f - src/nvidia-modeset/src/nvkms-evo.c -7d0e38f9d79e0c928bdc67276b8ecb0c18470b88 - src/nvidia-modeset/src/nvkms-hw-flip.c +23e71bf8f57bc6777ee6ee419dfdd44d7a2a3c6e - src/nvidia-modeset/kapi/interface/nvkms-kapi.h +26144f7b6e9358a5418735c5c357c964047b52ca - src/nvidia-modeset/src/nvkms-modeset.c +5f559582336ab0e252f25039d43b114a6630758c - src/nvidia-modeset/src/nvkms-evo.c +aa185dd37a2ece9f7698c9076ec5c9fc79b6a476 - src/nvidia-modeset/src/nvkms-hw-flip.c 6a35b80a6995777dc9500cac9659e6f0f0c12d23 - src/nvidia-modeset/src/nvkms-cursor3.c -710b38a93fee94fa4659309451bd4e7baa7ff0d6 - src/nvidia-modeset/src/nvkms-rm.c +4f973e22225946be9c5c726a06ea3ad915ec4a03 - src/nvidia-modeset/src/nvkms-rm.c 30ad7839985dea46e6b6d43499210a3056da51ad - src/nvidia-modeset/src/nvkms-utils-flip.c -1769a95e465762c8efa53cf17c40679754292003 - src/nvidia-modeset/src/nvkms-evo3.c -b13bd89b5ac60ceab56e9c2398cf7668375ab7ad - src/nvidia-modeset/src/nvkms-flip.c +6a84fae64ca00bc8b5d9ae75c291140f23d8fd4d - src/nvidia-modeset/src/nvkms-evo3.c +c13871725cc47dfb99b3d66ed41a57d2ea5f8f97 - 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 -083cd2c0d7e9e0f351e15a5ad85cdbd50a583d13 - src/nvidia-modeset/src/nvkms.c +d01a59a7c22d3998f1cf97f2812c6f99dab4c097 - 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 @@ -1256,7 +1258,7 @@ 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 93ab81a362c4ba29ed817dd14fbd75f2b36b62b8 - src/nvidia-modeset/src/nvkms-lut.c @@ -1271,8 +1273,8 @@ a2a4b7063fa903cc434163ebceb7c8d48f703c33 - src/nvidia-modeset/src/dp/nvdp-connec 69fed95ab3954dd5cb26590d02cd8ba09cdff1ac - src/nvidia-modeset/src/dp/nvdp-connector-event-sink.hpp 372ea4c8e7bbc0bdeb899e6f163c8f20c663ad22 - src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h 0a0650835e8835d32418891a2fd25031f5d8770e - src/nvidia-modeset/os-interface/include/nvkms.h -5c987d408208e74a7e0e50d79e96508b07955d8e - src/nvidia-modeset/interface/nvkms-api.h +7987b3cd8d56be40767c76286d78cf5962cd166c - src/nvidia-modeset/interface/nvkms-api.h b986bc6591ba17a74ad81ec4c93347564c6d5165 - src/nvidia-modeset/interface/nvkms-format.h 2ea1436104463c5e3d177e8574c3b4298976d37e - src/nvidia-modeset/interface/nvkms-ioctl.h -314f2400c5f4342ebec578c24689329ab79e497d - src/nvidia-modeset/interface/nvkms-api-types.h +1e9c09285aabbfd1010e786f08494cba36658a0d - src/nvidia-modeset/interface/nvkms-api-types.h 8e3e74d2b3f45381e7b0012d930cf451cbd1728f - src/nvidia-modeset/interface/nvkms-sync.h diff --git a/kernel-open/common/inc/nvkms-api-types.h b/kernel-open/common/inc/nvkms-api-types.h index a01a9b1..2ec168d 100644 --- a/kernel-open/common/inc/nvkms-api-types.h +++ b/kernel-open/common/inc/nvkms-api-types.h @@ -55,6 +55,7 @@ typedef NvU32 NvKmsFrameLockHandle; typedef NvU32 NvKmsDeferredRequestFifoHandle; typedef NvU32 NvKmsSwapGroupHandle; typedef NvU32 NvKmsVblankSyncObjectHandle; +typedef NvU32 NvKmsVblankIntrCallbackHandle; struct NvKmsSize { NvU16 width; @@ -545,6 +546,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, @@ -558,19 +589,17 @@ enum NvKmsInputColorSpace { /* 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_REC709 = 4, + NVKMS_INPUT_COLORSPACE_BT709 = 5, /* Rec709 colorspace with linear (identity) gamma */ - NVKMS_INPUT_COLORSPACE_REC709_LINEAR = 5 -}; + NVKMS_INPUT_COLORSPACE_BT709_LINEAR = 6, -enum NvKmsOutputColorSpace { - /* Unknown colorspace; no re-gamma will be applied */ - NVKMS_OUTPUT_COLORSPACE_NONE = 0, - - /* sRGB gamma transfer function will be applied */ - NVKMS_OUTPUT_COLORSPACE_SRGB = 1 + /* Rec2020 colorspace with Rec2020 gamma transfer function */ + NVKMS_INPUT_COLORSPACE_BT2020 = 7, }; enum NvKmsOutputTf { @@ -661,4 +690,6 @@ struct NvKmsSuperframeInfo { } view[NVKMS_MAX_SUPERFRAME_VIEWS]; }; +typedef void (*NVVBlankIntrCallbackProc)(NvU64 param1, NvU64 param2); + #endif /* NVKMS_API_TYPES_H */ diff --git a/kernel-open/common/inc/nvkms-kapi.h b/kernel-open/common/inc/nvkms-kapi.h index 6a24895..3f1da53 100644 --- a/kernel-open/common/inc/nvkms-kapi.h +++ b/kernel-open/common/inc/nvkms-kapi.h @@ -248,6 +248,7 @@ struct NvKmsKapiLayerConfig { NvU16 dstWidth, dstHeight; enum NvKmsInputColorSpace inputColorSpace; + enum NvKmsInputColorRange inputColorRange; }; struct NvKmsKapiLayerRequestedConfig { @@ -301,6 +302,10 @@ struct NvKmsKapiHeadModeSetConfig { struct NvKmsKapiDisplayMode mode; NvBool vrrEnabled; + + enum NvKmsOutputColorimetry colorimetry; + + enum NvKmsDpyAttributeColorRangeValue outputColorRange; }; struct NvKmsKapiHeadRequestedConfig { @@ -309,6 +314,8 @@ struct NvKmsKapiHeadRequestedConfig { NvBool activeChanged : 1; NvBool displaysChanged : 1; NvBool modeChanged : 1; + NvBool colorrangeChanged: 1; + NvBool colorimetryChanged : 1; } flags; struct NvKmsKapiCursorRequestedConfig cursorRequestedConfig; @@ -1397,6 +1404,18 @@ struct NvKmsKapiFunctionsTable { ( 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); }; /** @} */ diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 391374f..65de6a7 100644 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -5767,24 +5767,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 - 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 diff --git a/kernel-open/nvidia-drm/nvidia-drm-connector.c b/kernel-open/nvidia-drm/nvidia-drm-connector.c index 18965cf..cb8c725 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-connector.c +++ b/kernel-open/nvidia-drm/nvidia-drm-connector.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015- 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"), @@ -216,6 +216,51 @@ 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; + + 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); + + 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 +272,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 +437,89 @@ nv_drm_connector_best_encoder(struct drm_connector *connector) return NULL; } +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); + + 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 +530,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; @@ -405,6 +574,23 @@ nv_drm_connector_new(struct drm_device *dev, DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; } + /* attach nvidia defined connector properties */ + 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 (drm_mode_create_hdmi_colorspace_property(&nv_connector->base) == 0) { + 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 (drm_mode_create_dp_colorspace_property(&nv_connector->base) == 0) { + 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); diff --git a/kernel-open/nvidia-drm/nvidia-drm-connector.h b/kernel-open/nvidia-drm/nvidia-drm-connector.h index 34ef213..fc9d847 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-connector.h +++ b/kernel-open/nvidia-drm/nvidia-drm-connector.h @@ -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"), @@ -77,6 +77,24 @@ 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; +}; + +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) { diff --git a/kernel-open/nvidia-drm/nvidia-drm-crtc.c b/kernel-open/nvidia-drm/nvidia-drm-crtc.c index 22abfff..118e4ac 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-crtc.c +++ b/kernel-open/nvidia-drm/nvidia-drm-crtc.c @@ -48,6 +48,8 @@ #include #endif +#include + #if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA) static int nv_drm_atomic_replace_property_blob_from_id(struct drm_device *dev, @@ -339,6 +341,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; @@ -609,6 +614,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 +646,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) { @@ -700,6 +711,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; @@ -856,7 +868,6 @@ nv_drm_atomic_crtc_duplicate_state(struct drm_crtc *crtc) __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( &(to_nv_crtc_state(crtc->state)->req_config), @@ -888,6 +899,41 @@ 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, @@ -895,6 +941,8 @@ static struct drm_crtc_funcs nv_crtc_funcs = { .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, }; /* @@ -1020,6 +1068,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( @@ -1166,6 +1219,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 = @@ -1235,6 +1289,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. */ @@ -1261,9 +1353,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, diff --git a/kernel-open/nvidia-drm/nvidia-drm-crtc.h b/kernel-open/nvidia-drm/nvidia-drm-crtc.h index 2562e87..4e0e533 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-crtc.h +++ b/kernel-open/nvidia-drm/nvidia-drm-crtc.h @@ -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( diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c index 61842e8..0179486 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.c +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c @@ -94,6 +94,8 @@ #include #endif +#include "nv-kthread-q.h" + static int nv_drm_revoke_modeset_permission(struct drm_device *dev, struct drm_file *filep, NvU32 dpyId); @@ -111,6 +113,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"); @@ -118,6 +130,38 @@ 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) static void nv_drm_output_poll_changed(struct drm_device *dev) @@ -226,10 +270,10 @@ static void nv_drm_event_callback(const struct NvKmsKapiEvent *event) 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; @@ -360,14 +404,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 = @@ -378,14 +419,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, @@ -555,9 +629,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 @@ -618,6 +692,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); diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.h b/kernel-open/nvidia-drm/nvidia-drm-drv.h index 710f6ab..90ee946 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.h +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.h @@ -24,6 +24,7 @@ #define __NVIDIA_DRM_DRV_H__ #include "nvidia-drm-conftest.h" +#include "nv-kthread-q.h" #if defined(NV_DRM_AVAILABLE) diff --git a/kernel-open/nvidia-drm/nvidia-drm-modeset.c b/kernel-open/nvidia-drm/nvidia-drm-modeset.c index 7968ee4..97c7108 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-modeset.c +++ b/kernel-open/nvidia-drm/nvidia-drm-modeset.c @@ -85,28 +85,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 +118,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( @@ -268,23 +272,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); + } } } @@ -294,6 +310,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, @@ -303,6 +321,26 @@ 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); + } + + } + } + if (commit && nv_dev->supportsSyncpts) { nv_drm_for_each_crtc_in_state(state, crtc, crtc_state, i) { /*! loop over affected crtcs and get NvKmsKapiModeSetReplyConfig */ @@ -333,6 +371,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 @@ -340,48 +415,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, @@ -393,6 +491,8 @@ 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); /* @@ -476,52 +576,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) { /* @@ -555,9 +625,6 @@ int nv_drm_atomic_commit(struct drm_device *dev, NV_DRM_DEV_LOG_ERR( nv_dev, "Flip event timeout on head %u", nv_crtc->head); - while (!list_empty(&nv_crtc->flip_list)) { - __nv_drm_handle_flip_event(nv_crtc); - } } } } @@ -576,16 +643,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 diff --git a/kernel-open/nvidia-drm/nvidia-drm-modeset.h b/kernel-open/nvidia-drm/nvidia-drm-modeset.h index 40df631..6a1ae8a 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-modeset.h +++ b/kernel-open/nvidia-drm/nvidia-drm-modeset.h @@ -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); diff --git a/kernel-open/nvidia-drm/nvidia-drm-priv.h b/kernel-open/nvidia-drm/nvidia-drm-priv.h index 60b3f6c..bdefb8a 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-priv.h +++ b/kernel-open/nvidia-drm/nvidia-drm-priv.h @@ -153,11 +153,15 @@ struct nv_drm_device { 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 nv_drm_device *next; + + nv_kthread_q_t nv_kthread_q; }; static inline struct nv_drm_device *to_nv_device( diff --git a/kernel-open/nvidia-drm/nvidia-drm.Kbuild b/kernel-open/nvidia-drm/nvidia-drm.Kbuild index f672a9e..a771373 100644 --- a/kernel-open/nvidia-drm/nvidia-drm.Kbuild +++ b/kernel-open/nvidia-drm/nvidia-drm.Kbuild @@ -127,7 +127,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 diff --git a/push_info.txt b/push_info.txt index d7d8727..8f8e502 100644 --- a/push_info.txt +++ b/push_info.txt @@ -1 +1 @@ -rel-36_eng_2024-08-29 +rel-36_eng_2024-10-24 diff --git a/src/common/displayport/inc/dp_auxdefs.h b/src/common/displayport/inc/dp_auxdefs.h index 26f34c9..1804a08 100644 --- a/src/common/displayport/inc/dp_auxdefs.h +++ b/src/common/displayport/inc/dp_auxdefs.h @@ -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 // diff --git a/src/common/displayport/inc/dp_connector.h b/src/common/displayport/inc/dp_connector.h index 74ac4fe..3662841 100644 --- a/src/common/displayport/inc/dp_connector.h +++ b/src/common/displayport/inc/dp_connector.h @@ -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, diff --git a/src/common/displayport/inc/dp_connectorimpl.h b/src/common/displayport/inc/dp_connectorimpl.h index 74e4f8c..4b2e9f8 100644 --- a/src/common/displayport/inc/dp_connectorimpl.h +++ b/src/common/displayport/inc/dp_connectorimpl.h @@ -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 intransitionGroups; LinkedList addStreamMSTIntransitionGroups; + LinkedList 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,7 @@ namespace DisplayPort bool allocateTimeslice(GroupImpl * targetGroup); void freeTimeslice(GroupImpl * targetGroup); void flushTimeslotsToHardware(); + void hdcpRenegotiate(NvU64 cN, NvU64 cKsv); bool getHDCPAbortCodesDP12(NvU32 &hdcpAbortCodesDP12); bool getOuiSink(unsigned &ouiId, char * modelName, size_t modelNameBufferSize, NvU8 & chipRevision); bool hdcpValidateKsv(const NvU8 *ksv, NvU32 Size); diff --git a/src/common/displayport/inc/dp_deviceimpl.h b/src/common/displayport/inc/dp_deviceimpl.h index c9964b9..5b1c486 100644 --- a/src/common/displayport/inc/dp_deviceimpl.h +++ b/src/common/displayport/inc/dp_deviceimpl.h @@ -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 diff --git a/src/common/displayport/inc/dp_evoadapter.h b/src/common/displayport/inc/dp_evoadapter.h index 478a275..53b0f37 100644 --- a/src/common/displayport/inc/dp_evoadapter.h +++ b/src/common/displayport/inc/dp_evoadapter.h @@ -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); diff --git a/src/common/displayport/inc/dp_groupimpl.h b/src/common/displayport/inc/dp_groupimpl.h index d421e7d..4f265bf 100644 --- a/src/common/displayport/inc/dp_groupimpl.h +++ b/src/common/displayport/inc/dp_groupimpl.h @@ -37,11 +37,14 @@ namespace DisplayPort { + class StreamEncryptionStatusDetection; struct GroupImpl : public Group, ListElement, Timer::TimerCallback { ConnectorImpl * parent; LinkedList 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(); diff --git a/src/common/displayport/inc/dp_linkconfig.h b/src/common/displayport/inc/dp_linkconfig.h index cb711bc..1033121 100644 --- a/src/common/displayport/inc/dp_linkconfig.h +++ b/src/common/displayport/inc/dp_linkconfig.h @@ -202,6 +202,9 @@ namespace DisplayPort struct HDCPValidateData { + NvU8 vP[NV0073_CTRL_HDCP_VPRIME_SIZE]; + NvU64 aN; + NvU64 mP; }; typedef enum diff --git a/src/common/displayport/inc/dp_mainlink.h b/src/common/displayport/inc/dp_mainlink.h index b3d44a9..0e41a29 100644 --- a/src/common/displayport/inc/dp_mainlink.h +++ b/src/common/displayport/inc/dp_mainlink.h @@ -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; diff --git a/src/common/displayport/inc/dp_messagecodings.h b/src/common/displayport/inc/dp_messagecodings.h index e483d00..c2baf12 100644 --- a/src/common/displayport/inc/dp_messagecodings.h +++ b/src/common/displayport/inc/dp_messagecodings.h @@ -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 diff --git a/src/common/displayport/inc/dp_messages.h b/src/common/displayport/inc/dp_messages.h index 01231ff..8e344dd 100644 --- a/src/common/displayport/inc/dp_messages.h +++ b/src/common/displayport/inc/dp_messages.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), diff --git a/src/common/displayport/inc/dp_qse.h b/src/common/displayport/inc/dp_qse.h new file mode 100644 index 0000000..22283e3 --- /dev/null +++ b/src/common/displayport/inc/dp_qse.h @@ -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 diff --git a/src/common/displayport/inc/dp_regkeydatabase.h b/src/common/displayport/inc/dp_regkeydatabase.h index 3d36761..fb0bb8a 100644 --- a/src/common/displayport/inc/dp_regkeydatabase.h +++ b/src/common/displayport/inc/dp_regkeydatabase.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; diff --git a/src/common/displayport/inc/dptestutil/dp_testmessage.h b/src/common/displayport/inc/dptestutil/dp_testmessage.h index b841dc0..aa8021f 100644 --- a/src/common/displayport/inc/dptestutil/dp_testmessage.h +++ b/src/common/displayport/inc/dptestutil/dp_testmessage.h @@ -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, diff --git a/src/common/displayport/src/dp_connectorimpl.cpp b/src/common/displayport/src/dp_connectorimpl.cpp index 1383adf..94919dd 100644 --- a/src/common/displayport/src/dp_connectorimpl.cpp +++ b/src/common/displayport/src/dp_connectorimpl.cpp @@ -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; } @@ -2069,6 +2148,128 @@ 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(); + curStrmEncrEnblGroup->hdcpSetEncrypted(true); + } + } + } + else if (tag == &tagHDCPReauthentication) + { + if (authRetries < HDCP_AUTHENTICATION_RETRIES) + { + HDCPState hdcpState = {0}; + main->configureHDCPGetHDCPState(hdcpState); + + unsigned authDelay = (hdcpState.HDCP_State_22_Capable ? + HDCP22_AUTHENTICATION_COOLDOWN : 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; + main->configureHDCPRenegotiate(); + main->configureHDCPGetHDCPState(hdcpState); + + if (hdcpState.HDCP_State_Authenticated) + { + isHDCPAuthOn = true; + authRetries = 0; + // 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); + // 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 +3099,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 +3244,40 @@ 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; + } + } } + // + // 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 +3305,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 +3398,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 +3454,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. @@ -3858,6 +4136,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 +4187,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 +4223,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 +4269,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 +6334,8 @@ void ConnectorImpl::notifyLongPulseInternal(bool statusConnected) delete messageManager; messageManager = 0; discoveryManager = 0; + delete qseNonceGenerator; + qseNonceGenerator = 0; cancelHdcpCallbacks(); if (hal->getSupportsMultistream() && main->hasMultistream()) @@ -5947,6 +6365,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 +6403,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 +6625,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 +7062,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 +7118,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) diff --git a/src/common/displayport/src/dp_deviceimpl.cpp b/src/common/displayport/src/dp_deviceimpl.cpp index 7600a34..78de6aa 100644 --- a/src/common/displayport/src/dp_deviceimpl.cpp +++ b/src/common/displayport/src/dp_deviceimpl.cpp @@ -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; iBKSV[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; iBKSV[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())); } } diff --git a/src/common/displayport/src/dp_evoadapter.cpp b/src/common/displayport/src/dp_evoadapter.cpp index 9dee498..70440d9 100644 --- a/src/common/displayport/src/dp_evoadapter.cpp +++ b/src/common/displayport/src/dp_evoadapter.cpp @@ -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 @@ -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 = (streamType == NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_1); + + 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, diff --git a/src/common/displayport/src/dp_groupimpl.cpp b/src/common/displayport/src/dp_groupimpl.cpp index 35944b7..5434980 100644 --- a/src/common/displayport/src/dp_groupimpl.cpp +++ b/src/common/displayport/src/dp_groupimpl.cpp @@ -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,186 @@ 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; + } + } + } + } + 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 +519,120 @@ 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; + } + } +} + void GroupImpl::updateVbiosScratchRegister(Device * lastDev) { if (!parent->bDisableVbiosScratchRegisterUpdate && diff --git a/src/common/displayport/src/dp_messagecodings.cpp b/src/common/displayport/src/dp_messagecodings.cpp index 20f98d8..0bf1d9a 100644 --- a/src/common/displayport/src/dp_messagecodings.cpp +++ b/src/common/displayport/src/dp_messagecodings.cpp @@ -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, diff --git a/src/common/displayport/src/dp_qse.cpp b/src/common/displayport/src/dp_qse.cpp new file mode 100644 index 0000000..66292be --- /dev/null +++ b/src/common/displayport/src/dp_qse.cpp @@ -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 + +using namespace DisplayPort; + +NvU64 +QSENonceGenerator::random() +{ + NvU64 randomNumber; + + previousRandomLSB = static_cast(((NvU64)1664525 * previousRandomLSB + 1013904223)); + previousRandomMSB = static_cast(((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( rnd & 0xFF); + clientId.data[1] = static_cast((rnd >> 8) & 0xFF); + clientId.data[2] = static_cast((rnd >> 16) & 0xFF); + clientId.data[3] = static_cast((rnd >> 24) & 0xFF); + clientId.data[4] = static_cast((rnd >> 32) & 0xFF); + clientId.data[5] = static_cast((rnd >> 40) & 0xFF); + clientId.data[6] = static_cast((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); +} diff --git a/src/common/displayport/src/dptestutil/dp_testmessage.cpp b/src/common/displayport/src/dptestutil/dp_testmessage.cpp index 5813e3f..c49506e 100644 --- a/src/common/displayport/src/dptestutil/dp_testmessage.cpp +++ b/src/common/displayport/src/dptestutil/dp_testmessage.cpp @@ -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; } diff --git a/src/common/sdk/nvidia/inc/class/clc370_notification.h b/src/common/sdk/nvidia/inc/class/clc370_notification.h index c94556e..292c255 100644 --- a/src/common/sdk/nvidia/inc/class/clc370_notification.h +++ b/src/common/sdk/nvidia/inc/class/clc370_notification.h @@ -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" */ diff --git a/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h b/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h index 00698b7..28eb3d0 100644 --- a/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h +++ b/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h @@ -467,7 +467,117 @@ typedef struct NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS { #define NV0073_CTRL_SPECIFIC_CONNECTOR_PLATFORM_CRUSH_DEFAULT 0x00000020U #define NV0073_CTRL_SPECIFIC_CONNECTOR_PLATFORM_UNKNOWN 0xFFFFFFFFU +/* + * NV0073_CTRL_CMD_SYSTEM_GET_HDCP_REPEATER_INFO + * + * This command is used to get HDCP repeater information. From the + * repeater device this call returns KsvList,BStatus and VPrime. If the + * device is implemented internally, the client call supply a Cksv and Cn + * And in turn following parameters are returned: MPrime, Dksv which are used + * for upstream authentication. In addition to this the flag bAuthRequired + * shall be set to indicate that upstream authentication is required along with + * comparing the KsvList with SRM. On the other hand, if the device is an + * external implementation MPrime and Dksv values shall be ignored and the flag + * bAuthRequired will not be set indicating upstream authentication not + * required and just the comparison of KsvList with upstream SRM is required. + * + * 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. + * displayId + * This parameter indicates the digital display device's + * displayId. This comes as input to this command. + * bRepeaterPending + * The repeater pending flag as the output to this command. + * The flag returned indicating whether repeater is ready or not + * TRUE if repeater is not ready and FALSE otherwise. + * Cn + * This parameter is the input value Cn a 64 bit random number + * to be provided to this command. Cn value is Upstream protocol's + * exchange random number.This value must be written by software + * before the KSV is written if the transmitter device follows the HDCP + * upstream protocol. If the transmitter supports a proprietary method of + * authenticating the repeater device, Cn can be ignored. + * Cksv + * This parameter is the input value Cksv (a unique identifier) of 40 bit + * size to be provided to this command. This input value shall contain 20 + * ones and 20 zeros in accordance with the HDCP specification. This value + * must be written by software before the KSV is written if the transmitter + * device follows the HDCP upstream protocol. If the transmitter supports + * a proprietary method of authenticating the repeater device, Cksv can be + * ignored. + * actualKsvSize + * The actual KSV list size(in bytes) returned back as output while reading + * KSV list. + * ksvList + * In case downstream device is repeater then this will give the list of + * KSV's of all downstream devices attached to the repeater. It differs + * from actualKsvSize because this allocates maximum allowed size. + * If downstream device is receiver then this array will contain all zeros. + * BStatus + * The BSTATUS value as output by this command.This value's bit fields + * contains information returned by repeater device such as total number of + * downstream devices attached to the repeater excluding HDCP repeater, + * value for the depth indicating number of connection levels through + * connection topology, this value also gives information about maximum + * cascaded and devices exceeded (127). + * VPrime + * The VPRIME value returned as output by this command from the repeater + * device. This value should be used to compare the verification value + * during the HDCP upstream protocol using SHA1 in accordance with the + * upstream protocol. This value can be ignored if bAuthRequired is not + * set indicating the verification is done by the transmitter device. + * bAuthrequired + * The authentication flag as the output to this command. + * The Flag returned indicating whether authentication is required or not + * TRUE if authentication required and FALSE otherwise. + * MPrime + * The MPRIME value returned as output by this command. + * MPrime shall be decrypted by the client and used in the SHA-1 + * computation of V during upstream authentication. This value can be + * ignored if bAuthRequired is not set indicating the verification is + * done by the transmitter device. + * Dksv + * This parameter is the output value DKSV of 40 bit size. + * As per the HDCP specification this value should contain 20 ones and + * 20 zeros.This value can be ignored if bAuthRequired is not set + * indicating the verification is done by the transmitter device. + * + * Possible status values returned are: + * NV_OK + * NV_ERR_INVALID_PARAM_STRUCT + * NV_ERR_INVALID_ARGUMENT + */ +#define NV0073_CTRL_REP_KSV_SIZE (5U) +#define NV0073_CTRL_DKSV_SIZE (5U) +#define NV0073_CTRL_MPRIME_SIZE (0x2U) /* finn: Evaluated from "(8 / 4)" */ +#define NV0073_CTRL_CN_SIZE (0x2U) /* finn: Evaluated from "(8 / 4)" */ +#define NV0073_CTRL_CKSV_SIZE (5U) +#define NV0073_CTRL_VPRIME_SIZE (0x5U) /* finn: Evaluated from "(20 / 4)" */ +#define NV0073_CTRL_MAX_HDCP_REPEATER_COUNT (0x27bU) /* finn: Evaluated from "(NV0073_CTRL_REP_KSV_SIZE * 127)" */ + +#define NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_REPEATER_INFO (0x730260U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS_MESSAGE_ID (0x60U) + +typedef struct NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU8 bRepeaterPending; + NvU32 Cn[NV0073_CTRL_CN_SIZE]; + NvU8 Cksv[NV0073_CTRL_CKSV_SIZE]; + NvU32 actualKsvSize; + NvU8 ksvList[NV0073_CTRL_MAX_HDCP_REPEATER_COUNT]; + NvU16 BStatus; + NvU32 VPrime[NV0073_CTRL_VPRIME_SIZE]; + NvU8 bAuthrequired; + NvU32 MPrime[NV0073_CTRL_MPRIME_SIZE]; + NvU8 Dksv[NV0073_CTRL_DKSV_SIZE]; +} NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS; /* * NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_ENABLE @@ -584,7 +694,847 @@ typedef struct NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS { #define NV0073_CTRL_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_FALSE (0x00000000U) #define NV0073_CTRL_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_TRUE (0x00000001U) +/* + * NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_STATE + * + * This command is used to obtain that state of hdcp for the specified attach + * point (that being the displayId). + * + * 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. + * displayId + * This parameter specifies the display for which information is to be + * returned. Only one display may be indicated in this parameter. + * If more than one displayId is used a failing status of + * NV_ERR_INVALID_ARGUMENT will be returned. + * flags + * This parameter specifies the state of the attach point resource. + * Here are the current defined fields: + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING + * This comes as an output to this command. The attach point + * is currently encrypting hdcp content over the attach point + * link. This state of this field is determined by + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED. The + * default is to return cached hdcp state. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED + * This comes as an input to this command. If set to 1, the return + * value in NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING is based + * on the Status Word. If the uncached hdcp state fails, + * such as the case for external hdcp designs that do not support + * Upstream Status register, then if the flag + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED is set, RM + * will unclear it and return the cached value instead. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_CAPABLE + * This comes as an output to this command. + * This bit indicates that the attach point resource is capable + * of hdcp encryption. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DUAL_LINK_CAPABLE + * This comes as an output to this command. + * This bit indicates that the attach point resource is capable + * of hdcp encryption in a dual-link configuration. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DISALLOWED + * This bit indicates that the attach point resource should not + * have HDCP available even if capable. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_RECEIVER_CAPABLE + * This comes as an output to this command. + * This bit indicates that the receiver attached to this attach point + * resource is capable of hdcp encryption. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_REPEATER_CAPABLE + * This comes as an output to this command. + * This bit indicates that the receiver attached to this attach point + * resource is capable of hdcp repeater operation. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_FP_INTERNAL + * This comes as output to this command. + * This bit indicates that the associated display is an HDCP-capable + * internal panel. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_RECEIVER_CAPABLE + * This comes as output to this command. + * This bit indicates that the receiver attached to this attach point + * resource is capable of hdcp22 encryption. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_REPEATER_CAPABLE + * This comes as output to this command. + * This bit indicates that the receiver attached to this attach point + * resource is capable of hdcp22 repeater operation. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTING + * This comes as an output to this command. The attach point + * is currently encrypting hdcp22 content over the attach point + * link. This state of this field is determined by + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED, return hdcp22 uncached + * status by default. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_TYPE1 + * This comes as an output to this command. The attach point + * is currently encrypting hdcp22 content with stream Type 1 over the + * link. This state of this field is determined by + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED, return hdcp22 uncached + * status of stream type by default. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AUTHENTICATED + * This comes an output to this command. + * This bit indicates if the receiver attached to this attach point + * completes authenticaion with source or not. To non DP-MST receiver, the state + * should be identical to NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTING, while + * DP MST needs to assign ECF after authenticated. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_HDCP22_CAPABLE + * This comes as an output to this command. + * This bit indicates that the attach point resource is capable + * of hdcp2.2 encryption. + * + * Possible status values returned are: + * NV_OK + * NV_ERR_INVALID_PARAM_STRUCT + * NV_ERR_INVALID_ARGUMENT + */ +#define NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_STATE (0x730280U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS_MESSAGE_ID (0x80U) + +typedef struct NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; +} NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS; + +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED_TRUE (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_ENCRYPTING_CACHED_FALSE (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTION_INPROGRESS 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTION_INPROGRESS_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTION_INPROGRESS_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_CAPABLE 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DUAL_LINK_CAPABLE 5:5 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DUAL_LINK_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DUAL_LINK_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DISALLOWED 6:6 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DISALLOWED_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_DISALLOWED_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_RECEIVER_CAPABLE 8:8 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_RECEIVER_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_RECEIVER_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_REPEATER_CAPABLE 9:9 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_REPEATER_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_REPEATER_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_FP_INTERNAL 10:10 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_FP_INTERNAL_FALSE (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_FP_INTERNAL_TRUE (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_RECEIVER_CAPABLE 11:11 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_RECEIVER_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_RECEIVER_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_REPEATER_CAPABLE 12:12 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_REPEATER_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_REPEATER_CAPABLE_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTING 13:13 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTING_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_ENCRYPTING_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_TYPE1 14:14 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_TYPE1_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_HDCP22_TYPE1_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AUTHENTICATED 15:15 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AUTHENTICATED_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AUTHENTICATED_YES (0x00000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_HDCP22_CAPABLE 16:16 +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_HDCP22_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_STATE_AP_HDCP22_CAPABLE_YES (0x00000001U) + +/* + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_INFO + * + * This structure describes stStatus information. + * + * displayId + * This parameter returns the displayId associated with the + * attach point index. + * S + * Each element contains the attach-point S. This value's bit + * field contains information pertaining to STATUS of each attach point. + * The stStatus parameter is broken down as follows: + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_ENCRYPTING + * This field specifies that the attach-point is transmitting and + * has output encryption enabled. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_REPEATER + * This field specifies that the attach-point is transmitting to a + * repeater device. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_USER_ACCESSIBLE + * This field specifies that the attach-point is transmitting on a + * user-accessible external digital port. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_EXTERNALLY_UNPROTECTED + * This field specifies that the attach-point is transmitting + * externally and is unprotected. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_ATTACH_PORT_INDEX + * This field specifies the port/attach-point index. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_NUM_PORTS + * This field specifies the number of connectable attach-ports. + * The default is 8. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_INTERNAL_PANEL + * This field specifies a compliant internal/non-user accessible + * port panel without hdcp encryption. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_WIDE_SCOPE + * This field specifies _CS is not enough to determine the presence + * of non-compliant outputs (this field is always 1). + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_CS_CAPABLE + * This field specifies that connection-state is supported. + * This field is always 1. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_READZ_CAPABLE + * This field specifies that readZ is supported. + * This field is always 0. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_DUAL_LINK_EVEN + * This field specifies the even half of a dual-link (0x74). + * This field *NOT* yet supported. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_DUAL_LINK_ODD + * This field specifies the odd half of a dual-link (0x76) + * This field *NOT* yet supported. + */ +typedef struct NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_INFO { + NvU32 displayId; + NV_DECLARE_ALIGNED(NvU64 S, 8); +} NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_INFO; + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_ENCRYPTING 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_REPEATER 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_USER_ACCESSIBLE 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_EXTERNALLY_UNPROTECTED 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_ATTACH_PORT_INDEX 7:4 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_NUM_PORTS 11:8 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_INTERNAL_PANEL 12:12 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_WIDE_SCOPE 13:13 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_CS_CAPABLE 14:14 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_READZ_CAPABLE 15:15 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_RESERVED0 39:16 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_DUAL_LINK_EVEN 40:40 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_S_DUAL_LINK_ODD 41:41 + +/* + * NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL + * + * This command is used to do HDCP controls on the specified attach + * point (that being the displayId). + * + * 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. + * displayId + * This parameter specifies the display for which information is to be + * returned. Only one display may be indicated in this parameter. + * If more than one displayId is used a failing status of + * NV_ERR_INVALID_ARGUMENT will be returned. + * err + * This parameter specifies provides info regarding the outcome + * of this calling control call. If zero, no errors were found. + * Otherwise, this parameter will specify the error detected. + * The valid parameter is broken down as follows: + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_UNSUCCESSFUL + * If set to _YES, this indicates at least one of the calling + * functions failed. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_PENDING + * If set to _YES, this indicates at renogiation is not complete and + * that the client should check status later. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_BAD_TOKEN_TYPE + * If set to _YES, the session ID or KSV was rejected. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_LINK_FAILED + * If set to _YES, renogiation could not complete. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_INVALID_PARAMETER + * If set to _YES, one or more of the calling parameters was invalid. + * cmd + * This parameter specifies a bitmask of the legal defined fields. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_NULL + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_RENEGOTIATE + * This command forces the specified displayId to renegotiate the + * hdcp link. The client should supply as an input, + * cN and cKsv. On return, bStatus, stStatus and cS is returned. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_DISABLE_AUTHENTICATION + * This command forces the specified displayId to off authentication the + * hdcp link. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_READ_LINK_STATUS + * This command reads the status of the cipher returning a signed + * S (ie: kP) and cS for the requested displayId, as well as + * the relevant parameters necessary for the client to verify + * the information provided. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_VALIDATE_LINK + * This command returns the parameters necessary to validiate the + * links for the displayId. The client should supply as input + * cN and cKsv. On return, bStatus, cS, stStatus, aN, numBksvs, + * bKsvList, vP, mP, and dKsv are returned. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_QUERY_HEAD_CONFIG + * This command enumerates ports attached to a head. + * On input, Cn and cKsv should be provided and on return + * bSTatus, status, and connection state is returned. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_ABORT_AUTHENTICATION + * This command causes the specified AP to abort authentication + * protocol after KSV list is read, or during next time it's + * renegotiated. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_GET_ALL_FLAGS + * This command provides all possible valid device data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_GET_SPECIFIED_FLAGS + * This command provides data specified by flags field set by the + * client. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_FORWARD_PENDING_KSVLIST_READY + * This command provides client to tell there's pending Hdcp1X KsvList + * Ready notification at BStatus read. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_READ_LINK_STATUS_NO_DISPLAY + * This command reads the status of the cipher returning a signed + * S (ie: kP) and cS and the relevant parameters necessary for the client to + * verify upstream. + * flags + * This parameter specifies a bitmask of the legal defined fields and the + * reason AbortAuthentication. + * The client shall set the desired fields and on return if valid, + * the resource manager will set which flags are actually valid. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BCAPS_PRESENT + * IN: Request hdcp receiver bcaps register state. + * OUT: Bcaps parameter contains valid receiver bcaps register data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BSTATUS_PRESENT + * IN: Request hdcp receiver bstatus register state. + * OUT: BStatus parameter contains valid receiver bstatus register data + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_PRESENT + * IN: Request hdcp receiver key selection vector: BKSV + * Driver will read BKSV from receiver and update RM states if + * the cmd is _GET_SPECIFIED_FLAGS and _KP_PRESENT is unset. + * Otherwise, driver returns cached BKSV. + * OUT: Bksv parameter contains valid receiver bksv data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_LIST_PRESENT + * IN: Request list of downstream BKSV from repeater + * OUT: BksvList parameter contains valid data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_PRESENT + * IN: Request hdcp transmitter key selection vector: DKSV + * OUT: Dksv parameter contains valid receiver DKSV data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_PRESENT + * IN: Request hdcp parameter An + * OUT: An parameter contains valid data + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_PRESENT + * IN: Request hdcp transmitter downstream key selection vector: AKSV + * OUT: Aksv parameter contains valid receiver Aksv data. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_VP_PRESENT + * IN: Request VPrime data + * OUT: VPrime parameter contains valid data + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_MP_PRESENT + * IN: Request MPrime data used for repeater authentication + * OUT: MPrime parameter contains valid data + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_PRESENT + * IN: Request SPrime data + * OUT: SPrime parameter contains valid data + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_IMPLICIT_HEAD + * IN: The head to use if no legal head could be located. + * Use NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_IMPLICIT_HEAD_NONE + * if no implicit head should be used. + * OUT: n/a + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_FORCE_REAUTH + * IN: Request to execute authentication protocol even encryption + * enabled. + * OUT: n/a + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_RXIDMSG_PENDING + * IN: Request to execute repeater authentication protocol with pending + * ID List message information. + * OUT: n/a + * Reason of AbortAuthentication. + * When pass in by client, it indicates the reason why client issue an + * Abort. When return by RM, it indicates the reason of last successful + * Abort. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_NONE + * Default value + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_UNTRUST + * Abort due to Kp mismatch + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_UNRELBL + * Abort due to repeated link failure + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSV_LEN + * Abort due to KSV length + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSV_SIG + * Abort due to KSV signature + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_SRM_SIG + * Abort due to SRM signature + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_SRM_REV + * Abort due to SRM revocation + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_NORDY + * Abort due to repeater not ready + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSVTOP + * Abort due to KSV topology error + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_BADBKSV + * Abort due to invalid Bksv + * linkCount + * This parameter specifies how many links are valid. This is important + * when determining AKSV, BKSV, AN, etc... and is an output to this + * command. + * apIndex + * Each element of this parameter specifies the hardware attach-point index + * for the requested displayId. The 2nd element is only valid in the case + * where the resource output is capable of dual-link determined when the + * linkCount is greater than 1. + * cN + * This parameter is the input value Cn a 64 bit random number + * to be provided to this command. Cn value is Upstream protocol's + * exchange random number.This value must be written by software + * before the KSV is written if the transmitter device follows the HDCP + * upstream protocol. + * cKsv + * This parameter is the input value Cksv (a unique identifier) of 40 bit + * size to be provided to this command. This input value shall contain 20 + * ones and 20 zeros in accordance with the HDCP specification. This value + * must be written by software before the KSV is written if the transmitter + * device follows the HDCP upstream protocol. + * aN + * Each element of this buffer specifies the output value aN, + * a 64 bit random number used during hdcp authentication and validating + * the upstream link in which case only the first 40 bits are used. + * The 2nd element is only valid in the case where the resource output is + * capable of dual-link determined when the linkCount is greater than 1. + * aKsv + * Each element of this buffer specifies output value aKsv of 40 bit size. + * As per the HDCP specification this value should contain 20 ones and + * 20 zeros. + * The 2nd element is only valid in the case where the resource output is + * capable of dual-link determined when the linkCount is greater than 1. + * bStatus + * Each element contains the attach-point bStatus data returned by the + * repeater/receiver device (if valid). The bStatus value is an output + * by this command. For HDCP on DP, bInfo is the one we should look at. + * bInfo is defined exactly the same with bStatus on DVI. Hal is taking + * care of the difference here. + * This bStatus info is broken down as follows: + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_DEVICE_COUNT + * Specifies the total number of receivers excluding repeater. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_MAX_DEVICES_EXCEEDED + * Specifies a topology error in which greater than 127 devices are + * detected in the overall hdcp configuration. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_REPEATER_DEPTH + * Specifies the repeater depth. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_MAX_CASCADE_EXCEEDED + * Specifies a topology error in which greater than 7 levels are + * detected in the overall hdcp configuration. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDMI_MODE + * Specifies that the hdcp receiver is in HDMI mode. + * bCaps + * The BCAPS value is an output by this command. This value's bit fields + * contains information returned by receiver device. Bcaps can be used + * to determine if receiver is a repeater and when the ksvlist and vprime + * data is ready. + * The BCAPS is defined different in the spec of HDCP on DP. It's been + * split to BCAPS and BSTATUS. Here we'll end a flag to indicate + * the client if it's a DP. + * The bCaps parameter is broken down as follows based on HDCP spec 1.1: + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_FAST_REAUTHENTICATION + * This field when set to 1, specifies the receiver is capable of + * receiving(unencrypted) video signal during session + * re-authentication. All HDMI capable receivers shall be capable of + * performing the fast authentication even if this bit is not set. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_EESS_1_1 + * This field when set to 1, specifies this HDCP receiver supports + * Enhanced Encryption Status Signaling (EESS), Advance cipher, and + * Enhanced Link Verification options. For the HDMI protocol, EESS + * capability is assumed regardless of this bit setting. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_READY_KSV_FIFO + * This field when set to 1, specifies this HDCP repeater has built + * the list of attached KSVs and computed the verification value V'. + * This value is always zero during the computation of V'. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_FAST + * This field when set to 1, specifies this device supports 400khz + * transfers. When zero, 100 khz is the maximum transfer rate + * supported. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_REPEATER + * This field when set to 1, specifies the HDCP receiver supports + * downstream connections as permitted by Digital Content + * Protection LLC licence. This bit does not change while the HDCP + * receiver is active. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDMI_RESERVED + * This field is reserved and HDCP receivers not capable of + * support HDMI must clear this bit to 0. + * stStatus + * This parameter specifies the attach point stStatus. See + * the description of NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_INFO for + * details on stStatus information. + * cS + * This parameter provides the connection-state for the status of + * all port/attach-points on this head. + * The connection-state is broken down as follows: + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_ATTACH_POINTS + * This field specifies the transmitting attach-points. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_NON_HDCP + * This field specifies the transmitting attach-points. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HEAD_INDEX + * This field specifies the index of the head. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_RFUPLANES + * This field specifies the RFUPLANES. + * This field *NOT* yet supported. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_NUM_ACTIVE_HEADS + * This field specifies the number of heads - 1. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_ATTACH_PLANES + * This field specifies attach planes. + * This field *NOT* yet supported. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_CLONE_MODE + * This field specifies dual-display clone mode. + * This field *NOT* yet supported. + * NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_SPAN_MODE + * This field specifies dual-display span mode. + * This field *NOT* yet supported. + * bKsvList + * In case downstream device is repeater then this will give the list of + * KSV's of all downstream devices attached to the repeater. It differs + * from actualKsvSize because this allocates maximum allowed size. + * If downstream device is receiver then this array will contain all zeros. + * numBksvs + * Total number of Bksv from all downstream devices in the bKsvList. + * This info can also be obtained via bStatus. + * vP + * The VPRIME value returned as output by this command from the repeater + * device. This value should be used to compare the verification value + * during the HDCP upstream protocol using SHA1 in accordance with the + * upstream protocol. This value can be ignored if bAuthRequired is not + * set indicating the verification is done by the transmitter device. + * kP + * The KP value is returned as an output by this command. This + * parameter is the signature computed by hardware and the client + * should compute the signature to compare this value. + * The 2nd element is only valid in the case where the resource output is + * capable of dual-link determined when the linkCount is greater than 1. + * mP + * The MPRIME value returned as output by this command. + * MPrime shall be decrypted by the client and used in the SHA-1 + * computation of V during upstream authentication. This value can be + * ignored if bAuthRequired is not set indicating the verification is + * done by the transmitter device. + * dKsv + * Each element of this buffer is the output value DKSV of 40 bit size. + * As per the HDCP specification this value should contain 20 ones and + * 20 zeros. + * The 2nd element is only valid in the case where the resource output is + * capable of dual-link determined when the linkCount is greater than 1. + * streamIndex + * Each content stream is assigned an index value bye upstream client. + * HDMI: The index must be 0. + * DP SST: The index must be 0. + * DP MST: Assigned stream index. + * streamType + * Each content stream is assigned a type value by the upstream content + * control function. + * 0x00: Type 0 content stream. May be transimtted by the HDCP repeater to + * all HDCP devices. + * 0x01: Type 1 content stream. Must not be transmitted by the HDCP + * repeater to HDCP 1.x-compliant devices and HDCP 2.0-compliant + * repeaters. + * 0x02-0xFF: reserved for futures use only. + * bEnforceType0Hdcp1xDS + * If this bit is set, DPU enforces Type0 if it finds Hdcp1x monitor downstream + * Possible status values returned are: + * NV_OK + * NV_ERR_INVALID_PARAM_STRUCT + * NV_ERR_INVALID_ARGUMENT + */ + +#define NV0073_CTRL_CMD_SPECIFIC_HDCP_CTRL (0x730282U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_HDCP_LINK_COUNT (0x0000002U) +#define NV0073_CTRL_HDCP_VPRIME_SIZE (0x0000014U) +#define NV0073_CTRL_HDCP_MAX_DEVICE_COUNT (0x00000FFU) +#define NV0073_CTRL_HDCP_KSV_SIZE (0x0000005U) +#define NV0073_CTRL_HDCP_MAX_NUM_APS (0x0000010U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS_MESSAGE_ID (0x82U) + +typedef struct NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + + NvU32 err; + + NvU32 cmd; + NvU32 flags; + NvU8 linkCount; + + NV_DECLARE_ALIGNED(NvU64 cN, 8); + NV_DECLARE_ALIGNED(NvU64 cKsv, 8); + + NvU32 apIndex[NV0073_CTRL_HDCP_LINK_COUNT]; + + NV_DECLARE_ALIGNED(NvU64 aN[NV0073_CTRL_HDCP_LINK_COUNT], 8); + NV_DECLARE_ALIGNED(NvU64 aKsv[NV0073_CTRL_HDCP_LINK_COUNT], 8); + + NvU32 bStatus[NV0073_CTRL_HDCP_MAX_NUM_APS]; + NvU32 bCaps[NV0073_CTRL_HDCP_MAX_NUM_APS]; + + NV_DECLARE_ALIGNED(NV0073_CTRL_SPECIFIC_HDCP_CTRL_STATUS_INFO stStatus[NV0073_CTRL_HDCP_MAX_NUM_APS], 8); + + NV_DECLARE_ALIGNED(NvU64 cS, 8); + + NV_DECLARE_ALIGNED(NvU64 bKsv[NV0073_CTRL_HDCP_LINK_COUNT], 8); + NV_DECLARE_ALIGNED(NvU64 bKsvList[NV0073_CTRL_HDCP_MAX_DEVICE_COUNT], 8); + NvU32 numBksvs; + + NvU8 vP[NV0073_CTRL_HDCP_VPRIME_SIZE]; + NV_DECLARE_ALIGNED(NvU64 kP[NV0073_CTRL_HDCP_LINK_COUNT], 8); + + NV_DECLARE_ALIGNED(NvU64 mP, 8); + NV_DECLARE_ALIGNED(NvU64 dKsv[NV0073_CTRL_HDCP_LINK_COUNT], 8); + + NvU32 streamIndex; + NvU8 streamType; + NvBool bEnforceType0Hdcp1xDS; + + NvBool bPendingKsvListReady; +} NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS; + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_UNSUCCESSFUL 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_UNSUCCESSFUL_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_UNSUCCESSFUL_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_PENDING 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_PENDING_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_PENDING_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_BAD_TOKEN_TYPE 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_BAD_TOKEN_TYPE_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_BAD_TOKEN_TYPE_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_LINK_FAILED 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_LINK_FAILED_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_LINK_FAILED_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_INVALID_PARAMETER 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_INVALID_PARAMETER_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_ERR_INVALID_PARAMETER_YES (0x0000001U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD 31:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_NULL (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_READ_LINK_STATUS (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_VALIDATE_LINK (0x0000002U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_QUERY_HEAD_CONFIG (0x0000003U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_RENEGOTIATE (0x0000004U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_GET_ALL_FLAGS (0x0000005U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_GET_SPECIFIED_FLAGS (0x0000006U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_ABORT_AUTHENTICATION (0x0000007U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_DISABLE_AUTHENTICATION (0x0000008U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_SET_TYPE (0x0000009U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_FORWARD_KSVLIST_READY (0x000000AU) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CMD_READ_LINK_STATUS_NO_DISPLAY (0x000000BU) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BCAPS_PRESENT 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BCAPS_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BCAPS_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BSTATUS_PRESENT 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BSTATUS_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BSTATUS_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_PRESENT 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_S_PRESENT 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_S_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_S_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_LIST_PRESENT 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_LIST_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_BKSV_LIST_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_PRESENT 5:5 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_S_PRESENT 6:6 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_S_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AN_S_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_PRESENT 7:7 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_S_PRESENT 8:8 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_S_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_AKSV_S_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_PRESENT 9:9 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_S_PRESENT 10:10 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_S_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_DKSV_S_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_MP_PRESENT 11:11 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_MP_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_MP_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_VP_PRESENT 12:12 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_VP_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_VP_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CN_PRESENT 13:13 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CN_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CN_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CKSV_PRESENT 14:14 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CKSV_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CKSV_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_PRESENT 15:15 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_S_PRESENT 16:16 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_S_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_KP_S_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_STATUS_PRESENT 17:17 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_STATUS_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_STATUS_PRESENT_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CS_PRESENT 18:18 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CS_PRESENT_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_CS_PRESENT_YES (0x0000001U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT 22:19 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_NONE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_UNTRUST (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_UNRELBL (0x0000002U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSV_LEN (0x0000003U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSV_SIG (0x0000004U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_SRM_SIG (0x0000005U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_SRM_REV (0x0000006U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_NORDY (0x0000007U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_KSVTOP (0x0000008U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_ABORT_BADBKSV (0x0000009U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_IMPLICIT_HEAD 25:23 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_IMPLICIT_HEAD_NONE (0x0000007U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_TYPE_CHANGED 26:26 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_TYPE_CHANGED_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_TYPE_CHANGED_YES (0x0000001U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_FORCE_REAUTH 27:27 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_FORCE_REAUTH_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_FORCE_REAUTH_YES (0x0000001U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_RXIDMSG_PENDING 28:28 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_RXIDMSG_PENDING_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_FLAGS_RXIDMSG_PENDING_YES (0x0000001U) + +/* BCaps definition of HDCP over TMDS */ +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_FAST_REAUTHENTICATION 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_EESS_1_1 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_FAST 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_READY_KSV_FIFO 5:5 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_REPEATER 6:6 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDMI_RESERVED 7:7 +/* BCaps definition of HDCP over DP */ +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_DP_HDCP_CAPABLE 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_DP_REPEATER 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_DP_READY_KSV_FIFO 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_DP_R0_AVAILABLE 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_DP_LINK_INTEGRITY_FAILURE 4:4 + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_DEVICE_COUNT 6:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_MAX_DEVICES_EXCEEDED 7:7 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_REPEATER_DEPTH 10:8 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BSTATUS_MAX_CASCADE_EXCEEDED 11:11 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDMI_MODE 12:12 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_RESERVED_0 31:13 + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_ATTACH_POINTS 15:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_NON_HDCP 16:16 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HEAD_INDEX 20:17 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_RFUPLANES 28:21 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_NUM_ACTIVE_HEADS 30:29 +// Bit 39-29 are implementation dependent connection state information +// for HDCP22 from gm206 (v02_06) onwards Bit-30 says HDCP22 encryption status. +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_ENCRYPTION 30:30 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_ENCRYPTION_YES 0x00000001U +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_ENCRYPTION_NO 0x00000000U +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_TYPE1 31:31 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_TYPE1_YES 0x00000001U +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_HDCP22_TYPE1_NO 0x00000000U +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_RESERVED_0 39:32 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_ATTACH_PLANES 47:40 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_CLONE_MODE 48:48 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_CS_SPAN_MODE 49:49 + +/* This HDCP_MODE definition applies to both DP and TMDS */ +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_MODE 15:15 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_MODE_TMDS (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_MODE_DP (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_VERSION 23:16 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_VERSION_1X (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_BCAPS_HDCP_VERSION_22 (0x0000022U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_REPEATER 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_REPEATER_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_REPEATER_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_HDCP_CAPABLE 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_HDCP_CAPABLE_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BCAPS_HDCP_CAPABLE_YES (0x0000001U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DP_READY 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DP_HPRIME_AVAILABLE 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DP_PAIRING_AVAILABLE 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DP_REAUTH_REQ 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DP_LINK_INTEGRITY_FAILURE 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_HDCP1_REPEATER_DOWNSTREAM 5:5 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_HDCP2_0_REPEATER_DOWNSTREAM 6:6 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_MAX_CASCADE_EXCEEDED 7:7 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_MAX_DEVS_EXCEEDED 8:8 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_DEVICE_COUNT 13:9 +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_BSTATUS_REPEATER_DEPTH 16:14 + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_0 (0x00U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_TYPE_1 (0x01U) + +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_ENFORCE_TYPE0_HDCP1XDS_NO (0x00U) +#define NV0073_CTRL_SPECIFIC_HDCP_CTRL_HDCP22_ENFORCE_TYPE0_HDCP1XDS_YES (0x01U) + + + +/* + * NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_DIAGNOSTICS + * + * This command is used to obtain diagnostic info, useful when hdcp + * fails for the specified attach point (that being the displayId). + * + * 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. + * displayId + * This parameter specifies the display for which information is to be + * returned. Only one display may be indicated in this parameter. + * If more than one displayId is used a failing status of + * NV_ERR_INVALID_ARGUMENT will be returned. + * flags + * This parameter specifies the diagnostics obtained from the attach point + * resource. Here are the current defined fields: + * NV0073_CTRL_SPECIFIC_HDCP_STATE_ROM_ERROR + * The hdcp hardware detected an error with the rom. Possible + * causes are that a rom is not present or if present, the hardware + * is not able to access the rom. + * NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_BOND_NOT_ENABLED + * The hdcp fuse register has not been set. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_AKSV_INVALID + * If the AKSV (key selection vector) of the hardware does not return + * 20 1s and 0s, this bit will be set. This is an indication that + * the ROM is not programmed correctly and may need to be corrected + * by replacing the external hdcp cryptorom. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_BKSV_INVALID + * If the BKSV (key selection vector) of the display receiver hardware + * does not return 20 1s and 0s, this bit will be set. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_DKSV_INVALID + * If the DKSV (key selection vector) of the upstream hdcp hardware + * does not return 20 1s and 0s, this bit will be set. + * NV0073_CTRL_SPECIFIC_HDCP_STATE_DUAL_LINK_INUSE + * This bit is set if the attach point is currently outputting dual-link + * NV0073_CTRL_SPECIFIC_HDCP_STATE_DOWNSTREAM_CHECKSUM_FAILED + * This bit is set if hardware reports that its checksum BIST of its + * downstream HDCP keys failed. + * + * Possible status values returned are: + * NV_OK + * NV_ERR_INVALID_PARAM_STRUCT + * NV_ERR_INVALID_ARGUMENT + */ +#define NV0073_CTRL_CMD_SPECIFIC_GET_HDCP_DIAGNOSTICS (0x730281U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS_MESSAGE_ID (0x81U) + +typedef struct NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; +} NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS; + +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_ROM_ERROR 0:0 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_BOND_NOT_ENABLED 1:1 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_AKSV_INVALID 2:2 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_BKSV_INVALID 3:3 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_DKSV_INVALID 4:4 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_DUAL_LINK_INUSE 5:5 +#define NV0073_CTRL_SPECIFIC_HDCP_DIAGNOSTICS_DOWNSTREAM_CHECKSUM_FAILED 6:6 /* * NV0073_CTRL_SPECIFIC_ACPI_ID_MAPPING @@ -1145,6 +2095,72 @@ typedef struct NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS { #define NV0073_CTRL_SPECIFIC_OR_LOCATION_CHIP (0x00000000U) #define NV0073_CTRL_SPECIFIC_OR_LOCATION_BOARD (0x00000001U) +/* + * NV0073_CTRL_CMD_SPECIFIC_HDCP_KSVLIST_VALIDATE + * + * This Command initiate the KSV validation for the specific device + * if it is a repeater. + * + * 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. + * displayId + * This parameter specifies the ID of the root port device for which KsvList is to be validated + * bUseCachedKsvList + * The parameter specifies RM to use cachedKsvList in case BCAPS's READY bit not set to read + * ksvList. + * + * Possible status values returned are: + * NV_OK + * NV_ERR_NOT_SUPPORTED + * NV_ERR_NOT_READY + */ +#define NV0073_CTRL_CMD_SPECIFIC_HDCP_KSVLIST_VALIDATE (0x73028dU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS_MESSAGE_ID (0x8DU) + +typedef struct NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvBool bUseCachedKsvList; +} NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS; + +/* + * NV0073_CTRL_CMD_SPECIFIC_HDCP_UPDATE + * + * This Command updates the display to the proper HDCP state based on + * whether it has been newly connected or disconnected. This is called + * during a hotplug event. + * + * 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. + * displayId + * This parameter specifies the ID of the root port device to update + * bIsConnected + * This parameter specifies whether the device has been connected (NV_TRUE) + * or disconnected (NV_FALSE). + * + * Possible status values returned are: + * NV_OK + * NV_ERR_NOT_SUPPORTED + */ +#define NV0073_CTRL_CMD_SPECIFIC_HDCP_UPDATE (0x73028eU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS_MESSAGE_ID (0x8EU) + +typedef struct NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvBool bIsConnected; +} NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS; + /* diff --git a/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h b/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h index 91c9a50..44c3706 100644 --- a/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h +++ b/src/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h @@ -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 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 diff --git a/src/nvidia-modeset/include/nvkms-evo.h b/src/nvidia-modeset/include/nvkms-evo.h index cab9bc4..bc4015d 100644 --- a/src/nvidia-modeset/include/nvkms-evo.h +++ b/src/nvidia-modeset/include/nvkms-evo.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, diff --git a/src/nvidia-modeset/include/nvkms-flip-workarea.h b/src/nvidia-modeset/include/nvkms-flip-workarea.h index 55794d3..419a181 100644 --- a/src/nvidia-modeset/include/nvkms-flip-workarea.h +++ b/src/nvidia-modeset/include/nvkms-flip-workarea.h @@ -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,7 @@ typedef struct { struct { enum NvKmsOutputTf tf; + enum NvKmsOutputColorimetry colorimetry; enum NvKmsDpyAttributeCurrentColorSpaceValue colorSpace; enum NvKmsDpyAttributeColorBpcValue colorBpc; enum NvKmsDpyAttributeColorRangeValue colorRange; diff --git a/src/nvidia-modeset/include/nvkms-modeset-types.h b/src/nvidia-modeset/include/nvkms-modeset-types.h index 1d82352..9193b21 100644 --- a/src/nvidia-modeset/include/nvkms-modeset-types.h +++ b/src/nvidia-modeset/include/nvkms-modeset-types.h @@ -37,12 +37,12 @@ typedef struct { NVDpyIdList dpyIdList; NVAttributesSetEvoRec attributes; struct NvKmsSetLutCommonParams lut; - enum NvKmsOutputColorSpace outputColorSpace; NVDispStereoParamsEvoRec stereo; NVDscInfoEvoRec dscInfo; NVDispHeadInfoFrameStateEvoRec infoFrame; NvU8 allowFlipLockGroup; enum NvKmsOutputTf tf; + enum NvKmsOutputColorimetry colorimetry; NvBool colorSpaceSpecified : 1; NvBool colorRangeSpecified : 1; NvBool hs10bpcHint : 1; diff --git a/src/nvidia-modeset/include/nvkms-modeset.h b/src/nvidia-modeset/include/nvkms-modeset.h index 09ba6b6..5259652 100644 --- a/src/nvidia-modeset/include/nvkms-modeset.h +++ b/src/nvidia-modeset/include/nvkms-modeset.h @@ -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 diff --git a/src/nvidia-modeset/include/nvkms-types.h b/src/nvidia-modeset/include/nvkms-types.h index 20081d9..3271a93 100644 --- a/src/nvidia-modeset/include/nvkms-types.h +++ b/src/nvidia-modeset/include/nvkms-types.h @@ -693,6 +693,7 @@ typedef struct { NvBool disableMidFrameAndDWCFWatermark; enum NvKmsOutputTf tf; + enum NvKmsOutputColorimetry colorimetry; NvBool skipLayerPendingFlips[NVKMS_MAX_LAYERS_PER_HEAD]; struct { @@ -701,6 +702,7 @@ typedef struct { NvBool cursorPosition : 1; NvBool tf : 1; NvBool hdrStaticMetadata : 1; + NvBool colorimetry : 1; NvBool layerPosition[NVKMS_MAX_LAYERS_PER_HEAD]; NvBool layerSyncObjects[NVKMS_MAX_LAYERS_PER_HEAD]; @@ -928,9 +930,10 @@ 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 = 3, + NVKMS_GAMMA_LUT_LAST = 4, }; /* Device-specific EVO state (subdevice- and channel-independent) */ @@ -1747,6 +1750,8 @@ typedef struct _NVDispHeadStateEvoRec { enum NvKmsOutputTf tf; + enum NvKmsOutputColorimetry colorimetry; + struct { enum NvKmsHDROutputState outputState; struct NvKmsHDRStaticMetadata staticMetadata; @@ -1758,8 +1763,6 @@ typedef struct _NVDispHeadStateEvoRec { NvBool baseLutEnabled : 1; } lut; - enum NvKmsOutputColorSpace outputColorSpace; - /* * The api head can be mapped onto the N harware heads, a frame presented * by the api head gets split horizontally into N tiles, 'tilePosition' @@ -1797,6 +1800,9 @@ typedef struct _NVDispApiHeadStateEvoRec { NVAttributesSetEvoRec attributes; enum NvKmsOutputTf tf; + + enum NvKmsOutputColorimetry colorimetry; + nvkms_timer_handle_t *hdrToSdrTransitionTimer; /* @@ -1934,6 +1940,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) @@ -1998,6 +2006,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); diff --git a/src/nvidia-modeset/interface/nvkms-api-types.h b/src/nvidia-modeset/interface/nvkms-api-types.h index a01a9b1..2ec168d 100644 --- a/src/nvidia-modeset/interface/nvkms-api-types.h +++ b/src/nvidia-modeset/interface/nvkms-api-types.h @@ -55,6 +55,7 @@ typedef NvU32 NvKmsFrameLockHandle; typedef NvU32 NvKmsDeferredRequestFifoHandle; typedef NvU32 NvKmsSwapGroupHandle; typedef NvU32 NvKmsVblankSyncObjectHandle; +typedef NvU32 NvKmsVblankIntrCallbackHandle; struct NvKmsSize { NvU16 width; @@ -545,6 +546,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, @@ -558,19 +589,17 @@ enum NvKmsInputColorSpace { /* 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_REC709 = 4, + NVKMS_INPUT_COLORSPACE_BT709 = 5, /* Rec709 colorspace with linear (identity) gamma */ - NVKMS_INPUT_COLORSPACE_REC709_LINEAR = 5 -}; + NVKMS_INPUT_COLORSPACE_BT709_LINEAR = 6, -enum NvKmsOutputColorSpace { - /* Unknown colorspace; no re-gamma will be applied */ - NVKMS_OUTPUT_COLORSPACE_NONE = 0, - - /* sRGB gamma transfer function will be applied */ - NVKMS_OUTPUT_COLORSPACE_SRGB = 1 + /* Rec2020 colorspace with Rec2020 gamma transfer function */ + NVKMS_INPUT_COLORSPACE_BT2020 = 7, }; enum NvKmsOutputTf { @@ -661,4 +690,6 @@ struct NvKmsSuperframeInfo { } view[NVKMS_MAX_SUPERFRAME_VIEWS]; }; +typedef void (*NVVBlankIntrCallbackProc)(NvU64 param1, NvU64 param2); + #endif /* NVKMS_API_TYPES_H */ diff --git a/src/nvidia-modeset/interface/nvkms-api.h b/src/nvidia-modeset/interface/nvkms-api.h index 1971101..d5d48c8 100644 --- a/src/nvidia-modeset/interface/nvkms-api.h +++ b/src/nvidia-modeset/interface/nvkms-api.h @@ -268,6 +268,8 @@ enum NvKmsIoctlCommand { 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, }; @@ -748,6 +750,14 @@ struct NvKmsFlipCommonParams { NvBool specified; } tf; + /* + * Specifies required output color space value. + */ + struct { + NvBool specified; + enum NvKmsOutputColorimetry val; + } colorimetry; + struct { struct { NvKmsSurfaceHandle handle[NVKMS_MAX_EYES]; @@ -1760,22 +1770,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 @@ -1819,18 +1813,6 @@ struct NvKmsSetModeOneHeadRequest { */ struct NvKmsSetLutCommonParams lut; - /*! - * If specified, this will determine the gamma encoding of the output. - * Note: this will take precendence over a custom output lut ramp if that - * is also supplied via the `lut` member variable above. - * Note: if neither this nor a custom OLUT is specified, the driver will - * default to an Identity OLUT (i.e. no regamma). - */ - struct { - NvBool specified; - enum NvKmsOutputColorSpace val; - } outputColorSpace; - /*! * Describe the surfaces to present on this head. */ @@ -4067,4 +4049,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 */ diff --git a/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h b/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h index 91b9e9f..6c11e8a 100644 --- a/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h +++ b/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.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); diff --git a/src/nvidia-modeset/kapi/interface/nvkms-kapi.h b/src/nvidia-modeset/kapi/interface/nvkms-kapi.h index 6a24895..3f1da53 100644 --- a/src/nvidia-modeset/kapi/interface/nvkms-kapi.h +++ b/src/nvidia-modeset/kapi/interface/nvkms-kapi.h @@ -248,6 +248,7 @@ struct NvKmsKapiLayerConfig { NvU16 dstWidth, dstHeight; enum NvKmsInputColorSpace inputColorSpace; + enum NvKmsInputColorRange inputColorRange; }; struct NvKmsKapiLayerRequestedConfig { @@ -301,6 +302,10 @@ struct NvKmsKapiHeadModeSetConfig { struct NvKmsKapiDisplayMode mode; NvBool vrrEnabled; + + enum NvKmsOutputColorimetry colorimetry; + + enum NvKmsDpyAttributeColorRangeValue outputColorRange; }; struct NvKmsKapiHeadRequestedConfig { @@ -309,6 +314,8 @@ struct NvKmsKapiHeadRequestedConfig { NvBool activeChanged : 1; NvBool displaysChanged : 1; NvBool modeChanged : 1; + NvBool colorrangeChanged: 1; + NvBool colorimetryChanged : 1; } flags; struct NvKmsKapiCursorRequestedConfig cursorRequestedConfig; @@ -1397,6 +1404,18 @@ struct NvKmsKapiFunctionsTable { ( 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); }; /** @} */ diff --git a/src/nvidia-modeset/kapi/src/nvkms-kapi.c b/src/nvidia-modeset/kapi/src/nvkms-kapi.c index 52b1ec8..c62ad5f 100644 --- a/src/nvidia-modeset/kapi/src/nvkms-kapi.c +++ b/src/nvidia-modeset/kapi/src/nvkms-kapi.c @@ -2631,6 +2631,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) { @@ -2731,6 +2734,9 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms( 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) { @@ -2895,6 +2901,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 */); @@ -2923,6 +2932,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 = @@ -3112,6 +3124,12 @@ 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; + } + if (headModeSetConfig->vrrEnabled) { params->request.allowVrr = NV_TRUE; } @@ -3209,7 +3227,8 @@ static NvBool ApplyModeSetConfig( bRequiredModeset = headRequestedConfig->flags.activeChanged || headRequestedConfig->flags.displaysChanged || - headRequestedConfig->flags.modeChanged; + headRequestedConfig->flags.modeChanged || + headRequestedConfig->flags.colorrangeChanged; /* * NVKMS flip ioctl could not validate flip configuration for an @@ -3374,6 +3393,94 @@ static void nvKmsKapiSetSuspendResumeCallback 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 @@ -3455,6 +3562,8 @@ NvBool nvKmsKapiGetFunctionsTableInternal funcsTable->setSemaphoreSurfaceValue = nvKmsKapiSetSemaphoreSurfaceValue; funcsTable->setSuspendResumeCallback = nvKmsKapiSetSuspendResumeCallback; + funcsTable->RegisterVblankIntrCallback = RegisterVblankIntrCallback; + funcsTable->UnregisterVblankIntrCallback = UnregisterVblankIntrCallback; return NV_TRUE; } diff --git a/src/nvidia-modeset/src/nvkms-attributes.c b/src/nvidia-modeset/src/nvkms-attributes.c index c5d8a05..369fc36 100644 --- a/src/nvidia-modeset/src/nvkms-attributes.c +++ b/src/nvidia-modeset/src/nvkms-attributes.c @@ -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); diff --git a/src/nvidia-modeset/src/nvkms-console-restore.c b/src/nvidia-modeset/src/nvkms-console-restore.c index cb815df..dbf8f3c 100644 --- a/src/nvidia-modeset/src/nvkms-console-restore.c +++ b/src/nvidia-modeset/src/nvkms-console-restore.c @@ -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. diff --git a/src/nvidia-modeset/src/nvkms-evo.c b/src/nvidia-modeset/src/nvkms-evo.c index 7912c5b..7d3edef 100644 --- a/src/nvidia-modeset/src/nvkms-evo.c +++ b/src/nvidia-modeset/src/nvkms-evo.c @@ -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 // NV5070_CTRL_CMD_SYSTEM_GET_CAPS_V2 #include // NV5070_CTRL_CMD_SET_SOR_FLUSH_MODE #include // NV0073_CTRL_DP_CTRL +#include // 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; diff --git a/src/nvidia-modeset/src/nvkms-evo3.c b/src/nvidia-modeset/src/nvkms-evo3.c index 3b9f41f..6f98cb7 100644 --- a/src/nvidia-modeset/src/nvkms-evo3.c +++ b/src/nvidia-modeset/src/nvkms-evo3.c @@ -76,6 +76,10 @@ #define SRGB_EOTF_LUT_NUM_ENTRIES 935 #define SRGB_OETF_LUT_NUM_ENTRIES 178 + +#define BT709_EOTF_LUT_NUM_ENTRIES 883 +#define BT709_OETF_LUT_NUM_ENTRIES 228 + #define PQ_EOTF_LUT_NUM_ENTRIES 508 #define PQ_OETF_LUT_NUM_ENTRIES 337 @@ -351,17 +355,183 @@ static const NvU32 OetfPQ512SegSizesLog2[33] = { 5, }; +static const NvU16 BT709EOTFLUTEntries[BT709_EOTF_LUT_NUM_ENTRIES] = { + 0x0000, 0x1c72, 0x2072, 0x22ab, 0x2472, 0x2476, 0x247b, 0x247f, 0x2484, + 0x2488, 0x248d, 0x2491, 0x2495, 0x249a, 0x249e, 0x24a3, 0x24a7, 0x24ac, + 0x24b0, 0x24b5, 0x24b9, 0x24bd, 0x24c2, 0x24c6, 0x24cb, 0x24cf, 0x24d4, + 0x24d8, 0x24dd, 0x24e1, 0x24e5, 0x24ea, 0x24ee, 0x24f3, 0x24f7, 0x24fc, + 0x2500, 0x2505, 0x2509, 0x250d, 0x2512, 0x2516, 0x251b, 0x251f, 0x2524, + 0x2528, 0x252d, 0x2531, 0x2535, 0x253a, 0x253e, 0x2543, 0x2547, 0x254c, + 0x2550, 0x2555, 0x2559, 0x255d, 0x2562, 0x2566, 0x256b, 0x256f, 0x2574, + 0x2578, 0x257d, 0x2581, 0x2585, 0x258a, 0x258e, 0x2593, 0x2597, 0x259c, + 0x25a0, 0x25a5, 0x25a9, 0x25ad, 0x25b2, 0x25b6, 0x25bb, 0x25bf, 0x25bf, + 0x25c4, 0x25c8, 0x25cc, 0x25d1, 0x25d5, 0x25da, 0x25de, 0x25e3, 0x25e7, + 0x25ec, 0x25f0, 0x25f5, 0x25f9, 0x25fe, 0x2602, 0x2607, 0x260c, 0x2610, + 0x2615, 0x2619, 0x261e, 0x2622, 0x2627, 0x262c, 0x2630, 0x2635, 0x263a, + 0x263e, 0x2643, 0x2647, 0x264c, 0x2651, 0x2655, 0x265a, 0x265f, 0x2664, + 0x2668, 0x266d, 0x2672, 0x2676, 0x267b, 0x2680, 0x2685, 0x2689, 0x268e, + 0x2693, 0x2698, 0x269c, 0x26a1, 0x26a6, 0x26ab, 0x26b0, 0x26c3, 0x26d6, + 0x26ea, 0x26fe, 0x2711, 0x2725, 0x2739, 0x274e, 0x2762, 0x2776, 0x278b, + 0x27a0, 0x27b4, 0x27c9, 0x27de, 0x27f3, 0x2825, 0x2850, 0x287d, 0x28ab, + 0x28ae, 0x28b1, 0x28b4, 0x28b7, 0x28ba, 0x28bd, 0x28bf, 0x28c2, 0x28c5, + 0x28c8, 0x28cb, 0x28ce, 0x28d1, 0x28d4, 0x28d7, 0x28da, 0x28dd, 0x28e0, + 0x28e3, 0x28e6, 0x28e9, 0x28ec, 0x28ef, 0x28f2, 0x28f5, 0x28f8, 0x28fb, + 0x28fe, 0x2901, 0x2904, 0x2907, 0x290a, 0x290d, 0x2910, 0x2913, 0x2916, + 0x2919, 0x291c, 0x291f, 0x2922, 0x2925, 0x2928, 0x292b, 0x292e, 0x2931, + 0x2934, 0x2937, 0x293a, 0x293e, 0x2941, 0x2944, 0x2947, 0x294a, 0x294d, + 0x2950, 0x2953, 0x2956, 0x2959, 0x295d, 0x2960, 0x2963, 0x2966, 0x2969, + 0x296c, 0x296f, 0x2973, 0x2976, 0x2979, 0x297c, 0x297f, 0x2982, 0x2986, + 0x2989, 0x298c, 0x298f, 0x2992, 0x2995, 0x2999, 0x299c, 0x299f, 0x29a2, + 0x29a5, 0x29a9, 0x29ac, 0x29af, 0x29b2, 0x29b6, 0x29b9, 0x29bc, 0x29bf, + 0x29c3, 0x29c6, 0x29c9, 0x29cc, 0x29d0, 0x29d3, 0x29d6, 0x29d9, 0x29dd, + 0x29e0, 0x29e3, 0x29e7, 0x29ea, 0x29ed, 0x29f0, 0x29f4, 0x29f7, 0x29fa, + 0x29fe, 0x2a01, 0x2a04, 0x2a08, 0x2a0b, 0x2a0e, 0x2a12, 0x2a15, 0x2a18, + 0x2a1c, 0x2a1f, 0x2a22, 0x2a26, 0x2a29, 0x2a2d, 0x2a30, 0x2a33, 0x2a37, + 0x2a3a, 0x2a3d, 0x2a74, 0x2aac, 0x2ae5, 0x2b1f, 0x2b5a, 0x2b96, 0x2bd3, + 0x2c08, 0x2c48, 0x2c8a, 0x2c8e, 0x2c92, 0x2c96, 0x2c9b, 0x2c9f, 0x2ca3, + 0x2ca7, 0x2cab, 0x2cb0, 0x2cb4, 0x2cb8, 0x2cbc, 0x2cc1, 0x2cc5, 0x2cc9, + 0x2cce, 0x2cd2, 0x2cd6, 0x2cdb, 0x2cdf, 0x2ce3, 0x2ce8, 0x2cec, 0x2cf0, + 0x2cf5, 0x2cf9, 0x2cfd, 0x2d02, 0x2d06, 0x2d0b, 0x2d0f, 0x2d14, 0x2d18, + 0x2d1c, 0x2d21, 0x2d25, 0x2d2a, 0x2d2e, 0x2d33, 0x2d37, 0x2d3c, 0x2d40, + 0x2d45, 0x2d49, 0x2d4e, 0x2d52, 0x2d57, 0x2d5c, 0x2d60, 0x2d65, 0x2d69, + 0x2d6e, 0x2d73, 0x2d77, 0x2d7c, 0x2d80, 0x2d85, 0x2d8a, 0x2d8e, 0x2d93, + 0x2d98, 0x2d9c, 0x2da1, 0x2da6, 0x2df2, 0x2e41, 0x2e55, 0x2e69, 0x2e7d, + 0x2e91, 0x2ea6, 0x2ebb, 0x2ecf, 0x2ee4, 0x2f39, 0x2f91, 0x2fea, 0x3023, + 0x3052, 0x3082, 0x30b3, 0x30e6, 0x30e7, 0x30e9, 0x30eb, 0x30ec, 0x30ee, + 0x30ef, 0x30f1, 0x30f3, 0x30f4, 0x30f6, 0x30f7, 0x30f9, 0x30fb, 0x30fc, + 0x30fe, 0x30ff, 0x3101, 0x3103, 0x3104, 0x3106, 0x3108, 0x3109, 0x310b, + 0x310c, 0x310e, 0x3110, 0x3111, 0x3113, 0x3115, 0x3116, 0x3118, 0x3119, + 0x311b, 0x311d, 0x311e, 0x3120, 0x3122, 0x3123, 0x3125, 0x3126, 0x3128, + 0x312a, 0x312b, 0x312d, 0x312f, 0x3130, 0x3132, 0x3134, 0x3135, 0x3137, + 0x3139, 0x313a, 0x313c, 0x313d, 0x313f, 0x3141, 0x3142, 0x3144, 0x3146, + 0x3147, 0x3149, 0x314b, 0x314c, 0x314e, 0x3150, 0x3151, 0x3153, 0x3155, + 0x3156, 0x3158, 0x315a, 0x315b, 0x315d, 0x315f, 0x3160, 0x3162, 0x3164, + 0x3165, 0x3167, 0x3169, 0x316b, 0x316c, 0x316e, 0x3170, 0x3171, 0x3173, + 0x3175, 0x3176, 0x3178, 0x317a, 0x317b, 0x317d, 0x317f, 0x3181, 0x3182, + 0x3184, 0x3186, 0x3187, 0x3189, 0x318b, 0x318c, 0x318e, 0x3190, 0x3192, + 0x3193, 0x3195, 0x3197, 0x3198, 0x319a, 0x319c, 0x319e, 0x319f, 0x31a1, + 0x31a3, 0x31a4, 0x31a6, 0x31a8, 0x31aa, 0x31ab, 0x31ad, 0x31af, 0x31b0, + 0x31b2, 0x31b4, 0x31b6, 0x31b7, 0x31b9, 0x31bb, 0x31c9, 0x31d7, 0x31e5, + 0x31f3, 0x3201, 0x3210, 0x321e, 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, + 0x3235, 0x3237, 0x3239, 0x323b, 0x323d, 0x323e, 0x3240, 0x3242, 0x3244, + 0x3246, 0x3248, 0x3249, 0x324b, 0x324d, 0x324f, 0x3251, 0x3253, 0x3254, + 0x3256, 0x3258, 0x325a, 0x325c, 0x325e, 0x325f, 0x3261, 0x3263, 0x3265, + 0x3267, 0x3269, 0x326a, 0x326c, 0x326e, 0x3270, 0x3272, 0x3274, 0x3276, + 0x3277, 0x3279, 0x327b, 0x327d, 0x327f, 0x3281, 0x3283, 0x3284, 0x3286, + 0x3288, 0x328a, 0x328c, 0x328e, 0x3290, 0x3292, 0x3293, 0x3295, 0x3297, + 0x3299, 0x329b, 0x329d, 0x329f, 0x32a1, 0x32a2, 0x331d, 0x335c, 0x339d, + 0x33de, 0x3411, 0x3455, 0x349c, 0x34e5, 0x34ef, 0x34f8, 0x3502, 0x350b, + 0x3515, 0x351e, 0x3528, 0x3531, 0x3545, 0x3558, 0x356c, 0x3580, 0x35d0, + 0x35fa, 0x3624, 0x362e, 0x3639, 0x3643, 0x364e, 0x3659, 0x3664, 0x366e, + 0x3679, 0x36d2, 0x36ff, 0x372c, 0x378a, 0x37e9, 0x3826, 0x3858, 0x388c, + 0x38c1, 0x38f8, 0x38f9, 0x38f9, 0x38fa, 0x38fb, 0x38fc, 0x38fd, 0x38fe, + 0x38ff, 0x39ff, 0x3900, 0x3901, 0x3902, 0x3903, 0x3904, 0x3905, 0x3906, + 0x3906, 0x3907, 0x3908, 0x3909, 0x390a, 0x390b, 0x390c, 0x390c, 0x390d, + 0x390e, 0x390f, 0x3910, 0x3911, 0x3912, 0x3913, 0x3913, 0x3914, 0x3915, + 0x3916, 0x3917, 0x3918, 0x3919, 0x391a, 0x391a, 0x391b, 0x391c, 0x391d, + 0x391e, 0x391f, 0x3920, 0x3920, 0x3921, 0x3922, 0x3923, 0x3924, 0x3925, + 0x3926, 0x3927, 0x3928, 0x3928, 0x3929, 0x392a, 0x392b, 0x392c, 0x392d, + 0x392e, 0x392f, 0x392f, 0x3930, 0x3931, 0x3932, 0x3934, 0x3935, 0x3936, + 0x3936, 0x3937, 0x3938, 0x3939, 0x393a, 0x393b, 0x393c, 0x393d, 0x393e, + 0x393e, 0x393f, 0x3940, 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, + 0x3946, 0x3947, 0x3948, 0x3949, 0x394a, 0x394b, 0x394c, 0x394d, 0x394e, + 0x394e, 0x394f, 0x3950, 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, 0x3956, + 0x3956, 0x3957, 0x3958, 0x3959, 0x395a, 0x395b, 0x395c, 0x395d, 0x395e, + 0x395f, 0x395f, 0x3960, 0x3961, 0x3962, 0x3963, 0x3964, 0x3965, 0x3966, + 0x3967, 0x3968, 0x3968, 0x396a, 0x396c, 0x396e, 0x3970, 0x3971, 0x3973, + 0x3975, 0x3977, 0x3979, 0x397b, 0x397c, 0x397e, 0x3980, 0x3982, 0x3984, + 0x3985, 0x3987, 0x3989, 0x398b, 0x398d, 0x398f, 0x3990, 0x3992, 0x3994, + 0x3996, 0x3998, 0x399a, 0x399b, 0x399d, 0x399f, 0x39a1, 0x39a3, 0x39a5, + 0x39a6, 0x39a8, 0x39aa, 0x39ac, 0x39ae, 0x39b0, 0x39b2, 0x39b3, 0x39b5, + 0x39b7, 0x39b9, 0x39bb, 0x39bd, 0x39bf, 0x39c0, 0x39c2, 0x39c4, 0x39c6, + 0x39c8, 0x39ca, 0x39cc, 0x39ce, 0x39cf, 0x39d1, 0x39d3, 0x39d5, 0x39d7, + 0x39d9, 0x39db, 0x39dd, 0x39de, 0x39e0, 0x39e2, 0x39e4, 0x39e6, 0x39e8, + 0x39ea, 0x39ec, 0x39ee, 0x39ef, 0x39f1, 0x39f3, 0x39f5, 0x39f7, 0x39f9, + 0x39fb, 0x39fd, 0x39ff, 0x3a01, 0x3a03, 0x3a04, 0x3a06, 0x3a08, 0x3a0a, + 0x3a0c, 0x3a0e, 0x3a10, 0x3a12, 0x3a14, 0x3a16, 0x3a18, 0x3a1a, 0x3a1b, + 0x3a1d, 0x3a1f, 0x3a21, 0x3a23, 0x3a25, 0x3a27, 0x3a29, 0x3a2b, 0x3a2d, + 0x3a2f, 0x3a31, 0x3a33, 0x3a35, 0x3a37, 0x3a39, 0x3a3a, 0x3a3c, 0x3a3e, + 0x3a40, 0x3a42, 0x3a44, 0x3a46, 0x3a48, 0x3a4a, 0x3a4c, 0x3a4e, 0x3a50, + 0x3a52, 0x3a54, 0x3a56, 0x3a58, 0x3a5a, 0x3a99, 0x3adb, 0x3b1d, 0x3b61, + 0x3ba6, 0x3bec, 0x3c1a, 0x3c3f, 0x3c64, 0x3c8a, 0x3cb1, 0x3cd8, 0x3d00, +}; + +static const NvU16 BT709EOTFLUTVSSHeader[16] = { + 0x6000, 0xb653, 0x3694, 0x0000, + 0x124b, 0x467b, 0x6002, 0x0000, + 0x8642, 0x0000, 0xbb00, 0x0000, + 0x016d, 0x0000, 0x0000, 0x0000, +}; + +static const NvU16 BT709OETFLUTEntries[BT709_OETF_LUT_NUM_ENTRIES] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0004, 0x0004, 0x0008, 0x0010, 0x0024, 0x0048, 0x0090, 0x0120, + 0x0240, 0x0480, 0x0900, 0x1200, 0x1224, 0x1248, 0x126c, 0x1290, + 0x12b4, 0x12d8, 0x12fc, 0x1320, 0x1344, 0x1368, 0x138c, 0x13b0, + 0x13d4, 0x13f8, 0x141c, 0x1440, 0x1464, 0x1488, 0x14ac, 0x14e0, + 0x1504, 0x1528, 0x154c, 0x1570, 0x1594, 0x15b4, 0x15d8, 0x15fc, + 0x1620, 0x1640, 0x1664, 0x1688, 0x16a8, 0x16cc, 0x16ec, 0x1710, + 0x1730, 0x1754, 0x1774, 0x1798, 0x17b8, 0x17d8, 0x17fc, 0x181c, + 0x183c, 0x185c, 0x1880, 0x18a0, 0x18c0, 0x18e0, 0x1900, 0x1920, + 0x1940, 0x1960, 0x1980, 0x19a0, 0x19c0, 0x19e0, 0x1a00, 0x1a20, + 0x1a40, 0x1a60, 0x1a80, 0x1aa0, 0x1abc, 0x1adc, 0x1afc, 0x1b1c, + 0x1b38, 0x1b58, 0x1b78, 0x1b94, 0x1bb4, 0x1bd0, 0x1bf0, 0x1c10, + 0x1c2c, 0x1c4c, 0x1c68, 0x1c88, 0x1ca4, 0x1cc0, 0x1ce0, 0x1cfc, + 0x1d1c, 0x1d38, 0x1d54, 0x1d74, 0x1d90, 0x1dac, 0x1dc8, 0x1de8, + 0x1e04, 0x1e20, 0x1e3c, 0x1e58, 0x1e78, 0x1e94, 0x1eb0, 0x1ecc, + 0x1ee8, 0x1f04, 0x1f20, 0x1f3c, 0x1f58, 0x1f74, 0x1f90, 0x1fac, + 0x1fc8, 0x1fe4, 0x2000, 0x201c, 0x2038, 0x2054, 0x206c, 0x2088, + 0x20a4, 0x20c0, 0x20dc, 0x20f4, 0x2110, 0x212c, 0x2148, 0x2160, + 0x217c, 0x2198, 0x21b0, 0x21cc, 0x2504, 0x280c, 0x2ae8, 0x2da4, + 0x303c, 0x32bc, 0x3524, 0x3774, 0x39b0, 0x3bd8, 0x3df0, 0x3ffc, + 0x41f8, 0x43e4, 0x45c8, 0x47a0, 0x496c, 0x4b2c, 0x4ce4, 0x4e94, + 0x503c, 0x51dc, 0x5374, 0x5504, 0x5814, 0x5b08, 0x5de4, 0x60ac, + 0x6364, 0x6608, 0x6898, 0x6b1c, 0x6d90, 0x6ff8, 0x7250, 0x74a0, + 0x76e4, 0x7918, 0x7b48, 0x7d6c, 0x8198, 0x85a0, 0x8988, 0x8d58, + 0x910c, 0x94a4, 0x9828, 0x9b98, 0x9ef4, 0xa23c, 0xa570, 0xa898, + 0xabac, 0xaeb4, 0xb1ac, 0xb498, 0xba4c, 0xbfd0, 0xc528, 0xca5c, + 0xcf68, 0xd454, 0xd924, 0xddd4, 0xe268, 0xe6e4, 0xeb48, 0xef94, + 0xf3cc, 0xf7f0, 0xfc00, 0xfffc, +}; + +static const NvU16 BT709OETFLUTVSSHeader[16] = { + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x923e, 0x0000, + 0x0004, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, +}; + enum FMTCoeffType { FMT_COEFF_TYPE_IDENTITY = 0, + FMT_COEFF_TYPE_REC601_YUV_8BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_8BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_10BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_10BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_12BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_12BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_16BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC601_YUV_16BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC709_YUV_8BPC_LTD_TO_RGB_16BPC_FULL, FMT_COEFF_TYPE_REC709_YUV_8BPC_FULL_TO_RGB_16BPC_FULL, FMT_COEFF_TYPE_REC709_YUV_10BPC_LTD_TO_RGB_16BPC_FULL, FMT_COEFF_TYPE_REC709_YUV_10BPC_FULL_TO_RGB_16BPC_FULL, FMT_COEFF_TYPE_REC709_YUV_12BPC_LTD_TO_RGB_16BPC_FULL, FMT_COEFF_TYPE_REC709_YUV_12BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC709_YUV_16BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC709_YUV_16BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_8BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_8BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_10BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_10BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_12BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_12BPC_FULL_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_16BPC_LTD_TO_RGB_16BPC_FULL, + FMT_COEFF_TYPE_REC2020_YUV_16BPC_FULL_TO_RGB_16BPC_FULL, // FMT is always identity for RGB to avoid possible calculation error. // must be the last entry @@ -372,6 +542,22 @@ static const NvU32 FMTMatrix[FMT_COEFF_TYPE_MAX][12] = { // FMT_COEFF_TYPE_IDENTITY { 0x10000, 0, 0, 0, 0, 0x10000, 0, 0, 0, 0, 0x10000, 0 }, + // FMT_COEFF_TYPE_REC601_YUV_8BPC_LTD_TO_RGB_16BPC_FULL + { 0x19A29, 0x12B3C, 0, 0x1F2038, 0x1F2F14, 0x12B3C, 0x1F9B52, 0x8819, 0, 0x12B3C, 0x20668, 0x1EEA18 }, + // FMT_COEFF_TYPE_REC601_YUV_8BPC_FULL_TO_RGB_16BPC_FULL + { 0x1684C, 0x100FD, 0, 0x1F4D42, 0x1F487A, 0x100FD, 0x1FA790, 0x86EB, 0, 0x100FD, 0x1C762, 0x1F1E16 }, + // FMT_COEFF_TYPE_REC601_YUV_10BPC_LTD_TO_RGB_16BPC_FULL + { 0x19A29, 0x12B3C, 0, 0x1F2038, 0x1F2F14, 0x12B3C, 0x1F9B52, 0x8819, 0, 0x12B3C, 0x20668, 0x1EEA18 }, + // FMT_COEFF_TYPE_REC601_YUV_10BPC_FULL_TO_RGB_16BPC_FULL + { 0x1673E, 0x1003C, 0, 0x1F4CBB, 0x1F4903, 0x1003C, 0x1FA7D2, 0x8751, 0, 0x1003C, 0x1C60C, 0x1F1D6B }, + // FMT_COEFF_TYPE_REC601_YUV_12BPC_LTD_TO_RGB_16BPC_FULL + { 0x19A29, 0x12B3C, 0, 0x1F2038, 0x1F2F14, 0x12B3C, 0x1F9B52, 0x8819, 0, 0x12B3C, 0x20668, 0x1EEA18 }, + // FMT_COEFF_TYPE_REC601_YUV_12BPC_FULL_TO_RGB_16BPC_FULL + { 0x166FA, 0x1000C, 0, 0x1F4C99, 0x1F4926, 0x1000C, 0x1FA7E3, 0x876B, 0, 0x1000C, 0x1C5B7, 0x1F1D41 }, + // FMT_COEFF_TYPE_REC601_YUV_16BPC_LTD_TO_RGB_16BPC_FULL + { 0x19A29, 0x12B3C, 0, 0x1F2038, 0x1F2F14, 0x12B3C, 0x1F9B52, 0x8819, 0, 0x12B3C, 0x20668, 0x1EEA18 }, + // FMT_COEFF_TYPE_REC601_YUV_16BPC_FULL_TO_RGB_16BPC_FULL + { 0x166E5, 0xFFFD, 0, 0x1F4C8F, 0x1F4931, 0xFFFD, 0x1FA7E8, 0x8773, 0, 0xFFFD, 0x1C59C, 0x1F1D34 }, // FMT_COEFF_TYPE_REC709_YUV_8BPC_LTD_TO_RGB_16BPC_FULL { 0x1CCB7, 0x12B3C, 0, 0x1F06F1, 0x1F770C, 0x12B3C, 0x1FC933, 0x4D2D, 0, 0x12B3C, 0x21EDD, 0x1EDDDE }, // FMT_COEFF_TYPE_REC709_YUV_8BPC_FULL_TO_RGB_16BPC_FULL @@ -384,6 +570,26 @@ static const NvU32 FMTMatrix[FMT_COEFF_TYPE_MAX][12] = { 0x1CCB7, 0x12B3C, 0, 0x1F06F1, 0x1F770C, 0x12B3C, 0x1FC933, 0x4D2D, 0, 0x12B3C, 0x21EDD, 0x1EDDDE }, // FMT_COEFF_TYPE_REC709_YUV_12BPC_FULL_TO_RGB_16BPC_FULL { 0x19339, 0x1000C, 0, 0x1F367D, 0x1F8823, 0x1000C, 0x1FD009, 0x53DF, 0, 0x1000C, 0x1DB1F, 0x1F128E }, + // FMT_COEFF_TYPE_REC709_YUV_16BPC_LTD_TO_RGB_16BPC_FULL + { 0x1CCB7, 0x12B3C, 0, 0x1F06F1, 0x1F770C, 0x12B3C, 0x1FC933, 0x4D2D, 0, 0x12B3C, 0x21EDD, 0x1EDDDE }, + // FMT_COEFF_TYPE_REC709_YUV_16BPC_FULL_TO_RGB_16BPC_FULL + { 0x19321, 0xFFFD, 0, 0x1F3671, 0x1F882A, 0xFFFD, 0x1FD00C, 0x53E4, 0, 0xFFFD, 0x1DB03, 0x1F1280 }, + // FMT_COEFF_TYPE_REC2020_YUV_8BPC_LTD_TO_RGB_16BPC_FULL + { 0x1AF66, 0x12B3C, 0, 0x1F1599, 0x1F58D9, 0x12B3C, 0x1FCFDC, 0x58F2, 0, 0x12B3C, 0x22669, 0x1EDA18 }, + // FMT_COEFF_TYPE_REC2020_YUV_8BPC_FULL_TO_RGB_16BPC_FULL + { 0x17AF4, 0x100FD, 0, 0x1F4401, 0x1F6D2B, 0x100FD, 0x1FD5B6, 0x5DD2, 0, 0x100FD, 0x1E37F, 0x1F1024 }, + // FMT_COEFF_TYPE_REC2020_YUV_10BPC_LTD_TO_RGB_16BPC_FULL + { 0x1AF66, 0x12B3C, 0, 0x1F1599, 0x1F58D9, 0x12B3C, 0x1FCFDC, 0x58F2, 0, 0x12B3C, 0x22669, 0x1EDA18 }, + // FMT_COEFF_TYPE_REC2020_YUV_10BPC_FULL_TO_RGB_16BPC_FULL + { 0x179D8, 0x1003C, 0, 0x1F4372, 0x1F6D99, 0x1003C, 0x1FD5D6, 0x5E19, 0, 0x1003C, 0x1E214, 0x1F0F6E }, + // FMT_COEFF_TYPE_REC2020_YUV_12BPC_LTD_TO_RGB_16BPC_FULL + { 0x1AF66, 0x12B3C, 0, 0x1F1599, 0x1F58D9, 0x12B3C, 0x1FCFDC, 0x58F2, 0, 0x12B3C, 0x22669, 0x1EDA18 }, + // FMT_COEFF_TYPE_REC2020_YUV_12BPC_FULL_TO_RGB_16BPC_FULL + { 0x17991, 0x1000C, 0, 0x1F434F, 0x1F6DB5, 0x1000C, 0x1FD5DE, 0x5E2B, 0, 0x1000C, 0x1E1BA, 0x1F0F41 }, + // FMT_COEFF_TYPE_REC2020_YUV_16BPC_LTD_TO_RGB_16BPC_FULL + { 0x1AF66, 0x12B3C, 0, 0x1F1599, 0x1F58D9, 0x12B3C, 0x1FCFDC, 0x58F2, 0, 0x12B3C, 0x22669, 0x1EDA18 }, + // FMT_COEFF_TYPE_REC2020_YUV_16BPC_FULL_TO_RGB_16BPC_FULL + { 0x1797B, 0xFFFD, 0, 0x1F4344, 0x1F6DBE, 0xFFFD, 0x1FD5E0, 0x5E30, 0, 0xFFFD, 0x1E19E, 0x1F0F33 }, }; static void SetCsc00MatrixC5(NVEvoChannelPtr pChannel, @@ -612,6 +818,16 @@ static const struct NvKmsCscMatrix Rec709RGBToLMS = {{ { 0x8fc, 0x2818, 0xcef0, 0 }, }}; +/* + * This is a 3x4 matrix with S5.14 coefficients (truncated from S5.16 + * SW-specified values). + */ +static const struct NvKmsCscMatrix Rec601RGBToLMS = {{ + { 0x49f0, 0x9dc4, 0x184c, 0 }, + { 0x28d4, 0xb5b0, 0x217c, 0 }, + { 0x8d4, 0x2644, 0xd0ec, 0 }, +}}; + /* * This is a 3x4 matrix with S5.14 coefficients (truncated from S5.16 * SW-specified values). @@ -622,6 +838,16 @@ static const struct NvKmsCscMatrix LMSToRec709RGB = {{ { 0x1ffd00, 0x1fbc34, 0x146c4, 0 }, }}; +/* + * This is a 3x4 matrix with S5.14 coefficients (truncated from S5.16 + * SW-specified values). + */ +static const struct NvKmsCscMatrix LMSToRec601RGB = {{ + { 0x6a668, 0x1a3144, 0x2838, 0 }, + { 0x1e81cc, 0x2c31c, 0x1fbb28, 0 }, + { 0x1e4, 0x1fbd48, 0x14498, 0 }, +}}; + /* * This is a 3x4 matrix with S5.14 coefficients (truncated from S5.16 * SW-specified values). @@ -719,6 +945,8 @@ static void ConfigureCsc0C5(NVDevEvoPtr pDevEvo, if (enable) { if (colorspace == NVKMS_INPUT_COLORSPACE_BT2100_PQ) { matrix = Rec2020RGBToLMS; + } else if (colorspace == NVKMS_INPUT_COLORSPACE_BT601) { + matrix = Rec601RGBToLMS; } else { matrix = Rec709RGBToLMS; } @@ -1106,7 +1334,9 @@ static void ConfigureCsc1C5(NVDevEvoPtr pDevEvo, // XXX HDR TODO: Support other transfer functions nvAssert(pHeadState->tf == NVKMS_OUTPUT_TF_PQ); matrix = LMSToRec2020RGB; - } else { + } else if (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT601) { + matrix = LMSToRec601RGB; + } else if (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT709) { matrix = LMSToRec709RGB; } @@ -1236,28 +1466,74 @@ static const NvU32* EvoGetFMTMatrixC5( // Choose FMT matrix based on input colorspace, bpc, and colorrange. if (pFormatInfo->isYUV) { NvBool specifiedFull = (pHwState->colorRange == NVKMS_INPUT_COLORRANGE_FULL); - if (pFormatInfo->yuv.depthPerComponent == 8) { - if (specifiedFull) { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_8BPC_FULL_TO_RGB_16BPC_FULL]; - } else { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_8BPC_LTD_TO_RGB_16BPC_FULL]; + switch (pHwState->colorSpace) { + case NVKMS_INPUT_COLORSPACE_BT601: + if (pFormatInfo->yuv.depthPerComponent == 8) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_8BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_8BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 10) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_10BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_10BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 12) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_12BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC601_YUV_12BPC_LTD_TO_RGB_16BPC_FULL]; + } + } + break; + case NVKMS_INPUT_COLORSPACE_BT709: + if (pFormatInfo->yuv.depthPerComponent == 8) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_8BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_8BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 10) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_10BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_10BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 12) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_12BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_12BPC_LTD_TO_RGB_16BPC_FULL]; + } + } + break; + case NVKMS_INPUT_COLORSPACE_BT2100_PQ: + if (pFormatInfo->yuv.depthPerComponent == 8) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_8BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_8BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 10) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_10BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_10BPC_LTD_TO_RGB_16BPC_FULL]; + } + } else if (pFormatInfo->yuv.depthPerComponent == 12) { + if (specifiedFull) { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_12BPC_FULL_TO_RGB_16BPC_FULL]; + } else { + retValue = FMTMatrix[FMT_COEFF_TYPE_REC2020_YUV_12BPC_LTD_TO_RGB_16BPC_FULL]; + } + } + break; + default: + // Unsupported bit depth, fail silently by defaulting to identity. + retValue = FMTMatrix[FMT_COEFF_TYPE_IDENTITY]; } - } else if (pFormatInfo->yuv.depthPerComponent == 10) { - if (specifiedFull) { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_10BPC_FULL_TO_RGB_16BPC_FULL]; - } else { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_10BPC_LTD_TO_RGB_16BPC_FULL]; - } - } else if (pFormatInfo->yuv.depthPerComponent == 12) { - if (specifiedFull) { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_12BPC_FULL_TO_RGB_16BPC_FULL]; - } else { - retValue = FMTMatrix[FMT_COEFF_TYPE_REC709_YUV_12BPC_LTD_TO_RGB_16BPC_FULL]; - } - } else { - // Unsupported bit depth, fail silently by defaulting to identity. - retValue = FMTMatrix[FMT_COEFF_TYPE_IDENTITY]; - } } else { // All inputs with RGB colorspace receive an identity FMT. retValue = FMTMatrix[FMT_COEFF_TYPE_IDENTITY]; @@ -1414,6 +1690,13 @@ void nvEvoInitDefaultLutC5(NVDevEvoPtr pDevEvo) pData = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_PQ]->subDeviceAddress[sd]; EvoSetupPQEotfBaseLutC5(pData); EvoSetupPQOetfOutputLutC5(pData); + + // Polulate BT 709 ILUT (degamma) and OLUT (regamma). + pData = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_BT709]->subDeviceAddress[sd]; + FillLut(pData->base, BT709EOTFLUTEntries, + BT709_EOTF_LUT_NUM_ENTRIES, BT709EOTFLUTVSSHeader); + FillLut(pData->output, BT709OETFLUTEntries, + BT709_OETF_LUT_NUM_ENTRIES, BT709OETFLUTVSSHeader); } } @@ -4685,7 +4968,7 @@ EvoFlipC5Common(NVDevEvoPtr pDevEvo, // Assert that the colorspace is a linear encoding. nvAssert((pHwState->colorSpace == NVKMS_INPUT_COLORSPACE_SCRGB_LINEAR) || (pHwState->colorSpace == NVKMS_INPUT_COLORSPACE_NONE) || - (pHwState->colorSpace == NVKMS_INPUT_COLORSPACE_REC709_LINEAR)); + (pHwState->colorSpace == NVKMS_INPUT_COLORSPACE_BT709_LINEAR)); ctxDma = 0; } else if (pHwState->colorSpace != NVKMS_INPUT_COLORSPACE_NONE) { switch (pHwState->colorSpace) { @@ -4694,7 +4977,15 @@ EvoFlipC5Common(NVDevEvoPtr pDevEvo, lutSize = NV_LUT_VSS_HEADER_SIZE + PQ_EOTF_LUT_NUM_ENTRIES; isLutModeVss = TRUE; break; - case NVKMS_INPUT_COLORSPACE_REC709: + case NVKMS_INPUT_COLORSPACE_BT601: + // BT601 also uses the same degamma calculation as 709. + // Hence using the 709 degamma table for 601 also. + + ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_BT709]->surfaceDesc.ctxDmaHandle; + lutSize = NV_LUT_VSS_HEADER_SIZE + BT709_EOTF_LUT_NUM_ENTRIES; + isLutModeVss = TRUE; + break; + case NVKMS_INPUT_COLORSPACE_BT709: // When the output is sRGB, We use sRGB degamma instead of // Rec709 degamma because Rec709 gamma-encoded inputs are // are designed to be compatible with sRGB in the sense @@ -4708,19 +4999,29 @@ EvoFlipC5Common(NVDevEvoPtr pDevEvo, // Therefore, given a gamma-encoded input signal, the // de/regamma process is purely for conversion to and from // linear space for the sake of linear processing - // operations. - ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_SRGB]->surfaceDesc.ctxDmaHandle; - lutSize = NV_LUT_VSS_HEADER_SIZE + SRGB_EOTF_LUT_NUM_ENTRIES; + // operations + if (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_SRGB) { + ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_SRGB]->surfaceDesc.ctxDmaHandle; + lutSize = NV_LUT_VSS_HEADER_SIZE + SRGB_EOTF_LUT_NUM_ENTRIES; + } else { // If output is not sRGB, use BT709 degamma + ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_BT709]->surfaceDesc.ctxDmaHandle; + lutSize = NV_LUT_VSS_HEADER_SIZE + BT709_EOTF_LUT_NUM_ENTRIES; + } isLutModeVss = TRUE; break; - // TODO(mtrost): add support for Rec709 EOTF LUT when the output - // is not sRGB. case NVKMS_INPUT_COLORSPACE_SRGB: ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_SRGB]->surfaceDesc.ctxDmaHandle; lutSize = NV_LUT_VSS_HEADER_SIZE + SRGB_EOTF_LUT_NUM_ENTRIES; isLutModeVss = TRUE; break; - case NVKMS_INPUT_COLORSPACE_REC709_LINEAR: + case NVKMS_INPUT_COLORSPACE_BT2020: + // if bit depth is < 12, ELUT/OLUT are exactly same as BT709. + // TODO: Add a check for bit depth and use BT709 only if it is < 12. + ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_BT709]->surfaceDesc.ctxDmaHandle; + lutSize = NV_LUT_VSS_HEADER_SIZE + BT709_EOTF_LUT_NUM_ENTRIES; + isLutModeVss = TRUE; + break; + case NVKMS_INPUT_COLORSPACE_BT709_LINEAR: default: // XXX HDR TODO: Handle other colorspaces ctxDma = pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_IDENTITY]->surfaceDesc.ctxDmaHandle; lutSize = NV_LUT_VSS_HEADER_SIZE + NV_NUM_EVO_LUT_ENTRIES; @@ -5401,7 +5702,7 @@ void nvSetupOutputLUT5(NVDevEvoPtr pDevEvo, /* Use the default OLUT if the client didn't provide one */ *pSurfaceDesc = &pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_IDENTITY]->surfaceDesc; - // Choose the appropriate OLUT based on NvKmsOutputColorSpace. + // Choose the appropriate OLUT based on NvKmsOutputColorimetry. for (sd = 0; sd < pDevEvo->numSubDevices; sd++) { if (pHeadState->hdr.outputState == NVKMS_HDR_OUTPUT_STATE_HDR) { // XXX HDR TODO: Support other transfer functions @@ -5417,13 +5718,24 @@ void nvSetupOutputLUT5(NVDevEvoPtr pDevEvo, * XXX HDR TODO: Assumes input is in this range, SDR is not. */ *fpNormScale = 0xFFFFFFFF / 125; - } else if (pHeadState->outputColorSpace == NVKMS_OUTPUT_COLORSPACE_SRGB) { + } else if (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_SRGB) { *isLutModeVss = TRUE; *lutSize = SRGB_OETF_LUT_NUM_ENTRIES; *pSurfaceDesc = &pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_SRGB]->surfaceDesc; // 0xFFFFFFFF / (100.0 / 80.0) which assumes a standard SDR luminance range. *fpNormScale = 0xcccccccc; + } else if ((pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT601) || + (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT709) || + (pHeadState->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2020)) { + // BT601, BT709 and BT2020 ( for bit depth < 12) uses exactly same + // OETF curve as BT709. + // TODO: Add a check for bit depth also for BT2020 case + *isLutModeVss = TRUE; + *lutSize = BT709_OETF_LUT_NUM_ENTRIES; + *pSurfaceDesc = &pDevEvo->lut.gammaLUTs[NVKMS_GAMMA_LUT_BT709]->surfaceDesc; + // For SDR fp Norm scale value is 0xFFFFFFFF + *fpNormScale = 0xFFFFFFFF; } else { // If no output color space specified, or if the specified // color space is NONE, use Identity OLUT. @@ -5473,7 +5785,7 @@ static void EvoSetLUTContextDmaC5(const NVDispEvoRec *pDispEvo, // XXX HDR TODO: Enable custom output LUTs with HDR if ((pHeadState->hdr.outputState == NVKMS_HDR_OUTPUT_STATE_HDR) || - (pHeadState->outputColorSpace != NVKMS_OUTPUT_COLORSPACE_NONE)) { + (pHeadState->colorimetry != NVKMS_OUTPUT_COLORIMETRY_DEFAULT)) { enableOutputLut = FALSE; } @@ -8243,7 +8555,7 @@ NVEvoHAL nvEvoC6 = { FALSE, /* supportsImageSharpening */ TRUE, /* supportsHDMIVRR */ FALSE, /* supportsCoreChannelSurface */ - TRUE, /* supportsHDMIFRL */ + FALSE, /* supportsHDMIFRL */ FALSE, /* supportsSetStorageMemoryLayout */ TRUE, /* supportsIndependentAcqRelSemaphore */ FALSE, /* supportsCoreLut */ diff --git a/src/nvidia-modeset/src/nvkms-flip.c b/src/nvidia-modeset/src/nvkms-flip.c index 7765fc4..37da421 100644 --- a/src/nvidia-modeset/src/nvkms-flip.c +++ b/src/nvidia-modeset/src/nvkms-flip.c @@ -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,12 @@ 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->tf.specified) { const NVDpyEvoRec *pDpyEvo = nvGetOneArbitraryDpyEvo(pApiHeadState->activeDpys, pDispEvo); @@ -156,7 +162,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 +359,7 @@ static void InitNvKmsFlipWorkArea(const NVDevEvoRec *pDevEvo, &pDispEvo->apiHeadState[apiHead]; pProposedApiHead->hdr.tf = pApiHeadState->tf; + pProposedApiHead->hdr.colorimetry = pApiHeadState->colorimetry; pProposedApiHead->hdr.colorSpace = pApiHeadState->attributes.colorSpace; pProposedApiHead->hdr.colorBpc = @@ -398,6 +405,7 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo, nvUpdateCurrentHardwareColorSpaceAndRangeEvo( pDispEvo, head, + pProposedApiHead->hdr.colorimetry, pProposedApiHead->hdr.colorSpace, pProposedApiHead->hdr.colorRange, pUpdateState); @@ -420,6 +428,8 @@ static void FlipEvoOneApiHead(NVDispEvoRec *pDispEvo, pApiHeadState->tf = pProposedApiHead->hdr.tf; + pApiHeadState->colorimetry = pProposedApiHead->hdr.colorimetry; + nvUpdateInfoFrames(pDpyEvo); } diff --git a/src/nvidia-modeset/src/nvkms-hdmi.c b/src/nvidia-modeset/src/nvkms-hdmi.c index a7acd20..b5419a3 100644 --- a/src/nvidia-modeset/src/nvkms-hdmi.c +++ b/src/nvidia-modeset/src/nvkms-hdmi.c @@ -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); diff --git a/src/nvidia-modeset/src/nvkms-hw-flip.c b/src/nvidia-modeset/src/nvkms-hw-flip.c index 1b70940..22f715d 100644 --- a/src/nvidia-modeset/src/nvkms-hw-flip.c +++ b/src/nvidia-modeset/src/nvkms-hw-flip.c @@ -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,11 @@ NvBool nvUpdateFlipEvoHwState( pFlipState->tf = pParams->tf.val; } + if (pParams->colorimetry.specified) { + pFlipState->dirty.colorimetry = TRUE; + pFlipState->colorimetry = pParams->colorimetry.val; + } + for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) { if (layer == NVKMS_MAIN_LAYER) { if (!UpdateMainLayerFlipEvoHwState(pOpenDev, pDevEvo, sd, head, @@ -1565,6 +1576,11 @@ static void UpdateHDR(NVDevEvoPtr pDevEvo, dirty = TRUE; } + if (pFlipState->dirty.colorimetry) { + pHeadState->colorimetry = pFlipState->colorimetry; + dirty = TRUE; + } + if (dirty) { // Update OCSC / OLUT nvEvoSetLUTContextDma(pDispEvo, head, updateState); diff --git a/src/nvidia-modeset/src/nvkms-modeset.c b/src/nvidia-modeset/src/nvkms-modeset.c index 2229885..0948c3e 100644 --- a/src/nvidia-modeset/src/nvkms-modeset.c +++ b/src/nvidia-modeset/src/nvkms-modeset.c @@ -312,7 +312,7 @@ GetColorSpaceAndColorRange( if (!nvChooseCurrentColorSpaceAndRangeEvo(pOneArbitraryDpyEvo, &pProposedApiHead->timings, pProposedPrimaryHead->hdmiFrlBpc, - pProposedApiHead->tf, + pProposedApiHead->colorimetry, requestedColorSpace, requestedColorRange, &pProposedApiHead->attributes.colorSpace, @@ -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,9 +1175,8 @@ AssignProposedModeSetHwState(NVDevEvoRec *pDevEvo, pProposedApiHead->lut.input.specified = FALSE; } - if (pRequestHead->outputColorSpace.specified) { - pProposedApiHead->outputColorSpace = - pRequestHead->outputColorSpace.val; + 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 @@ -2343,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, @@ -2413,6 +2423,9 @@ ApplyProposedModeSetStateOneDispFlip( } } + pDispEvo->apiHeadState[apiHead].colorimetry = + pProposedApiHead->colorimetry; + pDispEvo->apiHeadState[apiHead].viewPortPointIn = pProposedApiHead->viewPortPointIn; } @@ -2470,7 +2483,7 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate( nvEvoColorSpaceBpcToPixelDepth(pProposedApiHead->attributes.colorSpace, pProposedApiHead->attributes.colorBpc); pHeadState->audio = pProposedHead->audio; - pHeadState->outputColorSpace = pProposedApiHead->outputColorSpace; + pHeadState->colorimetry = pProposedApiHead->colorimetry; /* Update current LUT to hardware */ nvEvoSetLUTContextDma(pDispEvo, head, updateState); @@ -2487,6 +2500,7 @@ ApplyProposedModeSetHwStateOneHeadPreUpdate( /* Update hardware's current colorSpace and colorRange */ nvUpdateCurrentHardwareColorSpaceAndRangeEvo(pDispEvo, head, + pProposedApiHead->colorimetry, pProposedApiHead->attributes.colorSpace, pProposedApiHead->attributes.colorRange, updateState); @@ -2652,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) { @@ -3785,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. * diff --git a/src/nvidia-modeset/src/nvkms-rm.c b/src/nvidia-modeset/src/nvkms-rm.c index 5567ab5..602a75b 100644 --- a/src/nvidia-modeset/src/nvkms-rm.c +++ b/src/nvidia-modeset/src/nvkms-rm.c @@ -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; diff --git a/src/nvidia-modeset/src/nvkms.c b/src/nvidia-modeset/src/nvkms.c index f6afb38..2d81dbb 100644 --- a/src/nvidia-modeset/src/nvkms.c +++ b/src/nvidia-modeset/src/nvkms.c @@ -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; } @@ -3984,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. * @@ -4098,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; diff --git a/src/nvidia-modeset/srcs.mk b/src/nvidia-modeset/srcs.mk index c969965..d30b719 100644 --- a/src/nvidia-modeset/srcs.mk +++ b/src/nvidia-modeset/srcs.mk @@ -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 diff --git a/src/nvidia/generated/g_disp_objs_nvoc.c b/src/nvidia/generated/g_disp_objs_nvoc.c index 51d0107..38c7e45 100644 --- a/src/nvidia/generated/g_disp_objs_nvoc.c +++ b/src/nvidia/generated/g_disp_objs_nvoc.c @@ -2481,6 +2481,66 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm { /* [8] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSystemValidateSrm_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x73015eu, + /*paramSize=*/ sizeof(NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSystemValidateSrm" +#endif + }, + { /* [9] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSystemGetSrmStatus_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x73015fu, + /*paramSize=*/ sizeof(NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSystemGetSrmStatus" +#endif + }, + { /* [10] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSystemHdcpRevocationCheck_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730161u, + /*paramSize=*/ sizeof(NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSystemHdcpRevocationCheck" +#endif + }, + { /* [11] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSystemUpdateSrm_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730162u, + /*paramSize=*/ sizeof(NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSystemUpdateSrm" +#endif + }, + { /* [12] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, #else /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSystemGetBootDisplays_IMPL, #endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) @@ -2493,7 +2553,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemGetBootDisplays" #endif }, - { /* [9] */ + { /* [13] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x0u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2508,7 +2568,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemGetHotplugUnplugState" #endif }, - { /* [10] */ + { /* [14] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2523,7 +2583,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemArmLightweightSupervisor" #endif }, - { /* [11] */ + { /* [15] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2538,7 +2598,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemConfigVrrPstateSwitch" #endif }, - { /* [12] */ + { /* [16] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2553,7 +2613,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemQueryDisplayIdsWithMux" #endif }, - { /* [13] */ + { /* [17] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x4u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2568,7 +2628,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemAllocateDisplayBandwidth" #endif }, - { /* [14] */ + { /* [18] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2583,7 +2643,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemGetHotplugEventConfig" #endif }, - { /* [15] */ + { /* [19] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2598,7 +2658,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemSetHotplugEventConfig" #endif }, - { /* [16] */ + { /* [20] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2613,7 +2673,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSystemCheckSidebandI2cSupport" #endif }, - { /* [17] */ + { /* [21] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2628,7 +2688,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetI2cPortid" #endif }, - { /* [18] */ + { /* [22] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x206u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2643,7 +2703,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetType" #endif }, - { /* [19] */ + { /* [23] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2658,7 +2718,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificFakeDevice" #endif }, - { /* [20] */ + { /* [24] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2673,7 +2733,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetEdidV2" #endif }, - { /* [21] */ + { /* [25] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2688,7 +2748,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetEdidV2" #endif }, - { /* [22] */ + { /* [26] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2703,7 +2763,22 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetConnectorData" #endif }, - { /* [23] */ + { /* [27] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730260u, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo" +#endif + }, + { /* [28] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2718,7 +2793,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetHdmiEnable" #endif }, - { /* [24] */ + { /* [29] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2733,7 +2808,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificCtrlHdmi" #endif }, - { /* [25] */ + { /* [30] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2748,7 +2823,52 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetHdmiAudioMutestream" #endif }, - { /* [26] */ + { /* [31] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificGetHdcpState_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730280u, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificGetHdcpState" +#endif + }, + { /* [32] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificGetHdcpDiagnostics_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730281u, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificGetHdcpDiagnostics" +#endif + }, + { /* [33] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificHdcpCtrl_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x730282u, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificHdcpCtrl" +#endif + }, + { /* [34] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2763,7 +2883,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetAllHeadMask" #endif }, - { /* [27] */ + { /* [35] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2778,7 +2898,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetOdPacket" #endif }, - { /* [28] */ + { /* [36] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2793,7 +2913,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetOdPacketCtrl" #endif }, - { /* [29] */ + { /* [37] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2808,7 +2928,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetPclkLimit" #endif }, - { /* [30] */ + { /* [38] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x206u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2823,7 +2943,37 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificOrGetInfo" #endif }, - { /* [31] */ + { /* [39] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificHdcpKsvListValidate_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x73028du, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificHdcpKsvListValidate" +#endif + }, + { /* [40] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdSpecificHdcpUpdate_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x73028eu, + /*paramSize=*/ sizeof(NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdSpecificHdcpUpdate" +#endif + }, + { /* [41] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2838,7 +2988,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetHdmiSinkCaps" #endif }, - { /* [32] */ + { /* [42] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2853,7 +3003,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetMonitorPower" #endif }, - { /* [33] */ + { /* [43] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2868,7 +3018,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetHdmiFrlLinkConfig" #endif }, - { /* [34] */ + { /* [44] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2883,7 +3033,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetRegionalCrcs" #endif }, - { /* [35] */ + { /* [45] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2898,7 +3048,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificApplyEdidOverrideV2" #endif }, - { /* [36] */ + { /* [46] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2913,7 +3063,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetHdmiGpuCaps" #endif }, - { /* [37] */ + { /* [47] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2928,7 +3078,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetHdmiScdcData" #endif }, - { /* [38] */ + { /* [48] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2943,7 +3093,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificIsDirectmodeDisplay" #endif }, - { /* [39] */ + { /* [49] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2958,7 +3108,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetHdmiFrlCapacityComputation" #endif }, - { /* [40] */ + { /* [50] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2973,7 +3123,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificSetSharedGenericPacket" #endif }, - { /* [41] */ + { /* [51] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -2988,7 +3138,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificAcquireSharedGenericPacket" #endif }, - { /* [42] */ + { /* [52] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3003,7 +3153,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificReleaseSharedGenericPacket" #endif }, - { /* [43] */ + { /* [53] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3018,7 +3168,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificDispI2cReadWrite" #endif }, - { /* [44] */ + { /* [54] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3033,7 +3183,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificGetValidHeadWindowAssignment" #endif }, - { /* [45] */ + { /* [55] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3048,7 +3198,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdSpecificDefaultAdaptivesyncDisplay" #endif }, - { /* [46] */ + { /* [56] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x600u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3063,7 +3213,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdInternalGetHotplugUnplugState" #endif }, - { /* [47] */ + { /* [57] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x212u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3078,7 +3228,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpGetInfo" #endif }, - { /* [48] */ + { /* [58] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3093,7 +3243,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpGetDisplayportDongleInfo" #endif }, - { /* [49] */ + { /* [59] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3108,7 +3258,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpSetEldAudioCaps" #endif }, - { /* [50] */ + { /* [60] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3123,7 +3273,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpUpdateDynamicDfpCache" #endif }, - { /* [51] */ + { /* [61] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3138,7 +3288,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpSetAudioEnable" #endif }, - { /* [52] */ + { /* [62] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3153,7 +3303,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpAssignSor" #endif }, - { /* [53] */ + { /* [63] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3168,7 +3318,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpGetPadlinkMask" #endif }, - { /* [54] */ + { /* [64] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3183,7 +3333,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpConfigTwoHeadOneOr" #endif }, - { /* [55] */ + { /* [65] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3198,7 +3348,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpDscCrcControl" #endif }, - { /* [56] */ + { /* [66] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x200u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3213,7 +3363,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpInitMuxData" #endif }, - { /* [57] */ + { /* [67] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3228,7 +3378,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpGetDsiModeTiming" #endif }, - { /* [58] */ + { /* [68] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x206u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3243,7 +3393,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDfpGetFixedModeTiming" #endif }, - { /* [59] */ + { /* [69] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x8204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3258,7 +3408,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpAuxchCtrl" #endif }, - { /* [60] */ + { /* [70] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3273,7 +3423,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpAuxchSetSema" #endif }, - { /* [61] */ + { /* [71] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x8204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3288,7 +3438,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpCtrl" #endif }, - { /* [62] */ + { /* [72] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3303,7 +3453,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetLaneData" #endif }, - { /* [63] */ + { /* [73] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3318,7 +3468,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetLaneData" #endif }, - { /* [64] */ + { /* [74] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3333,7 +3483,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetTestpattern" #endif }, - { /* [65] */ + { /* [75] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3348,7 +3498,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetPreemphasisDrivecurrentPostcursor2Data" #endif }, - { /* [66] */ + { /* [76] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3363,7 +3513,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data" #endif }, - { /* [67] */ + { /* [77] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3378,7 +3528,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpMainLinkCtrl" #endif }, - { /* [68] */ + { /* [78] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3393,7 +3543,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetAudioMuteStream" #endif }, - { /* [69] */ + { /* [79] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3408,7 +3558,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpTopologyAllocateDisplayId" #endif }, - { /* [70] */ + { /* [80] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3423,7 +3573,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpTopologyFreeDisplayId" #endif }, - { /* [71] */ + { /* [81] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3438,7 +3588,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetLinkConfig" #endif }, - { /* [72] */ + { /* [82] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3453,7 +3603,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetEDPData" #endif }, - { /* [73] */ + { /* [83] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3468,7 +3618,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigStream" #endif }, - { /* [74] */ + { /* [84] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3483,7 +3633,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetRateGov" #endif }, - { /* [75] */ + { /* [85] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3498,7 +3648,22 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetManualDisplayPort" #endif }, - { /* [76] */ + { /* [86] */ +#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*pFunc=*/ (void (*)(void)) NULL, +#else + /*pFunc=*/ (void (*)(void)) dispcmnCtrlCmdDpSetEcf_IMPL, +#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + /*flags=*/ 0x204u, + /*accessRight=*/0x0u, + /*methodId=*/ 0x731366u, + /*paramSize=*/ sizeof(NV0073_CTRL_CMD_DP_SET_ECF_PARAMS), + /*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo), +#if NV_PRINTF_STRINGS_ALLOWED + /*func=*/ "dispcmnCtrlCmdDpSetEcf" +#endif + }, + { /* [87] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3513,7 +3678,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSendACT" #endif }, - { /* [77] */ + { /* [88] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x206u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3528,7 +3693,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetCaps" #endif }, - { /* [78] */ + { /* [89] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x4u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3543,7 +3708,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGenerateFakeInterrupt" #endif }, - { /* [79] */ + { /* [90] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3558,7 +3723,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigRadScratchReg" #endif }, - { /* [80] */ + { /* [91] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3573,7 +3738,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigSingleHeadMultiStream" #endif }, - { /* [81] */ + { /* [92] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3588,7 +3753,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetTriggerSelect" #endif }, - { /* [82] */ + { /* [93] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3603,7 +3768,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetTriggerAll" #endif }, - { /* [83] */ + { /* [94] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3618,7 +3783,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetAuxLogData" #endif }, - { /* [84] */ + { /* [95] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3633,7 +3798,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigIndexedLinkRates" #endif }, - { /* [85] */ + { /* [96] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3648,7 +3813,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpSetStereoMSAProperties" #endif }, - { /* [86] */ + { /* [97] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3663,7 +3828,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigureFec" #endif }, - { /* [87] */ + { /* [98] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3678,7 +3843,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpConfigMacroPad" #endif }, - { /* [88] */ + { /* [99] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3693,7 +3858,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetGenericInfoframe" #endif }, - { /* [89] */ + { /* [100] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3708,7 +3873,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm /*func=*/ "dispcmnCtrlCmdDpGetMsaAttributes" #endif }, - { /* [90] */ + { /* [101] */ #if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) /*pFunc=*/ (void (*)(void)) NULL, #else @@ -3728,7 +3893,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm const struct NVOC_EXPORT_INFO __nvoc_export_info_DispCommon = { - /*numEntries=*/ 91, + /*numEntries=*/ 102, /*pExportEntries=*/ __nvoc_exported_method_def_DispCommon }; @@ -3764,6 +3929,46 @@ __nvoc_ctor_DispCommon_exit: static void __nvoc_init_funcTable_DispCommon_1(DispCommon *pThis) { PORT_UNREFERENCED_VARIABLE(pThis); +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificGetHdcpState__ = &dispcmnCtrlCmdSpecificGetHdcpState_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificHdcpCtrl__ = &dispcmnCtrlCmdSpecificHdcpCtrl_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo__ = &dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificGetHdcpDiagnostics__ = &dispcmnCtrlCmdSpecificGetHdcpDiagnostics_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificHdcpKsvListValidate__ = &dispcmnCtrlCmdSpecificHdcpKsvListValidate_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSpecificHdcpUpdate__ = &dispcmnCtrlCmdSpecificHdcpUpdate_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSystemValidateSrm__ = &dispcmnCtrlCmdSystemValidateSrm_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSystemGetSrmStatus__ = &dispcmnCtrlCmdSystemGetSrmStatus_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSystemHdcpRevocationCheck__ = &dispcmnCtrlCmdSystemHdcpRevocationCheck_IMPL; +#endif + +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdSystemUpdateSrm__ = &dispcmnCtrlCmdSystemUpdateSrm_IMPL; +#endif + #if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u) pThis->__dispcmnCtrlCmdSystemGetCapsV2__ = &dispcmnCtrlCmdSystemGetCapsV2_IMPL; #endif @@ -4124,6 +4329,10 @@ static void __nvoc_init_funcTable_DispCommon_1(DispCommon *pThis) { pThis->__dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data__ = &dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data_IMPL; #endif +#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) + pThis->__dispcmnCtrlCmdDpSetEcf__ = &dispcmnCtrlCmdDpSetEcf_IMPL; +#endif + #if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x204u) pThis->__dispcmnCtrlCmdSpecificGetRegionalCrcs__ = &dispcmnCtrlCmdSpecificGetRegionalCrcs_IMPL; #endif diff --git a/src/nvidia/generated/g_disp_objs_nvoc.h b/src/nvidia/generated/g_disp_objs_nvoc.h index ebccb4a..d7b3476 100644 --- a/src/nvidia/generated/g_disp_objs_nvoc.h +++ b/src/nvidia/generated/g_disp_objs_nvoc.h @@ -7,7 +7,7 @@ extern "C" { #endif /* - * 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 @@ -59,6 +59,9 @@ extern "C" { #define DISPLAY_PRIVILEGED PRIVILEGED #include "ctrl/ctrl0073.h" +#include "ctrl/ctrl0073/ctrl0073system.h" +#include "ctrl/ctrl0073/ctrl0073dp.h" +#include "ctrl/ctrl0073/ctrl0073specific.h" #include "ctrl/ctrl5070/ctrl5070event.h" #include "ctrl/ctrl5070/ctrl5070or.h" #include "ctrl/ctrl5070/ctrl5070seq.h" @@ -1301,6 +1304,16 @@ struct DispCommon { struct Notifier *__nvoc_pbase_Notifier; struct DisplayApi *__nvoc_pbase_DisplayApi; struct DispCommon *__nvoc_pbase_DispCommon; + NV_STATUS (*__dispcmnCtrlCmdSpecificGetHdcpState__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSpecificHdcpCtrl__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSpecificGetHdcpDiagnostics__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSpecificHdcpKsvListValidate__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSpecificHdcpUpdate__)(struct DispCommon *, NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSystemValidateSrm__)(struct DispCommon *, NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSystemGetSrmStatus__)(struct DispCommon *, NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSystemHdcpRevocationCheck__)(struct DispCommon *, NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdSystemUpdateSrm__)(struct DispCommon *, NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdSystemGetCapsV2__)(struct DispCommon *, NV0073_CTRL_SYSTEM_GET_CAPS_V2_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdSystemGetNumHeads__)(struct DispCommon *, NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdSystemGetScanline__)(struct DispCommon *, NV0073_CTRL_SYSTEM_GET_SCANLINE_PARAMS *); @@ -1391,6 +1404,7 @@ struct DispCommon { NV_STATUS (*__dispcmnCtrlCmdDpConfigMacroPad__)(struct DispCommon *, NV0073_CTRL_CMD_DP_CONFIG_MACRO_PAD_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdDpSetPreemphasisDrivecurrentPostcursor2Data__)(struct DispCommon *, NV0073_CTRL_DP_SET_PREEMPHASIS_DRIVECURRENT_POSTCURSOR2_DATA_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data__)(struct DispCommon *, NV0073_CTRL_DP_GET_PREEMPHASIS_DRIVECURRENT_POSTCURSOR2_DATA_PARAMS *); + NV_STATUS (*__dispcmnCtrlCmdDpSetEcf__)(struct DispCommon *, NV0073_CTRL_CMD_DP_SET_ECF_PARAMS *); NV_STATUS (*__dispcmnCtrlCmdSpecificGetRegionalCrcs__)(struct DispCommon *, NV0073_CTRL_CMD_SPECIFIC_GET_REGIONAL_CRCS_PARAMS *); NvBool (*__dispcmnShareCallback__)(struct DispCommon *, struct RsClient *, struct RsResourceRef *, RS_SHARE_POLICY *); NV_STATUS (*__dispcmnCheckMemInterUnmap__)(struct DispCommon *, NvBool); @@ -1450,6 +1464,16 @@ NV_STATUS __nvoc_objCreate_DispCommon(DispCommon**, Dynamic*, NvU32, struct CALL #define __objCreate_DispCommon(ppNewObj, pParent, createFlags, arg_pCallContext, arg_pParams) \ __nvoc_objCreate_DispCommon((ppNewObj), staticCast((pParent), Dynamic), (createFlags), arg_pCallContext, arg_pParams) +#define dispcmnCtrlCmdSpecificGetHdcpState(pDispCommon, pParams) dispcmnCtrlCmdSpecificGetHdcpState_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSpecificHdcpCtrl(pDispCommon, pParams) dispcmnCtrlCmdSpecificHdcpCtrl_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo(pDispCommon, pParams) dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSpecificGetHdcpDiagnostics(pDispCommon, pParams) dispcmnCtrlCmdSpecificGetHdcpDiagnostics_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSpecificHdcpKsvListValidate(pDispCommon, pKsvListValidateParams) dispcmnCtrlCmdSpecificHdcpKsvListValidate_DISPATCH(pDispCommon, pKsvListValidateParams) +#define dispcmnCtrlCmdSpecificHdcpUpdate(pDispCommon, pHdcpUpdateParams) dispcmnCtrlCmdSpecificHdcpUpdate_DISPATCH(pDispCommon, pHdcpUpdateParams) +#define dispcmnCtrlCmdSystemValidateSrm(pDispCommon, pParams) dispcmnCtrlCmdSystemValidateSrm_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSystemGetSrmStatus(pDispCommon, pParams) dispcmnCtrlCmdSystemGetSrmStatus_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSystemHdcpRevocationCheck(pDispCommon, pParams) dispcmnCtrlCmdSystemHdcpRevocationCheck_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdSystemUpdateSrm(pDispCommon, pParams) dispcmnCtrlCmdSystemUpdateSrm_DISPATCH(pDispCommon, pParams) #define dispcmnCtrlCmdSystemGetCapsV2(pDispCommon, pCapsParams) dispcmnCtrlCmdSystemGetCapsV2_DISPATCH(pDispCommon, pCapsParams) #define dispcmnCtrlCmdSystemGetNumHeads(pDispCommon, pNumHeadsParams) dispcmnCtrlCmdSystemGetNumHeads_DISPATCH(pDispCommon, pNumHeadsParams) #define dispcmnCtrlCmdSystemGetScanline(pDispCommon, pScanlineParams) dispcmnCtrlCmdSystemGetScanline_DISPATCH(pDispCommon, pScanlineParams) @@ -1540,6 +1564,7 @@ NV_STATUS __nvoc_objCreate_DispCommon(DispCommon**, Dynamic*, NvU32, struct CALL #define dispcmnCtrlCmdDpConfigMacroPad(pDispCommon, pParams) dispcmnCtrlCmdDpConfigMacroPad_DISPATCH(pDispCommon, pParams) #define dispcmnCtrlCmdDpSetPreemphasisDrivecurrentPostcursor2Data(pDispCommon, pParams) dispcmnCtrlCmdDpSetPreemphasisDrivecurrentPostcursor2Data_DISPATCH(pDispCommon, pParams) #define dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data(pDispCommon, pParams) dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data_DISPATCH(pDispCommon, pParams) +#define dispcmnCtrlCmdDpSetEcf(pDispCommon, pCtrlEcfParams) dispcmnCtrlCmdDpSetEcf_DISPATCH(pDispCommon, pCtrlEcfParams) #define dispcmnCtrlCmdSpecificGetRegionalCrcs(pDispCommon, pParams) dispcmnCtrlCmdSpecificGetRegionalCrcs_DISPATCH(pDispCommon, pParams) #define dispcmnShareCallback(pResource, pInvokingClient, pParentRef, pSharePolicy) dispcmnShareCallback_DISPATCH(pResource, pInvokingClient, pParentRef, pSharePolicy) #define dispcmnCheckMemInterUnmap(pRmResource, bSubdeviceHandleProvided) dispcmnCheckMemInterUnmap_DISPATCH(pRmResource, bSubdeviceHandleProvided) @@ -1567,6 +1592,66 @@ NV_STATUS __nvoc_objCreate_DispCommon(DispCommon**, Dynamic*, NvU32, struct CALL #define dispcmnGetNotificationShare(pNotifier) dispcmnGetNotificationShare_DISPATCH(pNotifier) #define dispcmnMap(pResource, pCallContext, pParams, pCpuMapping) dispcmnMap_DISPATCH(pResource, pCallContext, pParams, pCpuMapping) #define dispcmnGetOrAllocNotifShare(pNotifier, hNotifierClient, hNotifierResource, ppNotifShare) dispcmnGetOrAllocNotifShare_DISPATCH(pNotifier, hNotifierClient, hNotifierResource, ppNotifShare) +NV_STATUS dispcmnCtrlCmdSpecificGetHdcpState_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificGetHdcpState_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_STATE_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificGetHdcpState__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSpecificHdcpCtrl_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificHdcpCtrl_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_CTRL_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificHdcpCtrl__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_REPEATER_INFO_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificGetHdcpRepeaterInfo__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSpecificGetHdcpDiagnostics_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificGetHdcpDiagnostics_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_GET_HDCP_DIAGNOSTICS_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificGetHdcpDiagnostics__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSpecificHdcpKsvListValidate_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS *pKsvListValidateParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificHdcpKsvListValidate_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_KSVLIST_VALIDATE_PARAMS *pKsvListValidateParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificHdcpKsvListValidate__(pDispCommon, pKsvListValidateParams); +} + +NV_STATUS dispcmnCtrlCmdSpecificHdcpUpdate_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS *pHdcpUpdateParams); + +static inline NV_STATUS dispcmnCtrlCmdSpecificHdcpUpdate_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SPECIFIC_HDCP_UPDATE_PARAMS *pHdcpUpdateParams) { + return pDispCommon->__dispcmnCtrlCmdSpecificHdcpUpdate__(pDispCommon, pHdcpUpdateParams); +} + +NV_STATUS dispcmnCtrlCmdSystemValidateSrm_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSystemValidateSrm_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_VALIDATE_SRM_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSystemValidateSrm__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSystemGetSrmStatus_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSystemGetSrmStatus_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_GET_SRM_STATUS_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSystemGetSrmStatus__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSystemHdcpRevocationCheck_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSystemHdcpRevocationCheck_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_HDCP_REVOCATE_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSystemHdcpRevocationCheck__(pDispCommon, pParams); +} + +NV_STATUS dispcmnCtrlCmdSystemUpdateSrm_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS *pParams); + +static inline NV_STATUS dispcmnCtrlCmdSystemUpdateSrm_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_UPDATE_SRM_PARAMS *pParams) { + return pDispCommon->__dispcmnCtrlCmdSystemUpdateSrm__(pDispCommon, pParams); +} + NV_STATUS dispcmnCtrlCmdSystemGetCapsV2_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_GET_CAPS_V2_PARAMS *pCapsParams); static inline NV_STATUS dispcmnCtrlCmdSystemGetCapsV2_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_SYSTEM_GET_CAPS_V2_PARAMS *pCapsParams) { @@ -2107,6 +2192,12 @@ static inline NV_STATUS dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Dat return pDispCommon->__dispcmnCtrlCmdDpGetPreemphasisDrivecurrentPostcursor2Data__(pDispCommon, pParams); } +NV_STATUS dispcmnCtrlCmdDpSetEcf_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_SET_ECF_PARAMS *pCtrlEcfParams); + +static inline NV_STATUS dispcmnCtrlCmdDpSetEcf_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_SET_ECF_PARAMS *pCtrlEcfParams) { + return pDispCommon->__dispcmnCtrlCmdDpSetEcf__(pDispCommon, pCtrlEcfParams); +} + NV_STATUS dispcmnCtrlCmdSpecificGetRegionalCrcs_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_SPECIFIC_GET_REGIONAL_CRCS_PARAMS *pParams); static inline NV_STATUS dispcmnCtrlCmdSpecificGetRegionalCrcs_DISPATCH(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_SPECIFIC_GET_REGIONAL_CRCS_PARAMS *pParams) { diff --git a/src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c b/src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c index 0fe8712..1b7c03f 100644 --- a/src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c +++ b/src/nvidia/src/kernel/gpu/dce_client/dce_client_rpc.c @@ -334,8 +334,8 @@ void dceclientHandleAsyncRpcCallback NV_STATUS nvStatus = NV_OK; // Get the notification list that contains this event. - NV_ASSERT(CliGetEventInfo(rpc_params->hClient, - rpc_params->hEvent, &pEvent)); + NV_CHECK_OR_RETURN_VOID(LEVEL_ERROR, CliGetEventInfo(rpc_params->hClient, + rpc_params->hEvent, &pEvent)); if (pEvent->pNotifierShare != NULL) pNotifyList = pEvent->pNotifierShare->pEventList;